public void TestAPIManager()
        {
            Manager manager = this.manager;
            Assert.IsTrue(manager != null);

            foreach (string dbName in manager.AllDatabaseNames)
            {
                Database db = manager.GetDatabase(dbName);
                Log.I(TAG, "Database '" + dbName + "':" + db.DocumentCount + " documents");
            }

            var options = new ManagerOptions();
            options.ReadOnly = true;
            options.CallbackScheduler = new SingleTaskThreadpoolScheduler();

            var roManager = new Manager(new DirectoryInfo(manager.Directory), options);
            Assert.IsTrue(roManager != null);

            var nonExistantDatabase = roManager.GetDatabase("foo");
            Assert.IsNull(nonExistantDatabase);

            var dbNames = manager.AllDatabaseNames;
            Assert.IsFalse(dbNames.Contains<String>("foo"));
            Assert.IsTrue(dbNames.Contains(DefaultTestDb));
        }
 /// <exception cref="Couchbase.Lite.CouchbaseLiteException"></exception>
 public virtual void TestLoadDBPerformance()
 {
     long startMillis = Runtime.CurrentTimeMillis();
     string[] bigObj = new string[GetSizeOfDocument()];
     for (int i = 0; i < GetSizeOfDocument(); i++)
     {
         bigObj[i] = _propertyValue;
     }
     for (int j = 0; j < GetNumberOfShutAndReloadCycles(); j++)
     {
         //Force close and reopen of manager and database to ensure cold
         //start before doc creation
         try
         {
             TearDown();
             manager = new Manager(new LiteTestContext(), Manager.DefaultOptions);
             database = manager.GetExistingDatabase(DefaultTestDb);
         }
         catch (Exception ex)
         {
             Log.E(Tag, "DB teardown", ex);
             Fail();
         }
         for (int k = 0; k < GetNumberOfDocuments(); k++)
         {
             //create a document
             IDictionary<string, object> props = new Dictionary<string, object>();
             props.Put("bigArray", bigObj);
             Body body = new Body(props);
             RevisionInternal rev1 = new RevisionInternal(body, database);
             Status status = new Status();
             try
             {
                 rev1 = database.PutRevision(rev1, null, false, status);
             }
             catch (Exception t)
             {
                 Log.E(Tag, "Document creation failed", t);
                 Fail();
             }
         }
     }
     Log.V("PerformanceStats", Tag + "," + Sharpen.Extensions.ValueOf(Runtime.CurrentTimeMillis
         () - startMillis).ToString() + "," + GetNumberOfDocuments() + "," + GetSizeOfDocument
         () + ",," + GetNumberOfShutAndReloadCycles());
 }
示例#3
0
		//SERVER & DOCUMENTS
		/// <exception cref="System.Exception"></exception>
		public virtual void TestAPIManager()
		{
			Manager manager = this.manager;
			NUnit.Framework.Assert.IsTrue(manager != null);
			foreach (string dbName in manager.GetAllDatabaseNames())
			{
				Database db = manager.GetDatabase(dbName);
				Log.I(Tag, "Database '" + dbName + "':" + db.GetDocumentCount() + " documents");
			}
			ManagerOptions options = new ManagerOptions();
			options.SetReadOnly(true);
			Manager roManager = new Manager(new FilePath(manager.GetDirectory()), options);
			NUnit.Framework.Assert.IsTrue(roManager != null);
			Database db_1 = roManager.GetDatabase("foo");
			NUnit.Framework.Assert.IsNull(db_1);
			IList<string> dbNames = manager.GetAllDatabaseNames();
			NUnit.Framework.Assert.IsFalse(dbNames.Contains("foo"));
			NUnit.Framework.Assert.IsTrue(dbNames.Contains(DefaultTestDb));
		}
示例#4
0
		/// <exception cref="System.Exception"></exception>
		public virtual void TestUpgradeOldDatabaseFiles()
		{
			string directoryName = "test-directory-" + Runtime.CurrentTimeMillis();
			string normalFilesDir = GetRootDirectory().GetAbsolutePath();
			string fakeFilesDir = string.Format("%s/%s", normalFilesDir, directoryName);
			FilePath directory = new FilePath(fakeFilesDir);
			if (!directory.Exists())
			{
				bool result = directory.Mkdir();
				if (!result)
				{
					throw new IOException("Unable to create directory " + directory);
				}
			}
			FilePath oldTouchDbFile = new FilePath(directory, string.Format("old%s", Manager.
				DatabaseSuffixOld));
			oldTouchDbFile.CreateNewFile();
			FilePath newCbLiteFile = new FilePath(directory, string.Format("new%s", Manager.DatabaseSuffix
				));
			newCbLiteFile.CreateNewFile();
			FilePath migratedOldFile = new FilePath(directory, string.Format("old%s", Manager
				.DatabaseSuffix));
			migratedOldFile.CreateNewFile();
			base.StopCBLite();
			manager = new Manager(new FilePath(GetRootDirectory(), directoryName), Manager.DefaultOptions
				);
			NUnit.Framework.Assert.IsTrue(migratedOldFile.Exists());
			//cannot rename old.touchdb in old.cblite, old.cblite already exists
			NUnit.Framework.Assert.IsTrue(oldTouchDbFile.Exists());
			NUnit.Framework.Assert.IsTrue(newCbLiteFile.Exists());
			FilePath dir = new FilePath(GetRootDirectory(), directoryName);
			NUnit.Framework.Assert.AreEqual(3, dir.ListFiles().Length);
			base.StopCBLite();
			migratedOldFile.Delete();
			manager = new Manager(new FilePath(GetRootDirectory(), directoryName), Manager.DefaultOptions
				);
			//rename old.touchdb in old.cblite, previous old.cblite already doesn't exist
			NUnit.Framework.Assert.IsTrue(migratedOldFile.Exists());
			NUnit.Framework.Assert.IsTrue(oldTouchDbFile.Exists() == false);
			NUnit.Framework.Assert.IsTrue(newCbLiteFile.Exists());
			dir = new FilePath(GetRootDirectory(), directoryName);
			NUnit.Framework.Assert.AreEqual(2, dir.ListFiles().Length);
		}
        /// <summary>
        /// Initializes a new instance of the <see cref="Couchbase.Lite.Database"/> class.
        /// </summary>
        /// <param name="path">Path.</param>
        /// <param name="manager">Manager.</param>
        internal Database(String path, Manager manager)
        {
            Debug.Assert(System.IO.Path.IsPathRooted(path));

            //path must be absolute
            Path = path;
            Name = FileDirUtils.GetDatabaseNameFromPath(path);
            Manager = manager;
            DocumentCache = new LruCache<string, Document>(MaxDocCacheSize);
            UnsavedRevisionDocumentCache = new Dictionary<string, WeakReference>();
 
            // FIXME: Not portable to WinRT/WP8.
            ActiveReplicators = new List<Replication>();
            AllReplicators = new List<Replication> ();

            _changesToNotify = new AList<DocumentChange>();

            StartTime = DateTime.UtcNow.ToMillisecondsSinceEpoch ();

            MaxRevTreeDepth = DefaultMaxRevs;
        }
示例#6
0
        /// <summary>Constructor</summary>
        internal Database(String path, Manager manager)
        {
			#if PORTABLE
			Debug.Assert((path.StartsWith("/", StringComparison.CurrentCultureIgnoreCase)));
			#else
			Debug.Assert((path.StartsWith("/", StringComparison.InvariantCultureIgnoreCase)));
			#endif

            //path must be absolute
            Path = path;
            Name = FileDirUtils.GetDatabaseNameFromPath(path);
            Manager = manager;
            DocumentCache = new LruCache<string, Document>(MaxDocCacheSize);

            // TODO: Make Synchronized ICollection
            ActiveReplicators = new HashSet<Replication>();
            AllReplicators = new HashSet<Replication>();

            ChangesToNotify = new AList<DocumentChange>();

            StartTime = DateTime.UtcNow.ToMillisecondsSinceEpoch ();

            MaxRevTreeDepth = DefaultMaxRevs;
        }
        private static Replication SetupReplication(Manager manager, bool continuous, bool createTarget,
            Uri remoteUri, bool isPull, string user, string password)
        {
            if (remoteUri == null) {
                return null;
            }

            var databaseName = remoteUri.Segments.Last();
            var authenticator = default(IAuthenticator);
            if (user != null && password != null) {
                Logger.I("Listener", "Setting session credentials for user '{0}'", user);
                authenticator = AuthenticatorFactory.CreateBasicAuthenticator(user, password);
            }

            if (isPull) {
                Logger.I("Listener", "Pulling from <{0}> --> {1}", remoteUri, databaseName);
            } else {
                Logger.I("Listener", "Pushing {0} --> <{1}>", databaseName, remoteUri);
            }

            var db = manager.GetExistingDatabase(databaseName);
            if (isPull && db == null) {
                db = manager.GetDatabase(databaseName);
            }

            if (db == null) {
                Logger.E("Listener", "Couldn't open database {0}", databaseName);
                return null;
            }

            var repl = isPull ? db.CreatePullReplication(remoteUri) : db.CreatePushReplication(remoteUri);
            repl.Continuous = continuous;
            repl.CreateTarget = createTarget;
            repl.Authenticator = authenticator;
            repl.Changed += (sender, e) => 
            {
                Logger.I("Listener", "*** Replicator status changed ({0} {1}/{2}) ***", e.Status, e.CompletedChangesCount,
                    e.ChangesCount);
                if(e.LastError != null) {
                    Logger.W("Listener", "*** Replicator reported error ***", e);
                } else if(e.Status == ReplicationStatus.Stopped) {
                    Logger.I("Listener", "*** Replicator finished ***");
                }
            };

            repl.Start();
            return repl;
        }
        public void TestReadOnlyDb()
        {
            CreateDocuments(database, 10);
            database.Close();

            var options = new ManagerOptions();
            options.ReadOnly = true;
            var readOnlyManager = new Manager(new DirectoryInfo(manager.Directory), options);
            database = readOnlyManager.GetExistingDatabase(database.Name);
            Assert.IsNotNull(database);
            var e = Assert.Throws<CouchbaseLiteException>(() => CreateDocuments(database, 1));
            Assert.AreEqual(StatusCode.Forbidden, e.Code);
            database.Close();

            var dbOptions = new DatabaseOptions();
            dbOptions.ReadOnly = true;
            database = manager.OpenDatabase(database.Name, dbOptions);
            Assert.IsNotNull(database);
            e = Assert.Throws<CouchbaseLiteException>(() => CreateDocuments(database, 1));
            Assert.AreEqual(StatusCode.Forbidden, e.Code);
            database.Close();

            dbOptions.ReadOnly = false;
            database = manager.OpenDatabase(database.Name, dbOptions);
            Assert.DoesNotThrow(() => CreateDocuments(database, 1));
        }
示例#9
0
        internal void UpdateIndex()
        {
            Log.V(Database.Tag, "Re-indexing view " + Name + " ...");
            System.Diagnostics.Debug.Assert((Map != null));

            if (Id < 0)
            {
                var msg = string.Format("View.Id < 0");
                throw new CouchbaseLiteException(msg, new Status(StatusCode.NotFound));
            }

            Database.BeginTransaction();

            var    result = new Status(StatusCode.InternalServerError);
            Cursor cursor = null;

            try
            {
                var lastSequence  = LastSequenceIndexed;
                var dbMaxSequence = Database.LastSequenceNumber;

                if (lastSequence == dbMaxSequence)
                {
                    // nothing to do (eg,  kCBLStatusNotModified)
                    var msg = String.Format("lastSequence ({0}) == dbMaxSequence ({1}), nothing to do", lastSequence, dbMaxSequence);
                    Log.D(Database.Tag, msg);
                    result.SetCode(StatusCode.Ok);
                    return;
                }

                // First remove obsolete emitted results from the 'maps' table:
                var sequence = lastSequence;
                if (lastSequence < 0)
                {
                    var msg = string.Format("lastSequence < 0 ({0})", lastSequence);
                    throw new CouchbaseLiteException(msg, new Status(StatusCode.InternalServerError));
                }
                if (lastSequence == 0)
                {
                    // If the lastSequence has been reset to 0, make sure to remove
                    // any leftover rows:
                    var whereArgs = new string[] { Sharpen.Extensions.ToString(Id) };
                    Database.StorageEngine.Delete("maps", "view_id=@", whereArgs);
                }
                else
                {
                    // Delete all obsolete map results (ones from since-replaced
                    // revisions):
                    var args = new [] {
                        Id.ToString(),
                        lastSequence.ToString(),
                        lastSequence.ToString()
                    };

                    Database.StorageEngine.ExecSQL(
                        "DELETE FROM maps WHERE view_id=@ AND sequence IN ("
                        + "SELECT parent FROM revs WHERE sequence>@ " + "AND parent>0 AND parent<=@)",
                        args);
                }
                var deleted = 0;
                cursor = Database.StorageEngine.RawQuery("SELECT changes()", null); // TODO: Convert to ADO params.
                cursor.MoveToNext();
                deleted = cursor.GetInt(0);
                cursor.Close();

                // find a better way to propagate this back
                // Now scan every revision added since the last time the view was
                // indexed:
                var selectArgs = new[] { Convert.ToString(lastSequence) };
                cursor = Database.StorageEngine.RawQuery("SELECT revs.doc_id, sequence, docid, revid, json FROM revs, docs "
                                                         + "WHERE sequence>@ AND current!=0 AND deleted=0 " + "AND revs.doc_id = docs.doc_id "
                                                         + "ORDER BY revs.doc_id, revid DESC", CommandBehavior.SequentialAccess, selectArgs);
                cursor.MoveToNext();

                var lastDocID = 0L;
                while (!cursor.IsAfterLast())
                {
                    long docID = cursor.GetLong(0);
                    if (docID != lastDocID)
                    {
                        // Only look at the first-iterated revision of any document,
                        // because this is the
                        // one with the highest revid, hence the "winning" revision
                        // of a conflict.
                        lastDocID = docID;
                        // Reconstitute the document as a dictionary:
                        sequence = cursor.GetLong(1);
                        string docId = cursor.GetString(2);
                        if (docId.StartsWith("_design/", StringCompare.IgnoreCase))
                        {
                            // design docs don't get indexed!
                            cursor.MoveToNext();
                            continue;
                        }
                        var revId      = cursor.GetString(3);
                        var json       = cursor.GetBlob(4);
                        var properties = Database.DocumentPropertiesFromJSON(
                            json, docId, revId, false, sequence, EnumSet.NoneOf <TDContentOptions>()
                            );
                        if (properties != null)
                        {
                            // Call the user-defined map() to emit new key/value
                            // pairs from this revision:
                            Log.V(Database.Tag, "  call map for sequence=" + System.Convert.ToString(sequence
                                                                                                     ));
                            // This is the emit() block, which gets called from within the
                            // user-defined map() block
                            // that's called down below.

                            var enclosingView = this;
                            var thisSequence  = sequence;
                            var map           = Map;

                            if (map == null)
                            {
                                throw new CouchbaseLiteException("Map function is missing.");
                            }

                            EmitDelegate emitBlock = (key, value) =>
                            {
                                // TODO: Do we need to do any null checks on key or value?
                                try
                                {
                                    var keyJson   = Manager.GetObjectMapper().WriteValueAsString(key);
                                    var valueJson = value == null ? null : Manager.GetObjectMapper().WriteValueAsString(value);
                                    Log.V(Database.Tag, String.Format("    emit({0}, {1})", keyJson, valueJson));

                                    var insertValues = new ContentValues();
                                    insertValues.Put("view_id", enclosingView.Id);
                                    insertValues["sequence"] = thisSequence;
                                    insertValues["key"]      = keyJson;
                                    insertValues["value"]    = valueJson;

                                    enclosingView.Database.StorageEngine.Insert("maps", null, insertValues);
                                }
                                catch (Exception e)
                                {
                                    Log.E(Database.Tag, "Error emitting", e);
                                }
                            };

                            map(properties, emitBlock);
                        }
                    }
                    cursor.MoveToNext();
                }
                // Finally, record the last revision sequence number that was
                // indexed:
                ContentValues updateValues = new ContentValues();
                updateValues["lastSequence"] = dbMaxSequence;
                var whereArgs_1 = new string[] { Sharpen.Extensions.ToString(Id) };
                Database.StorageEngine.Update("views", updateValues, "view_id=@", whereArgs_1);
                // FIXME actually count number added :)
                Log.V(Database.Tag, "...Finished re-indexing view " + Name + " up to sequence " +
                      System.Convert.ToString(dbMaxSequence) + " (deleted " + deleted + " added " + "?" + ")");
                result.SetCode(StatusCode.Ok);
            }
            catch (SQLException e)
            {
                throw new CouchbaseLiteException(e, new Status(StatusCode.DbError));
            }
            finally
            {
                if (cursor != null)
                {
                    cursor.Close();
                }
                if (!result.IsSuccessful())
                {
                    Log.W(Database.Tag, "Failed to rebuild view " + Name + ": " + result.GetCode());
                }
                if (Database != null)
                {
                    Database.EndTransaction(result.IsSuccessful());
                }
            }
        }
示例#10
0
        public void TestSharedMapBlocks()
        {
            var path = new DirectoryInfo(Path.Combine(RootDirectory.FullName, "API_SharedMapBlocks"));
            var mgr = new Manager(path, Manager.DefaultOptions);
            var db = mgr.GetDatabase("db");

            db.Open();
            db.SetFilter("phil", (r, p) => true);
            db.SetValidation("val", (p1, p2) => true);

            var view = db.GetView("view");
            var ok = view.SetMapReduce((p1, p2)=>{ return; }, (a, b, c) => { return null; }, "1");

            Assert.IsNotNull(ok, "Couldn't set map/reduce");

            var map = view.Map;
            var reduce = view.Reduce;
            var filter = db.GetFilter("phil");
            var validation = db.GetValidation("val");
            var result = mgr.RunAsync("db", (database)=>
                {
                    Assert.IsNotNull(database);
                    var serverView = database.GetExistingView("view");
                    Assert.IsNotNull(serverView);
                    Assert.AreEqual(database.GetFilter("phil"), filter);
                    Assert.AreEqual(database.GetValidation("val"), validation);
                    Assert.AreEqual(serverView.Map, map);
                    Assert.AreEqual(serverView.Reduce, reduce);
                    return true;
                });
            result.Wait(TimeSpan.FromSeconds(5));
            // blocks until async task has run
            db.Close();
            mgr.Close();
        }
示例#11
0
        public void TestUpgradeOldDatabaseFiles()
        {
            var testDirName = "test-directory-" + Runtime.CurrentTimeMillis();
            var rootDirPath = RootDirectory.FullName;
            var testDirPath = Path.Combine(rootDirPath, testDirName);
            var testDirInfo = Directory.CreateDirectory(testDirPath);

            var dbStream = GetAsset("withattachments.cblite");
            var destStream = File.OpenWrite(Path.Combine(testDirPath, "withattachments" + Manager.DatabaseSuffix));
            dbStream.CopyTo(destStream);
            dbStream.Dispose();
            destStream.Dispose();

            var attStream = GetAsset("attachment.blob");
            Directory.CreateDirectory(Path.Combine(testDirPath, "withattachments/attachments"));
            destStream = File.OpenWrite(Path.Combine(testDirPath, "withattachments/attachments/356a192b7913b04c54574d18c28d46e6395428ab.blob"));
            attStream.CopyTo(destStream);
            destStream.Dispose();
            attStream.Dispose();

            StopCBLite();
            manager = new Manager(testDirInfo, Manager.DefaultOptions);
            var db = manager.GetDatabaseWithoutOpening("withattachments", true);
            int version = DatabaseUpgraderFactory.SchemaVersion(db.Path);
            Assert.IsTrue(version >= 101, "Upgrade failed");
            Assert.IsFalse(Directory.Exists(Path.Combine(testDirPath, "withattachments/attachments")), "Failed to remove old attachments dir");
            Assert.IsTrue(Directory.Exists(Path.Combine(testDirPath, "withattachments attachments")), "Failed to create new attachments dir");
        }
示例#12
0
        public static void Main(string[] args)
        {
            var timeoutStr = "90000";
            var options = new OptionSet() {
                { "push", "push replication", v => _isPush = v == "push" },
                { "pull", "pull replication", v => _isPull = v == "pull" },
                { "f|file=",  "CBLite file path", v =>
                    _path = v },
                { "u|url=",  "URL to replicate with", v => _url = v },
                { "t|timeout=", "Set the timeout for HTTP requests in milliseconds (default is 90000)", v => timeoutStr = v },
                { "h|help",  "show this message and exit", v => _showHelp = v != null },

            };

            List<string> extra;
            try {
                extra = options.Parse(args);
                if (extra.Count == 1)
                {
                    // Should be just a file path. Will validate below.
                    _path = extra[0];
                }
            } catch (OptionException e) {
                Console.Write("cbreplicate: ");
                OutputUsingColor(
                    color: ConsoleColor.Red,
                    format: e.Message
                );
                Console.WriteLine();
                Console.WriteLine("Try `cbreplicate --help' for more information.");
                Environment.ExitCode = (int)Exit.InvalidOptions;
                return;
            }

            if (_showHelp || args.Length == 0) {
                var writer = new StringWriter(new StringBuilder("usage: cb-replicate [options] [file path]" + Environment.NewLine + Environment.NewLine));
                options.WriteOptionDescriptions(writer);

                _helpText = writer.ToString();

                writer.Close();

                ShowHelp();
                return;
            }

            int timeout;
            if(Int32.TryParse(timeoutStr, out timeout)) {
                Manager.DefaultOptions.RequestTimeout = TimeSpan.FromMilliseconds(timeout);
            }

            if (String.IsNullOrWhiteSpace(_path)) {
                OutputUsingColor(
                    color: ConsoleColor.Red,
                    format: "The path to the database was empty text or all whitespace.{0}",
                    args: Environment.NewLine
                );
                ShowHelp();
                Environment.ExitCode = (int)Exit.PathIsNullOrEmpty;
                return;
            }

            FileInfo file;
            if (!File.Exists(_path)) {
                // See if they gave us a relative path.
                _path = Path.Combine(Environment.CurrentDirectory, _path);
                if (!File.Exists(_path) && _isPush) {
                    OutputUsingColor(
                        color: ConsoleColor.Red,
                        format: "The path {0} is not valid. A valid CBLite database is required for push replication",
                        args: _path
                    );
                    Environment.ExitCode = (int)Exit.PathDoesNotExist;
                    return;
                }
            }

            file = new FileInfo(_path);

            var man = new Manager(file.Directory, Manager.DefaultOptions);

            try
            {
                _db = _isPull ? man.GetDatabase(file.Name.Split('.')[0]) : man.GetExistingDatabase(file.Name.Split('.')[0]);
            }
            catch (Exception ex)
            {
                OutputUsingColor(
                    color: ConsoleColor.Red,
                    format: "Error opening the database: {0}{1}",
                    args: new[] { ex.Message, Environment.NewLine }
                );
                Environment.ExitCode = (int)Exit.CannotOpenDatabase;
                return;
            }

            if (_db == null)
            {
                OutputUsingColor(
                    color: ConsoleColor.Red,
                    format: "No CBLite db found at '{0}'. Push replication requires and existing CBLite database.",
                    args: _path
                );
                Environment.ExitCode = (int)Exit.PathDoesNotExist;
                return;
            }

            if (_isPush)
            {
                try
                {
                    Push();
                }
                catch (Exception ex)
                {
                    OutputUsingColor(
                        color: ConsoleColor.Red,
                        format: "Unhandled exception during push replication: {0}",
                        args: ex.Message
                    );
                    Environment.ExitCode = (int)Exit.UnhandledException;
                    return;
                }
            }
            else if (_isPull)
            {
                try
                {
                    Pull();
                }
                catch (Exception ex)
                {
                    OutputUsingColor(
                        color: ConsoleColor.Red,
                        format: "Unhandled exception during pull replication: {0}",
                        args: ex.Message
                    );
                    Environment.ExitCode = (int)Exit.UnhandledException;
                    return;
                }
            }

            bool doneWaiting;

            Console.CancelKeyPress += (sender, e) => {
                if (e.Cancel) {
                    _done = _mre.Set();
                }
            };

            do {
                doneWaiting = _mre.WaitOne(100);
            } while(!_done || !doneWaiting);
        }
示例#13
0
		public Database(string path, Manager manager)
		{
			System.Diagnostics.Debug.Assert((path.StartsWith("/")));
			//path must be absolute
			this.path = path;
			this.name = FileDirUtils.GetDatabaseNameFromPath(path);
			this.manager = manager;
			this.changeListeners = Sharpen.Collections.SynchronizedList(new AList<Database.ChangeListener
				>());
			this.docCache = new LruCache<string, Document>(MaxDocCacheSize);
			this.startTime = Runtime.CurrentTimeMillis();
			this.changesToNotify = new AList<DocumentChange>();
			this.activeReplicators = Sharpen.Collections.SynchronizedSet(new HashSet<Replication
				>());
			this.allReplicators = Sharpen.Collections.SynchronizedSet(new HashSet<Replication
				>());
		}
        public CouchbaseLiteFacade()
        {
            _manager = Manager.SharedInstance;

            _database = _manager.GetDatabase(DB_NAME + DateTime.Now.GetHashCode());
        }
        public void Test09LoadDB()
        {
            RunTest("Test09LoadDB", (parameters) =>
            {
                var numDocs = Convert.ToInt32(parameters[NUMDOCS_KEY]);
                var docSize = Convert.ToInt32(parameters[DOCSIZE_KEY]);

                var docs = new Document[numDocs];
                database.RunInTransaction(() =>
                {
                    var props = CreateTestProperties(docSize);
                    for (var i = 0; i < docs.Length; i++)
                    {
                        var doc = database.CreateDocument();
                        doc.PutProperties(props);
                        docs[i] = doc;
                    }

                    return true;
                });

                var stopwatch = Stopwatch.StartNew();

                database.Close();
                manager.Close();

                var path = new DirectoryInfo(GetServerPath() + "/tests");
                manager = new Manager(path, Manager.DefaultOptions);
                database = manager.GetDatabase(DefaultTestDb);

                stopwatch.Stop();

                return stopwatch.ElapsedMilliseconds;
            });
        }
示例#16
0
        public void TestUpgradeOldDatabaseFiles()
        {
            var testDirName = "test-directory-" + Runtime.CurrentTimeMillis();
            var rootDirPath = GetRootDirectory().FullName;
            var testDirPath = Path.Combine(rootDirPath, testDirName);
            var testDirInfo = Directory.CreateDirectory(testDirPath);

            var oldTouchDb = Path.Combine(testDirPath, "old" + Manager.DatabaseSuffixOld);
            File.Create(oldTouchDb);

            var newCbLiteDb = Path.Combine(testDirPath, "new" + Manager.DatabaseSuffix);
            File.Create(newCbLiteDb);

            var migratedOldFile = Path.Combine(testDirPath, "old" + Manager.DatabaseSuffix);
            File.Create(migratedOldFile);

            StopCBLite();
            manager = new Manager(testDirInfo, Manager.DefaultOptions);

            var oldTouchDbInfo = new FileInfo(oldTouchDb);
            var newCbLiteDbInfo = new FileInfo(newCbLiteDb);
            var migratedOldInfo = new FileInfo(migratedOldFile);

            Assert.IsTrue(migratedOldInfo.Exists);
            //cannot rename old.touchdb in old.cblite, old.cblite already exists
            Assert.IsTrue(oldTouchDbInfo.Exists);
            Assert.IsTrue(newCbLiteDbInfo.Exists);
            Assert.AreEqual(3, testDirInfo.GetFiles().Length);

            StopCBLite();
            migratedOldInfo.Delete();
            manager = new Manager(testDirInfo, Manager.DefaultOptions);

            oldTouchDbInfo = new FileInfo(oldTouchDb);
            newCbLiteDbInfo = new FileInfo(newCbLiteDb);
            migratedOldInfo = new FileInfo(migratedOldFile);

            //rename old.touchdb in old.cblite, previous old.cblite already doesn't exist
            Assert.IsTrue(migratedOldInfo.Exists);
            Assert.IsFalse(oldTouchDbInfo.Exists);
            Assert.IsTrue(newCbLiteDbInfo.Exists);    
            Assert.AreEqual(2, testDirInfo.GetFiles().Length); 
        }
示例#17
0
        private Status ParseReplicationProperties(IDictionary <string, object> properties, out bool isPush, out bool createTarget,
                                                  IDictionary <string, object> results)
        {
            // http://wiki.apache.org/couchdb/Replication
            isPush       = false;
            createTarget = false;

            var sourceDict = ParseSourceOrTarget(properties, "source");
            var targetDict = ParseSourceOrTarget(properties, "target");
            var source     = sourceDict.Get("url") as string;
            var target     = targetDict.Get("url") as string;

            if (source == null || target == null)
            {
                return(new Status(StatusCode.BadRequest));
            }

            createTarget = properties.Get("create_target") is bool && (bool)properties.Get("create_target");

            IDictionary <string, object> remoteDict = null;
            bool targetIsLocal = Manager.IsValidDatabaseName(target);

            if (Manager.IsValidDatabaseName(source))
            {
                //Push replication
                if (targetIsLocal)
                {
                    // This is a local-to-local replication. Turn the remote into a full URL to keep the
                    // replicator happy:
                    Database targetDb;
                    if (createTarget)
                    {
                        targetDb = Manager.SharedInstance.GetDatabase(target);
                    }
                    else
                    {
                        targetDb = Manager.SharedInstance.GetExistingDatabase(target);
                    }

                    if (targetDb == null)
                    {
                        return(new Status(StatusCode.BadRequest));
                    }

                    targetDict["url"] = "http://localhost:20000" + targetDb.DbDirectory;
                }

                remoteDict = targetDict;
                if (results.ContainsKey("database"))
                {
                    results["database"] = GetExistingDatabase(source);
                }

                isPush = true;
            }
            else if (targetIsLocal)
            {
                //Pull replication
                remoteDict = sourceDict;
                if (results.ContainsKey("database"))
                {
                    Database db;
                    if (createTarget)
                    {
                        db = GetDatabase(target);
                        if (db == null)
                        {
                            return(new Status(StatusCode.DbError));
                        }
                    }
                    else
                    {
                        db = GetExistingDatabase(target);
                    }
                    results["database"] = db;
                }
            }
            else
            {
                return(new Status(StatusCode.BadId));
            }

            Uri remote = new Uri(remoteDict["url"] as string);

            if (!remote.Scheme.Equals("http") && !remote.Scheme.Equals("https") && !remote.Scheme.Equals("cbl"))
            {
                return(new Status(StatusCode.BadRequest));
            }

            var database = results.Get("database");

            if (database == null)
            {
                return(new Status(StatusCode.NotFound));
            }

            if (results.ContainsKey("remote"))
            {
                results["remote"] = remote;
            }

            if (results.ContainsKey("headers"))
            {
                results["headers"] = remoteDict.Get("headers");
            }

            if (results.ContainsKey("authorizer"))
            {
                var auth = remoteDict.Get("auth") as IDictionary <string, object>;
                if (auth != null)
                {
                    //var oauth = auth["oauth"] as IDictionary<string, object>;
                    var persona  = auth.Get("persona") as IDictionary <string, object>;
                    var facebook = auth.Get("facebook") as IDictionary <string, object>;
                    //TODO: OAuth

                    /*if (oauth != null) {
                     *  string consumerKey = oauth.Get("consumer_key") as string;
                     *  string consumerSec = oauth.Get("consumer_secret") as string;
                     *  string token = oauth.Get("token") as string;
                     *  string tokenSec = oauth.Get("token_secret") as string;
                     *  string sigMethod = oauth.Get("signature_method") as string;
                     *  results["authorizer"] =
                     * }*/
                    if (persona != null)
                    {
                        string email = persona.Get("email") as string;
                        results["authorizer"] = new PersonaAuthorizer(email);
                    }
                    else if (facebook != null)
                    {
                        string email = facebook.Get("email") as string;
                        results["authorizer"] = new FacebookAuthorizer(email);
                    }
                    else
                    {
                        Log.To.Sync.W(TAG, "Invalid authorizer settings {0}",
                                      new SecureLogJsonString(auth, LogMessageSensitivity.Insecure));
                    }
                }
            }

            // Can't specify both a filter and doc IDs
            if (properties.ContainsKey("filter") && properties.ContainsKey("doc_ids"))
            {
                return(new Status(StatusCode.BadRequest));
            }

            return(new Status(StatusCode.Ok));
        }
        internal Database(string directory, string name, Manager manager, bool readOnly)
        {
            Debug.Assert(Path.IsPathRooted(directory));

            //path must be absolute
            DbDirectory = directory;
            Name = name ?? FileDirUtils.GetDatabaseNameFromPath(DbDirectory);
            Manager = manager;
            DocumentCache = new LruCache<string, Document>(MAX_DOC_CACHE_SIZE);
            _readonly = readOnly;

            // FIXME: Not portable to WinRT/WP8.
            ActiveReplicators = new List<Replication>();
            AllReplicators = new List<Replication>();

            _changesToNotify = new List<DocumentChange>();
            Scheduler = new TaskFactory(new SingleTaskThreadpoolScheduler());
            StartTime = (ulong)DateTime.UtcNow.TimeSinceEpoch().TotalMilliseconds;
        }
示例#19
0
		public static Database CreateEmptyDBAtPath(string path, Manager manager)
		{
			if (!FileDirUtils.RemoveItemIfExists(path))
			{
				return null;
			}
			Database result = new Database(path, manager);
			FilePath af = new FilePath(result.GetAttachmentStorePath());
			//recursively delete attachments path
			if (!FileDirUtils.DeleteRecursive(af))
			{
				return null;
			}
			if (!result.Open())
			{
				return null;
			}
			return result;
		}
示例#20
0
		/// <exception cref="System.Exception"></exception>
		public virtual void TestChangeUUID()
		{
			Manager mgr = new Manager(new FilePath(GetRootDirectory(), "ChangeUUID"), Manager
				.DefaultOptions);
			Database db = mgr.GetDatabase("db");
			db.Open();
			string pub = db.PublicUUID();
			string priv = db.PrivateUUID();
			NUnit.Framework.Assert.IsTrue(pub.Length > 10);
			NUnit.Framework.Assert.IsTrue(priv.Length > 10);
			NUnit.Framework.Assert.IsTrue("replaceUUIDs failed", db.ReplaceUUIDs());
			NUnit.Framework.Assert.IsFalse(pub.Equals(db.PublicUUID()));
			NUnit.Framework.Assert.IsFalse(priv.Equals(db.PrivateUUID()));
			mgr.Close();
		}
        /// <exception cref="System.IO.IOException"></exception>
        protected void StartCBLite()
        {
            string serverPath = GetServerPath();
            var path = new DirectoryInfo(serverPath);

            if (path.Exists)
                path.Delete(true);

            path.Create();

            var testPath = path.CreateSubdirectory("tests");
            manager = new Manager(testPath, Manager.DefaultOptions);
        }
示例#22
0
		/// <summary>
		/// Make sure that a database's map/reduce functions are shared with the shadow database instance
		/// running in the background server.
		/// </summary>
		/// <remarks>
		/// Make sure that a database's map/reduce functions are shared with the shadow database instance
		/// running in the background server.
		/// </remarks>
		/// <exception cref="System.Exception"></exception>
		public virtual void TestSharedMapBlocks()
		{
			Manager mgr = new Manager(new FilePath(GetRootDirectory(), "API_SharedMapBlocks")
				, Manager.DefaultOptions);
			Database db = mgr.GetDatabase("db");
			db.Open();
			db.SetFilter("phil", new _ReplicationFilter_931());
			db.SetValidation("val", new _Validator_938());
			View view = db.GetView("view");
			bool ok = view.SetMapReduce(new _Mapper_945(), new _Reducer_950(), "1");
			NUnit.Framework.Assert.IsNotNull("Couldn't set map/reduce", ok);
			Mapper map = view.GetMap();
			Reducer reduce = view.GetReduce();
			ReplicationFilter filter = db.GetFilter("phil");
			Validator validation = db.GetValidation("val");
			Future result = mgr.RunAsync("db", new _AsyncTask_965(filter, validation, map, reduce
				));
			result.Get();
			// blocks until async task has run
			db.Close();
			mgr.Close();
		}
示例#23
0
        public void TestChangeUUID()
        {
            var path = new DirectoryInfo(Path.Combine(RootDirectory.FullName, "ChangeUUID"));
            var mgr = new Manager(path, Manager.DefaultOptions);
            var db = mgr.GetDatabase("db");

            db.Open();

            var pub = db.PublicUUID();
            var priv = db.PrivateUUID();
            Assert.IsTrue(pub.Length > 10);
            Assert.IsTrue(priv.Length > 10);
            Assert.IsTrue(db.ReplaceUUIDs(), "replaceUUIDs failed");
            Assert.IsFalse(pub.Equals(db.PublicUUID()));
            Assert.IsFalse(priv.Equals(db.PrivateUUID()));
            mgr.Close();
        }
 public SimpleModel(Manager manager, string dbName)
 {
     _db = manager.GetDatabase(dbName);
 }
示例#25
0
 public override IDisposable OpenDB()
 {
     var manager = new Manager(new DirectoryInfo(this.Path), ManagerOptions.Default);
     manager.StorageType = "ForestDB";
     return this.db = manager.GetDatabase("cbdb");
 }
        private void InitializeDatabase()
        {
            {
                Debug.WriteLine("Initializeing CouchbaseLite");
                try
                {
                    Log.SetDefaultLoggerWithLevel(SourceLevels.Verbose);

                    _dbPath = new DirectoryInfo(Environment.CurrentDirectory);
                    Log.I(TAG, "Creating manager in " + _dbPath);
                    Debug.WriteLine("Creating manager in " + _dbPath);

                    _manager = new Manager(_dbPath, ManagerOptions.Default);
                    Debug.WriteLine("Creating database " + DB_NAME);
                    Log.I(TAG, "Creating database " + DB_NAME);

                    _database = _manager.GetDatabase(DB_NAME);

                }
                catch (Exception ex)
                {
                    var msg = "Could not load database in path " + _dbPath.ToString();
                    MessageBox.Show(msg);
                }
            }
        }
示例#27
0
        internal Database(string path, string name, Manager manager)
        {
            Debug.Assert(System.IO.Path.IsPathRooted(path));

            //path must be absolute
            Path = path;
            Name = name ?? FileDirUtils.GetDatabaseNameFromPath(path);
            Manager = manager;
            DocumentCache = new LruCache<string, Document>(MAX_DOC_CACHE_SIZE);
            UnsavedRevisionDocumentCache = new Dictionary<string, WeakReference>();
 
            // FIXME: Not portable to WinRT/WP8.
            ActiveReplicators = new List<Replication>();
            AllReplicators = new List<Replication> ();

            _changesToNotify = new List<DocumentChange>();
            Scheduler = new TaskFactory(new SingleTaskThreadpoolScheduler());
            StartTime = DateTime.UtcNow.ToMillisecondsSinceEpoch ();
        }
示例#28
0
        private Status ParseReplicationProperties(IDictionary <string, object> properties, out bool isPush, out bool createTarget, IDictionary <string, object> results)
        {
            // http://wiki.apache.org/couchdb/Replication
            isPush       = false;
            createTarget = false;
            var sourceDict = ParseSourceOrTarget(properties, "source");
            var targetDict = ParseSourceOrTarget(properties, "target");
            var source     = sourceDict.GetCast <string>("url");
            var target     = targetDict.GetCast <string>("url");

            if (source == null || target == null)
            {
                return(new Status(StatusCode.BadRequest));
            }

            createTarget = properties.GetCast <bool>("create_target", false);
            IDictionary <string, object> remoteDict = null;
            bool targetIsLocal = Manager.IsValidDatabaseName(target);

            if (Manager.IsValidDatabaseName(source))
            {
                //Push replication
                if (targetIsLocal)
                {
                    // This is a local-to-local replication. It is not supported on .NET.
                    return(new Status(StatusCode.NotImplemented));
                }

                remoteDict = targetDict;
                if (results.ContainsKey("database"))
                {
                    results["database"] = GetExistingDatabase(source);
                }

                isPush = true;
            }
            else if (targetIsLocal)
            {
                //Pull replication
                remoteDict = sourceDict;
                if (results.ContainsKey("database"))
                {
                    Database db;
                    if (createTarget)
                    {
                        db = GetDatabase(target);
                        if (db == null)
                        {
                            return(new Status(StatusCode.DbError));
                        }
                    }
                    else
                    {
                        db = GetExistingDatabase(target);
                    }
                    results["database"] = db;
                }
            }
            else
            {
                return(new Status(StatusCode.BadId));
            }

            Uri remote;

            if (!Uri.TryCreate(remoteDict.GetCast <string>("url"), UriKind.Absolute, out remote))
            {
                Log.To.Router.W(TAG, "Unparseable replication URL <{0}> received", remoteDict.GetCast <string>("url"));
                return(new Status(StatusCode.BadRequest));
            }

            if (!remote.Scheme.Equals("http") && !remote.Scheme.Equals("https") && !remote.Scheme.Equals("ws") && !remote.Scheme.Equals("wss"))
            {
                Log.To.Router.W(TAG, "Replication URL <{0}> has unsupported scheme", remote);
                return(new Status(StatusCode.BadRequest));
            }

            var split = remote.PathAndQuery.Split('?');

            if (split.Length != 1)
            {
                Log.To.Router.W(TAG, "Replication URL <{0}> must not contain a query", remote);
                return(new Status(StatusCode.BadRequest));
            }

            var path = split[0];

            if (String.IsNullOrEmpty(path) || path == "/")
            {
                Log.To.Router.W(TAG, "Replication URL <{0}> missing database name", remote);
                return(new Status(StatusCode.BadRequest));
            }

            var database = results.Get("database");

            if (database == null)
            {
                return(new Status(StatusCode.NotFound));
            }

            if (results.ContainsKey("remote"))
            {
                results["remote"] = remote;
            }

            if (results.ContainsKey("headers"))
            {
                results["headers"] = remoteDict.Get("headers") ?? new Dictionary <string, string>();
            }

            if (results.ContainsKey("authorizer"))
            {
                var auth = remoteDict.Get("auth") as IDictionary <string, object>;
                if (auth != null)
                {
                    var persona  = auth.Get("persona") as IDictionary <string, object>;
                    var facebook = auth.Get("facebook") as IDictionary <string, object>;
                    if (persona != null)
                    {
                        string email = persona.Get("email") as string;
                        results["authorizer"] = new PersonaAuthorizer(email);
                    }
                    else if (facebook != null)
                    {
                        string email = facebook.Get("email") as string;
                        results["authorizer"] = new FacebookAuthorizer(email);
                    }
                    else
                    {
                        Log.To.Sync.W(TAG, "Invalid authorizer settings {0}",
                                      new SecureLogJsonString(auth, LogMessageSensitivity.Insecure));
                    }
                }
            }



            // Can't specify both a filter and doc IDs
            if (properties.ContainsKey("filter") && properties.ContainsKey("doc_ids"))
            {
                return(new Status(StatusCode.BadRequest));
            }

            return(new Status(StatusCode.Ok));
        }