diff --git a/.gitattributes b/.gitattributes index 045ad95f73..3ad07cd5b2 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,4 +1,4 @@ -* text=auto +* text=auto eol=lf *.sh eol=lf *.png binary *.ttf binary diff --git a/.gitignore b/.gitignore index 85fd23dd87..79c5a47490 100644 --- a/.gitignore +++ b/.gitignore @@ -1,233 +1,233 @@ -## Ignore Visual Studio temporary files, build results, and -## files generated by popular Visual Studio add-ons. - -# User-specific files -*.suo -*.user -*.userosscache -*.sln.docstates - -# User-specific files (MonoDevelop/Xamarin Studio) -*.userprefs - -# Build results -[Dd]ebug/ -[Dd]ebugPublic/ -[Rr]elease/ -[Rr]eleases/ -x64/ -x86/ -bld/ -[Bb]in/ -[Oo]bj/ - -# Visual Studo 2015 cache/options directory -.vs/ - -# MSTest test Results -[Tt]est[Rr]esult*/ -[Bb]uild[Ll]og.* - -packages - -connection.txt - -# NUNIT -*.VisualState.xml -TestResult.xml - -# Build Results of an ATL Project -[Dd]ebugPS/ -[Rr]eleasePS/ -dlldata.c - -*_i.c -*_p.c -*_i.h -*.ilk -*.meta -*.obj -*.pch -*.pdb -*.pgc -*.pgd -*.rsp -*.sbr -*.tlb -*.tli -*.tlh -*.tmp -*.tmp_proj -*.log -*.vspscc -*.vssscc -.builds -*.pidb -*.svclog -*.scc - -# Chutzpah Test files -_Chutzpah* - -# Visual C++ cache files -ipch/ -*.aps -*.ncb -*.opensdf -*.sdf -*.cachefile - -# Visual Studio profiler -*.psess -*.vsp -*.vspx - -# TFS 2012 Local Workspace -$tf/ - -# Guidance Automation Toolkit -*.gpState - -# ReSharper is a .NET coding add-in -_ReSharper*/ -*.[Rr]e[Ss]harper -*.DotSettings.user - -# JustCode is a .NET coding addin-in -.JustCode - -# TeamCity is a build add-in -_TeamCity* - -# DotCover is a Code Coverage Tool -*.dotCover - -# NCrunch -_NCrunch_* -.*crunch*.local.xml - -# MightyMoose -*.mm.* -AutoTest.Net/ - -# Web workbench (sass) -.sass-cache/ - -# Installshield output folder -[Ee]xpress/ - -# DocProject is a documentation generator add-in -DocProject/buildhelp/ -DocProject/Help/*.HxT -DocProject/Help/*.HxC -DocProject/Help/*.hhc -DocProject/Help/*.hhk -DocProject/Help/*.hhp -DocProject/Help/Html2 -DocProject/Help/html - -# Click-Once directory -publish/ - -# Publish Web Output -*.[Pp]ublish.xml -*.azurePubxml -# TODO: Comment the next line if you want to checkin your web deploy settings -# but database connection strings (with potential passwords) will be unencrypted -*.pubxml -*.publishproj - -# NuGet Packages -*.nupkg -*.snupkg -# The packages folder can be ignored because of Package Restore -**/packages/* -# except build/, which is used as an MSBuild target. -!**/packages/build/ -# Uncomment if necessary however generally it will be regenerated when needed -#!**/packages/repositories.config - -# Windows Azure Build Output -csx/ -*.build.csdef - -# Windows Store app package directory -AppPackages/ - -# Others -*.[Cc]ache -ClientBin/ -[Ss]tyle[Cc]op.* -~$* -*~ -*.dbmdl -*.dbproj.schemaview -*.pfx -*.publishsettings -node_modules/ -bower_components/ - -# RIA/Silverlight projects -Generated_Code/ - -# Backup & report files from converting an old project file -# to a newer Visual Studio version. Backup files are not needed, -# because we have git ;-) -_UpgradeReport_Files/ -Backup*/ -UpgradeLog*.XML -UpgradeLog*.htm - -# SQL Server files -*.mdf -*.ldf - -# Business Intelligence projects -*.rdl.data -*.bim.layout -*.bim_*.settings - -# Microsoft Fakes -FakesAssemblies/ - -# Node.js Tools for Visual Studio -.ntvs_analysis.dat - -# Visual Studio 6 build log -*.plg - -# Visual Studio 6 workspace options file -*.opt - -artifacts -src/CommonAssemblyInfo.cs -paket.exe -.idea/ -*.iml - -*.DotSettings - -/results - -# Keeps ELMAH error logs out of the sample app -App_Data/ - -project.lock.json -*.project.lock.json - -src/DinnerParty/public/*.js -src/DinnerParty/public/*.css -src/DinnerParty/public/*.map - -doc-target - -BenchmarkDotNet.Artifacts -*.DS_Store - -stresults.htm - -*.ncrunch* - -docs/.vitepress/dist - -src/CommandLineRunner/Internal/* +## Ignore Visual Studio temporary files, build results, and +## files generated by popular Visual Studio add-ons. + +# User-specific files +*.suo +*.user +*.userosscache +*.sln.docstates + +# User-specific files (MonoDevelop/Xamarin Studio) +*.userprefs + +# Build results +[Dd]ebug/ +[Dd]ebugPublic/ +[Rr]elease/ +[Rr]eleases/ +x64/ +x86/ +bld/ +[Bb]in/ +[Oo]bj/ + +# Visual Studo 2015 cache/options directory +.vs/ + +# MSTest test Results +[Tt]est[Rr]esult*/ +[Bb]uild[Ll]og.* + +packages + +connection.txt + +# NUNIT +*.VisualState.xml +TestResult.xml + +# Build Results of an ATL Project +[Dd]ebugPS/ +[Rr]eleasePS/ +dlldata.c + +*_i.c +*_p.c +*_i.h +*.ilk +*.meta +*.obj +*.pch +*.pdb +*.pgc +*.pgd +*.rsp +*.sbr +*.tlb +*.tli +*.tlh +*.tmp +*.tmp_proj +*.log +*.vspscc +*.vssscc +.builds +*.pidb +*.svclog +*.scc + +# Chutzpah Test files +_Chutzpah* + +# Visual C++ cache files +ipch/ +*.aps +*.ncb +*.opensdf +*.sdf +*.cachefile + +# Visual Studio profiler +*.psess +*.vsp +*.vspx + +# TFS 2012 Local Workspace +$tf/ + +# Guidance Automation Toolkit +*.gpState + +# ReSharper is a .NET coding add-in +_ReSharper*/ +*.[Rr]e[Ss]harper +*.DotSettings.user + +# JustCode is a .NET coding addin-in +.JustCode + +# TeamCity is a build add-in +_TeamCity* + +# DotCover is a Code Coverage Tool +*.dotCover + +# NCrunch +_NCrunch_* +.*crunch*.local.xml + +# MightyMoose +*.mm.* +AutoTest.Net/ + +# Web workbench (sass) +.sass-cache/ + +# Installshield output folder +[Ee]xpress/ + +# DocProject is a documentation generator add-in +DocProject/buildhelp/ +DocProject/Help/*.HxT +DocProject/Help/*.HxC +DocProject/Help/*.hhc +DocProject/Help/*.hhk +DocProject/Help/*.hhp +DocProject/Help/Html2 +DocProject/Help/html + +# Click-Once directory +publish/ + +# Publish Web Output +*.[Pp]ublish.xml +*.azurePubxml +# TODO: Comment the next line if you want to checkin your web deploy settings +# but database connection strings (with potential passwords) will be unencrypted +*.pubxml +*.publishproj + +# NuGet Packages +*.nupkg +*.snupkg +# The packages folder can be ignored because of Package Restore +**/packages/* +# except build/, which is used as an MSBuild target. +!**/packages/build/ +# Uncomment if necessary however generally it will be regenerated when needed +#!**/packages/repositories.config + +# Windows Azure Build Output +csx/ +*.build.csdef + +# Windows Store app package directory +AppPackages/ + +# Others +*.[Cc]ache +ClientBin/ +[Ss]tyle[Cc]op.* +~$* +*~ +*.dbmdl +*.dbproj.schemaview +*.pfx +*.publishsettings +node_modules/ +bower_components/ + +# RIA/Silverlight projects +Generated_Code/ + +# Backup & report files from converting an old project file +# to a newer Visual Studio version. Backup files are not needed, +# because we have git ;-) +_UpgradeReport_Files/ +Backup*/ +UpgradeLog*.XML +UpgradeLog*.htm + +# SQL Server files +*.mdf +*.ldf + +# Business Intelligence projects +*.rdl.data +*.bim.layout +*.bim_*.settings + +# Microsoft Fakes +FakesAssemblies/ + +# Node.js Tools for Visual Studio +.ntvs_analysis.dat + +# Visual Studio 6 build log +*.plg + +# Visual Studio 6 workspace options file +*.opt + +artifacts +src/CommonAssemblyInfo.cs +paket.exe +.idea/ +*.iml + +*.DotSettings + +/results + +# Keeps ELMAH error logs out of the sample app +App_Data/ + +project.lock.json +*.project.lock.json + +src/DinnerParty/public/*.js +src/DinnerParty/public/*.css +src/DinnerParty/public/*.map + +doc-target + +BenchmarkDotNet.Artifacts +*.DS_Store + +stresults.htm + +*.ncrunch* + +docs/.vitepress/dist + +src/CommandLineRunner/Internal/* diff --git a/README.md b/README.md index d56cc13e9f..7cb4e60030 100644 --- a/README.md +++ b/README.md @@ -1,171 +1,171 @@ -# Marten -## .NET Transactional Document DB and Event Store on PostgreSQL - -[![Join the chat at https://gitter.im/JasperFx/Marten](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/JasperFx/Marten?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) -![Twitter Follow](https://img.shields.io/twitter/follow/marten_lib?logo=Twitter&style=flat-square) -[![Windows Build Status](https://ci.appveyor.com/api/projects/status/va5br63j7sbx74cm/branch/master?svg=true)](https://ci.appveyor.com/project/jasper-ci/marten/branch/master) -[![Linux Build status](https://dev.azure.com/jasperfx-marten/marten/_apis/build/status/marten?branchName=master)](https://dev.azure.com/jasperfx-marten/marten/_build/latest?definitionId=1&branchName=master) -[![Nuget Package](https://badgen.net/nuget/v/marten)](https://www.nuget.org/packages/Marten/) -[![Nuget](https://img.shields.io/nuget/dt/marten)](https://www.nuget.org/packages/Marten/) - -![marten logo](https://martendb.io/v3/content/images/banner.png) - -The Marten library provides .NET developers with the ability to use the proven [PostgreSQL database engine](http://www.postgresql.org/) and its [fantastic JSON support](https://www.compose.io/articles/is-postgresql-your-next-json-database/) as a fully fledged [document database](https://en.wikipedia.org/wiki/Document-oriented_database). The Marten team believes that a document database has far reaching benefits for developer productivity over relational databases with or without an ORM tool. - -Marten also provides .NET developers with an ACID-compliant event store with user-defined projections against event streams. - -Access docs [here](https://martendb.io/) and v3.x docs [here](https://martendb.io/v3). - -## Working with the Code - -Before getting started you will need the following in your environment: - -**1. .NET Core SDK 5.0+ and the .NET Core 3.1 Runtime** - -Available [here](https://dotnet.microsoft.com/download) - -**2. PostgreSQL 9.6 or above database with PLV8** - -The fastest possible way to develop with Marten is to run PostgreSQL in a Docker container. Assuming that you have -Docker running on your local box, type `dotnet run --framework net6.0 -- init-db` at the command line to spin up a Postgresql database with -PLv8 enabled and configured in the database. The default Marten test configuration tries to find this database if no -PostgreSQL database connection string is explicitly configured following the steps below: - -You need to enable the PLV8 extension inside of PostgreSQL for running JavaScript stored procedures for the nascent projection support. - -Ensure the following: - -- The login you are using to connect to your database is a member of the `postgres` role -- An environment variable of `marten_testing_database` is set to the connection string for the database you want to use as a testbed. (See the [Npgsql documentation](http://www.npgsql.org/doc/connection-string-parameters.html) for more information about PostgreSQL connection strings ). - -_Help with PSQL/PLV8_ - -- On Windows, see [this link](http://www.postgresonline.com/journal/archives/360-PLV8-binaries-for-PostgreSQL-9.5-windows-both-32-bit-and-64-bit.html) for pre-built binaries of PLV8 -- On *nix, check [marten-local-db](https://github.com/eouw0o83hf/marten-local-db) for a Docker based PostgreSQL instance including PLV8. - -Once you have the codebase and the connection string file, run the [build command](https://github.com/JasperFx/marten#build-commands) or use the dotnet CLI to restore and build the solution. - -You are now ready to contribute to Marten. - -See more in [Contribution Guidelines](CONTRIBUTING.md). - -### Tooling - -* Unit Tests rely on [xUnit](http://xunit.github.io/) and [Shouldly](https://github.com/shouldly/shouldly) -* [Bullseye](https://github.com/adamralph/bullseye) is used for build automation. -* [Node.js](https://nodejs.org/en/) runs our Mocha specs. -* [Storyteller](http://storyteller.github.io) for some of the data intensive automated tests - -### Build Commands - -| Description | Windows Commandline | PowerShell | Linux Shell | DotNet CLI | -| ----------------------------------- | ------------------------ | ------------------------ | ----------------------- | -------------------------------------------------- | -| Run restore, build and test | `build.cmd` | `build.ps1` | `build.sh` | `dotnet build src\Marten.sln` | -| Run all tests including mocha tests | `build.cmd test` | `build.ps1 test` | `build.sh test` | `dotnet run -p build/build.csproj -- test` | -| Run just mocha tests | `build.cmd mocha` | `build.ps1 mocha` | `build.sh mocha` | `dotnet run -p build/build.csproj -- mocha` | -| Run StoryTeller tests | `build.cmd storyteller` | `build.ps1 storyteller` | `build.sh storyteller` | `dotnet run -p build/build.csproj -- storyteller` | -| Open StoryTeller editor | `build.cmd open_st` | `build.ps1 open_st` | `build.sh open_st` | `dotnet run -p build/build.csproj -- open_st` | -| Run docs website locally | `build.cmd docs` | `build.ps1 docs` | `build.ps1 docs` | `dotnet run -p build/build.csproj -- docs` | -| Publish docs | `build.cmd publish-docs` | `build.ps1 publish-docs` | `build.sh publish-docs` | `dotnet run -p build/build.csproj -- publish-docs` | -| Run benchmarks | `build.cmd benchmarks` | `build.ps1 benchmarks` | `build.sh benchmarks` | `dotnet run -p build/build.csproj -- benchmarks` | - -> Note: You should have a running Postgres instance while running unit tests or StoryTeller tests. - -### xUnit.Net Specs - -The tests for the main library are now broken into three testing projects: - -1. `CoreTests` -- basic services like retries, schema management basics -1. `DocumentDbTests` -- anything specific to the document database features of Marten -1. `EventSourcingTests` -- anything specific to the event sourcing features of Marten - -To aid in integration testing, Marten.Testing has a couple reusable base classes that can be use -to make integration testing through Postgresql be more efficient and allow the xUnit.Net tests -to run in parallel for better throughput. - - -- `IntegrationContext` -- if most of the tests will use an out of the box configuration - (i.e., no fluent interface configuration of any document types), use this base type. Warning though, - this context type will **not** clean out the main `public` database schema between runs, - but will delete any existing data -- `DestructiveIntegrationContext` -- similar to `IntegrationContext`, but will wipe out any and all - Postgresql schema objects in the `public` schema between tests. Use this sparingly please. -- `OneOffConfigurationsContext` -- if a test suite will need to frequently re-configure - the `DocumentStore`, this context is appropriate. You do *not* need to decorate any of these - test classes with the `[Collection]` attribute. This fixture will use an isolated schema using the name of the - test fixture type as the schema name -- `BugIntegrationContext` -- the test harnesses for bugs tend to require custom `DocumentStore` - configuration, and this context is a specialization of `OneOffConfigurationsContext` for - the *bugs* schema. -- `StoreFixture` and `StoreContext` are helpful if a series of tests use the same custom - `DocumentStore` configuration. You'd need to write a subclass of `StoreFixture`, then use - `StoreContext` as the base class to share the `DocumentStore` between - test runs with xUnit.Net's shared context (`IClassFixture`) - -### Mocha Specs - -Refer to the build commands section to look up the commands to run Mocha tests. There is also `npm run tdd` to run the mocha specifications -in a watched mode with growl turned on. - -> Note: remember to run `npm install` - -### Storyteller Specs - -Refer to build commands section to look up the commands to open the StoryTeller editor or run the StoryTeller specs. - -## Documentation - -All the documentation is written in Markdown and the docs are published as a static site hosted in Netlify. v4.x and v3.x use different documentation tools hence are detailed below in separate sub-sections. - -### v4.x and above - -[VitePress](https://vitepress.vuejs.org/) is used as documentation tool. Along with this, [MarkdownSnippets](https://github.com/SimonCropp/MarkdownSnippets) is used for adding code snippets to docs from source code and [Algolia DocSearch](https://docsearch.algolia.com/) is used for searching the docs via the search box. - -The documentation content is the Markdown files in the `/docs` directory directly under the project root. To run the docs locally use `npm run docs` with auto-refresh on any changes. - -To add code samples/snippets from the tests in docs, follow the steps below: - -Use C# named regions to mark a code block as described in the sample below - -```csharp -#region sample_my_snippet -// code sample/snippet -// ... -#endregion -``` - -All code snippet identifier starts with `sample_` as a convention to clearly identify that the region block corresponds to a sample code/snippet used in docs. Recommend to use snake case for the identifiers with words in lower case. - -Use the below to include the code snippet in a docs page - -
-<!-- snippet: sample_my_snippet -->
-<!-- endSnippet -->
-
- -Note that when you run the docs locally, the above placeholder block in the Markdown file will get updated inline with the actual code snippet from the source code. Please commit the changes with the auto-generated inline code snippet as-is after you preview the docs page. This helps with easier change tracking when you send PR's. - -Few gotchas: - -- Any changes to the code snippets will need to done in the source code. Do not edit/update any of the auto-generated inline code snippet directly in the Markdown files. -- The latest snippet are always pulled into the docs while we publish the docs. Hence do not worry about the inline code snippet in Markdown file getting out of sync with the snippet in source code. - -### v3.x - -[stdocs](https://www.nuget.org/packages/dotnet-stdocs/) is used as documentation tool. The documentation content is the markdown files in the `/documentation` directory directly under the project root. Any updates to v3.x docs will need to done in [3.14 branch](https://github.com/JasperFx/marten/tree/3.14). To run the documentation website locally with auto-refresh, refer to the build commands section above. - -If you wish to insert code samples/snippet to a documentation page from the tests, wrap the code you wish to insert with -`// SAMPLE: name-of-sample` and `// ENDSAMPLE`. -Then to insert that code to the documentation, add `<[sample:name-of-sample]>`. - -> Note: content is published to the `gh-pages` branch of this repository. Refer to build commands section to lookup the command for publishing docs. - -## License - -Copyright © Jeremy D. Miller, Babu Annamalai, Oskar Dudycz, Joona-Pekka Kokko and contributors. - -Marten is provided as-is under the MIT license. For more information see [LICENSE](LICENSE). - -## Code of Conduct - -This project has adopted the code of conduct defined by the [Contributor Covenant](http://contributor-covenant.org/) to clarify expected behavior in our community. +# Marten +## .NET Transactional Document DB and Event Store on PostgreSQL + +[![Join the chat at https://gitter.im/JasperFx/Marten](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/JasperFx/Marten?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) +![Twitter Follow](https://img.shields.io/twitter/follow/marten_lib?logo=Twitter&style=flat-square) +[![Windows Build Status](https://ci.appveyor.com/api/projects/status/va5br63j7sbx74cm/branch/master?svg=true)](https://ci.appveyor.com/project/jasper-ci/marten/branch/master) +[![Linux Build status](https://dev.azure.com/jasperfx-marten/marten/_apis/build/status/marten?branchName=master)](https://dev.azure.com/jasperfx-marten/marten/_build/latest?definitionId=1&branchName=master) +[![Nuget Package](https://badgen.net/nuget/v/marten)](https://www.nuget.org/packages/Marten/) +[![Nuget](https://img.shields.io/nuget/dt/marten)](https://www.nuget.org/packages/Marten/) + +![marten logo](https://martendb.io/v3/content/images/banner.png) + +The Marten library provides .NET developers with the ability to use the proven [PostgreSQL database engine](http://www.postgresql.org/) and its [fantastic JSON support](https://www.compose.io/articles/is-postgresql-your-next-json-database/) as a fully fledged [document database](https://en.wikipedia.org/wiki/Document-oriented_database). The Marten team believes that a document database has far reaching benefits for developer productivity over relational databases with or without an ORM tool. + +Marten also provides .NET developers with an ACID-compliant event store with user-defined projections against event streams. + +Access docs [here](https://martendb.io/) and v3.x docs [here](https://martendb.io/v3). + +## Working with the Code + +Before getting started you will need the following in your environment: + +**1. .NET Core SDK 5.0+ and the .NET Core 3.1 Runtime** + +Available [here](https://dotnet.microsoft.com/download) + +**2. PostgreSQL 9.6 or above database with PLV8** + +The fastest possible way to develop with Marten is to run PostgreSQL in a Docker container. Assuming that you have +Docker running on your local box, type `dotnet run --framework net6.0 -- init-db` at the command line to spin up a Postgresql database with +PLv8 enabled and configured in the database. The default Marten test configuration tries to find this database if no +PostgreSQL database connection string is explicitly configured following the steps below: + +You need to enable the PLV8 extension inside of PostgreSQL for running JavaScript stored procedures for the nascent projection support. + +Ensure the following: + +- The login you are using to connect to your database is a member of the `postgres` role +- An environment variable of `marten_testing_database` is set to the connection string for the database you want to use as a testbed. (See the [Npgsql documentation](http://www.npgsql.org/doc/connection-string-parameters.html) for more information about PostgreSQL connection strings ). + +_Help with PSQL/PLV8_ + +- On Windows, see [this link](http://www.postgresonline.com/journal/archives/360-PLV8-binaries-for-PostgreSQL-9.5-windows-both-32-bit-and-64-bit.html) for pre-built binaries of PLV8 +- On *nix, check [marten-local-db](https://github.com/eouw0o83hf/marten-local-db) for a Docker based PostgreSQL instance including PLV8. + +Once you have the codebase and the connection string file, run the [build command](https://github.com/JasperFx/marten#build-commands) or use the dotnet CLI to restore and build the solution. + +You are now ready to contribute to Marten. + +See more in [Contribution Guidelines](CONTRIBUTING.md). + +### Tooling + +* Unit Tests rely on [xUnit](http://xunit.github.io/) and [Shouldly](https://github.com/shouldly/shouldly) +* [Bullseye](https://github.com/adamralph/bullseye) is used for build automation. +* [Node.js](https://nodejs.org/en/) runs our Mocha specs. +* [Storyteller](http://storyteller.github.io) for some of the data intensive automated tests + +### Build Commands + +| Description | Windows Commandline | PowerShell | Linux Shell | DotNet CLI | +| ----------------------------------- | ------------------------ | ------------------------ | ----------------------- | -------------------------------------------------- | +| Run restore, build and test | `build.cmd` | `build.ps1` | `build.sh` | `dotnet build src\Marten.sln` | +| Run all tests including mocha tests | `build.cmd test` | `build.ps1 test` | `build.sh test` | `dotnet run -p build/build.csproj -- test` | +| Run just mocha tests | `build.cmd mocha` | `build.ps1 mocha` | `build.sh mocha` | `dotnet run -p build/build.csproj -- mocha` | +| Run StoryTeller tests | `build.cmd storyteller` | `build.ps1 storyteller` | `build.sh storyteller` | `dotnet run -p build/build.csproj -- storyteller` | +| Open StoryTeller editor | `build.cmd open_st` | `build.ps1 open_st` | `build.sh open_st` | `dotnet run -p build/build.csproj -- open_st` | +| Run docs website locally | `build.cmd docs` | `build.ps1 docs` | `build.ps1 docs` | `dotnet run -p build/build.csproj -- docs` | +| Publish docs | `build.cmd publish-docs` | `build.ps1 publish-docs` | `build.sh publish-docs` | `dotnet run -p build/build.csproj -- publish-docs` | +| Run benchmarks | `build.cmd benchmarks` | `build.ps1 benchmarks` | `build.sh benchmarks` | `dotnet run -p build/build.csproj -- benchmarks` | + +> Note: You should have a running Postgres instance while running unit tests or StoryTeller tests. + +### xUnit.Net Specs + +The tests for the main library are now broken into three testing projects: + +1. `CoreTests` -- basic services like retries, schema management basics +1. `DocumentDbTests` -- anything specific to the document database features of Marten +1. `EventSourcingTests` -- anything specific to the event sourcing features of Marten + +To aid in integration testing, Marten.Testing has a couple reusable base classes that can be use +to make integration testing through Postgresql be more efficient and allow the xUnit.Net tests +to run in parallel for better throughput. + + +- `IntegrationContext` -- if most of the tests will use an out of the box configuration + (i.e., no fluent interface configuration of any document types), use this base type. Warning though, + this context type will **not** clean out the main `public` database schema between runs, + but will delete any existing data +- `DestructiveIntegrationContext` -- similar to `IntegrationContext`, but will wipe out any and all + Postgresql schema objects in the `public` schema between tests. Use this sparingly please. +- `OneOffConfigurationsContext` -- if a test suite will need to frequently re-configure + the `DocumentStore`, this context is appropriate. You do *not* need to decorate any of these + test classes with the `[Collection]` attribute. This fixture will use an isolated schema using the name of the + test fixture type as the schema name +- `BugIntegrationContext` -- the test harnesses for bugs tend to require custom `DocumentStore` + configuration, and this context is a specialization of `OneOffConfigurationsContext` for + the *bugs* schema. +- `StoreFixture` and `StoreContext` are helpful if a series of tests use the same custom + `DocumentStore` configuration. You'd need to write a subclass of `StoreFixture`, then use + `StoreContext` as the base class to share the `DocumentStore` between + test runs with xUnit.Net's shared context (`IClassFixture`) + +### Mocha Specs + +Refer to the build commands section to look up the commands to run Mocha tests. There is also `npm run tdd` to run the mocha specifications +in a watched mode with growl turned on. + +> Note: remember to run `npm install` + +### Storyteller Specs + +Refer to build commands section to look up the commands to open the StoryTeller editor or run the StoryTeller specs. + +## Documentation + +All the documentation is written in Markdown and the docs are published as a static site hosted in Netlify. v4.x and v3.x use different documentation tools hence are detailed below in separate sub-sections. + +### v4.x and above + +[VitePress](https://vitepress.vuejs.org/) is used as documentation tool. Along with this, [MarkdownSnippets](https://github.com/SimonCropp/MarkdownSnippets) is used for adding code snippets to docs from source code and [Algolia DocSearch](https://docsearch.algolia.com/) is used for searching the docs via the search box. + +The documentation content is the Markdown files in the `/docs` directory directly under the project root. To run the docs locally use `npm run docs` with auto-refresh on any changes. + +To add code samples/snippets from the tests in docs, follow the steps below: + +Use C# named regions to mark a code block as described in the sample below + +```csharp +#region sample_my_snippet +// code sample/snippet +// ... +#endregion +``` + +All code snippet identifier starts with `sample_` as a convention to clearly identify that the region block corresponds to a sample code/snippet used in docs. Recommend to use snake case for the identifiers with words in lower case. + +Use the below to include the code snippet in a docs page + +
+<!-- snippet: sample_my_snippet -->
+<!-- endSnippet -->
+
+ +Note that when you run the docs locally, the above placeholder block in the Markdown file will get updated inline with the actual code snippet from the source code. Please commit the changes with the auto-generated inline code snippet as-is after you preview the docs page. This helps with easier change tracking when you send PR's. + +Few gotchas: + +- Any changes to the code snippets will need to done in the source code. Do not edit/update any of the auto-generated inline code snippet directly in the Markdown files. +- The latest snippet are always pulled into the docs while we publish the docs. Hence do not worry about the inline code snippet in Markdown file getting out of sync with the snippet in source code. + +### v3.x + +[stdocs](https://www.nuget.org/packages/dotnet-stdocs/) is used as documentation tool. The documentation content is the markdown files in the `/documentation` directory directly under the project root. Any updates to v3.x docs will need to done in [3.14 branch](https://github.com/JasperFx/marten/tree/3.14). To run the documentation website locally with auto-refresh, refer to the build commands section above. + +If you wish to insert code samples/snippet to a documentation page from the tests, wrap the code you wish to insert with +`// SAMPLE: name-of-sample` and `// ENDSAMPLE`. +Then to insert that code to the documentation, add `<[sample:name-of-sample]>`. + +> Note: content is published to the `gh-pages` branch of this repository. Refer to build commands section to lookup the command for publishing docs. + +## License + +Copyright © Jeremy D. Miller, Babu Annamalai, Oskar Dudycz, Joona-Pekka Kokko and contributors. + +Marten is provided as-is under the MIT license. For more information see [LICENSE](LICENSE). + +## Code of Conduct + +This project has adopted the code of conduct defined by the [Contributor Covenant](http://contributor-covenant.org/) to clarify expected behavior in our community. diff --git a/docs/.editorconfig b/docs/.editorconfig new file mode 100644 index 0000000000..ad4e7d816a --- /dev/null +++ b/docs/.editorconfig @@ -0,0 +1,5 @@ +# Editor configuration, see http://editorconfig.org +root = true + +[*] +end_of_line = lf diff --git a/docs/.vscode/settings.json b/docs/.vscode/settings.json index d3def91314..e2f3c0411a 100644 --- a/docs/.vscode/settings.json +++ b/docs/.vscode/settings.json @@ -1,3 +1,6 @@ { - "editor.formatOnSave": false -} + "editor.formatOnPaste": false, + "editor.formatOnSave": true, + "files.eol": "\n" + } + \ No newline at end of file diff --git a/documentation/documentation/documents/configuration/full_text.md b/documentation/documentation/documents/configuration/full_text.md index 38046e1322..5e784e4bad 100644 --- a/documentation/documentation/documents/configuration/full_text.md +++ b/documentation/documentation/documents/configuration/full_text.md @@ -1,72 +1,72 @@ - - -Full Text Indexes in Marten are built based on <[linkto:documentation/documents/configuration/gin_or_gist_index;title=Gin Indexes]> utilizing [Postgres built in Text Search functions](https://www.postgresql.org/docs/10/textsearch-controls.html). This enables the possibility to do more sophisticated searching through text fields. - -
-To use this feature, you will need to use PostgreSQL version 10.0 or above, as this is the first version that support text search function on jsonb column - this is also the data type that Marten use to store it's data. -
- -## Definining Full Text Index through Store options - -Full Text Indexes can be created using the fluent interface of `StoreOptions` like this: - - -* one index for whole document - all document properties values will be indexed - -<[sample:using_whole_document_full_text_index_through_store_options_with_default]> - -
-If you don't specify language (regConfig) - by default it will be created with 'english' value. -
- -* single property - there is possibility to specify specific property to be indexed - -<[sample:using_a_single_property_full_text_index_through_store_options_with_default]> - -* single property with custom settings - -<[sample:using_a_single_property_full_text_index_through_store_options_with_custom_settings]> - -* multiple properties - -<[sample:using_multiple_properties_full_text_index_through_store_options_with_default]> - -* multiple properties with custom settings - -<[sample:using_multiple_properties_full_text_index_through_store_options_with_custom_settings]> - -* more than one index for document with different languages (regConfig) - -<[sample:using_more_than_one_full_text_index_through_store_options_with_different_reg_config]> - -## Defining Full Text Index through Attribute - -Full Text Indexes can be created using the `[FullTextIndex]` attribute like this: - -* one index for whole document - by setting attribute on the class all document properties values will be indexed - -<[sample:using_a_full_text_index_through_attribute_on_class_with_default]> - -* single property - -<[sample:using_a_single_property_full_text_index_through_attribute_with_default]> - -
-If you don't specify regConfig - by default it will be created with 'english' value. -
- -* single property with custom settings - -<[sample:using_a_single_property_full_text_index_through_attribute_with_custom_settings]> - -* multiple properties - -<[sample:using_multiple_properties_full_text_index_through_attribute_with_default]> - -
-To group multiple properties into single index you need to specify the same values in `IndexName` parameters. -
- -* multiple indexes for multiple properties with custom settings - -<[sample:using_multiple_properties_full_text_index_through_attribute_with_custom_settings]> + + +Full Text Indexes in Marten are built based on <[linkto:documentation/documents/configuration/gin_or_gist_index;title=Gin Indexes]> utilizing [Postgres built in Text Search functions](https://www.postgresql.org/docs/10/textsearch-controls.html). This enables the possibility to do more sophisticated searching through text fields. + +
+To use this feature, you will need to use PostgreSQL version 10.0 or above, as this is the first version that support text search function on jsonb column - this is also the data type that Marten use to store it's data. +
+ +## Definining Full Text Index through Store options + +Full Text Indexes can be created using the fluent interface of `StoreOptions` like this: + + +* one index for whole document - all document properties values will be indexed + +<[sample:using_whole_document_full_text_index_through_store_options_with_default]> + +
+If you don't specify language (regConfig) - by default it will be created with 'english' value. +
+ +* single property - there is possibility to specify specific property to be indexed + +<[sample:using_a_single_property_full_text_index_through_store_options_with_default]> + +* single property with custom settings + +<[sample:using_a_single_property_full_text_index_through_store_options_with_custom_settings]> + +* multiple properties + +<[sample:using_multiple_properties_full_text_index_through_store_options_with_default]> + +* multiple properties with custom settings + +<[sample:using_multiple_properties_full_text_index_through_store_options_with_custom_settings]> + +* more than one index for document with different languages (regConfig) + +<[sample:using_more_than_one_full_text_index_through_store_options_with_different_reg_config]> + +## Defining Full Text Index through Attribute + +Full Text Indexes can be created using the `[FullTextIndex]` attribute like this: + +* one index for whole document - by setting attribute on the class all document properties values will be indexed + +<[sample:using_a_full_text_index_through_attribute_on_class_with_default]> + +* single property + +<[sample:using_a_single_property_full_text_index_through_attribute_with_default]> + +
+If you don't specify regConfig - by default it will be created with 'english' value. +
+ +* single property with custom settings + +<[sample:using_a_single_property_full_text_index_through_attribute_with_custom_settings]> + +* multiple properties + +<[sample:using_multiple_properties_full_text_index_through_attribute_with_default]> + +
+To group multiple properties into single index you need to specify the same values in `IndexName` parameters. +
+ +* multiple indexes for multiple properties with custom settings + +<[sample:using_multiple_properties_full_text_index_through_attribute_with_custom_settings]> diff --git a/documentation/documentation/documents/configuration/noda_time.md b/documentation/documentation/documents/configuration/noda_time.md index a26e4e8b59..9a646a6b5c 100644 --- a/documentation/documentation/documents/configuration/noda_time.md +++ b/documentation/documentation/documents/configuration/noda_time.md @@ -11,22 +11,22 @@ See more in: Marten provides **Marten.NodaTime** plugin. That provides nessesary setup. -Install it through the [Nuget package](https://www.nuget.org/packages/Marten.NodaTime/). - -``` -PM> Install-Package Marten.NodaTime +Install it through the [Nuget package](https://www.nuget.org/packages/Marten.NodaTime/). + +``` +PM> Install-Package Marten.NodaTime ``` Then call `UseNodaTime()` method in your `DocumentStore` setup: - + <[sample:noda_time_default_setup]> By default it also sets up the `JsonNetSerializer` options (see more details in [NodaTime documentation](https://nodatime.org/2.4.x/api/NodaTime.Serialization.JsonNet.Extensions.html)). If you're using custom Json serializer or you'd like to maintain fully its configuration then you can set disable default configuration by setting `shouldConfigureJsonNetSerializer` parameter to `false`. By changing this setting you need to configure NodaTime Json serialization by yourself. - + <[sample:noda_time_setup_without_json_net_serializer_configuration]> -
-By using NodaTime plugin - you're opting out of DateTime type handling. Using DateTime in your Document will end up getting NotSupportedException exception. +
+By using NodaTime plugin - you're opting out of DateTime type handling. Using DateTime in your Document will end up getting NotSupportedException exception.
\ No newline at end of file diff --git a/documentation/documentation/documents/configuration/unique.md b/documentation/documentation/documents/configuration/unique.md index 01fa5d2821..8508f3ea12 100644 --- a/documentation/documentation/documents/configuration/unique.md +++ b/documentation/documentation/documents/configuration/unique.md @@ -1,82 +1,82 @@ - - -[Unique Indexes](https://www.postgresql.org/docs/current/static/indexes-unique.html) are used to enforce uniqueness of property value. They can be combined to handle also uniqueness of multiple properties. - -Marten supports both <[linkto:documentation/documents/configuration/duplicated_fields]> and <[linkto:documentation/documents/configuration/computed_index]> uniqueness. Using Duplicated Field brings benefits to queries but brings additional complexity, while Computed Index reuses current JSON structure without adding additional db column. - -## Definining Unique Index through Store options - -Unique Indexes can be created using the fluent interface of `StoreOptions` like this: - -1. **Computed**: - -- single property - -<[sample:using_a_single_property_computed_unique_index_through_store_options]> - -- multiple properties - -<[sample:using_a_multiple_properties_computed_unique_index_through_store_options]> - -
-If you don't specify first parameter (index type) - by default it will be created as computed index. -
- -2. **Duplicated field**: - -- single property - -<[sample:using_a_single_property_duplicate_field_unique_index_through_store_options]> - -- multiple properties - -<[sample:using_a_multiple_properties_duplicate_field_unique_index_through_store_options]> - -## Defining Unique Index through Attribute - -Unique Indexes can be created using the `[UniqueIndex]` attribute like this: - -1. **Computed**: - -- single property - -<[sample:using_a_single_property_computed_unique_index_through_attribute]> - -- multiple properties - -<[sample:using_a_multiple_properties_computed_unique_index_through_store_attribute]> - -
-If you don't specify IndexType parameter - by default it will be created as computed index. -
- -2. **Duplicated field**: - -- single property - -<[sample:using_a_single_property_duplicate_field_unique_index_through_store_attribute]> - -- multiple properties - -<[sample:using_a_multiple_properties_duplicate_field_unique_index_through_attribute]> - -
-To group multiple properties into single index you need to specify the same values in `IndexName` parameters. -
- -## Defining Unique Index through Index customization - -You have some ability to extend to Computed Index definition to be unique index by passing a second Lambda `Action` into -the `Index()` method and definining `IsUnique` property as `true` as shown below: - -<[sample:customizing-calculated-index]> - -Same can be configured for Duplicated Field: - -<[sample:IndexExamples]> - -## Unique Index per Tenant - -For tables which have been configured for <[linkto:documentation/documents/tenancy]>, index definitions may also be scoped per tenant. - -<[sample:per-tenant-unique-index]> + + +[Unique Indexes](https://www.postgresql.org/docs/current/static/indexes-unique.html) are used to enforce uniqueness of property value. They can be combined to handle also uniqueness of multiple properties. + +Marten supports both <[linkto:documentation/documents/configuration/duplicated_fields]> and <[linkto:documentation/documents/configuration/computed_index]> uniqueness. Using Duplicated Field brings benefits to queries but brings additional complexity, while Computed Index reuses current JSON structure without adding additional db column. + +## Definining Unique Index through Store options + +Unique Indexes can be created using the fluent interface of `StoreOptions` like this: + +1. **Computed**: + +- single property + +<[sample:using_a_single_property_computed_unique_index_through_store_options]> + +- multiple properties + +<[sample:using_a_multiple_properties_computed_unique_index_through_store_options]> + +
+If you don't specify first parameter (index type) - by default it will be created as computed index. +
+ +2. **Duplicated field**: + +- single property + +<[sample:using_a_single_property_duplicate_field_unique_index_through_store_options]> + +- multiple properties + +<[sample:using_a_multiple_properties_duplicate_field_unique_index_through_store_options]> + +## Defining Unique Index through Attribute + +Unique Indexes can be created using the `[UniqueIndex]` attribute like this: + +1. **Computed**: + +- single property + +<[sample:using_a_single_property_computed_unique_index_through_attribute]> + +- multiple properties + +<[sample:using_a_multiple_properties_computed_unique_index_through_store_attribute]> + +
+If you don't specify IndexType parameter - by default it will be created as computed index. +
+ +2. **Duplicated field**: + +- single property + +<[sample:using_a_single_property_duplicate_field_unique_index_through_store_attribute]> + +- multiple properties + +<[sample:using_a_multiple_properties_duplicate_field_unique_index_through_attribute]> + +
+To group multiple properties into single index you need to specify the same values in `IndexName` parameters. +
+ +## Defining Unique Index through Index customization + +You have some ability to extend to Computed Index definition to be unique index by passing a second Lambda `Action` into +the `Index()` method and definining `IsUnique` property as `true` as shown below: + +<[sample:customizing-calculated-index]> + +Same can be configured for Duplicated Field: + +<[sample:IndexExamples]> + +## Unique Index per Tenant + +For tables which have been configured for <[linkto:documentation/documents/tenancy]>, index definitions may also be scoped per tenant. + +<[sample:per-tenant-unique-index]> diff --git a/documentation/documentation/events/streams.md b/documentation/documentation/events/streams.md index 11566828ea..a0e7e5a1bb 100644 --- a/documentation/documentation/events/streams.md +++ b/documentation/documentation/events/streams.md @@ -1,40 +1,40 @@ - - - -## Fetch Events for a Stream - -You can retrieve the events for a single stream at any time with the `IEventStore.FetchStream()` methods shown below: - -<[sample:using-fetch-stream]> - -The data returned is a list of `IEvent` objects, where each is a strongly-typed `Event` object shown below: - -<[sample:IEvent]> - -## Stream State - -If you just need to check on the state of an event stream - what version (effectively the number of events in the stream) it is and what, if any, aggregate type it represents - you can use the `IEventStore.FetchStreamState()/FetchStreamStateAsync()` methods or `IBatchQuery.Events.FetchStreamState()`, as shown below: - -<[sample:fetching_stream_state]> - -Furthermore, `StreamState` contains metadata for when the stream was created, `StreamState.Created`, and when the stream was last updated, `StreamState.LastTimestamp`. - -## Fetch a Single Event - -You can fetch the information for a single event by id, including its version number within the stream, by using `IEventStore.Load()` as shown below: - -<[sample:load-a-single-event]> - -## Querying Directly Against Event Data - -We urge caution about this functionality because it requires a search against the entire `mt_events` table. To issue Linq queries against any specific event type, use the method shown below: - -<[sample:query-against-event-data]> - -You can use any Linq operator that Marten supports to query against event data. We think that this functionality is probably more useful for diagnostics or troubleshooting rather than something you would routinely use to support your application. We recommend that you favor event projection views over querying within the raw event table. - -With Marten 1.0, you can issue queries with Marten's full Linq support against the raw event data with this method: - -<[sample:example_of_querying_for_event_data]> - + + + +## Fetch Events for a Stream + +You can retrieve the events for a single stream at any time with the `IEventStore.FetchStream()` methods shown below: + +<[sample:using-fetch-stream]> + +The data returned is a list of `IEvent` objects, where each is a strongly-typed `Event` object shown below: + +<[sample:IEvent]> + +## Stream State + +If you just need to check on the state of an event stream - what version (effectively the number of events in the stream) it is and what, if any, aggregate type it represents - you can use the `IEventStore.FetchStreamState()/FetchStreamStateAsync()` methods or `IBatchQuery.Events.FetchStreamState()`, as shown below: + +<[sample:fetching_stream_state]> + +Furthermore, `StreamState` contains metadata for when the stream was created, `StreamState.Created`, and when the stream was last updated, `StreamState.LastTimestamp`. + +## Fetch a Single Event + +You can fetch the information for a single event by id, including its version number within the stream, by using `IEventStore.Load()` as shown below: + +<[sample:load-a-single-event]> + +## Querying Directly Against Event Data + +We urge caution about this functionality because it requires a search against the entire `mt_events` table. To issue Linq queries against any specific event type, use the method shown below: + +<[sample:query-against-event-data]> + +You can use any Linq operator that Marten supports to query against event data. We think that this functionality is probably more useful for diagnostics or troubleshooting rather than something you would routinely use to support your application. We recommend that you favor event projection views over querying within the raw event table. + +With Marten 1.0, you can issue queries with Marten's full Linq support against the raw event data with this method: + +<[sample:example_of_querying_for_event_data]> + This mechanism will allow you to query by any property of the `IEvent` interface shown above. \ No newline at end of file diff --git a/documentation/migration_guide.md b/documentation/migration_guide.md index bf886fe6e2..82e47d809b 100644 --- a/documentation/migration_guide.md +++ b/documentation/migration_guide.md @@ -1,35 +1,35 @@ - - - -# Key changes in 3.0.0 - -Main goal of this release was to accommodate the **Npgsql 4.*** dependency. - -Besides the usage of Npgsql 4, our biggest change was making the **default schema object creation mode** to `CreateOrUpdate`. Meaning that Marten even in its default mode will not drop any existing tables, even in development mode. You can still opt into the full "sure, I’ll blow away a table and start over if it’s incompatible" mode, but we felt like this option was safer after a few user problems were reported with the previous rules. See <[linkto:documentation/schema/migrations;title=Schema Migrations and Patches]> for more information. - -We also aligned usage of `EnumStorage`. Previously, <[linkto:documentation/documents/configuration/duplicated_fields;title=Enum Duplicated Field]> was always stored as `varchar`. Now it's using setting from `JsonSerializer` options - so by default it's `integer`. We felt that it's not consistent to have different default setting for Enums stored in json and in duplicated fields. - -See full list of the fixed issues on [GitHub](https://github.com/JasperFx/marten/milestone/26?closed=1). - -You can also read more in [Jeremy's blog post from](https://jeremydmiller.com/2018/09/27/marten-3-0-is-released-and-introducing-the-new-core-team/). - -# Migration from 2.* - -- To keep Marten fully rebuilding your schema (so to allow Marten drop tables) set store options to: - -
-AutoCreateSchemaObjects = AutoCreate.All
-
- -- To keep <[linkto:documentation/documents/configuration/duplicated_fields;title=Duplicated Enum Fields]> being stored as `varchar` set store options to: - -
-DuplicatedFieldEnumStorage = EnumStorage.AsString;
-
- - -- To keep <[linkto:documentation/documents/configuration/duplicated_fields;title=Duplicated DateTime Fields]> being stored as `timestamp with time zone` set store options to: - -
-DuplicatedFieldUseTimestampWithoutTimeZoneForDateTime = false;
-
+ + + +# Key changes in 3.0.0 + +Main goal of this release was to accommodate the **Npgsql 4.*** dependency. + +Besides the usage of Npgsql 4, our biggest change was making the **default schema object creation mode** to `CreateOrUpdate`. Meaning that Marten even in its default mode will not drop any existing tables, even in development mode. You can still opt into the full "sure, I’ll blow away a table and start over if it’s incompatible" mode, but we felt like this option was safer after a few user problems were reported with the previous rules. See <[linkto:documentation/schema/migrations;title=Schema Migrations and Patches]> for more information. + +We also aligned usage of `EnumStorage`. Previously, <[linkto:documentation/documents/configuration/duplicated_fields;title=Enum Duplicated Field]> was always stored as `varchar`. Now it's using setting from `JsonSerializer` options - so by default it's `integer`. We felt that it's not consistent to have different default setting for Enums stored in json and in duplicated fields. + +See full list of the fixed issues on [GitHub](https://github.com/JasperFx/marten/milestone/26?closed=1). + +You can also read more in [Jeremy's blog post from](https://jeremydmiller.com/2018/09/27/marten-3-0-is-released-and-introducing-the-new-core-team/). + +# Migration from 2.* + +- To keep Marten fully rebuilding your schema (so to allow Marten drop tables) set store options to: + +
+AutoCreateSchemaObjects = AutoCreate.All
+
+ +- To keep <[linkto:documentation/documents/configuration/duplicated_fields;title=Duplicated Enum Fields]> being stored as `varchar` set store options to: + +
+DuplicatedFieldEnumStorage = EnumStorage.AsString;
+
+ + +- To keep <[linkto:documentation/documents/configuration/duplicated_fields;title=Duplicated DateTime Fields]> being stored as `timestamp with time zone` set store options to: + +
+DuplicatedFieldUseTimestampWithoutTimeZoneForDateTime = false;
+
diff --git a/package-lock.json b/package-lock.json index 16fb9a31e6..ce137746cf 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,5 +1,5 @@ { - "name": "marten_main_repo", + "name": "marten", "lockfileVersion": 2, "requires": true, "packages": {