View Source Ecto.ULID Next

Elixir CI Hex

An Ecto.Type implementation of ULID.

Ecto.ULID should be compatible anywhere that Ecto.UUID is supported. It has been confirmed to work with PostgreSQL and MySQL on Ecto ~> 3.2.

ULID is a 128-bit universally unique lexicographically sortable identifier. ULID is binary-compatible with UUID, so it can be stored in a uuid column in a database.

This is a fork of TheRealReal/ecto-ulid, which doesn't seem to be maintained anymore. The aim is to ensure compatibility with current and future Ecto versions.

features

Features

  • Generate ULID in Base32 or binary format.
  • Generate ULID for a given timestamp.
  • Autogenerate ULID when used as a primary key.
  • Supports reading and writing ULID in a database backed by its native uuid type (no database extensions required).
  • Supports Ecto ~> 3.2.
  • Supports the officially supported Elixir versions (currently ~> 1.10).
  • Confirmed working on PostgreSQL and MySQL.
  • Optimized for high throughput.

performance

Performance

Since one use case of ULID is to handle a large volume of events, Ecto.ULID is optimized to be as fast as possible. It borrows techniques from Ecto.UUID to achieve sub-microsecond times for most operations.

A benchmark suite is included. Download the repository and run mix run bench/ulid_bench.exs to test the performance on your system.

usage

Usage

Usage is very similar to Ecto.UUID. The following example shows how to use Ecto.ULID as a primary key in a database table, but it can be used for other columns just as easily.

API documentation is available on hexdocs.

install

Install

Install ecto_ulid_next from Hex by adding it to the dependencies in mix.exs:

defp deps do
  [{:ecto_ulid_next, "~> 1.0.0"}]
end

migration

Migration

Since ULID is binary-compatible with UUID, the migrations look the same for both types. Use :binary_id when defining a column in a migration:

create table(:events, primary_key: false) do
  add :id, :binary_id, null: false, primary_key: true
  # more columns ...
end

Alternatively, if you plan to use ULID as the primary key type for all of your tables, you can set migration_primary_key when configuring your Repo:

config :my_app, MyApp.Repo, migration_primary_key: [name: :id, type: :binary_id]

In this case, you do not need to specify the id column in your migrations:

create table(:events) do
  # more columns ...
end

schema

Schema

When defining a model's schema, use Ecto.ULID as the @primary_key or @foreign_key_type as appropriate for your schema. Here's an example of using both:

defmodule MyApp.Event do
  use Ecto.Schema

  @primary_key {:id, Ecto.ULID, autogenerate: false}
  @foreign_key_type Ecto.ULID

  schema "events" do
    # more columns ...
  end
end

Ecto.ULID supports autogenerate: true as well as autogenerate: false when used as the primary key.

application-usage

Application Usage

A ULID can be generated in string or binary format by calling generate/0 or bingenerate/0. This can be useful when generating ULIDs to send to external systems:

iex> Ecto.ULID.generate()
"01BZ13RV29T5S8HV45EDNC748P"

iex> Ecto.ULID.bingenerate()
<<1, 95, 194, 60, 108, 73, 209, 114, 136, 236, 133, 115, 106, 195, 145, 22>>

To backfill old data, it may be helpful to pass a timestamp to generate/1 or bingenerate/1. See the API documentation for more details.