Skip to content

Exposing DB::Connection#last_insert_id #228

Description

@Blacksmoke16

Extracted from #227:


I wanted to propose a few ideas/suggestions based on my experience working on https://forum.crystal-lang.org/t/athena-orm-alpha-version-testers-wanted/8904. Most of these are things I just had to work around/monkeypatch in, but are worth discussing if it'd be useful implementing them upstream natively.

DB::Connection#last_insert_id

One of the first things I ran into was dealing with knowing the PK of a record that was inserted. Each DB has its own standards so there is no super clear way to handle this. E.g. Postgres relies on RETURNING and always returns 0 for DB::ExecResult#last_insert_id, while MySQL doesn't support RETURNING. For some of them you can make use of like SELECT LASTVAL() (or similar), but then others don't support something like that at all.

MOST databases do seem to support some form of SELECT LASTVAL() so it felt like a reasonable default, which I ended up going with. However because it's only exposed on DB::ExecResult it wasn't the easiest to use. It would be more useful to add DB::Connection#last_insert_id that essentially does self.scalar("SELECT LASTVAL()").as Int64 | String (or whatever the exact statement is for the DB). This would at least be a good fallback for DB's that don't support something better (like RETURNING).

DB's that do NOT support this should raise a specific exception, or if the result in not a valid identifier (like it returns false or nil or something).

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions