🔥 initial commit 🔥
This commit is contained in:
4
priv/repo/migrations/.formatter.exs
Normal file
4
priv/repo/migrations/.formatter.exs
Normal file
@@ -0,0 +1,4 @@
|
||||
[
|
||||
import_deps: [:ecto_sql],
|
||||
inputs: ["*.exs"]
|
||||
]
|
||||
@@ -0,0 +1,143 @@
|
||||
defmodule Mixer.Repo.Migrations.InitializeAndAddAuthenticationResourcesAndAddPasswordAuthenticationAndAddPasswordAuthAndAddMagicLinkAuthAndAddApiKeyAuthExtensions1 do
|
||||
@moduledoc """
|
||||
Installs any extensions that are mentioned in the repo's `installed_extensions/0` callback
|
||||
|
||||
This file was autogenerated with `mix ash_postgres.generate_migrations`
|
||||
"""
|
||||
|
||||
use Ecto.Migration
|
||||
|
||||
def up do
|
||||
execute("""
|
||||
CREATE OR REPLACE FUNCTION ash_elixir_or(left BOOLEAN, in right ANYCOMPATIBLE, out f1 ANYCOMPATIBLE)
|
||||
AS $$ SELECT COALESCE(NULLIF($1, FALSE), $2) $$
|
||||
LANGUAGE SQL
|
||||
SET search_path = ''
|
||||
IMMUTABLE;
|
||||
""")
|
||||
|
||||
execute("""
|
||||
CREATE OR REPLACE FUNCTION ash_elixir_or(left ANYCOMPATIBLE, in right ANYCOMPATIBLE, out f1 ANYCOMPATIBLE)
|
||||
AS $$ SELECT COALESCE($1, $2) $$
|
||||
LANGUAGE SQL
|
||||
SET search_path = ''
|
||||
IMMUTABLE;
|
||||
""")
|
||||
|
||||
execute("""
|
||||
CREATE OR REPLACE FUNCTION ash_elixir_and(left BOOLEAN, in right ANYCOMPATIBLE, out f1 ANYCOMPATIBLE) AS $$
|
||||
SELECT CASE
|
||||
WHEN $1 IS TRUE THEN $2
|
||||
ELSE $1
|
||||
END $$
|
||||
LANGUAGE SQL
|
||||
SET search_path = ''
|
||||
IMMUTABLE;
|
||||
""")
|
||||
|
||||
execute("""
|
||||
CREATE OR REPLACE FUNCTION ash_elixir_and(left ANYCOMPATIBLE, in right ANYCOMPATIBLE, out f1 ANYCOMPATIBLE) AS $$
|
||||
SELECT CASE
|
||||
WHEN $1 IS NOT NULL THEN $2
|
||||
ELSE $1
|
||||
END $$
|
||||
LANGUAGE SQL
|
||||
SET search_path = ''
|
||||
IMMUTABLE;
|
||||
""")
|
||||
|
||||
execute("""
|
||||
CREATE OR REPLACE FUNCTION ash_trim_whitespace(arr text[])
|
||||
RETURNS text[] AS $$
|
||||
DECLARE
|
||||
start_index INT = 1;
|
||||
end_index INT = array_length(arr, 1);
|
||||
BEGIN
|
||||
WHILE start_index <= end_index AND arr[start_index] = '' LOOP
|
||||
start_index := start_index + 1;
|
||||
END LOOP;
|
||||
|
||||
WHILE end_index >= start_index AND arr[end_index] = '' LOOP
|
||||
end_index := end_index - 1;
|
||||
END LOOP;
|
||||
|
||||
IF start_index > end_index THEN
|
||||
RETURN ARRAY[]::text[];
|
||||
ELSE
|
||||
RETURN arr[start_index : end_index];
|
||||
END IF;
|
||||
END; $$
|
||||
LANGUAGE plpgsql
|
||||
SET search_path = ''
|
||||
IMMUTABLE;
|
||||
""")
|
||||
|
||||
execute("""
|
||||
CREATE OR REPLACE FUNCTION ash_raise_error(json_data jsonb)
|
||||
RETURNS BOOLEAN AS $$
|
||||
BEGIN
|
||||
-- Raise an error with the provided JSON data.
|
||||
-- The JSON object is converted to text for inclusion in the error message.
|
||||
RAISE EXCEPTION 'ash_error: %', json_data::text;
|
||||
RETURN NULL;
|
||||
END;
|
||||
$$ LANGUAGE plpgsql
|
||||
STABLE
|
||||
SET search_path = '';
|
||||
""")
|
||||
|
||||
execute("""
|
||||
CREATE OR REPLACE FUNCTION ash_raise_error(json_data jsonb, type_signal ANYCOMPATIBLE)
|
||||
RETURNS ANYCOMPATIBLE AS $$
|
||||
BEGIN
|
||||
-- Raise an error with the provided JSON data.
|
||||
-- The JSON object is converted to text for inclusion in the error message.
|
||||
RAISE EXCEPTION 'ash_error: %', json_data::text;
|
||||
RETURN NULL;
|
||||
END;
|
||||
$$ LANGUAGE plpgsql
|
||||
STABLE
|
||||
SET search_path = '';
|
||||
""")
|
||||
|
||||
execute("""
|
||||
CREATE OR REPLACE FUNCTION uuid_generate_v7()
|
||||
RETURNS UUID
|
||||
AS $$
|
||||
DECLARE
|
||||
timestamp TIMESTAMPTZ;
|
||||
microseconds INT;
|
||||
BEGIN
|
||||
timestamp = clock_timestamp();
|
||||
microseconds = (cast(extract(microseconds FROM timestamp)::INT - (floor(extract(milliseconds FROM timestamp))::INT * 1000) AS DOUBLE PRECISION) * 4.096)::INT;
|
||||
|
||||
RETURN encode(
|
||||
set_byte(
|
||||
set_byte(
|
||||
overlay(uuid_send(gen_random_uuid()) placing substring(int8send(floor(extract(epoch FROM timestamp) * 1000)::BIGINT) FROM 3) FROM 1 FOR 6
|
||||
),
|
||||
6, (b'0111' || (microseconds >> 8)::bit(4))::bit(8)::int
|
||||
),
|
||||
7, microseconds::bit(8)::int
|
||||
),
|
||||
'hex')::UUID;
|
||||
END
|
||||
$$
|
||||
LANGUAGE PLPGSQL
|
||||
SET search_path = ''
|
||||
VOLATILE;
|
||||
""")
|
||||
|
||||
execute("CREATE EXTENSION IF NOT EXISTS \"citext\"")
|
||||
end
|
||||
|
||||
def down do
|
||||
# Uncomment this if you actually want to uninstall the extensions
|
||||
# when this migration is rolled back:
|
||||
execute(
|
||||
"DROP FUNCTION IF EXISTS uuid_generate_v7(), timestamp_from_uuid_v7(uuid), ash_raise_error(jsonb), ash_raise_error(jsonb, ANYCOMPATIBLE), ash_elixir_and(BOOLEAN, ANYCOMPATIBLE), ash_elixir_and(ANYCOMPATIBLE, ANYCOMPATIBLE), ash_elixir_or(ANYCOMPATIBLE, ANYCOMPATIBLE), ash_elixir_or(BOOLEAN, ANYCOMPATIBLE), ash_trim_whitespace(text[])"
|
||||
)
|
||||
|
||||
# execute("DROP EXTENSION IF EXISTS \"citext\"")
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,66 @@
|
||||
defmodule Mixer.Repo.Migrations.InitializeAndAddAuthenticationResourcesAndAddPasswordAuthenticationAndAddPasswordAuthAndAddMagicLinkAuthAndAddApiKeyAuth do
|
||||
@moduledoc """
|
||||
Updates resources based on their most recent snapshots.
|
||||
|
||||
This file was autogenerated with `mix ash_postgres.generate_migrations`
|
||||
"""
|
||||
|
||||
use Ecto.Migration
|
||||
|
||||
def up do
|
||||
create table(:users, primary_key: false) do
|
||||
add :id, :uuid, null: false, default: fragment("gen_random_uuid()"), primary_key: true
|
||||
add :email, :citext, null: false
|
||||
add :hashed_password, :text
|
||||
add :confirmed_at, :utc_datetime_usec
|
||||
end
|
||||
|
||||
create unique_index(:users, [:email], name: "users_unique_email_index")
|
||||
|
||||
create table(:tokens, primary_key: false) do
|
||||
add :jti, :text, null: false, primary_key: true
|
||||
add :subject, :text, null: false
|
||||
add :expires_at, :utc_datetime, null: false
|
||||
add :purpose, :text, null: false
|
||||
add :extra_data, :map
|
||||
|
||||
add :created_at, :utc_datetime_usec,
|
||||
null: false,
|
||||
default: fragment("(now() AT TIME ZONE 'utc')")
|
||||
|
||||
add :updated_at, :utc_datetime_usec,
|
||||
null: false,
|
||||
default: fragment("(now() AT TIME ZONE 'utc')")
|
||||
end
|
||||
|
||||
create table(:api_keys, primary_key: false) do
|
||||
add :id, :uuid, null: false, default: fragment("gen_random_uuid()"), primary_key: true
|
||||
add :api_key_hash, :binary, null: false
|
||||
add :expires_at, :utc_datetime_usec, null: false
|
||||
|
||||
add :user_id,
|
||||
references(:users,
|
||||
column: :id,
|
||||
name: "api_keys_user_id_fkey",
|
||||
type: :uuid,
|
||||
prefix: "public"
|
||||
)
|
||||
end
|
||||
|
||||
create unique_index(:api_keys, [:api_key_hash], name: "api_keys_unique_api_key_index")
|
||||
end
|
||||
|
||||
def down do
|
||||
drop_if_exists unique_index(:api_keys, [:api_key_hash], name: "api_keys_unique_api_key_index")
|
||||
|
||||
drop constraint(:api_keys, "api_keys_user_id_fkey")
|
||||
|
||||
drop table(:api_keys)
|
||||
|
||||
drop table(:tokens)
|
||||
|
||||
drop_if_exists unique_index(:users, [:email], name: "users_unique_email_index")
|
||||
|
||||
drop table(:users)
|
||||
end
|
||||
end
|
||||
11
priv/repo/seeds.exs
Normal file
11
priv/repo/seeds.exs
Normal file
@@ -0,0 +1,11 @@
|
||||
# Script for populating the database. You can run it as:
|
||||
#
|
||||
# mix run priv/repo/seeds.exs
|
||||
#
|
||||
# Inside the script, you can read and write to any of your
|
||||
# repositories directly:
|
||||
#
|
||||
# Mixer.Repo.insert!(%Mixer.SomeSchema{})
|
||||
#
|
||||
# We recommend using the bang functions (`insert!`, `update!`
|
||||
# and so on) as they will fail if something goes wrong.
|
||||
Reference in New Issue
Block a user