- Add `Json` module to return JSON strings and write JSON as it's read to a `PipeWriter`
- Add `docfx`-based documentation to allow how-to docs and API docs to be generated on the same site

Reviewed-on: #11
This commit was merged in pull request #11.
This commit is contained in:
2025-04-19 19:50:16 +00:00
parent 5580284910
commit 43fed5789a
45 changed files with 13140 additions and 1944 deletions

37
docs/upgrade/v2.md Normal file
View File

@@ -0,0 +1,37 @@
# Migrating from v1 to v2
_NOTE: This was an upgrade for the `BitBadger.Npgsql.Documents` library, which this library replaced as of v3._
## Why
In version 1 of this library, the document tables used by this library had two columns: `id` and `data`. `id` served as the primary key, and `data` was the `JSONB` column for the document. Since its release, the author learned that a field in a `JSONB` column could have a unique index that would then serve the role of a primary key.
Version 2 of this library implements this change, both in table setup and in how it constructs queries that occur by a document's ID.
## How
On the [GitHub release page][], there is a MigrateToV2 utility program - one for Windows, and one for Linux. Download and extract the single file in the archive; it requires no installation. It uses an environment variable for the connection string, and takes a table name and an ID column field via the command line.
A quick example under Linux/bash (assuming the ID field in the JSON document is named `Id`)...
```
export PGDOC_CONN_STR="Host=localhost;Port=5432;User ID=example_user;Password=example_pw;Database=my_docs"
./MigrateToV2 ex.doc_table
./MigrateToV2 ex.another_one
```
If the ID field has a different name, it can be passed as a second parameter. The utility will display the table name and ID field and ask for confirmation; if you are scripting it, you can set the environment variable `PGDOC_I_KNOW_WHAT_I_AM_DOING` to `true`, and it will bypass this confirmation. Note that the utility itself is quite basic; you are responsible for giving it sane input. If you have customized the tables or the JSON serializer, though, keep reading.
## What
If you have extended the original tables, you may need to handle this migration within either PostgreSQL/psql or your code. The process entails two steps. First, create a unique index on the ID field; in this example, we'll use `name` for the example ID field. Then, drop the `id` column. The below SQL will accomplish this for the fictional `my_table` table.
```sql
CREATE UNIQUE INDEX idx_my_table_key ON my_table ((data ->> 'name'));
ALTER TABLE my_table DROP COLUMN id;
```
If the ID field is different, you will also need to tell the library that. Use `Configuration.UseIdField("name")` (C#) / `Configuration.useIdField "name"` (F#) to specify the name. This will need to be done before queries are executed, as the library uses this field for ID queries. See the [Setting Up instructions][setup] for details on this new configuration parameter.
[GitHub release page]: https://github.com/bit-badger/BitBadger.Npgsql.Documents
[setup]: ../getting-started.md#configuring-document-ids "Getting Started • BitBadger.Documents"

11
docs/upgrade/v3.md Normal file
View File

@@ -0,0 +1,11 @@
# Upgrade from v2 to v3
The biggest change with this release is that `BitBadger.Npgsql.Documents` became `BitBadger.Documents`, a set of libraries providing the same API over both PostgreSQL and SQLite (provided the underlying database supports it). Existing PostgreSQL users should have a smooth transition.
* Drop `Npgsql` from namespace (`BitBadger.Npgsql.Documents` becomes `BitBadger.Documents`)
* Add implementation (PostgreSQL namespace is `BitBadger.Documents.Postgres`, SQLite is `BitBadger.Documents.Sqlite`)
* Both C# and F# idiomatic functions will be visible when those namespaces are `import`ed or `open`ed
* There is a `Field` constructor for creating field conditions (though look at [v4][]'s changes here as well)
[v4]: ./v4.md#op-type-removal "Upgrade from v3 to v4 • BitBadger.Documents"

35
docs/upgrade/v4.md Normal file
View File

@@ -0,0 +1,35 @@
# Upgrade from v3 to v4
## The Quick Version
- Add `BitBadger.Documents.[Postgres|Sqlite].Compat` to your list of `using` (C#) or `open` (F#) statements. This namespace has deprecated versions of the methods/functions that were removed in v4. These generate warnings, rather than the "I don't know what this is" compiler errors.
- If your code referenced `Query.[Action].[ById|ByField|etc]`, the sides of the query on each side of the `WHERE` clause are now separate. A query to patch a document by its ID would go from `Query.Patch.ById(tableName)` to `Query.ById(Query.Patch(tableName))`. These functions may also require more parameters; keep reading for details on that.
- Custom queries had to be used when querying more than one field, or when the results in the database needed to be ordered. v4 provides solutions for both of these within the library itself.
## `ByField` to `ByFields` and PostgreSQL Numbers
All methods/functions that ended with `ByField` now end with `ByFields`, and take a `FieldMatch` case (`Any` equates to `OR`, `All` equates to `AND`) and sequence of `Field` objects. These `Field`s need to have their values as well, because the PostgreSQL library will now cast the field from the document to numeric and bind the parameter as-is.
That is an action-packed paragraph; these changes have several ripple effects throughout the library:
- Queries like `Query.Find.ByField` would need the full collection of fields to generate the SQL. Instead, `Query.ByFields` takes a "first-half" statement as its first parameter, then the field match and parameters as its next two.
- `Field` instances in version 3 needed to have a parameter name, which was specified externally to the object itself. In version 4, `ParameterName` is an optional member of the `Field` object, and the library will generate parameter names if it is missing. In both C# and F#, the `.WithParameterName(string)` method can be chained to the `Field.[OP]` call to specify a name, and F# users can also use the language's `with` keyword (`{ Field.EQ "TheField" "value" with ParameterName = Some "@theField" }`).
## `Op` Type Removal
The `Op` type has been replaced with a `Comparison` type which captures both the type of comparison and the object of the comparison in one type. This is considered an internal implementation detail, as that type was not intended for use outside the library; however, it was `public`, so its removal warrants at least a mention.
Additionally, the addition of `In` and `InArray` field comparisons drove a change to the `Field` type's static creation functions. These now have the comparison spelled out, as opposed to the two-to-three character abbreviations. (These abbreviated functions still exists as aliases, so this change will not result in compile errors.) The functions to create fields are:
| Old | New |
|:-----:|-----------------------|
| `EQ` | `Equal` |
| `GT` | `Greater` |
| `GE` | `GreaterOrEqual` |
| `LT` | `Less` |
| `LE` | `LessOrEqual` |
| `NE` | `NotEqual` |
| `BT` | `Between` |
| `IN` | `In` _(since v4 rc1)_ |
| -- | `InArray` _(v4 rc4)_ |
| `EX` | `Exists` |
| `NEX` | `NotExists` |