Example #1
0
        public async Task Test_Use_Simple_Layer()
        {
            using (var db = MemoryDatabase.CreateNew("FOO"))
            {
                var location = db.GlobalSpace;

                var map   = new FdbMap <int, string>("Foos", db.GlobalSpace.Partition.ByKey("Foos"), KeyValueEncoders.Values.StringEncoder);
                var index = new FdbIndex <int, string>("Foos.ByColor", db.GlobalSpace.Partition.ByKey("Foos", "Color"));

                using (var tr = db.BeginTransaction(this.Cancellation))
                {
                    map.Set(tr, 3, @"{ ""name"": ""Juliet"", ""color"": ""red"" }");
                    map.Set(tr, 2, @"{ ""name"": ""Joey"", ""color"": ""blue"" }");
                    map.Set(tr, 1, @"{ ""name"": ""Bob"", ""color"": ""red"" }");

                    index.Add(tr, 3, "red");
                    index.Add(tr, 2, "blue");
                    index.Add(tr, 1, "red");

                    await tr.CommitAsync();
                }

                db.Debug_Dump(true);

                //// Collect memory
                //Trace.WriteLine("### GARBAGE COLLECT! ###");
                //db.Collect();
                //db.Debug_Dump();
            }
        }
        public async Task Test_FdbMap_List()
        {
            using (var db = await OpenTestPartitionAsync())
            {
                var location = await GetCleanDirectory(db, "Collections", "Maps");

                var map = new FdbMap <string, string>("Foos", location.Partition("Foos"), KeyValueEncoders.Values.StringEncoder);

                // write a bunch of keys
                await db.WriteAsync((tr) =>
                {
                    map.Set(tr, "foo", "foo_value");
                    map.Set(tr, "bar", "bar_value");
                }, this.Cancellation);

#if DEBUG
                await DumpSubspace(db, location);
#endif

                // read them back

                using (var tr = db.BeginTransaction(this.Cancellation))
                {
                    var value = await map.GetAsync(tr, "foo");

                    Assert.That(value, Is.EqualTo("foo_value"));

                    value = await map.GetAsync(tr, "bar");

                    Assert.That(value, Is.EqualTo("bar_value"));

                    Assert.That(async() => await map.GetAsync(tr, "baz"), Throws.InstanceOf <KeyNotFoundException>());

                    var opt = await map.TryGetAsync(tr, "baz");

                    Assert.That(opt.HasValue, Is.False);
                }
            }
        }
        public async Task Test_FdbMap_List()
        {
            using (var db = await OpenTestPartitionAsync())
            {
                var location = db.Root["Collections"]["Maps"];
                await CleanLocation(db, location);

                var mapFoos = new FdbMap <string, string>(location.ByKey("Foos"), BinaryEncoding.StringEncoder);

                // write a bunch of keys
                await mapFoos.WriteAsync(db, (tr, foos) =>
                {
                    foos.Set(tr, "foo", "foo_value");
                    foos.Set(tr, "bar", "bar_value");
                }, this.Cancellation);

#if FULL_DEBUG
                await DumpSubspace(db, location);
#endif

                // read them back

                await mapFoos.ReadAsync(db, async (tr, foos) =>
                {
                    var value = await foos.GetAsync(tr, "foo");
                    Assert.That(value, Is.EqualTo("foo_value"));

                    value = await foos.GetAsync(tr, "bar");
                    Assert.That(value, Is.EqualTo("bar_value"));

                    Assert.That(async() => await foos.GetAsync(tr, "baz"), Throws.InstanceOf <KeyNotFoundException>());

                    var opt = await foos.TryGetAsync(tr, "baz");
                    Assert.That(opt.HasValue, Is.False);
                }, this.Cancellation);
            }
        }
        public async Task Test_FdbMap_Read_Write_Delete()
        {
            using (var db = await OpenTestPartitionAsync())
            {
                var location = db.Root["Collections"]["Maps"];
                await CleanLocation(db, location);

                var mapFoos = new FdbMap <string, string>(location.ByKey("Foos"), BinaryEncoding.StringEncoder);

                string secret = "world:" + Guid.NewGuid().ToString();

                // read non existing value
                await mapFoos.WriteAsync(db, async (tr, foos) =>
                {
                    Assert.That(async() => await foos.GetAsync(tr, "hello"), Throws.InstanceOf <KeyNotFoundException>());

                    var value = await foos.TryGetAsync(tr, "hello");
                    Assert.That(value.HasValue, Is.False);
                    Assert.That(value.Value, Is.Null);
                }, this.Cancellation);

                // write value
                await mapFoos.WriteAsync(db, (tr, foos) => foos.Set(tr, "hello", secret), this.Cancellation);

#if FULL_DEBUG
                await DumpSubspace(db, location);
#endif

                // read value back
                await mapFoos.ReadAsync(db, async (tr, foos) =>
                {
                    var value = await foos.GetAsync(tr, "hello");
                    Assert.That(value, Is.EqualTo(secret));

                    var opt = await foos.TryGetAsync(tr, "hello");
                    Assert.That(opt.HasValue, Is.True);
                    Assert.That(opt.Value, Is.EqualTo(secret));
                }, this.Cancellation);

                // directly read the value, behind the table's back
                await mapFoos.ReadAsync(db, async (tr, foos) =>
                {
                    var value = await tr.GetAsync(foos.Subspace.AsDynamic().Encode("Foos", "hello"));
                    Assert.That(value, Is.Not.EqualTo(Slice.Nil));
                    Assert.That(value.ToString(), Is.EqualTo(secret));
                }, this.Cancellation);

                // delete the value
                await mapFoos.WriteAsync(db, (tr, foos) => foos.Remove(tr, "hello"), this.Cancellation);

#if FULL_DEBUG
                await DumpSubspace(db, location);
#endif

                // verifiy that it is gone
                await mapFoos.ReadAsync(db, async (tr, foos) =>
                {
                    Assert.That(async() => await foos.GetAsync(tr, "hello"), Throws.InstanceOf <KeyNotFoundException>());

                    var value = await foos.TryGetAsync(tr, "hello");
                    Assert.That(value.HasValue, Is.False);

                    // also check directly
                    var folder = await location.Resolve(tr);
                    var data   = await tr.GetAsync(folder.Encode("Foos", "hello"));
                    Assert.That(data, Is.EqualTo(Slice.Nil));
                }, this.Cancellation);
            }
        }
        public async Task Test_FdbMap_With_Custom_Key_Encoder()
        {
            // Use a table as a backing store for the rules of a Poor Man's firewall, where each keys are the IPEndPoint (tcp only!), and the values are "pass" or "block"

            // Encode IPEndPoint as the (IP, Port,) encoded with the Tuple codec
            // note: there is a much simpler way or creating composite keys, this is just a quick and dirty test!
            var keyEncoder = new KeyEncoder <IPEndPoint>(
                (ipe) => ipe == null ? Slice.Empty : TuPack.EncodeKey(ipe.Address, ipe.Port),
                (packed) =>
            {
                if (packed.IsNullOrEmpty)
                {
                    return(default(IPEndPoint));
                }
                var t = TuPack.Unpack(packed);
                return(new IPEndPoint(t.Get <IPAddress>(0), t.Get <int>(1)));
            }
                );

            var rules = new Dictionary <IPEndPoint, string>()
            {
                { new IPEndPoint(IPAddress.Parse("172.16.12.34"), 6667), "block" },
                { new IPEndPoint(IPAddress.Parse("192.168.34.56"), 80), "pass" },
                { new IPEndPoint(IPAddress.Parse("192.168.34.56"), 443), "pass" }
            };

            using (var db = await OpenTestPartitionAsync())
            {
                var location = db.Root["Collections"]["Maps"];
                await CleanLocation(db, location);

                var mapHosts = new FdbMap <IPEndPoint, string>(location.ByKey("Hosts").AsTyped <IPEndPoint>(keyEncoder), BinaryEncoding.StringEncoder);

                // import all the rules
                await mapHosts.WriteAsync(db, (tr, hosts) =>
                {
                    foreach (var rule in rules)
                    {
                        hosts.Set(tr, rule.Key, rule.Value);
                    }
                }, this.Cancellation);

#if FULL_DEBUG
                await DumpSubspace(db, location);
#endif

                // test the rules

                await mapHosts.ReadAsync(db, async (tr, hosts) =>
                {
                    var value = await hosts.GetAsync(tr, new IPEndPoint(IPAddress.Parse("172.16.12.34"), 6667));
                    Assert.That(value, Is.EqualTo("block"));

                    value = await hosts.GetAsync(tr, new IPEndPoint(IPAddress.Parse("192.168.34.56"), 443));
                    Assert.That(value, Is.EqualTo("pass"));

                    var baz = new IPEndPoint(IPAddress.Parse("172.16.12.34"), 80);
                    Assert.That(async() => await hosts.GetAsync(tr, baz), Throws.InstanceOf <KeyNotFoundException>());

                    var opt = await hosts.TryGetAsync(tr, baz);
                    Assert.That(opt.HasValue, Is.False);
                }, this.Cancellation);
            }
        }
        public async Task Test_FdbMap_Read_Write_Delete()
        {
            using (var db = await OpenTestPartitionAsync())
            {
                var location = await GetCleanDirectory(db, "Collections", "Maps");

                var map = new FdbMap <string, string>("Foos", location.Partition("Foos"), KeyValueEncoders.Values.StringEncoder);

                string secret = "world:" + Guid.NewGuid().ToString();

                // read non existing value
                using (var tr = db.BeginTransaction(this.Cancellation))
                {
                    Assert.That(async() => await map.GetAsync(tr, "hello"), Throws.InstanceOf <KeyNotFoundException>());

                    var value = await map.TryGetAsync(tr, "hello");

                    Assert.That(value.HasValue, Is.False);
                    Assert.That(value.GetValueOrDefault(), Is.Null);
                }

                // write value
                using (var tr = db.BeginTransaction(this.Cancellation))
                {
                    map.Set(tr, "hello", secret);
                    await tr.CommitAsync();
                }

#if DEBUG
                await DumpSubspace(db, location);
#endif

                // read value back
                using (var tr = db.BeginTransaction(this.Cancellation))
                {
                    var value = await map.GetAsync(tr, "hello");

                    Assert.That(value, Is.EqualTo(secret));

                    var opt = await map.TryGetAsync(tr, "hello");

                    Assert.That(opt.HasValue, Is.True);
                    Assert.That(opt.Value, Is.EqualTo(secret));
                }

                // directly read the value, behind the table's back
                using (var tr = db.BeginTransaction(this.Cancellation))
                {
                    var value = await tr.GetAsync(location.Pack("Foos", "hello"));

                    Assert.That(value, Is.Not.EqualTo(Slice.Nil));
                    Assert.That(value.ToString(), Is.EqualTo(secret));
                }

                // delete the value
                using (var tr = db.BeginTransaction(this.Cancellation))
                {
                    map.Remove(tr, "hello");
                    await tr.CommitAsync();
                }

#if DEBUG
                await DumpSubspace(db, location);
#endif

                // verifiy that it is gone
                using (var tr = db.BeginTransaction(this.Cancellation))
                {
                    Assert.That(async() => await map.GetAsync(tr, "hello"), Throws.InstanceOf <KeyNotFoundException>());

                    var value = await map.TryGetAsync(tr, "hello");

                    Assert.That(value.HasValue, Is.False);

                    // also check directly
                    var data = await tr.GetAsync(location.Pack("Foos", "hello"));

                    Assert.That(data, Is.EqualTo(Slice.Nil));
                }
            }
        }
		public async Task Test_Use_Simple_Layer()
		{
			using (var db = MemoryDatabase.CreateNew("FOO"))
			{
				var location = db.GlobalSpace;

				var map = new FdbMap<int, string>("Foos", db.GlobalSpace.Partition.ByKey("Foos"), KeyValueEncoders.Values.StringEncoder);
				var index = new FdbIndex<int, string>("Foos.ByColor", db.GlobalSpace.Partition.ByKey("Foos", "Color"));

				using (var tr = db.BeginTransaction(this.Cancellation))
				{
					map.Set(tr, 3, @"{ ""name"": ""Juliet"", ""color"": ""red"" }");
					map.Set(tr, 2, @"{ ""name"": ""Joey"", ""color"": ""blue"" }");
					map.Set(tr, 1, @"{ ""name"": ""Bob"", ""color"": ""red"" }");

					index.Add(tr, 3, "red");
					index.Add(tr, 2, "blue");
					index.Add(tr, 1, "red");

					await tr.CommitAsync();
				}

				db.Debug_Dump(true);

				//// Collect memory
				//Trace.WriteLine("### GARBAGE COLLECT! ###");
				//db.Collect();
				//db.Debug_Dump();
			}
		}
		public async Task Test_FdbMap_Read_Write_Delete()
		{

			using (var db = await OpenTestPartitionAsync())
			{
				var location = await GetCleanDirectory(db, "Collections", "Maps");

				var map = new FdbMap<string, string>("Foos", location.Partition("Foos"), KeyValueEncoders.Values.StringEncoder);

				string secret = "world:" + Guid.NewGuid().ToString();

				// read non existing value
				using (var tr = db.BeginTransaction(this.Cancellation))
				{
					Assert.That(async () => await map.GetAsync(tr, "hello"), Throws.InstanceOf<KeyNotFoundException>());

					var value = await map.TryGetAsync(tr, "hello");
					Assert.That(value.HasValue, Is.False);
					Assert.That(value.GetValueOrDefault(), Is.Null);
				}

				// write value
				using (var tr = db.BeginTransaction(this.Cancellation))
				{
					map.Set(tr, "hello", secret);
					await tr.CommitAsync();
				}

#if DEBUG
				await DumpSubspace(db, location);
#endif

				// read value back
				using (var tr = db.BeginTransaction(this.Cancellation))
				{
					var value = await map.GetAsync(tr, "hello");
					Assert.That(value, Is.EqualTo(secret));

					var opt = await map.TryGetAsync(tr, "hello");
					Assert.That(opt.HasValue, Is.True);
					Assert.That(opt.Value, Is.EqualTo(secret));
				}

				// directly read the value, behind the table's back
				using (var tr = db.BeginTransaction(this.Cancellation))
				{
					var value = await tr.GetAsync(location.Pack("Foos", "hello"));
					Assert.That(value, Is.Not.EqualTo(Slice.Nil));
					Assert.That(value.ToString(), Is.EqualTo(secret));
				}

				// delete the value
				using (var tr = db.BeginTransaction(this.Cancellation))
				{
					map.Remove(tr, "hello");
					await tr.CommitAsync();
				}

#if DEBUG
				await DumpSubspace(db, location);
#endif

				// verifiy that it is gone
				using (var tr = db.BeginTransaction(this.Cancellation))
				{
					Assert.That(async () => await map.GetAsync(tr, "hello"), Throws.InstanceOf<KeyNotFoundException>());

					var value = await map.TryGetAsync(tr, "hello");
					Assert.That(value.HasValue, Is.False);
					
					// also check directly
					var data = await tr.GetAsync(location.Pack("Foos", "hello"));
					Assert.That(data, Is.EqualTo(Slice.Nil));
				}

			}

		}
		public async Task Test_FdbMap_With_Custom_Key_Encoder()
		{
			// Use a table as a backing store for the rules of a Poor Man's firewall, where each keys are the IPEndPoint (tcp only!), and the values are "pass" or "block"

			// Encode IPEndPoint as the (IP, Port,) encoded with the Tuple codec
			// note: there is a much simpler way or creating composite keys, this is just a quick and dirty test!
			var keyEncoder = KeyValueEncoders.Bind<IPEndPoint>(
				(ipe) => ipe == null ? Slice.Empty : FdbTuple.Pack(ipe.Address, ipe.Port),
				(packed) =>
				{
					if (packed.IsNullOrEmpty) return default(IPEndPoint);
					var t = FdbTuple.Unpack(packed);
					return new IPEndPoint(t.Get<IPAddress>(0), t.Get<int>(1));
				}
			);

			var rules = new Dictionary<IPEndPoint, string>()
			{
				{ new IPEndPoint(IPAddress.Parse("172.16.12.34"), 6667), "block" },
				{ new IPEndPoint(IPAddress.Parse("192.168.34.56"), 80), "pass" },
				{ new IPEndPoint(IPAddress.Parse("192.168.34.56"), 443), "pass" }
			};

			using (var db = await OpenTestPartitionAsync())
			{
				var location = await GetCleanDirectory(db, "Collections", "Maps");

				var map = new FdbMap<IPEndPoint, string>("Firewall", location.Partition("Hosts"), keyEncoder, KeyValueEncoders.Values.StringEncoder);

				// import all the rules
				await db.WriteAsync((tr) =>
				{
					foreach(var rule in rules)
					{
						map.Set(tr, rule.Key, rule.Value);
					}
				}, this.Cancellation);

#if DEBUG
				await DumpSubspace(db, location);
#endif

				// test the rules

				using (var tr = db.BeginTransaction(this.Cancellation))
				{
					var value = await map.GetAsync(tr, new IPEndPoint(IPAddress.Parse("172.16.12.34"), 6667));
					Assert.That(value, Is.EqualTo("block"));

					value = await map.GetAsync(tr, new IPEndPoint(IPAddress.Parse("192.168.34.56"), 443));
					Assert.That(value, Is.EqualTo("pass"));

					var baz = new IPEndPoint(IPAddress.Parse("172.16.12.34"), 80);
					Assert.That(async () => await map.GetAsync(tr, baz), Throws.InstanceOf<KeyNotFoundException>());

					var opt = await map.TryGetAsync(tr, baz);
					Assert.That(opt.HasValue, Is.False);
				}

			}
		}
		public async Task Test_FdbMap_List()
		{
			using (var db = await OpenTestPartitionAsync())
			{
				var location = await GetCleanDirectory(db, "Collections", "Maps");

				var map = new FdbMap<string, string>("Foos", location.Partition("Foos"), KeyValueEncoders.Values.StringEncoder);

				// write a bunch of keys
				await db.WriteAsync((tr) =>
				{
					map.Set(tr, "foo", "foo_value");
					map.Set(tr, "bar", "bar_value");
				}, this.Cancellation);

#if DEBUG
				await DumpSubspace(db, location);
#endif

				// read them back

				using (var tr = db.BeginTransaction(this.Cancellation))
				{
					var value = await map.GetAsync(tr, "foo");
					Assert.That(value, Is.EqualTo("foo_value"));

					value = await map.GetAsync(tr, "bar");
					Assert.That(value, Is.EqualTo("bar_value"));

					Assert.That(async () => await map.GetAsync(tr, "baz"), Throws.InstanceOf<KeyNotFoundException>());

					var opt = await map.TryGetAsync(tr, "baz");
					Assert.That(opt.HasValue, Is.False);
				}

			}
		}