ksuid is a zero dependency Elixir library for generating and parsing KSUIDs.
Read more about ksuid here
Installation
def deps do [{:ksuid, "~> 0.1.2"}] end
How To
iex> Ksuid.generate() "0p9kxW1vWavpdq7VSgbv8piY0nr" iex> Ksuid.parse("0p9kxW1vWavpdq7VSgbv8piY0nr") { :ok, %DateTime{calendar: Calendar.ISO, day: 9, hour: 14, microsecond: {0, 0}, minute: 52, month: 6, second: 34, std_offset: 0, time_zone: "Etc/UTC", utc_offset: 0, year: 2017, zone_abbr: "UTC"}, <<166, 90, 80, 117, 89, 88, 196, 168, 113, 163, 157, 217, 224, 51, 151, 227>> }
Example Ecto Usage
Ecto Type
defmodule EctoKsuid do @behaviour Ecto.Type # uses string/varchar as storage type. def type, do: :string def cast(ksuid) when is_binary(ksuid), do: {:ok, ksuid} def cast(_), do: :error @doc """ Same as `cast/1` but raises `Ecto.CastError` on invalid arguments. """ def cast!(value) do case cast(value) do {:ok, ksuid} -> ksuid :error -> raise Ecto.CastError, type: __MODULE__, value: value end end def load(ksuid), do: {:ok, ksuid} def dump(binary) when is_binary(binary), do: {:ok, binary} def dump(_), do: :error # Callback invoked by autogenerate fields - this is all that really matters # just passing around the binary otherwise. @doc false def autogenerate, do: Ksuid.generate() end
Usage in a Schema
:inserted_at is a virtual field that can be derived/loaded from the autogenerated :id
defmodule TestSchema do use Ecto.Schema @primary_key {:id, EctoKsuid, autogenerate: true} schema "test" do field :name, :string field :inserted_at, :utc_datetime, virtual: true end def inserted_at(%TestSchema{id: ksuid} = row) do {:ok, time_stamp, _} = Ksuid.parse(ksuid) %TestSchema{row | inserted_at: time_stamp} end end
Migration
Create :id as :bytea, and primary key - similary to usage with :binary_id
def change do create table(:test, primary_key: false) do add :id, :string, primary_key: true, size: 26 add :name, :text end end
TODO
- Generate KSUID
- Parsing KSUIDS
- Decode BASE62 method
- Write tests
- Write Documentation