Esempio n. 1
0
        public ForestDBViewStore(ForestDBCouchStore dbStorage, string name, bool create)
        {
            Debug.Assert(dbStorage != null);
            Debug.Assert(name != null);
            _dbStorage = dbStorage;
            Name       = name;

            _path = Path.Combine(_dbStorage.Directory, ViewNameToFilename(name));
            if (!File.Exists(_path))
            {
                if (!create)
                {
                    throw new InvalidOperationException(String.Format(
                                                            "Create is false but no db file exists at {0}", _path));
                }

                OpenIndexWithOptions(C4DatabaseFlags.Create, true);
            }
        }
        internal void Open()
        {
            if (_isOpen) {
                return;
            }

            Log.D(TAG, "Opening {0}", Name);

            // Instantiate storage:
            string storageType = Manager.StorageType ?? "SQLite";
            #if !FORESTDB
            #if NOSQLITE
            #error No storage engine compilation options selected
            #endif
            if(storageType == "ForestDB") {
                throw new ApplicationException("ForestDB storage engine selected, but not compiled in library");
            }
            #elif FORESTDB
            #if NOSQLITE
            if(storageType == "SQLite") {
                throw new ApplicationException("SQLite storage engine selected, but not compiled in library");
            }
            #endif
            #endif

            var className = String.Format("Couchbase.Lite.Store.{0}CouchStore", storageType);
            var primaryStorage = Type.GetType(className, false, true);
            if(primaryStorage == null) {
                throw new InvalidOperationException(String.Format("'{0}' is not a valid storage type", storageType));
            }

            var isStore = primaryStorage.GetInterface("Couchbase.Lite.Store.ICouchStore") != null;
            if(!isStore) {
                throw new InvalidOperationException(String.Format("{0} does not implement ICouchStore", className));
            }

            #if !NOSQLITE
            #if FORESTDB
            var secondaryClass = "Couchbase.Lite.Store.ForestDBCouchStore";
            if(className == secondaryClass) {
                secondaryClass = "Couchbase.Lite.Store.SqliteCouchStore";
            }

            var secondaryStorage = Type.GetType(secondaryClass, false, true);
            Storage = (ICouchStore)Activator.CreateInstance(secondaryStorage);
            if(!Storage.DatabaseExistsIn(DbDirectory)) {
            #endif
                Storage = (ICouchStore)Activator.CreateInstance(primaryStorage);
            #if FORESTDB
            }
            #endif
            #else
            Storage = new ForestDBCouchStore();
            #endif

            var encryptionKey = default(SymmetricKey);
            var gotKey = Manager.Shared.TryGetValue("encryptionKey", "", Name, out encryptionKey);
            if (gotKey) {
                Storage.SetEncryptionKey(encryptionKey);
            }

            Storage.Delegate = this;
            Log.D(TAG, "Using {0} for db at {1}", Storage.GetType(), DbDirectory);
            try {
                Storage.Open(DbDirectory, Manager, false);

                // HACK: Needed to overcome the read connection not getting the write connection
                // changes until after the schema is written
                Storage.Close();
                Storage.Open(DbDirectory, Manager, false);
            } catch(CouchbaseLiteException) {
                Storage.Close();
                Log.W(TAG, "Failed to create storage engine");
                throw;
            } catch(Exception e) {
                throw new CouchbaseLiteException("Error creating storage engine", e) { Code = StatusCode.Exception };
            }

            Storage.AutoCompact = AUTO_COMPACT;

            // First-time setup:
            if (PrivateUUID() == null) {
                Storage.SetInfo("privateUUID", Misc.CreateGUID());
                Storage.SetInfo("publicUUID", Misc.CreateGUID());
            }

            var savedMaxRevDepth = _maxRevTreeDepth != 0 ? _maxRevTreeDepth.ToString() : Storage.GetInfo("max_revs");
            int maxRevTreeDepth = 0;
            if (savedMaxRevDepth != null && int.TryParse(savedMaxRevDepth, out maxRevTreeDepth)) {
                MaxRevTreeDepth = maxRevTreeDepth;
            } else {
                MaxRevTreeDepth = DEFAULT_MAX_REVS;
            }

            // Open attachment store:
            string attachmentsPath = AttachmentStorePath;

            try {
                Attachments = new BlobStore(attachmentsPath, encryptionKey);
            } catch(CouchbaseLiteException) {
                Log.E(TAG, "Error creating blob store at {0}", attachmentsPath);
                Storage.Close();
                Storage = null;
                throw;
            } catch(Exception e) {
                Storage.Close();
                Storage = null;
                throw new CouchbaseLiteException(String.Format("Unknown error creating blob store at {0}", attachmentsPath),
                    e) { Code = StatusCode.Exception };
            }
           
            _isOpen = true;
        }