diff --git a/samples/YesSql.Bench/YesSql.Bench.csproj b/samples/YesSql.Bench/YesSql.Bench.csproj index 21d3e066..9107c622 100644 --- a/samples/YesSql.Bench/YesSql.Bench.csproj +++ b/samples/YesSql.Bench/YesSql.Bench.csproj @@ -1,4 +1,4 @@ - + netcoreapp3.1 portable diff --git a/samples/YesSql.Samples.FullText/Program.cs b/samples/YesSql.Samples.FullText/Program.cs index fc18ef0f..1e72b497 100644 --- a/samples/YesSql.Samples.FullText/Program.cs +++ b/samples/YesSql.Samples.FullText/Program.cs @@ -20,8 +20,7 @@ public static async Task Main(string[] args) } var configuration = new Configuration() - .UseSqLite($"Data Source={filename};Cache=Shared") - ; + .UseSqLite($"Data Source={filename};Cache=Shared"); var store = await StoreFactory.CreateAndInitializeAsync(configuration); diff --git a/samples/YesSql.Samples.FullText/YesSql.Samples.FullText.csproj b/samples/YesSql.Samples.FullText/YesSql.Samples.FullText.csproj index 0a47143b..ab290d70 100644 --- a/samples/YesSql.Samples.FullText/YesSql.Samples.FullText.csproj +++ b/samples/YesSql.Samples.FullText/YesSql.Samples.FullText.csproj @@ -1,4 +1,4 @@ - + netcoreapp3.1 portable diff --git a/samples/YesSql.Samples.Hi/Indexes/BlogPostByTag.cs b/samples/YesSql.Samples.Hi/Indexes/BlogPostByTag.cs new file mode 100644 index 00000000..a7193049 --- /dev/null +++ b/samples/YesSql.Samples.Hi/Indexes/BlogPostByTag.cs @@ -0,0 +1,9 @@ +using YesSql.Indexes; + +namespace YesSql.Samples.Hi.Indexes +{ + public class BlogPostByTag : MapIndex + { + public string Tag { get; set; } + } +} diff --git a/samples/YesSql.Samples.Hi/Indexes/BlogPostIndexProvider.cs b/samples/YesSql.Samples.Hi/Indexes/BlogPostIndexProvider.cs index be9e38db..d399c0b5 100644 --- a/samples/YesSql.Samples.Hi/Indexes/BlogPostIndexProvider.cs +++ b/samples/YesSql.Samples.Hi/Indexes/BlogPostIndexProvider.cs @@ -1,3 +1,4 @@ +using System.Collections.Generic; using System.Linq; using YesSql.Indexes; using YesSql.Samples.Hi.Models; @@ -37,6 +38,10 @@ public override void Describe(DescribeContext context) return index.Count > 0 ? index : null; } ); + + // for each BlogPost, create BlogPostByTag index + context.For() + .Map(blogPost => blogPost.Tags.Select(tag => new BlogPostByTag { Tag = tag })); } } } \ No newline at end of file diff --git a/samples/YesSql.Samples.Hi/Program.cs b/samples/YesSql.Samples.Hi/Program.cs index b290f5e1..1caa27bc 100644 --- a/samples/YesSql.Samples.Hi/Program.cs +++ b/samples/YesSql.Samples.Hi/Program.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Threading.Tasks; using YesSql.Provider.SqlServer; using YesSql.Samples.Hi.Indexes; @@ -18,9 +18,7 @@ static async Task MainAsync(string[] args) { var store = await StoreFactory.CreateAndInitializeAsync( new Configuration() - .UseSqlServer(@"Data Source =.; Initial Catalog = yessql; Integrated Security = True") - .SetTablePrefix("Hi") - ); + .UseSqlServer(@"Data Source =.; Initial Catalog = yessql; Integrated Security = True")); using (var connection = store.Configuration.ConnectionFactory.CreateConnection()) { @@ -35,29 +33,50 @@ static async Task MainAsync(string[] args) .CreateReduceIndexTable(table => table .Column("Count") .Column("Day") - ); + ) + .CreateMapIndexTable(table => table + .Column("Tag") + ); transaction.Commit(); } - }; + } // register available indexes store.RegisterIndexes(); // creating a blog post - var post = new BlogPost + var post1 = new BlogPost { Title = "Hello YesSql", Author = "Bill", - Content = "Hello", + Content = "Hello Bill!", + PublishedUtc = DateTime.UtcNow, + Tags = new[] { "Hello", "YesSql", "Test" } + }; + var post2 = new BlogPost + { + Title = "Bye YesSql", + Author = "Bill", + Content = "Bye Bill!", PublishedUtc = DateTime.UtcNow, - Tags = new[] { "Hello", "YesSql" } + Tags = new[] { "Bye", "YesSql", "Test" } + }; + var post3 = new BlogPost + { + Title = "Other blog title", + Author = "Scott", + Content = "This is also content.", + PublishedUtc = DateTime.UtcNow, + Tags = new[] { "YesSql", "Test", "Blog", "Content" } }; // saving the post to the database using (var session = store.CreateSession()) { - session.Save(post); + session.Save(post1); + session.Save(post2); + session.Save(post3); await session.SaveChangesAsync(); } @@ -66,8 +85,9 @@ static async Task MainAsync(string[] args) using (var session = store.CreateSession()) { var p = await session.Query().For().FirstOrDefaultAsync(); - Console.WriteLine(p.Title); // > Hello YesSql + Console.WriteLine($"First blog: '{p.Title}'"); // > Hello YesSql } + Console.WriteLine(""); // loading blog posts by author using (var session = store.CreateSession()) @@ -76,9 +96,10 @@ static async Task MainAsync(string[] args) foreach (var p in ps) { - Console.WriteLine(p.Author); // > Bill + Console.WriteLine($"'{p.Title}' by {p.Author}"); // > Bill } } + Console.WriteLine(""); // loading blog posts by day of publication using (var session = store.CreateSession()) @@ -87,9 +108,10 @@ static async Task MainAsync(string[] args) foreach (var p in ps) { - Console.WriteLine(p.PublishedUtc); // > [Now] + Console.WriteLine($"'{p.Title}' published on {p.PublishedUtc}"); // > [Now] } } + Console.WriteLine(""); // counting blog posts by day using (var session = store.CreateSession()) @@ -98,9 +120,34 @@ static async Task MainAsync(string[] args) foreach (var day in days) { - Console.WriteLine(day.Day + ": " + day.Count); // > [Today]: 1 + Console.WriteLine($"Blogs count on {day.Day}: {day.Count}"); // > [Today]: 1 + } + } + Console.WriteLine(""); + + // load blog posts with tag "Hello" + using (var session = store.CreateSession()) + { + var ps = await session.Query(x => x.Tag == "Hello").ListAsync(); + + foreach (var p in ps) + { + Console.WriteLine($"'{p.Title}' has 'Hello' tag. Tag list: " + string.Join(", ", p.Tags)); + } + } + Console.WriteLine(""); + + // load blog posts with tag "Test" + using (var session = store.CreateSession()) + { + var ps = await session.Query(x => x.Tag == "Test").ListAsync(); + + foreach (var p in ps) + { + Console.WriteLine($"'{p.Title}' has 'Test' tag. Tag list: " + string.Join(", ", p.Tags)); } } + Console.WriteLine(""); } } } \ No newline at end of file diff --git a/samples/YesSql.Samples.Hi/YesSql.Samples.Hi.csproj b/samples/YesSql.Samples.Hi/YesSql.Samples.Hi.csproj index 648d6714..9b27c63d 100644 --- a/samples/YesSql.Samples.Hi/YesSql.Samples.Hi.csproj +++ b/samples/YesSql.Samples.Hi/YesSql.Samples.Hi.csproj @@ -1,4 +1,4 @@ - + netcoreapp3.1 portable @@ -17,7 +17,6 @@ false - \ No newline at end of file diff --git a/samples/YesSql.Samples.Performance/YesSql.Samples.Performance.csproj b/samples/YesSql.Samples.Performance/YesSql.Samples.Performance.csproj index 569e5974..59ea25e7 100644 --- a/samples/YesSql.Samples.Performance/YesSql.Samples.Performance.csproj +++ b/samples/YesSql.Samples.Performance/YesSql.Samples.Performance.csproj @@ -1,4 +1,4 @@ - + net5.0 YesSql.Samples.Performance diff --git a/samples/YesSql.Samples.Web/Controllers/HomeController.cs b/samples/YesSql.Samples.Web/Controllers/HomeController.cs index cc4b0a4d..ffbf7c63 100644 --- a/samples/YesSql.Samples.Web/Controllers/HomeController.cs +++ b/samples/YesSql.Samples.Web/Controllers/HomeController.cs @@ -9,6 +9,7 @@ using YesSql.Samples.Web.ModelBinding; using YesSql.Samples.Web.ViewModels; using YesSql.Samples.Web.Services; +using System.Linq; namespace YesSql.Samples.Web.Controllers { @@ -61,7 +62,19 @@ public async Task Index([ModelBinder(BinderType = typeof(QueryFil { new SelectListItem("Newest", BlogPostSort.Newest.ToString(), search.SelectedSort == BlogPostSort.Newest), new SelectListItem("Oldest", BlogPostSort.Oldest.ToString(), search.SelectedSort == BlogPostSort.Oldest) - }; + }; + + var tags = (BlogPostTags[])Enum.GetValues(typeof(BlogPostTags)); + search.Tags = new List(); + foreach(var value in tags) + { + var name = value.ToString(); + search.Tags.Add(new SelectListItem( + value == BlogPostTags.Default ? "Select..." : name, + value == BlogPostTags.Default ? "" : name, + search.SelectedTag == value) + ); + } var vm = new BlogPostViewModel { diff --git a/samples/YesSql.Samples.Web/Indexes/BlogPostIndexProvider.cs b/samples/YesSql.Samples.Web/Indexes/BlogPostIndexProvider.cs index 987d7161..3f956a1b 100644 --- a/samples/YesSql.Samples.Web/Indexes/BlogPostIndexProvider.cs +++ b/samples/YesSql.Samples.Web/Indexes/BlogPostIndexProvider.cs @@ -1,4 +1,5 @@ -using System; +using System; +using System.Linq; using YesSql.Indexes; using YesSql.Samples.Web.Models; @@ -11,9 +12,15 @@ public class BlogPostIndex : MapIndex public string Author { get; set; } public string Content { get; set; } + public DateTime PublishedUtc { get; set; } + public bool Published { get; set; } + } + public class BlogPostByTag : MapIndex + { + public string Tag { get; set; } } public class BlogPostIndexProvider : IndexProvider @@ -30,6 +37,12 @@ public override void Describe(DescribeContext context) PublishedUtc = blogPost.PublishedUtc, Published = blogPost.Published }); + + + // for each BlogPost, create BlogPostByTag index + context + .For() + .Map(blogPost => blogPost.Tags.Select(tag => new BlogPostByTag { Tag = tag })); } } } diff --git a/samples/YesSql.Samples.Web/Models/BlogPost.cs b/samples/YesSql.Samples.Web/Models/BlogPost.cs index 4927586e..2fdd9d0a 100644 --- a/samples/YesSql.Samples.Web/Models/BlogPost.cs +++ b/samples/YesSql.Samples.Web/Models/BlogPost.cs @@ -13,6 +13,7 @@ public class BlogPost public string Content { get; set; } public DateTime PublishedUtc { get; set; } + public bool Published { get; set; } public string[] Tags { get; set; } diff --git a/samples/YesSql.Samples.Web/Startup.cs b/samples/YesSql.Samples.Web/Startup.cs index 871a2f37..67aa3f4a 100644 --- a/samples/YesSql.Samples.Web/Startup.cs +++ b/samples/YesSql.Samples.Web/Startup.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.IO; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; @@ -113,6 +113,42 @@ public void ConfigureServices(IServiceCollection services) }) .AlwaysRun() ) + .WithNamedTerm("tag", b => b + .OneCondition((val, query) => + { + if (Enum.TryParse(val, true, out var e)) + { + switch (e) + { + case BlogPostTags.Default: + break; + default: + query.With(x => x.Tag == val); + break; + } + } + + return query; + }) + .MapTo((val, model) => + { + if (Enum.TryParse(val, true, out var e)) + { + model.SelectedTag = e; + } + }) + .MapFrom((model) => + { + if (model.SelectedTag != BlogPostTags.Default) + { + return (true, model.SelectedTag.ToString()); + } + + return (false, String.Empty); + + }) + .AlwaysRun() + ) .WithDefaultTerm("title", b => b .ManyCondition( ((val, query) => query.With(x => x.Title.Contains(val))), @@ -148,8 +184,12 @@ public void Configure(IApplicationBuilder app, IWebHostEnvironment env) .Column("Content") .Column("PublishedUtc") .Column("Published") + ) + .CreateMapIndexTable(table => table + .Column("Tag") ); + transaction.Commit(); } } @@ -163,7 +203,7 @@ public void Configure(IApplicationBuilder app, IWebHostEnvironment env) Content = "Steves first post", PublishedUtc = DateTime.UtcNow, Published = false, - Tags = Array.Empty() + Tags = new[] { "Steve", "beach", "sand", "first" } }); session.Save(new BlogPost @@ -173,7 +213,7 @@ public void Configure(IApplicationBuilder app, IWebHostEnvironment env) Content = "Bill first post", PublishedUtc = DateTime.UtcNow, Published = true, - Tags = Array.Empty() + Tags = new[] { "Bill", "beach", "first", "sand" } }); session.Save(new BlogPost @@ -183,7 +223,7 @@ public void Configure(IApplicationBuilder app, IWebHostEnvironment env) Content = "Pauls first post", PublishedUtc = DateTime.UtcNow, Published = true, - Tags = Array.Empty() + Tags = new[] { "Paul", "snow", "first", "mountain", "lake" } }); session.SaveChangesAsync().GetAwaiter().GetResult(); diff --git a/samples/YesSql.Samples.Web/ViewModels/BlogPostViewModel.cs b/samples/YesSql.Samples.Web/ViewModels/BlogPostViewModel.cs index 8608c9b3..78b1d9fe 100644 --- a/samples/YesSql.Samples.Web/ViewModels/BlogPostViewModel.cs +++ b/samples/YesSql.Samples.Web/ViewModels/BlogPostViewModel.cs @@ -21,6 +21,7 @@ public class Filter public string OriginalSearchText { get; set; } public BlogPostStatus SelectedStatus { get; set; } public BlogPostSort SelectedSort { get; set; } + public BlogPostTags SelectedTag { get; set; } [ModelBinder(BinderType = typeof(QueryFilterEngineModelBinder), Name = nameof(SearchText))] public QueryFilterResult FilterResult { get; set; } @@ -30,11 +31,15 @@ public class Filter [BindNever] public List Sorts { get; set; } = new(); + + [BindNever] + public List Tags { get; set; } = new(); } public enum BlogPostStatus { Default, + Draft, Published } @@ -44,4 +49,19 @@ public enum BlogPostSort Newest, Oldest, } + + public enum BlogPostTags + { + Default, + + First, + Bill, + Steve, + Paul, + Beach, + Sand, + Mountain, + Snow, + Lake + } } diff --git a/samples/YesSql.Samples.Web/Views/Home/Index.cshtml b/samples/YesSql.Samples.Web/Views/Home/Index.cshtml index fd053b1f..39181f97 100644 --- a/samples/YesSql.Samples.Web/Views/Home/Index.cshtml +++ b/samples/YesSql.Samples.Web/Views/Home/Index.cshtml @@ -11,7 +11,7 @@
- +
@@ -31,11 +31,17 @@
-
+
+ +
+ +
+ +
- - + +
@foreach (var blogPost in Model.BlogPosts) @@ -45,6 +51,14 @@

@blogPost.Title

By: @blogPost.Author - Posted: @@ @blogPost.PublishedUtc

@blogPost.Content

+

+ @foreach (var tag in blogPost.Tags) + { + + #@tag + + } +

} diff --git a/src/YesSql.Abstractions/YesSql.Abstractions.csproj b/src/YesSql.Abstractions/YesSql.Abstractions.csproj index 5109f18b..bad58990 100644 --- a/src/YesSql.Abstractions/YesSql.Abstractions.csproj +++ b/src/YesSql.Abstractions/YesSql.Abstractions.csproj @@ -1,4 +1,4 @@ - + diff --git a/src/YesSql.Core/YesSql.Core.csproj b/src/YesSql.Core/YesSql.Core.csproj index 0b4003de..6bbddd25 100644 --- a/src/YesSql.Core/YesSql.Core.csproj +++ b/src/YesSql.Core/YesSql.Core.csproj @@ -21,5 +21,4 @@ - \ No newline at end of file diff --git a/src/YesSql.Provider.MySql/YesSql.Provider.MySql.csproj b/src/YesSql.Provider.MySql/YesSql.Provider.MySql.csproj index e4dd5864..6f963bba 100644 --- a/src/YesSql.Provider.MySql/YesSql.Provider.MySql.csproj +++ b/src/YesSql.Provider.MySql/YesSql.Provider.MySql.csproj @@ -1,4 +1,4 @@ - + diff --git a/src/YesSql.Provider.PostgreSql/YesSql.Provider.PostgreSql.csproj b/src/YesSql.Provider.PostgreSql/YesSql.Provider.PostgreSql.csproj index a72e6479..5edcb139 100644 --- a/src/YesSql.Provider.PostgreSql/YesSql.Provider.PostgreSql.csproj +++ b/src/YesSql.Provider.PostgreSql/YesSql.Provider.PostgreSql.csproj @@ -1,4 +1,4 @@ - + diff --git a/src/YesSql.Provider.SqlServer/YesSql.Provider.SqlServer.csproj b/src/YesSql.Provider.SqlServer/YesSql.Provider.SqlServer.csproj index faae7d15..185782d1 100644 --- a/src/YesSql.Provider.SqlServer/YesSql.Provider.SqlServer.csproj +++ b/src/YesSql.Provider.SqlServer/YesSql.Provider.SqlServer.csproj @@ -1,4 +1,4 @@ - + diff --git a/src/YesSql.Provider.Sqlite/YesSql.Provider.Sqlite.csproj b/src/YesSql.Provider.Sqlite/YesSql.Provider.Sqlite.csproj index ae9f331d..f4c86103 100644 --- a/src/YesSql.Provider.Sqlite/YesSql.Provider.Sqlite.csproj +++ b/src/YesSql.Provider.Sqlite/YesSql.Provider.Sqlite.csproj @@ -1,4 +1,4 @@ - +