コード例 #1
0
ファイル: ParallelQuery_Tests.cs プロジェクト: zamis/LiteDB
        public void Query_Parallel()
        {
            using (var db = new LiteDatabase(new MemoryStream()))
            {
                var col = db.GetCollection <Person>("person");
                var all = DataGen.Person().ToArray();

                col.Insert(all);

                var bag    = new ConcurrentBag <Person>();
                var people = col.FindAll();

                Parallel.ForEach(people, person =>
                                 //foreach(var person in people)
                {
                    var col2   = db.GetCollection <Person>("person");
                    var exists = col2.Exists(x => x.Id == person.Id);

                    if (exists)
                    {
                        var col3 = db.GetCollection <Person>("person");

                        var item = col3.FindOne(x => x.Id == person.Id);

                        bag.Add(item);
                    }
                });

                all.Length.Should().Be(bag.Count);
            }
        }
コード例 #2
0
ファイル: Person_Tests.cs プロジェクト: tiandizhijian/LiteDB
        public Person_Tests()
        {
            this.local = DataGen.Person().ToArray();

            db         = new LiteDatabase(":memory:");
            collection = db.GetCollection <Person>("person");
            collection.Insert(this.local);
        }
コード例 #3
0
        public async Task Transaction_Avoid_Dirty_Read()
        {
            var data1 = DataGen.Person(1, 100).ToArray();
            var data2 = DataGen.Person(101, 200).ToArray();

            using (var db = new LiteDatabase(new MemoryStream()))
            {
                var person = db.GetCollection <Person>();

                // init person collection with 100 document
                person.Insert(data1);

                var taskASemaphore = new SemaphoreSlim(0, 1);
                var taskBSemaphore = new SemaphoreSlim(0, 1);

                // task A will open transaction and will insert +100 documents
                // but will commit only 1s later - this plus +100 document must be visible only inside task A
                var ta = Task.Run(() =>
                {
                    db.BeginTrans();

                    person.Insert(data2);

                    taskBSemaphore.Release();
                    taskASemaphore.Wait();

                    var count = person.Count();

                    count.Should().Be(data1.Length + data2.Length);

                    db.Commit();
                    taskBSemaphore.Release();
                });

                // task B will not open transaction and will wait 250ms before and count collection -
                // at this time, task A already insert +100 document but here I can't see (are not committed yet)
                // after task A finish, I can see now all 200 documents
                var tb = Task.Run(() =>
                {
                    taskBSemaphore.Wait();

                    var count = person.Count();

                    // read 100 documents
                    count.Should().Be(data1.Length);

                    taskASemaphore.Release();
                    taskBSemaphore.Wait();

                    // read 200 documents
                    count = person.Count();

                    count.Should().Be(data1.Length + data2.Length);
                });

                await Task.WhenAll(ta, tb);
            }
        }
コード例 #4
0
ファイル: GroupBy_Tests.cs プロジェクト: zamis/LiteDB
        public GroupBy_Tests()
        {
            local = DataGen.Person(1, 1000).ToArray();

            db         = new LiteDatabase(new MemoryStream());
            collection = db.GetCollection <Person>();

            collection.Insert(local);
            collection.EnsureIndex(x => x.Age);
        }
コード例 #5
0
        public void Transaction_Avoid_Drity_Read()
        {
            var data1 = DataGen.Person(1, 100).ToArray();
            var data2 = DataGen.Person(101, 200).ToArray();

            using (var db = new LiteDatabase(new MemoryStream()))
            {
                var person = db.GetCollection <Person>();

                // init person collection with 100 document
                person.Insert(data1);

                // task A will open transaction and will insert +100 documents
                // but will commit only 1s later - this plus +100 document must be visible only inside task A
                var ta = new Task(() =>
                {
                    db.BeginTrans();

                    person.Insert(data2);

                    Task.Delay(1000).Wait();

                    var count = person.Count();

                    Assert.AreEqual(data1.Length + data2.Length, count);

                    db.Commit();
                });

                // task B will not open transaction and will wait 250ms before and count collection -
                // at this time, task A already insert +100 document but here I cann't see (are not commited yet)
                // after task A finish, I can see now all 200 documents
                var tb = new Task(() =>
                {
                    Task.Delay(250).Wait();

                    var count = person.Count();

                    // read 100 documents
                    Assert.AreEqual(data1.Length, count);

                    ta.Wait();

                    // read 200 documets
                    count = person.Count();

                    Assert.AreEqual(data1.Length + data2.Length, count);
                });

                ta.Start();
                tb.Start();

                Task.WaitAll(ta, tb);
            }
        }
コード例 #6
0
        public async Task Transaction_Read_Version()
        {
            var data1 = DataGen.Person(1, 100).ToArray();
            var data2 = DataGen.Person(101, 200).ToArray();

            using (var db = new LiteDatabase(new MemoryStream()))
            {
                var person = db.GetCollection <Person>();

                // init person collection with 100 document
                person.Insert(data1);

                var taskASemaphore = new SemaphoreSlim(0, 1);
                var taskBSemaphore = new SemaphoreSlim(0, 1);

                // task A will insert more 100 documents but will commit only 1s later
                var ta = Task.Run(() =>
                {
                    db.BeginTrans();

                    person.Insert(data2);

                    taskBSemaphore.Release();
                    taskASemaphore.Wait();

                    db.Commit();

                    taskBSemaphore.Release();
                });

                // task B will open transaction too and will count 100 original documents only
                // but now, will wait task A finish - but is in transaction and must see only initial version
                var tb = Task.Run(() =>
                {
                    db.BeginTrans();

                    taskBSemaphore.Wait();

                    var count = person.Count();

                    // read 100 documents
                    count.Should().Be(data1.Length);

                    taskASemaphore.Release();
                    taskBSemaphore.Wait();

                    // keep reading 100 documents because i'm still in same transaction
                    count = person.Count();

                    count.Should().Be(data1.Length);
                });

                await Task.WhenAll(ta, tb);
            }
        }
コード例 #7
0
        public async Task Transaction_Write_Lock_Timeout()
        {
            var data1 = DataGen.Person(1, 100).ToArray();
            var data2 = DataGen.Person(101, 200).ToArray();

            using (var db = new LiteDatabase("filename=:memory:"))
            {
                // small timeout
                db.Pragma(Pragmas.TIMEOUT, 1);

                var person = db.GetCollection <Person>();

                // init person collection with 100 document
                person.Insert(data1);

                var taskASemaphore = new SemaphoreSlim(0, 1);
                var taskBSemaphore = new SemaphoreSlim(0, 1);

                // task A will open transaction and will insert +100 documents
                // but will commit only 2s later
                var ta = Task.Run(() =>
                {
                    db.BeginTrans();

                    person.Insert(data2);

                    taskBSemaphore.Release();
                    taskASemaphore.Wait();

                    var count = person.Count();

                    count.Should().Be(data1.Length + data2.Length);

                    db.Commit();
                });

                // task B will try delete all documents but will be locked during 1 second
                var tb = Task.Run(() =>
                {
                    taskBSemaphore.Wait();

                    db.BeginTrans();
                    person
                    .Invoking(personCol => personCol.DeleteMany("1 = 1"))
                    .Should()
                    .Throw <LiteException>()
                    .Where(ex => ex.ErrorCode == LiteException.LOCK_TIMEOUT);

                    taskASemaphore.Release();
                });

                await Task.WhenAll(ta, tb);
            }
        }
コード例 #8
0
        public void Transaction_Write_Lock_Timeout()
        {
            var data1 = DataGen.Person(1, 100).ToArray();
            var data2 = DataGen.Person(101, 200).ToArray();

            using (var db = new LiteDatabase("filename=:memory:;timeout=1"))
            {
                var person = db.GetCollection <Person>();

                // init person collection with 100 document
                person.Insert(data1);

                // task A will open transaction and will insert +100 documents
                // but will commit only 2s later
                var ta = new Task(() =>
                {
                    db.BeginTrans();

                    person.Insert(data2);

                    Task.Delay(4000).Wait();

                    var count = person.Count();

                    Assert.AreEqual(data1.Length + data2.Length, count);

                    db.Commit();
                });

                // task B will try delete all documents but will be locked during 1 second
                var tb = new Task(() =>
                {
                    Task.Delay(250).Wait();

                    db.BeginTrans();

                    try
                    {
                        person.DeleteMany("1 = 1");

                        Assert.Fail("Must be locked");
                    }
                    catch (LiteException ex) when(ex.ErrorCode == LiteException.LOCK_TIMEOUT)
                    {
                    }
                });

                ta.Start();
                tb.Start();

                Task.WaitAll(ta, tb);
            }
        }
コード例 #9
0
        public void Transaction_Read_Version()
        {
            var data1 = DataGen.Person(1, 100).ToArray();
            var data2 = DataGen.Person(101, 200).ToArray();

            using (var db = new LiteDatabase(new MemoryStream()))
            {
                var person = db.GetCollection <Person>();

                // init person collection with 100 document
                person.Insert(data1);

                // task A will insert more 100 documents but will commit only 1s later
                var ta = new Task(() =>
                {
                    db.BeginTrans();

                    person.Insert(data2);

                    Task.Delay(1000).Wait();

                    db.Commit();
                });

                // task B will open transaction too and will count 100 original documents only
                // but now, will wait task A finish - but is in transaction and must see only initial version
                var tb = new Task(() =>
                {
                    db.BeginTrans();

                    Task.Delay(250).Wait();

                    var count = person.Count();

                    // read 100 documents
                    Assert.AreEqual(data1.Length, count);

                    ta.Wait();

                    // keep reading 100 documets because i'm still in same transaction
                    count = person.Count();

                    Assert.AreEqual(data1.Length, count);
                });

                ta.Start();
                tb.Start();

                Task.WaitAll(ta, tb);
            }
        }
コード例 #10
0
        public void Test_Transaction_States()
        {
            var data0 = DataGen.Person(1, 10).ToArray();
            var data1 = DataGen.Person(11, 20).ToArray();

            using (var db = new LiteDatabase(new MemoryStream()))
            {
                var person = db.GetCollection <Person>();

                // first time transaction will be opened
                Assert.IsTrue(db.BeginTrans());

                // but in second type transaction will be same
                Assert.IsFalse(db.BeginTrans());

                person.Insert(data0);

                // must commit transaction
                Assert.IsTrue(db.Commit());

                // no transaction to commit
                Assert.IsFalse(db.Commit());

                // no transaction to rollback;
                Assert.IsFalse(db.Rollback());

                Assert.IsTrue(db.BeginTrans());

                // no page was changed but ok, let's rollback anyway
                Assert.IsTrue(db.Rollback());

                // auto-commit
                person.Insert(data1);

                Assert.AreEqual(20, person.Count());
            }
        }
コード例 #11
0
 public Person_Tests()
 {
     this.local = DataGen.Person().ToArray();
 }