Skip to main content

sqll/
lib.rs

1//! [<img alt="github" src="https://img.shields.io/badge/github-udoprog/sqll-8da0cb?style=for-the-badge&logo=github" height="20">](https://github.com/udoprog/sqll)
2//! [<img alt="crates.io" src="https://img.shields.io/crates/v/sqll.svg?style=for-the-badge&color=fc8d62&logo=rust" height="20">](https://crates.io/crates/sqll)
3//! [<img alt="docs.rs" src="https://img.shields.io/badge/docs.rs-sqll-66c2a5?style=for-the-badge&logoColor=white&logo=data:image/svg+xml;base64,PHN2ZyByb2xlPSJpbWciIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgdmlld0JveD0iMCAwIDUxMiA1MTIiPjxwYXRoIGZpbGw9IiNmNWY1ZjUiIGQ9Ik00ODguNiAyNTAuMkwzOTIgMjE0VjEwNS41YzAtMTUtOS4zLTI4LjQtMjMuNC0zMy43bC0xMDAtMzcuNWMtOC4xLTMuMS0xNy4xLTMuMS0yNS4zIDBsLTEwMCAzNy41Yy0xNC4xIDUuMy0yMy40IDE4LjctMjMuNCAzMy43VjIxNGwtOTYuNiAzNi4yQzkuMyAyNTUuNSAwIDI2OC45IDAgMjgzLjlWMzk0YzAgMTMuNiA3LjcgMjYuMSAxOS45IDMyLjJsMTAwIDUwYzEwLjEgNS4xIDIyLjEgNS4xIDMyLjIgMGwxMDMuOS01MiAxMDMuOSA1MmMxMC4xIDUuMSAyMi4xIDUuMSAzMi4yIDBsMTAwLTUwYzEyLjItNi4xIDE5LjktMTguNiAxOS45LTMyLjJWMjgzLjljMC0xNS05LjMtMjguNC0yMy40LTMzLjd6TTM1OCAyMTQuOGwtODUgMzEuOXYtNjguMmw4NS0zN3Y3My4zek0xNTQgMTA0LjFsMTAyLTM4LjIgMTAyIDM4LjJ2LjZsLTEwMiA0MS40LTEwMi00MS40di0uNnptODQgMjkxLjFsLTg1IDQyLjV2LTc5LjFsODUtMzguOHY3NS40em0wLTExMmwtMTAyIDQxLjQtMTAyLTQxLjR2LS42bDEwMi0zOC4yIDEwMiAzOC4ydi42em0yNDAgMTEybC04NSA0Mi41di03OS4xbDg1LTM4Ljh2NzUuNHptMC0xMTJsLTEwMiA0MS40LTEwMi00MS40di0uNmwxMDItMzguMiAxMDIgMzguMnYuNnoiPjwvcGF0aD48L3N2Zz4K" height="20">](https://docs.rs/sqll)
4//!
5//! Efficient interface to [SQLite] that doesn't get in your way.
6//!
7//! <br>
8//!
9//! ## Usage
10//!
11//! The two primary methods to interact with an SQLite database through this
12//! crate is through [`execute`] and [`prepare`].
13//!
14//! The [`execute`] function is used for batch statements, and allows for
15//! multiple queries to be specified. [`prepare`] only allows for a single
16//! statement to be specified, but in turn permits [reading rows] and [binding
17//! query parameters].
18//!
19//! Special consideration needs to be taken about the thread safety of
20//! connections. You can read more about that in the [`Connection`]
21//! documentation.
22//!
23//! You can find simple examples of this below.
24//!
25//! <br>
26//!
27//! #### Examples
28//!
29//! * [`examples/persons.rs`] - A simple table with users, a primary key,
30//!   inserting and querying.
31//! * [`examples/axum.rs`] - Create an in-memory database connection and serve
32//!   it using [`axum`]. This showcases how to properly handle external
33//!   synchronization for the best performance in a real-world scenario.
34//! * [`examples/tokio_async.rs`] - Using `sqll` in an asynchronous context with
35//!   `tokio`.
36//!
37//! <br>
38//!
39//! #### Connecting and querying
40//!
41//! Here is a simple example of setting up an in-memory connection, creating a
42//! table, inserting and querying back some rows:
43//!
44//! ```
45//! use sqll::{Connection, Result};
46//!
47//! let c = Connection::open_in_memory()?;
48//!
49//! c.execute(r#"
50//!     CREATE TABLE users (name TEXT, age INTEGER);
51//!
52//!     INSERT INTO users VALUES ('Alice', 42);
53//!     INSERT INTO users VALUES ('Bob', 52);
54//! "#)?;
55//!
56//! let results = c.prepare("SELECT name, age FROM users ORDER BY age")?
57//!     .iter::<(String, u32)>()
58//!     .collect::<Result<Vec<_>>>()?;
59//!
60//! assert_eq!(results, [("Alice".to_string(), 42), ("Bob".to_string(), 52)]);
61//! # Ok::<_, sqll::Error>(())
62//! ```
63//!
64//! <br>
65//!
66//! #### The [`Row`] trait.
67//!
68//! The [`Row`] trait can be used to conveniently read rows from a statement
69//! using [`next`]. It can be conveniently implemented using the [`Row`
70//! derive].
71//!
72//! ```
73//! use sqll::{Connection, Row};
74//!
75//! #[derive(Row)]
76//! struct Person<'stmt> {
77//!     name: &'stmt str,
78//!     age: u32,
79//! }
80//!
81//! let mut c = Connection::open_in_memory()?;
82//!
83//! c.execute(r#"
84//!     CREATE TABLE users (name TEXT, age INTEGER);
85//!
86//!     INSERT INTO users VALUES ('Alice', 42);
87//!     INSERT INTO users VALUES ('Bob', 52);
88//! "#)?;
89//!
90//! let mut results = c.prepare("SELECT name, age FROM users ORDER BY age")?;
91//!
92//! while let Some(person) = results.next::<Person<'_>>()? {
93//!     println!("{} is {} years old", person.name, person.age);
94//! }
95//! # Ok::<_, sqll::Error>(())
96//! ```
97//!
98//! <br>
99//!
100//! #### The [`Bind`] trait.
101//!
102//! The [`Bind`] trait can be used to conveniently [`bind`] parameters to
103//! prepared statements, and it can conveniently be implemented for structs
104//! using the [`Bind` derive].
105//!
106//! ```
107//! use sqll::{Bind, Connection, Row};
108//!
109//! #[derive(Bind, Row, PartialEq, Debug)]
110//! #[sql(named)]
111//! struct Person<'stmt> {
112//!     name: &'stmt str,
113//!     age: u32,
114//! }
115//!
116//! let c = Connection::open_in_memory()?;
117//!
118//! c.execute(r#"
119//!    CREATE TABLE persons (name TEXT, age INTEGER);
120//! "#)?;
121//!
122//! let mut stmt = c.prepare("INSERT INTO persons (name, age) VALUES (:name, :age)")?;
123//! stmt.execute(Person { name: "Alice", age: 30 })?;
124//! stmt.execute(Person { name: "Bob", age: 40 })?;
125//!
126//! let mut query = c.prepare("SELECT name, age FROM persons ORDER BY age")?;
127//!
128//! let p = query.next::<Person<'_>>()?;
129//! assert_eq!(p, Some(Person { name: "Alice", age: 30 }));
130//!
131//! let p = query.next::<Person<'_>>()?;
132//! assert_eq!(p, Some(Person { name: "Bob", age: 40 }));
133//! # Ok::<_, sqll::Error>(())
134//! ```
135//!
136//! <br>
137//!
138//! #### Efficient use of prepared Statements
139//!
140//! Correct handling of prepared statements are crucial to get good performance
141//! out of sqlite. They contain all the state associated with a query and are
142//! expensive to construct so they should be re-used.
143//!
144//! Using a [`PrepareWith::persistent`] prepared statement to perform multiple
145//! queries:
146//!
147//! ```
148//! use sqll::Connection;
149//!
150//! let c = Connection::open_in_memory()?;
151//!
152//! c.execute(r#"
153//!     CREATE TABLE users (name TEXT, age INTEGER);
154//!
155//!     INSERT INTO users VALUES ('Alice', 42);
156//!     INSERT INTO users VALUES ('Bob', 52);
157//! "#)?;
158//!
159//! let mut stmt = c.prepare_with("SELECT * FROM users WHERE age > ?")
160//!     .persistent()
161//!     .build()?;
162//!
163//! let mut rows = Vec::new();
164//!
165//! for age in [40, 50] {
166//!     stmt.bind(age)?;
167//!
168//!     while let Some(row) = stmt.next::<(String, i64)>()? {
169//!         rows.push(row);
170//!     }
171//! }
172//!
173//! let expected = vec![
174//!     (String::from("Alice"), 42),
175//!     (String::from("Bob"), 52),
176//!     (String::from("Bob"), 52),
177//! ];
178//!
179//! assert_eq!(rows, expected);
180//! # Ok::<_, sqll::Error>(())
181//! ```
182//!
183//! <br>
184//!
185//! #### Use in asynchronous contexts
186//!
187//! In order for sqlite to be used in asynchronous contexts, the [`Statement`]
188//! object usually needs to be `Send` and external synchronization necessary.
189//! Since sqlite is a synchronous library we have to defer any work done to a
190//! thread pool such as the one provided by [`tokio::task::spawn_blocking`]. To
191//! make a [`Statement`] `Send` you can use [`Statement::into_send`], but using
192//! it is `unsafe` since correct behavior depends on the build and runtime
193//! configuration of the sqlite library in use.
194//!
195//! See the [`tokio_async` example] for a complete example.
196//!
197//! <br>
198//!
199//! ## Features
200//!
201//! * `std` - Enable usage of the Rust standard library. Enabled by default.
202//! * `alloc` - Enable usage of the Rust alloc library. This is required and is
203//!   enabled by default. Disabling this option will currently cause a compile
204//!   error.
205//! * `derive` - Add a dependency to and re-export of the [`Row` derive]
206//!   macro.
207//! * `bundled` - Use a bundled version of sqlite. The bundle is provided by the
208//!   [`sqll-sys`] crate and the sqlite version used is part of the build
209//!   metadata of that crate[^sqll-sys].
210//! * `threadsafe` - Enable usage of sqlite with the threadsafe option set. We
211//!   assume any system level libraries have this build option enabled. If this
212//!   is disabled the `bundled` feature has to be enabled. If `threadsafe` is
213//!   disabled, `Connection` and `Statement` does not implement `Send`. But it
214//!   is also important to understand that if this option is not set, sqlite
215//!   **may not be used by multiple threads at all** even if threads have
216//!   distinct connections. To disable mutexes which allows for efficient one
217//!   connection per thread the [`OpenOptions::no_mutex`] option should be used
218//!   instead[^sqll-sys].
219//! * `strict` - Enable usage of sqlite with the strict compiler options
220//!   enabled[^sqll-sys].
221//!
222//! [^sqll-sys]: This is a forwarded sqll-sys option, see <https://docs.rs/sqll-sys>.
223//!
224//! <br>
225//!
226//! ## License
227//!
228//! This is a rewrite of the [`sqlite` crate], and components used from there
229//! have been copied under the MIT license.
230//!
231//! [`axum`]: https://docs.rs/axum
232//! [`Bind` derive]: https://docs.rs/sqll/latest/sqll/derive.Bind.html
233//! [`bind`]: https://docs.rs/sqll/latest/sqll/struct.Statement.html#method.bind
234//! [`Bind`]: https://docs.rs/sqll/latest/sqll/trait.Bind.html
235//! [`Connection`]: https://docs.rs/sqll/latest/sqll/struct.Connection.html#thread-safety
236//! [`examples/axum.rs`]: https://github.com/udoprog/sqll/blob/main/examples/axum.rs
237//! [`examples/persons.rs`]: https://github.com/udoprog/sqll/blob/main/examples/persons.rs
238//! [`examples/tokio_async.rs`]: https://github.com/udoprog/sqll/blob/main/examples/tokio_async.rs
239//! [`execute`]: https://docs.rs/sqll/latest/sqll/struct.Connection.html#method.execute
240//! [`next`]: https://docs.rs/sqll/latest/sqll/struct.Statement.html#method.next
241//! [`OpenOptions::no_mutex`]: https://docs.rs/sqll/latest/sqll/struct.OpenOptions.html#method.no_mutex
242//! [`prepare_with`]: https://docs.rs/sqll/latest/sqll/struct.Connection.html#method.prepare_with
243//! [`prepare`]: https://docs.rs/sqll/latest/sqll/struct.Connection.html#method.prepare
244//! [`PrepareWith::persistent`]: https://docs.rs/sqll/latest/sqll/struct.PrepareWith.html#method.persistent
245//! [`Row` derive]: https://docs.rs/sqll/latest/sqll/derive.Row.html
246//! [`Row`]: https://docs.rs/sqll/latest/sqll/trait.Row.html
247//! [`sqlite` crate]: https://github.com/stainless-steel/sqlite
248//! [`sqll-sys`]: https://crates.io/crates/sqll-sys
249//! [`Statement::into_send`]: https://docs.rs/sqll/latest/sqll/struct.Statement.html#method.into_send
250//! [`Statement`]: https://docs.rs/sqll/latest/sqll/struct.Statement.html
251//! [`tokio_async` example]: https://github.com/udoprog/sqll/blob/main/examples/tokio_async.rs
252//! [`tokio::task::spawn_blocking`]: https://docs.rs/tokio/latest/tokio/task/fn.spawn_blocking.html
253//! [binding query parameters]: https://docs.rs/sqll/latest/sqll/struct.Statement.html#method.bind
254//! [calling `execute`]: https://docs.rs/sqll/latest/sqll/struct.Connection.html#method.execute
255//! [reading rows]: https://docs.rs/sqll/latest/sqll/struct.Statement.html#method.next
256//! [SQLite]: https://www.sqlite.org
257
258#![no_std]
259#![allow(clippy::module_inception)]
260#![allow(clippy::new_without_default)]
261#![allow(clippy::should_implement_trait)]
262#![warn(rustdoc::broken_intra_doc_links)]
263#![cfg_attr(docsrs, feature(doc_cfg))]
264
265#[cfg(feature = "std")]
266extern crate std;
267
268#[cfg(feature = "alloc")]
269extern crate alloc;
270
271#[cfg(test)]
272mod tests;
273
274mod bind;
275mod bind_value;
276mod bytes;
277mod code;
278mod column;
279mod connection;
280mod error;
281mod ffi;
282mod fixed_blob;
283mod fixed_text;
284mod from_column;
285mod from_unsized_column;
286mod index;
287mod open_options;
288#[cfg(feature = "alloc")]
289mod owned;
290mod owned_bytes;
291mod row;
292mod statement;
293mod text;
294pub mod ty;
295mod utils;
296mod value;
297mod value_type;
298mod version;
299
300#[doc(inline)]
301pub use self::bind::Bind;
302#[doc(inline)]
303pub use self::bind_value::BindValue;
304#[doc(inline)]
305pub use self::code::Code;
306#[doc(inline)]
307pub use self::column::Column;
308#[doc(inline)]
309pub use self::connection::{Connection, Prepare, PrepareWith, SendConnection};
310#[doc(inline)]
311pub use self::error::{CapacityError, DatabaseNotFound, Error, NotThreadSafe, Result};
312#[doc(inline)]
313pub use self::fixed_blob::FixedBlob;
314#[doc(inline)]
315pub use self::fixed_text::FixedText;
316#[doc(inline)]
317pub use self::from_column::FromColumn;
318#[doc(inline)]
319pub use self::from_unsized_column::FromUnsizedColumn;
320#[doc(inline)]
321pub use self::index::Index;
322#[doc(inline)]
323pub use self::open_options::OpenOptions;
324#[doc(inline)]
325pub use self::owned_bytes::OwnedBytes;
326#[doc(inline)]
327pub use self::row::Row;
328#[doc(inline)]
329pub use self::statement::{Null, SendStatement, State, Statement};
330#[doc(inline)]
331pub use self::text::Text;
332#[doc(inline)]
333pub use self::value::Value;
334#[doc(inline)]
335pub use self::value_type::ValueType;
336#[doc(inline)]
337pub use self::version::{lib_version, lib_version_number};
338
339/// Derive macro for [`Bind`].
340///
341/// This can be used to automatically implement [`Bind`] for a struct and allows
342/// the struct to be used for structured binding of multiple parameters into a
343/// [`Statement`] using [`bind`].
344///
345/// This relies on [`BindValue`] being called for each field in the struct. By
346/// default the `#[sql(index)]` used starts at 0 and is incremented for each
347/// field. This behavior can be modified with attributes.
348///
349/// This also derive also supports convenient use of named parameters through
350/// `[sql(named)]` or a per-field `[sql(name = ..)]`.
351///
352/// ```
353/// use sqll::Bind;
354///
355/// #[derive(Bind)]
356/// struct Person<'stmt> {
357///     name: &'stmt str,
358///     age: u32,
359/// }
360/// ```
361///
362/// [`bind`]: Statement::bind
363///
364/// <br>
365///
366/// ## Container attributes
367///
368/// <br>
369///
370/// #### `#[sql(crate = ..)]`
371///
372/// This attributes allows specifying an alternative path to the `sqll` crate.
373///
374/// This is useful when the crate is renamed from the default `::sqll`.
375///
376/// ```
377/// # extern crate sqll as my_sqll;
378/// use my_sqll::Bind;
379///
380/// #[derive(Bind)]
381/// #[sql(crate = ::my_sqll)]
382/// struct Person<'stmt> {
383///     name: &'stmt str,
384///     age: u32,
385/// }
386/// ```
387///
388/// <br>
389///
390/// #### `#[sql(named)]`
391///
392/// This attribute enabled bindings to use field names instead of go by the
393/// default index.
394///
395/// When using `named`, the default binding names are the field names prefixed
396/// with a `:`. So a field named `name` will bind to `:name`.
397///
398/// ```
399/// use sqll::{Bind, Connection};
400///
401/// #[derive(Bind)]
402/// #[sql(named)]
403/// struct Person<'stmt> {
404///     name: &'stmt str,
405///     age: u32,
406/// }
407///
408/// let c = Connection::open_in_memory()?;
409///
410/// c.execute(r#"
411///    CREATE TABLE persons (name TEXT, age INTEGER);
412/// "#)?;
413///
414/// let mut stmt = c.prepare("INSERT INTO persons (name, age) VALUES (:name, :age)")?;
415/// let person = Person { name: "Alice", age: 30 };
416/// stmt.bind(person)?;
417/// # Ok::<_, sqll::Error>(())
418/// ```
419///
420/// <br>
421///
422/// ## Field attributes
423///
424/// <br>
425///
426/// #### `#[sql(index = ..)]`
427///
428/// This allows the index being used for a particular row to be overriden. Note
429/// that the underlying binding indexes are 1-based, so this is translated to
430/// that by adding 1 to the specified index in order to be compatible with other
431/// derives.
432///
433/// ```
434/// use sqll::{Bind, Connection};
435///
436/// #[derive(Bind)]
437/// struct Person<'stmt> {
438///     #[sql(index = 1)]
439///     name: &'stmt str,
440///     #[sql(index = 0)]
441///     age: u32,
442/// }
443///
444/// let c = Connection::open_in_memory()?;
445///
446/// c.execute(r#"
447///    CREATE TABLE persons (name TEXT, age INTEGER);
448/// "#)?;
449///
450/// let mut stmt = c.prepare("INSERT INTO persons (age, name) VALUES (?, ?)")?;
451/// stmt.execute(Person { name: "Alice", age: 30 })?;
452/// # Ok::<_, sqll::Error>(())
453/// ```
454///
455/// <br>
456///
457/// #### `#[sql(name = c"..")]`
458///
459/// This allows for specifying an explicit binding name to use, instead of the
460/// default which is to bind by index or a field derived name if `#[sql(named)]`
461/// is set.
462///
463/// Note that the name are literal references to what is expected by the SQLite
464/// API, so must be prefixed with `:`. If a string literal is used, it will be
465/// checked so that it doesn't contain any null bytes.
466///
467/// ```
468/// use sqll::{Bind, Connection};
469///
470/// #[derive(Bind)]
471/// struct Person<'stmt> {
472///     #[sql(name = c":notname")]
473///     name: &'stmt str,
474///     #[sql(name = c":notage")]
475///     age: u32,
476/// }
477/// # #[derive(Bind)]
478/// # struct PersonStr<'stmt> {
479/// #     #[sql(name = ":notname")]
480/// #     name: &'stmt str,
481/// #     #[sql(name = ":notage")]
482/// #     age: u32,
483/// # }
484///
485/// let c = Connection::open_in_memory()?;
486///
487/// c.execute(r#"
488///    CREATE TABLE persons (name TEXT, age INTEGER);
489/// "#)?;
490///
491/// let mut stmt = c.prepare("INSERT INTO persons (name, age) VALUES (:notname, :notage)")?;
492/// stmt.execute(Person { name: "Alice", age: 30 })?;
493/// # stmt.execute(PersonStr { name: "Alice", age: 30 })?;
494/// # Ok::<_, sqll::Error>(())
495/// ```
496#[cfg(feature = "derive")]
497#[cfg_attr(docsrs, doc(cfg(feature = "derive")))]
498pub use sqll_macros::Bind;
499
500/// Derive macro for [`Row`].
501///
502/// This can be used to automatically implement [`Row`] for a struct and allows
503/// the struct to be constructed from a [`Statement`] using [`next`] or
504/// [`iter`].
505///
506/// This relies on [`FromColumn`] being called to construct each field in the
507/// struct. By default the `#[sql(index)]` used starts at `0` and is incremented
508/// for each field. This behavior can be modified with attributes.
509///
510/// ```
511/// use sqll::{Connection, Row};
512///
513/// #[derive(Row)]
514/// struct Person<'stmt> {
515///     name: &'stmt str,
516///     age: u32,
517/// }
518///
519/// #[derive(Row)]
520/// struct PersonTuple<'stmt>(&'stmt str, u32);
521///
522/// let mut c = Connection::open_in_memory()?;
523///
524/// c.execute(r#"
525///     CREATE TABLE users (name TEXT, age INTEGER);
526///
527///     INSERT INTO users VALUES ('Alice', 42);
528///     INSERT INTO users VALUES ('Bob', 72);
529/// "#)?;
530///
531/// let mut results = c.prepare("SELECT name, age FROM users ORDER BY age")?;
532///
533/// while let Some(person) = results.next::<Person<'_>>()? {
534///     println!("{} is {} years old", person.name, person.age);
535/// }
536/// # Ok::<_, sqll::Error>(())
537/// ```
538///
539/// [`iter`]: Statement::iter
540/// [`next`]: Statement::next
541///
542/// <br>
543///
544/// ## Container attributes
545///
546/// <br>
547///
548/// #### `#[sql(crate = ..)]`
549///
550/// This attributes allows specifying an alternative path to the `sqll` crate.
551///
552/// This is useful when the crate is renamed from the default `::sqll`.
553///
554/// ```
555/// # extern crate sqll as my_sqll;
556/// use my_sqll::Row;
557///
558/// #[derive(Row)]
559/// #[sql(crate = ::my_sqll)]
560/// struct Person<'stmt> {
561///     name: &'stmt str,
562///     age: u32,
563/// }
564/// ```
565///
566/// <br>
567///
568/// ## Field attributes
569///
570/// <br>
571///
572/// #### `#[sql(index = ..)]`
573///
574/// This allows the index being used for a particular row to be overriden.
575///
576/// ```
577/// use sqll::Row;
578///
579/// #[derive(Row)]
580/// struct Person<'stmt> {
581///     #[sql(index = 1)]
582///     name: &'stmt str,
583///     #[sql(index = 0)]
584///     age: u32,
585/// }
586/// ```
587///
588/// <br>
589///
590/// #### Missing `#[sql(name)]`?
591///
592/// Unlike the `Bind` derive, there is no `#[sql(name = ..)]` attribute for the
593/// `Row` derive. This is due to the underlying API not efficiently supporting
594/// this, and implementing it in `sqll` would either require additional
595/// allocations or inefficient per-row lookups.
596///
597/// Note that it's also not uncommon for column names to simply *not* have a
598/// name, such as when computing expressions like `COUNT(*)` or `column + 1`.
599///
600/// # Errors
601///
602/// Trying to use the same index multiple times results in an error. This is to
603/// ensure that the implementation follows the safety requirements of the [`Row`
604/// trait].
605///
606/// ```compile_fail
607/// use sqll::Row;
608///
609/// #[derive(Row)]
610/// struct InvalidRow {
611///     #[sql(index = 0)]
612///     a: u32,
613///     #[sql(index = 0)]
614///     b: u32,
615/// }
616/// ```
617///
618/// [`Row` trait]: crate::Row
619#[cfg(feature = "derive")]
620#[cfg_attr(docsrs, doc(cfg(feature = "derive")))]
621pub use sqll_macros::Row;