rust-query 0.9.2

A query builder using rust concepts.
Documentation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
# Unreleased

# 0.9.2

- Fixed bug in `Rows::filter_some` (it would filter out `Some(false)`).
- Added support for renaming the primary key with `#[primary_key("new_name")]`.
- Improved `#[schema]` docs.

# 0.9.1

- Renamed private feature `mutants` to `__mutants`.
- Updated `k12` from `0.3` to `0.5`.
- Added keywords to `Cargo.toml`.

# 0.9.0

The dependency removal update.

- Added support for renaming tables with foreign key constraints to them.
- Updated rust-version to `1.95`
- Updated `rusqlite` (and removed `modern_sqlite` feature).
- Removed `sea-query`, `sqlite3-parser`, `r2d2` and `r2d2-sqlite` dependencies.
- Check that tables are `STRICT`.

# 0.8.1

- Fix `rust-query` not compiling when using the `jiff-02` feature without the `bundled` feature.

# 0.8.0

- Added support for `jiff::Timestamp` and `jiff::civil::Date` with check constraints.
- Added methods `Expr::to_second`, `Expr::subsec_nanosecond`, `Expr::from_second`,
  `Expr::add_nanosecond`, `Expr::to_date_in_tz`, `Expr::year`, `Expr::month`, `Expr::day`,
  `Expr::first_of_month`, `Expr::add_day`.

## Breaking

- Deprecated `Expr::unix_epoch`. Create timestamps outside of rust-query instead.
- Fixed missing check constraint for `Option<bool>` columns.
  For backwards compatibility, you have to change these columns in your schema to`Option<i64>`.
  Then you can define a migration to change the column type to `Option<bool>` with check constraint.

Make sure to use `rust_query::migration::hash_schema` to check that you migrated correctly.
```rust
// this code uses rust-query 0.7.1
#[rust_query::migration::schema(Schema)]
pub mod vN {
    pub struct Foo {
        pub some_col: Option<bool>,
    }
}

#[test]
fn schema_hash() {
    use rust_query::migration::hash_schema;
    expect_test::expect!["b5feac749e55f5bf"].assert_eq(&hash_schema::<v0::Schema>());
}
```

After migrating, the hash should be the same:
```rust
// this code uses rust-query 0.8.0
#[rust_query::migration::schema(Schema)]
pub mod vN {
    pub struct Foo {
        pub some_col: Option<i64>, // <-- type was changed
    }
}

#[test]
fn schema_hash() {
    use rust_query::migration::hash_schema;
    expect_test::expect!["b5feac749e55f5bf"].assert_eq(&hash_schema::<v0::Schema>());
}
```

# 0.7.1

- Fixed `Aggregate::exists` giving wrong result when used without any query decorrelation.
- Added more documentation examples (doctests).

# 0.7.0

- Changed table types in schema and `Expr` to be `TableRow<T>` instead of `T`.
- Added support for `use` items in `#[schema]` module.

One can fix their schema by wrapping all references between tables with `TableRow` like this:
```rust
#[schema(MySchema)]
pub mod vN {
    use rust_query::TableRow; // imports work!
    
    pub struct Foo {
        pub some_bar: TableRow<Bar>, // <-- here
    }
    pub struct Bar {
        pub name: String,
        pub foo: Option<TableRow<Foo>> // <-- here
    }
}
```

- Made the table insert struct not generic to improve error messages.

Errors can be fixed by manually converting to the required type:
```rust
txn.insert(User {
    name: "dsafdsf".to_owned(), // insert fields are not generic anymore, so we need manual conversion.
})
```

- Added `Conflict` type for insert and update with multiple unique constraints.
- Implemented `Error` for `TableRow<T>` and `Conflict`.
- Add required feature `base0` to prevent future breakage.
- Remove `dev` feature from `default`.
- Removed all deprecated methods and types.
- Fixed bug where conflicts during migration could panic or return the wrong row.

# 0.6.11

- Renamed `Expr::as_float` to `Expr::to_f64`.
- Renamed `Expr::truncate` to `Expr::to_i64`.
- Added `Expr::floor`, `Expr::ceil`, `Expr::round_with_precision`, 
  `Expr::replace`, `Expr::trim`, `Expr::ltrim` and `Expr::rtrim`.

# 0.6.10

- Allow `Transaction::downgrade` in `Migrator::fixup`.
- Deprecated `Config::init_stmt`.
- Improved documentation, added docs for `#[index]`.

# 0.6.9

- Added `Mutable::unique` to mutate unique columns.
- Deprecated `Transaction::update`.
- Added `Migrator::fixup` to mutate the database after a migration and within
  the same transaction.

# 0.6.8

- Allow mutating columns that are used in an index.
- Implement `IntoExpr` for `Lazy`.
- Add some more documentation.

# 0.6.7

- Fix to allow implicit reference to primary key in sqlite schema.
- Switch to `sqlite3-parser` for lexing the sqlite schema.
- Fix to allow unquoted column names in the schema.
- Recreate full table on index change.
  This is required when a unique index is defined in a table.
- Added cargo-mutants support.
- Fixed bug that would make a unique constraint violation in a migration into a panic.
- Allow changing indices on individual fields without new table.

# 0.6.6

- Check constraints from the database are now verified against the declared schema.
- Added support for booleans in schemas.
  This uses a check constraint of the form `"col" IN (0, 1)`.
- Added `Query::order_by` to order rows in queries.

# 0.6.5

- Fix `DatabaseAsync` to allow the waker to change.

# 0.6.4

- Added `Transaction::mutable` and `Transaction::mutable_vec`.
- Deprecated `Transaction::update_ok`.
- Fix, only allow `Transaction::lazy` on table valued expressions.
- Added `Expr::div`, `Expr::modulo`, `Expr::concat`, `Expr::max`, `Expr::min`,
  `Expr::truncate`, `Expr::lower`, `Expr::upper`, `Expr::sign`, `Expr::between`,
  `Expr::abs`, `Expr::zero_blob`, `Expr::unix_epoch`, `Expr::char_len` and
  `Expr::byte_len`.
- Deprecated `UnixEpoch`.
- Relaxed trait bound on `Aggregate::max` and `Aggregate::min` to allow table typed
  expressions.

Example usage of the new `Transaction::mutable` API:
```rust
// old
txn.update_ok(
    &order.customer,
    Customer {
        balance: Update::add(total_amount),
        delivery_cnt: Update::add(1),
        ..Default::default()
    },
);
// new
let mut customer = txn.mutable(&order.customer);
customer.balance += total_amount;
customer.delivery_cnt += 1;
drop(customer);
```

# 0.6.3

- Added `DatabaseAsync` to run transaction asynchronously on any runtime.
- Added some reuse of connections between transactions.
- Added `Database::new`, to create database without migrations.

# 0.6.2

- Added diagnostics for differences between rust code and database schema.
  The new diagnostics use the `annotate-snippets` crate to annotate the rust code.
  An example error looks like this:
  ```
  error: Unique constraint mismatch for `#[version(0)]`
     ╭▸ src/schema/test.rs:146:15
     │
  LL │             #[unique(baz, field2)]
     │               ━━━━━━ database does not have this unique constraint
  LL │             pub struct Foo {
     ╰╴                       ━━━ database has `#[unique(baz, field1)]`
  ```
- Improved schema reading code to be more flexible.

# 0.6.1

- Added automatic addition and removal of column indices without a new schema version.

# 0.6.0

## Breaking changes
- Unique constraints are now unnamed.
  Using a unique constraint can be done by using the column names in order e.g.
  `Stock.warehouse(w).item(i)` instead of `Stock::unique(w, i)`.
- Support for only filtering on some columns with unique constraint syntax e.g.
  you can do `rows.join(Stock.warehouse(w))`, which will join all rows from the Stock
  table that match the warehouse.
- To create an empty row you now have to use `txn.insert_ok(v0::Empty {})` instead or
  `txn.insert_ok(v0::Empty)`.
- `Optional::then` is renamed to `Optional::then_select`.
- `Optional::then_expr` is renamed to `Optional::then`.
- Migrations now use the `Lazy` type instead of a generic type `T: FromExpr`.

## Added
- `Transaction::lazy` and `Transaction::lazy_iter` are added, these methods
  return rows of type `Lazy<'t, Table>`, which lazily queries values when they
  are accessed.
- `Transaction::lazy_iter` accepts the same kind of argument as `Rows::join`.
  So any table, optionally filtered by an index can be queried. For example:
  `txn.lazy_iter(Post.author(my_user))` would iterate over all posts by `my_user`.
- `Query::into_iter` now returns an iterator that can be moved outside the
  `Transaction::query`. This makes it possible to return the iterator as a function result.
- `Optional::and_then` was added as a convenient way to combine `Optional::and`
  with `Optional::then`.
- Support for extra indices with the `#[index]` attribute. This works exactly
  like the `#[unique]` attribute, but it doesn't have a unique constraint.
  Defining an index will also add extra methods to filter on the indexed columns.

## Removed
- The generated macros for querying specific columns from tables were removed.
  This also means the removal of `MacroRoot`, which was only used by these macros.
  `Lazy` should be used instead.

# 0.5.2

- Add option to configure `foreign_keys`.
- Simplify generated query without joins.
- Preserve column definition order when creating unique constraint.
  This lets the user choose the ordering, allowing the unique constraint to be used as a covering index.
- Add lock for mutable transactions to fix transaction timeout under load.
  The lock is dropped before committing to allow the next mutable transaction to start.
- Optimize `LEFT JOIN` to `JOIN` when the joined row is guaranteed to exist.
  This allows sqlite to reorder more joins for faster execution plans.

# 0.5.1

- Changed default `synchronous` to `FULL`.
- Added the option to configure `synchronous` to `NORMAL`.
- Fixed panic propagation from transaction closures.
- Pinned sea-query release candidate version.

# 0.5.0

## Changed table column syntax
- Instead of methods `artist.name()`, you should now use fields `&artist.name`.
- `TableRow` does not have support for accessing columns anymore, instead convert the `TableRow` to an `Expr` using `IntoExpr`.
- Removed `ref_cast` dependency.

## All transactions now run on separate threads
- Removed all transaction lifetimes (`TableRow` no longer has a lifetime).
- Removed `LocalClient` (methods have been moved to `Database`).
- `Database::transaction` and `Database::transaction_mut` now accept a closure to run on a new thread.
- Removed `TransactionMut::commit` (commit now depends on the result returned from the transaction).
- Added `Database::transaction_mut_ok` for when the transaction is always commited.
- Removed `TransactionMut`, it is replaced by `&mut Transaction`.

## Other
- Removed deprecated `Table::join`.
- Removed deprecated `IntoSelectExt` (wit the `map_select` method).
- Removed deprecated `Aggregate::filter_on`.
- Updated to rusqlite 0.37

# 0.4.4

- Add support for doc comments on tables and columns.
- Add `Query::into_iter`, to lazily iterate over query results.

# 0.4.3

- Fix panic when inserting into table without columns.
- Add `Select::map` method.
- Deprecate `IntoSelectExt::map_select`.
- Deprecate `Aggregate::join_on`.

# 0.4.2

- Update the `Rows::join` method to take a constant argument.
This is now the prefered join syntax and all examples have been updated.
- Allow arbitrary correlated subqueries.
This means that `Aggregate` now has an implied bound that allows leaking `Expr` from the
out scope. Correlated subqueries are decorrelated before translating to SQL.
- Fix loose lifetime on `Optional`.

# 0.4.1

- Change conflicts back to using `TableRow` instead of `Expr`.
Changing the conflict type to `Expr` was a mistake, because the `Expr` can be invalidated.
- Fix `#[schema]` macro not showing errors for unique constraints.

# 0.4.0

Blog post: https://blog.lucasholten.com/rust-query-0-4/

## Optional Queries
- Added `optional` combinator.
- Changed `Expr` to be co-variant in its lifetime.

## Basic Datatypes and Operations
- Added support for `Vec<u8>` data type (sqlite `BLOB`).
- Added some more basic operations on expressions.

## Updates, Insert and Query
- Added safe updates of a subset of columns for each table.
- Update statements now use the `Update` type for each column.
- Insert and update conflict is now an `Expr` (`find_or_insert` returns an `Expr` now too).
- `Rows::into_vec` is no longer sorted automatically.

## Schema and Mirations
- Changed `#[schema]` syntax to be a module of structs.
- Added `#[from]` attribute to allow renaming tables and splitting tables in the schema.
- The generated migration structs have moved from e.g. `v1::update::UserMigration` to `v0::migrate::User`.
- Migrations now require explicit handling of potential unique constraint violations.
- Migrations now require explicit handling of foreign key violations.

## Type Driven Select
- Added a macro for each table to create ad-hoc column selection types like `User!(name, age)`.
- Added the `FromExpr` trait to allow custom column selection and conversion.

## Feature Flags and Dependencies
- `TransactionWeak::rusqlite_transaction` is renamed and no longer behind a feature flag.
- `hash_schema` method was moved behind `dev` feature which is enabled by default.
- Updated dependencies.

## Renaming
- Renamed `Dummy` to `Select`.
- Renamed `Column` to `Expr`.
- Renamed `try_insert` to `insert` and `insert` to `insert_ok`.
- Renamed `try_delete` to `delete` and `delete` to `delete_ok`.
- Renamed `try_update` to `update` and `update` to `update_ok`.

# 0.3.1

- Added error message when defining an `id` column.
- Added support for sqlite `LIKE` and `GLOB` operators (Contributed by @teamplayer3).
- Added support for `DELETE` using `TransactionWeak` and `#[no_reference]`.
- Added `TransactionWeak::unchecked_transaction` behind feature flag.
- Added `impl ToSql for TableRow` behind `unchecked_transaction` feature flag.
- Removed `impl RefCast for Transaction`, it was not intended to be public.
- Removed `impl FromSql for TableRow`, it was not intended to be public.

# 0.3.0

- Added support for updating rows.
- Added `Table::dummy` method, which makes it easier to do partial updates.
- Reused table types in the generated API for both naming `TableRow<User>` and dummies `User {name: "steve"}`.
- Forbid `Option` in unique constraints.
- Renamed `ThreadToken` to `LocalClient`.
- Renamed and moved `read` and `write_lock` to `transaction` and `transaction_mut`.
- Check `schema_version` at the start of every transaction.
- Simplify migration and borrow `LocalClient` only once.
- Renamed `Prepare` to `Config` and simplified its API.

# 0.2.2

- Bound the lifetime of `TableRow: IntoColumn` to the lifetime of the transaction.
Without the bound it was possible to sneak `TableRow`s into following transacions. <details>
`query_one` now checks that its input lives for as long as the transaction.
To make sure that `query_one` still checks that the dummy is "global", the transaction now has an invariant lifetime.
</details>

# 0.2.1

- Relax `Transaction` creation to not borrow the `Database`.
- Add missing lifetime bound on `try_insert`s return value.
Technically this is a breaking change, but it fixes a bug so it is still a patch release.
- Fix the version of the macro crate exactly (=0.2.0) to allow future internal API changes with only a patch release.

# 0.2.0

- Rewrote almost the whole library to specify the schema using enum syntax with a proc macro.
- Added a single Column type to handle a lot of query building.
- Dummy trait to retrieve multiple values at once and allow post processing.
- Added support for transactions and multiple schemas.

# 0.1.x

- This version was SQL schema first. It would generate the API based on the schema read from the database.