2015-06-18 23:04:41 +00:00
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
//
|
|
|
|
// Copyright 2015 Realm Inc.
|
|
|
|
//
|
|
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
// you may not use this file except in compliance with the License.
|
|
|
|
// You may obtain a copy of the License at
|
|
|
|
//
|
|
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
//
|
|
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
// See the License for the specific language governing permissions and
|
|
|
|
// limitations under the License.
|
|
|
|
//
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
#ifndef REALM_REALM_HPP
|
|
|
|
#define REALM_REALM_HPP
|
|
|
|
|
2015-08-25 23:39:32 +00:00
|
|
|
#include <map>
|
2015-06-18 23:04:41 +00:00
|
|
|
#include <memory>
|
|
|
|
#include <thread>
|
|
|
|
#include <vector>
|
2015-07-27 19:42:55 +00:00
|
|
|
|
2015-06-18 23:04:41 +00:00
|
|
|
#include "object_store.hpp"
|
|
|
|
|
|
|
|
namespace realm {
|
2015-08-26 23:11:45 +00:00
|
|
|
class ClientHistory;
|
2015-06-18 23:04:41 +00:00
|
|
|
class Realm;
|
2015-08-26 23:11:45 +00:00
|
|
|
class RealmCache;
|
2015-11-03 07:37:54 +00:00
|
|
|
class BindingContext;
|
2015-06-18 23:04:41 +00:00
|
|
|
typedef std::shared_ptr<Realm> SharedRealm;
|
|
|
|
typedef std::weak_ptr<Realm> WeakRealm;
|
|
|
|
|
2015-09-15 14:25:16 +00:00
|
|
|
namespace _impl {
|
|
|
|
class ExternalCommitHelper;
|
|
|
|
}
|
|
|
|
|
2015-07-27 19:42:55 +00:00
|
|
|
class Realm : public std::enable_shared_from_this<Realm>
|
2015-06-18 23:04:41 +00:00
|
|
|
{
|
|
|
|
public:
|
2015-07-27 19:42:55 +00:00
|
|
|
typedef std::function<void(SharedRealm old_realm, SharedRealm realm)> MigrationFunction;
|
|
|
|
|
2015-06-18 23:04:41 +00:00
|
|
|
struct Config
|
|
|
|
{
|
|
|
|
std::string path;
|
2015-08-24 20:12:49 +00:00
|
|
|
bool read_only = false;
|
|
|
|
bool in_memory = false;
|
2015-08-26 18:32:13 +00:00
|
|
|
bool cache = true;
|
2015-08-25 23:39:32 +00:00
|
|
|
std::vector<char> encryption_key;
|
2015-06-18 23:04:41 +00:00
|
|
|
|
2015-07-27 19:42:55 +00:00
|
|
|
std::unique_ptr<Schema> schema;
|
2015-08-24 20:12:49 +00:00
|
|
|
uint64_t schema_version = ObjectStore::NotVersioned;
|
2015-06-18 23:04:41 +00:00
|
|
|
|
2015-07-27 19:42:55 +00:00
|
|
|
MigrationFunction migration_function;
|
|
|
|
|
2015-08-24 20:12:49 +00:00
|
|
|
Config() = default;
|
|
|
|
Config(Config&&) = default;
|
2015-06-18 23:04:41 +00:00
|
|
|
Config(const Config& c);
|
2015-09-04 21:03:58 +00:00
|
|
|
~Config();
|
2015-08-25 23:39:32 +00:00
|
|
|
|
|
|
|
Config& operator=(Config const&);
|
|
|
|
Config& operator=(Config&&) = default;
|
2015-06-18 23:04:41 +00:00
|
|
|
};
|
|
|
|
|
2015-06-22 17:32:31 +00:00
|
|
|
// Get a cached Realm or create a new one if no cached copies exists
|
2015-08-25 23:39:32 +00:00
|
|
|
// Caching is done by path - mismatches for in_memory and read_only
|
|
|
|
// Config properties will raise an exception
|
|
|
|
// If schema/schema_version is specified, update_schema is called
|
|
|
|
// automatically on the realm and a migration is performed. If not
|
|
|
|
// specified, the schema version and schema are dynamically read from
|
|
|
|
// the the existing Realm.
|
|
|
|
static SharedRealm get_shared_realm(Config config);
|
|
|
|
|
|
|
|
// Updates a Realm to a given target schema/version creating tables and
|
|
|
|
// updating indexes as necessary. Uses the existing migration function
|
|
|
|
// on the Config, and the resulting Schema and version with updated
|
2015-06-22 17:32:31 +00:00
|
|
|
// column mappings are set on the realms config upon success.
|
|
|
|
// returns if any changes were made
|
2015-09-03 17:37:24 +00:00
|
|
|
bool update_schema(std::unique_ptr<Schema> schema, uint64_t version);
|
2015-06-22 17:32:31 +00:00
|
|
|
|
2015-08-27 18:38:30 +00:00
|
|
|
static uint64_t get_schema_version(Config const& config);
|
|
|
|
|
2015-06-18 23:04:41 +00:00
|
|
|
const Config &config() const { return m_config; }
|
|
|
|
|
|
|
|
void begin_transaction();
|
|
|
|
void commit_transaction();
|
|
|
|
void cancel_transaction();
|
2015-09-04 16:40:29 +00:00
|
|
|
bool is_in_transaction() const { return m_in_transaction; }
|
2015-06-18 23:04:41 +00:00
|
|
|
|
|
|
|
bool refresh();
|
|
|
|
void set_auto_refresh(bool auto_refresh) { m_auto_refresh = auto_refresh; }
|
2015-09-04 16:40:29 +00:00
|
|
|
bool auto_refresh() const { return m_auto_refresh; }
|
2015-06-18 23:04:41 +00:00
|
|
|
void notify();
|
|
|
|
|
|
|
|
void invalidate();
|
|
|
|
bool compact();
|
|
|
|
|
|
|
|
std::thread::id thread_id() const { return m_thread_id; }
|
2015-09-04 16:40:29 +00:00
|
|
|
void verify_thread() const;
|
2015-06-18 23:04:41 +00:00
|
|
|
|
2015-08-01 22:31:45 +00:00
|
|
|
// Close this Realm and remove it from the cache. Continuing to use a
|
|
|
|
// Realm after closing it will produce undefined behavior.
|
|
|
|
void close();
|
|
|
|
|
2015-09-04 00:59:20 +00:00
|
|
|
~Realm();
|
|
|
|
|
2015-06-18 23:04:41 +00:00
|
|
|
private:
|
2015-08-25 23:39:32 +00:00
|
|
|
Realm(Config config);
|
2015-06-22 17:32:31 +00:00
|
|
|
|
2015-06-18 23:04:41 +00:00
|
|
|
Config m_config;
|
2015-08-24 20:16:31 +00:00
|
|
|
std::thread::id m_thread_id = std::this_thread::get_id();
|
|
|
|
bool m_in_transaction = false;
|
|
|
|
bool m_auto_refresh = true;
|
2015-06-18 23:04:41 +00:00
|
|
|
|
2015-07-20 18:53:21 +00:00
|
|
|
std::unique_ptr<ClientHistory> m_history;
|
2015-06-18 23:04:41 +00:00
|
|
|
std::unique_ptr<SharedGroup> m_shared_group;
|
|
|
|
std::unique_ptr<Group> m_read_only_group;
|
|
|
|
|
2015-08-24 20:16:31 +00:00
|
|
|
Group *m_group = nullptr;
|
2015-06-18 23:04:41 +00:00
|
|
|
|
2015-09-15 14:25:16 +00:00
|
|
|
std::shared_ptr<_impl::ExternalCommitHelper> m_notifier;
|
2015-09-03 00:53:21 +00:00
|
|
|
|
2015-07-27 19:42:55 +00:00
|
|
|
public:
|
2015-11-03 07:37:54 +00:00
|
|
|
std::unique_ptr<BindingContext> m_binding_context;
|
2015-06-18 23:04:41 +00:00
|
|
|
|
2015-07-27 19:42:55 +00:00
|
|
|
// FIXME private
|
|
|
|
Group *read_group();
|
2015-08-12 19:02:56 +00:00
|
|
|
static RealmCache s_global_cache;
|
2015-06-18 23:04:41 +00:00
|
|
|
};
|
|
|
|
|
2015-07-27 19:42:55 +00:00
|
|
|
class RealmCache
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
SharedRealm get_realm(const std::string &path, std::thread::id thread_id = std::this_thread::get_id());
|
|
|
|
SharedRealm get_any_realm(const std::string &path);
|
|
|
|
void remove(const std::string &path, std::thread::id thread_id);
|
|
|
|
void cache_realm(SharedRealm &realm, std::thread::id thread_id = std::this_thread::get_id());
|
2015-08-12 19:02:56 +00:00
|
|
|
void clear();
|
2015-07-27 19:42:55 +00:00
|
|
|
|
|
|
|
private:
|
|
|
|
std::map<std::string, std::map<std::thread::id, WeakRealm>> m_cache;
|
|
|
|
std::mutex m_mutex;
|
|
|
|
};
|
|
|
|
|
|
|
|
class RealmFileException : public std::runtime_error
|
2015-06-18 23:04:41 +00:00
|
|
|
{
|
|
|
|
public:
|
|
|
|
enum class Kind
|
|
|
|
{
|
|
|
|
/** Thrown for any I/O related exception scenarios when a realm is opened. */
|
2015-07-27 19:42:55 +00:00
|
|
|
AccessError,
|
2015-06-18 23:04:41 +00:00
|
|
|
/** Thrown if the user does not have permission to open or create
|
|
|
|
the specified file in the specified access mode when the realm is opened. */
|
2015-07-27 19:42:55 +00:00
|
|
|
PermissionDenied,
|
2015-11-04 01:00:06 +00:00
|
|
|
/** Thrown if create_Always was specified and the file did already exist when the realm is opened. */
|
2015-07-27 19:42:55 +00:00
|
|
|
Exists,
|
2015-06-18 23:04:41 +00:00
|
|
|
/** Thrown if no_create was specified and the file was not found when the realm is opened. */
|
2015-07-27 19:42:55 +00:00
|
|
|
NotFound,
|
2015-06-18 23:04:41 +00:00
|
|
|
/** Thrown if the database file is currently open in another
|
|
|
|
process which cannot share with the current process due to an
|
|
|
|
architecture mismatch. */
|
|
|
|
IncompatibleLockFile,
|
|
|
|
};
|
2015-11-04 01:00:06 +00:00
|
|
|
RealmFileException(Kind kind, std::string path, std::string message) :
|
|
|
|
std::runtime_error(std::move(message)), m_kind(kind), m_path(std::move(path)) {}
|
2015-06-18 23:04:41 +00:00
|
|
|
Kind kind() const { return m_kind; }
|
2015-11-04 01:00:06 +00:00
|
|
|
const std::string& path() const { return m_path; }
|
2015-06-18 23:04:41 +00:00
|
|
|
|
|
|
|
private:
|
|
|
|
Kind m_kind;
|
2015-11-04 01:00:06 +00:00
|
|
|
std::string m_path;
|
2015-06-18 23:04:41 +00:00
|
|
|
};
|
|
|
|
|
2015-07-27 19:42:55 +00:00
|
|
|
class MismatchedConfigException : public std::runtime_error
|
2015-06-18 23:04:41 +00:00
|
|
|
{
|
|
|
|
public:
|
2015-07-27 19:42:55 +00:00
|
|
|
MismatchedConfigException(std::string message) : std::runtime_error(message) {}
|
|
|
|
};
|
2015-06-18 23:04:41 +00:00
|
|
|
|
2015-07-27 19:42:55 +00:00
|
|
|
class InvalidTransactionException : public std::runtime_error
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
InvalidTransactionException(std::string message) : std::runtime_error(message) {}
|
|
|
|
};
|
|
|
|
|
|
|
|
class IncorrectThreadException : public std::runtime_error
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
IncorrectThreadException(std::string message) : std::runtime_error(message) {}
|
2015-06-18 23:04:41 +00:00
|
|
|
};
|
2015-07-28 18:25:04 +00:00
|
|
|
|
|
|
|
class UnitializedRealmException : public std::runtime_error
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
UnitializedRealmException(std::string message) : std::runtime_error(message) {}
|
|
|
|
};
|
2015-11-16 19:16:09 +00:00
|
|
|
|
|
|
|
class ClosedRealmException : public std::runtime_error
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
ClosedRealmException(std::string message) : std::runtime_error(message) {}
|
|
|
|
};
|
2015-06-18 23:04:41 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#endif /* defined(REALM_REALM_HPP) */
|