Commit Graph

16 Commits

Author SHA1 Message Date
Claude 4c314c2f0b feat: add SQLite support behind a sqlite Cargo feature
Adds a SqliteDialect alongside PostgresDialect, gated by mutually exclusive
postgres (default) / sqlite Cargo features, plus a feature-selected
ActiveDatabase type alias used throughout the public Georm/Defaultable
traits. Basic CRUD and Defaultable are fully covered by a new SQLite test
suite (tests/sqlite/*) running against a real SQLite database, alongside
split migrations/sqlite/*.

Two real dialect differences surfaced beyond placeholder syntax:
- SQLite's INTEGER columns type-infer as i64 in sqlx's compile-time query
  macros (unlike Postgres SERIAL -> i32), so the SQLite test models use i64
  for integer PK/FK fields.
- sqlx's SQLite query macros need bind arguments bound to a place rather
  than passed as an inline expression (fixed once, centrally, in
  SqlDialect::generate_relation_lookup).

Composite-key entities with chrono::DateTime columns (tests/composite_key.rs)
are not yet ported to SQLite: SQLite has no TIMESTAMPTZ equivalent, so sqlx
infers TEXT date/time columns as String rather than DateTime<Utc> unless the
query explicitly overrides the column type. That needs per-field type
overrides threaded through the generated queries, left as follow-up.

CI now matrixes over both backends; formatting/audit only run once since
they don't vary by backend. examples/postgres/* stays out of
--no-default-features builds by scoping sqlite lint/test just recipes to
`-p georm` (it depends on georm's default postgres feature via Cargo
feature unification, so building it under --features sqlite at the
workspace level double-activates both dialects).
2026-07-21 19:06:35 +00:00
phundrak 5d8a1b1917 feat: deprecate create_or_update in favour of upsert
The `create_or_update` method has been deprecated and replaced by
`upsert` for clarity and consistency with common database terminology.

This commit also removes the file `src/entity.rs` which has been
forgotten in earlier commits and was no longer part of Georm.
2025-08-09 15:35:40 +02:00
phundrak 49c7d86102 feat: enable transaction support via sqlx::Executor
This commit abstracts the database operations to use the generic
`sqlx::Executor` trait instead of a concrete `&sqlx::PgPool`.

This change allows all generated methods (find, create, update,
delete, and relationships) to be executed within a
`sqlx::Transaction`, in addition to a connection pool. This is a
crucial feature for ensuring atomic operations and data consistency.

The public-facing traits `Georm` and `Defaultable` have been updated
to require `sqlx::Executor`, and the documentation has been updated to
reflect this new capability.
2025-08-09 15:35:40 +02:00
phundrak 3307aa679d feat: Add generated and generated_always attributes
This commit introduces support for PostgreSQL generated columns by
adding two new field attributes to the `Georm` derive macro:
`#[georm(generated)]` and `#[georm(generated_always)]`.

The `#[georm(generated_always)]` attribute is for fields that are
always generated by the database, such as `GENERATED ALWAYS AS
IDENTITY` columns or columns with a `GENERATED ALWAYS AS (expression)
STORED` clause. These fields are now excluded from `INSERT` and
`UPDATE` statements, preventing accidental writes and ensuring data
integrity at compile time.

The `#[georm(generated)]` attribute is for fields that have a default
value generated by the database but can also be manually overridden,
such as `GENERATED BY DEFAULT AS IDENTITY` columns. These fields
behave similarly to `#[georm(defaultable)]` fields, allowing them to
be omitted from `INSERT` statements to use the database-generated
value.

For now, the behaviour is the same between `#[georm(generated)]` and
`#[georm(defaultable)]`, but the addition of the former now will be
useful for future features.

Key changes:
- Added `generated` and `generated_always` attributes to
  `GeormFieldAttributes`.
- Introduced `GeneratedType` enum in the IR to represent the different
  generation strategies.
- Modified the `create` and `update` query generation to exclude
  fields marked with `#[georm(generated_always)]`.
- Integrated `#[georm(generated)]` fields with the existing
  defaultable struct logic.
- Added validation to prevent conflicting attribute usage, namely
  `#[georm(generated)]` and `#[georm(generated_always)]` on the same
  field.

Implements #3
2025-08-09 15:28:37 +02:00
phundrak 545dfa066d docs(README): clarify async support for Diesel
Fixes #2
2025-08-09 13:57:56 +02:00
phundrak 8468c3cd61 docs(README): update roadmap 2025-06-12 15:24:05 +02:00
phundrak 19284665e6 feat: implement preliminary composite primary key support
Add support for entities with composite primary keys using multiple
#[georm(id)] fields. Automatically generates {EntityName}Id structs for
type-safe composite key handling.

Features:
- Multi-field primary key detection and ID struct generation
- Full CRUD operations (find, create, update, delete, create_or_update)
- Proper SQL generation with AND clauses for composite keys
- Updated documNtation in README and lib.rs

Note: Relationships not yet supported for composite key entities
2025-06-09 22:41:39 +02:00
phundrak 190c4d7b1d feat(examples): add PostgreSQL example with user relationship
Adds an example demonstrating user, comment, and follower relationship
including:
- User management with profiles
- Comments (not really useful, just for showcasing)
- Follower/follozing relationships
- Ineractive CLI interface with CRUD operations
- Database migrations for the example schema
2025-06-09 21:30:35 +02:00
phundrak 9e56952dc6 feat: implement efficient upsert operation for create_or_update
Replace the existing two-query create_or_update implementation with a
single atomic PostgreSQL upsert using ON CONFLICT clause to eliminate
race conditions and improve performance.

Race condition fix:
The previous implementation had a critical race condition where
multiple concurrent requests could:
1. Both call find() and get None (record doesn't exist)
2. Both call create() and the second one fails with duplicate key
   error
3. Or between find() and create(), another transaction inserts the
   record

This created unreliable behavior in high-concurrency scenarios.

Changes:
- Add generate_upsert_query function in trait_implementation.rs
- Generate SQL with INSERT ... ON CONFLICT ... DO UPDATE SET pattern
- Remove default trait implementation that used separate
  find/create/update calls
- Update derive_trait to include upsert query generation
- Convert create_or_update from default implementation to required
  trait method

The new implementation eliminates race conditions while reducing
database round trips from 2-3 queries down to 1, significantly
improving both reliability and performance.
2025-06-09 21:30:35 +02:00
phundrak 0c3d5e6262 feat: upgrade to Rust 1.86 and edition 2024
Upgrades rust toolchain from 1.84 to 1.86, switches to Rust edition
2024, and updates dependencies including SQLx to 0.8.6.
2025-06-09 21:26:19 +02:00
phundrak ab2d80d2f6 chore: migrate development environment from Nix flakes to devenv
Replace Nix flake-based development setup with devenv for better
developer experience and more streamlined environment management.

Changes:
  - Remove flake.nix and flake.lock files
  - Add devenv.nix, devenv.yaml, and devenv.lock configuration
  - Update .envrc to use devenv instead of nix develop
  - Remove Docker development setup (compose.dev.yml, docker/mod.just)
  - Expand .gitignore with comprehensive IDE and OS exclusions
  - Remove Docker-related just commands from justfile
2025-06-07 15:46:10 +02:00
phundrak 7cdaa27f3b docs: complete rewrite of README
Replaces the existing README with a comprehensive guide that
significantly improves the developer and user experience. The new README
provides complete documentation for all Georm features and a detailed
development setup guide.

It also includes a roadmap with prioritized feature development plan.
2025-06-07 15:45:25 +02:00
phundrak aafbfb7964 feat: add foreign one_to_one relationships 2025-06-07 15:42:31 +02:00
phundrak f2e59cee7c fix: correct docs.rs link and switch to GitHub repository 2025-02-01 01:59:40 +01:00
phundrak d82f9fe2f4 docs: update readme 2025-02-01 01:25:55 +01:00
phundrak 39f757991a initial commit 2025-01-26 15:18:31 +01:00