Skip to content

jethrodaniel/sqlite_extensions-uuid

Repository files navigation

sqlite_extensions-uuid

SQLite's UUID v4 extension, packaged as a gem.

The main use-case is to allow using UUIDs as primary keys with SQLite in Rails apps.

Installation

Add this gem to your application's Gemfile by running this:

bundle add sqlite_extensions-uuid

or by adding this line and running bundle:

gem "sqlite_extensions-uuid"

In your Rails app, you'll need to load the extension in your config/database.yml like so:

development:
  adapter: sqlite3
  extensions:
    - <%= SqliteExtensions::UUID.to_path %>
  # ...

Usage

SQLite's uuid extension provides the following:

  • uuid() - generate a version 4 UUID as a string
  • uuid_str(X) - convert a UUID X into a well-formed UUID string
  • uuid_blob(X) - convert a UUID X into a 16-byte blob

For more information about the extension itself, see the extension's source code.

Examples

Use as a primary key in migrations:

bin/rails g model User email_address:uniq:index
class CreateUsers < ActiveRecord::Migration[8.0]
  def change
    create_table :users, id: :string, default: -> { "uuid()" }, limit: 36 do |t|
      t.string :email_address, null: false
      t.timestamps
    end
    add_index :users, :email_address, unique: true
  end
end

Call SQL directly:

ActiveRecord::Base.connection.execute("select uuid_str(uuid())")
#=> [{"uuid_str(uuid())"=>"56392d30-a2cf-47b9-895a-f8c1a1677bfc"}]

How it works

This gem compiles SQLite's uuid extension into a shared library using Ruby's native-gem functionality.

It doesn't actually compile a Ruby native extension, it just uses the ruby extension process to compile the SQLite UUID library.

It then exposes a method, SqliteExtensions::UUID.to_path, which returns the location of that shared library.

This can be passed to sqlite3 in Database.new(extensions: []) or Database#load_extension.

Issues

Missing .load command

The default sqlite3 on MacOS doesn't allow loading runtime extensions, so you'll need to use a version that does, e.g, from brew (brew install sqlite3).

% /usr/bin/sqlite3
SQLite version 3.43.2 2023-10-10 13:08:14
Enter ".help" for usage hints.
Connected to a transient in-memory database.
Use ".open FILENAME" to reopen on a persistent database.
sqlite> .load
Error: unknown command or invalid arguments:  "load". Enter ".help" for help

If using brew, you'll want to follow the suggestions from brew info sqlite3:

% brew info sqlite3
...
==> Caveats
sqlite is keg-only, which means it was not symlinked into /opt/homebrew,
because macOS already provides this software and installing another version in
parallel can cause all kinds of trouble.

If you need to have sqlite first in your PATH, run:
  echo 'export PATH="/opt/homebrew/opt/sqlite/bin:$PATH"' >> ~/.zshrc

For compilers to find sqlite you may need to set:
  export LDFLAGS="-L/opt/homebrew/opt/sqlite/lib"
  export CPPFLAGS="-I/opt/homebrew/opt/sqlite/include"

For pkg-config to find sqlite you may need to set:
  export PKG_CONFIG_PATH="/opt/homebrew/opt/sqlite/lib/pkgconfig"

Afterwards, check that .load support works:

% sqlite3
SQLite version 3.50.1 2025-06-06 14:52:32
Enter ".help" for usage hints.
Connected to a transient in-memory database.
Use ".open FILENAME" to reopen on a persistent database.
(ins)sqlite> .load
Usage: .load FILE ?ENTRYPOINT?

Development

# one-time setup
bundle

# build and run tests
bundle exec rake test

# install locally
bundle exec rake install

# uninstall
gem uninstall sqlite_extensions-uuid

Contributing

Bug reports and pull requests are welcome on GitHub at https://github.com/jethrodaniel/sqlite_extensions-uuid.

License

The gem is available as open source under the terms of the MIT License.

The following files are copied verbatim from SQLite, and are used under their own license, which is visible at the beginning of each file:

  • ext/sqlite_extensions/uuid/sqlite3ext.h
  • ext/sqlite_extensions/uuid/sqlite3.h
  • ext/sqlite_extensions/uuid/uuid.c

About

Easily use the SQLite UUID extension in Rails

Topics

Resources

License

Stars

Watchers

Forks

Sponsor this project