Skip to content

Commit

Permalink
update database migration toolkit
Browse files Browse the repository at this point in the history
Signed-off-by: keinsell <[email protected]>
  • Loading branch information
keinsell committed Jan 2, 2025
1 parent aff24dc commit dbb7f2d
Show file tree
Hide file tree
Showing 29 changed files with 488 additions and 540 deletions.
4 changes: 2 additions & 2 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
flake.lock linguist-generated=true
src/lib/migration/sql/*.sql linguist-detectable linguist-language=sql
src/lib/migration/sql/2_add_substance_data.sql binary linguist-vendored
src/lib/migration/migrations/*.sql linguist-detectable linguist-language=sql
src/lib/migration/sql/20250101000002_import_substance.sql binary linguist-vendored
docs/*.md linguist-detectable
17 changes: 17 additions & 0 deletions docs/JOURNAL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Project's Journal

## 2025

### January

#### 01

- **Spent 4 hours** working on implementing a migration toolkit with `Atlas`, only to realize that it’s not really
compatible with code-first ORMs like `SeaORM` and adds more complexity than just writing migrations manually in Rust.
Well, these things happen. For now, it’s fine for the current scope, but I’ll likely remove `Atlas` in the future. It
seems better suited for cloud-native applications, whereas for our **local-first application**, tools like `Sqitch`
and `Prisma` seem like more fitting options. **Atlas** does have its use cases, but it’s not a good fit here.

- **Cleaned up the database schema**—we had a lot of unnecessary, chemical-specific data that wasn’t adding any real
value to the project. Now, we’re only storing the essential information, which keeps the database clean and focused,
without unnecessary bloat.
2 changes: 1 addition & 1 deletion src/command/substance/get_substance.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ impl CommandHandler for GetSubstance
{
let substances = substance::Entity::find()
.filter(substance::Column::CommonNames.contains(&self.substance_name.to_lowercase()))
.order_by_asc(substance::Column::SystematicName)
.order_by_asc(substance::Column::Name)
.all(context.database_connection)
.await
.into_diagnostic()?;
Expand Down
8 changes: 7 additions & 1 deletion src/lib/migration/README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
# Running Migrator CLI
# Database Management

This directory introduces you to management of database schema in application.

```bash
curl -sSf https://atlasgo.sh | sh -s -- --community
```

- Generate a new migration file
```sh
Expand Down
59 changes: 59 additions & 0 deletions src/lib/migration/justfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
DEFAULT_DATABASE_CONNECTION_URI := "sqlite:///tmp/neuronek.sqlite"
schema_format := "{{ sql . }}"
dev_db := "sqlite://dev?mode=memory"
migration_dir := "./migrations"
schema_file := "schema.sql"

inspect connection_uri=DEFAULT_DATABASE_CONNECTION_URI:
atlas schema inspect -u {{ connection_uri }}

pull connection_uri=DEFAULT_DATABASE_CONNECTION_URI:
atlas schema inspect -u "{{ connection_uri }}" --format '{{ schema_format }}' > {{ schema_file }}

push connection_uri=DEFAULT_DATABASE_CONNECTION_URI:
atlas schema apply \
-u "{{ connection_uri }}" \
--to file://schema.sql \
--dev-url "{{ dev_db }}"

plan migration_name connection_uri=DEFAULT_DATABASE_CONNECTION_URI:
@just hash
atlas migrate diff {{ migration_name }} \
--dir "file://{{ migration_dir }}" \
--to "file://{{ schema_file }}" \
--dev-url "{{ dev_db }}"

create migration_name:
atlas migrate new {{ migration_name }}

up connection_uri=DEFAULT_DATABASE_CONNECTION_URI:
@just hash
atlas migrate apply \
--url "{{ connection_uri }}"

hash:
atlas migrate hash --dir="file://{{ migration_dir }}"

fresh:
@just hash
@just clean
@just up
@just pull

clean connection_uri=DEFAULT_DATABASE_CONNECTION_URI:
atlas schema clean -u "{{ connection_uri }}" --auto-approve

baseline connection_uri=DEFAULT_DATABASE_CONNECTION_URI:
atlas migrate diff baseline \
--dir "file://{{ migration_dir }}" \
--dev-url "{{ dev_db }}" \
--to "{{ connection_uri }}" \

generate:
sea-orm-cli generate entity \
--compact-format \
--ignore-tables=seaql_migrations,atlas_schema_revisions \
--output-dir="./../orm" \
-u="{{ DEFAULT_DATABASE_CONNECTION_URI }}" \
--with-serde=both \
--with-copy-enums
17 changes: 0 additions & 17 deletions src/lib/migration/m20020101_000002_create_database_schema.rs

This file was deleted.

61 changes: 0 additions & 61 deletions src/lib/migration/m20220101_000001_create_table.rs

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
-- Create "ingestion" table
CREATE TABLE `ingestion`
(
`id` integer NOT NULL PRIMARY KEY AUTOINCREMENT,
`substance_name` varchar NOT NULL,
`route_of_administration` varchar NOT NULL,
`dosage` float NOT NULL,
`ingested_at` datetime_text NOT NULL,
`updated_at` datetime_text NOT NULL,
`created_at` datetime_text NOT NULL
);
-- Create "seaql_migrations" table
CREATE TABLE IF NOT EXISTS `seaql_migrations`
(
`version` varchar NOT NULL,
`applied_at` bigint NOT NULL,
PRIMARY KEY (`version`)
);
Original file line number Diff line number Diff line change
@@ -1,3 +1,159 @@
-- Create "substance" table
CREATE TABLE `substance`
(
`id` text NOT NULL,
`name` text NOT NULL,
`common_names` text NOT NULL,
`brand_names` text NOT NULL,
`substitutive_name` text NULL,
`systematic_name` text NOT NULL,
`pubchem_cid` integer NOT NULL,
`unii` text NULL,
`cas_number` text NULL,
`inchi_key` text NOT NULL,
`smiles` text NOT NULL,
`psychonautwiki_url` text NULL,
`psychoactive_class` text NOT NULL,
`chemical_class` text NULL,
`description` text NULL,
PRIMARY KEY (`id`)
);
-- Create index "substance_id_key" to table: "substance"
CREATE UNIQUE INDEX `substance_id_key` ON `substance` (`id`);
-- Create index "substance_name_key" to table: "substance"
CREATE UNIQUE INDEX `substance_name_key` ON `substance` (`name`);
-- Create index "substance_substitutive_name_key" to table: "substance"
CREATE UNIQUE INDEX `substance_substitutive_name_key` ON `substance` (`substitutive_name`);
-- Create index "substance_systematic_name_key" to table: "substance"
CREATE UNIQUE INDEX `substance_systematic_name_key` ON `substance` (`systematic_name`);
-- Create index "substance_pubchem_cid_key" to table: "substance"
CREATE UNIQUE INDEX `substance_pubchem_cid_key` ON `substance` (`pubchem_cid`);
-- Create index "substance_cas_number_key" to table: "substance"
CREATE UNIQUE INDEX `substance_cas_number_key` ON `substance` (`cas_number`);
-- Create index "substance_inchi_key_key" to table: "substance"
CREATE UNIQUE INDEX `substance_inchi_key_key` ON `substance` (`inchi_key`);
-- Create index "substance_smiles_key" to table: "substance"
CREATE UNIQUE INDEX `substance_smiles_key` ON `substance` (`smiles`);
-- Create "substance_synonym" table
CREATE TABLE `substance_synonym`
(
`id` text NOT NULL,
`substanceId` text NOT NULL,
`name` text NOT NULL,
PRIMARY KEY (`id`),
CONSTRAINT `substance_synonym_substanceId_fkey` FOREIGN KEY (`substanceId`) REFERENCES `substance` (`id`) ON UPDATE CASCADE ON DELETE RESTRICT
);
-- Create index "substance_synonym_name_key" to table: "substance_synonym"
CREATE UNIQUE INDEX `substance_synonym_name_key` ON `substance_synonym` (`name`);
-- Create "substance_tolerance" table
CREATE TABLE `substance_tolerance`
(
`id` text NOT NULL,
`substanceId` text NOT NULL,
`mechanism` text NOT NULL,
`mechanism_desciption` text NULL,
`onset_mechanism` text NOT NULL,
`onset_description` text NULL,
`decline_mechanism` text NOT NULL,
`decline_description` text NULL,
`onset_duration` text NULL,
`decline_to_baseline_duration` text NULL,
`decline_to_half_duration` text NULL,
PRIMARY KEY (`id`),
CONSTRAINT `substance_tolerance_substanceId_fkey` FOREIGN KEY (`substanceId`) REFERENCES `substance` (`id`) ON UPDATE CASCADE ON DELETE RESTRICT
);
-- Create index "substance_tolerance_substanceId_key" to table: "substance_tolerance"
CREATE UNIQUE INDEX `substance_tolerance_substanceId_key` ON `substance_tolerance` (`substanceId`);
-- Create "chemical_class" table
CREATE TABLE `chemical_class`
(
`id` text NOT NULL,
`name` text NOT NULL,
`description` text NULL,
PRIMARY KEY (`id`)
);
-- Create index "chemical_class_name_key" to table: "chemical_class"
CREATE UNIQUE INDEX `chemical_class_name_key` ON `chemical_class` (`name`);
-- Create "psychoactive_class" table
CREATE TABLE `psychoactive_class`
(
`id` text NOT NULL,
`name` text NOT NULL,
`summary` text NULL,
`description` text NULL,
`substanceId` text NULL,
PRIMARY KEY (`id`),
CONSTRAINT `psychoactive_class_substanceId_fkey` FOREIGN KEY (`substanceId`) REFERENCES `substance` (`id`) ON UPDATE CASCADE ON DELETE SET NULL
);
-- Create index "psychoactive_class_name_key" to table: "psychoactive_class"
CREATE UNIQUE INDEX `psychoactive_class_name_key` ON `psychoactive_class` (`name`);
-- Create "substance_route_of_administration" table
CREATE TABLE `substance_route_of_administration`
(
`id` text NOT NULL,
`substanceName` text NOT NULL,
`name` text NOT NULL,
PRIMARY KEY (`id`),
CONSTRAINT `substance_route_of_administration_substanceName_fkey` FOREIGN KEY (`substanceName`) REFERENCES `substance` (`name`) ON UPDATE CASCADE ON DELETE RESTRICT
);
-- Create index "substance_route_of_administration_name_substanceName_key" to table: "substance_route_of_administration"
CREATE UNIQUE INDEX `substance_route_of_administration_name_substanceName_key` ON `substance_route_of_administration` (`name`, `substanceName`);
-- Create "substance_interactions" table
CREATE TABLE `substance_interactions`
(
`id` text NOT NULL,
`substanceId` text NULL,
PRIMARY KEY (`id`),
CONSTRAINT `SubstanceInteraction_substanceId_fkey` FOREIGN KEY (`substanceId`) REFERENCES `substance` (`id`) ON UPDATE CASCADE ON DELETE SET NULL
);
-- Create "effect" table
CREATE TABLE `effect`
(
`id` text NOT NULL,
`name` text NOT NULL,
`slug` text NOT NULL,
`category` text NULL,
`type` text NULL,
`tags` text NOT NULL,
`summary` text NULL,
`description` text NOT NULL,
`parameters` text NOT NULL,
`see_also` text NOT NULL,
`effectindex` text NULL,
`psychonautwiki` text NULL,
PRIMARY KEY (`id`)
);
-- Create index "Effect_name_key" to table: "effect"
CREATE UNIQUE INDEX `Effect_name_key` ON `effect` (`name`);
-- Create index "Effect_slug_key" to table: "effect"
CREATE UNIQUE INDEX `Effect_slug_key` ON `effect` (`slug`);
-- Create "substance_route_of_administration_phase" table
CREATE TABLE `substance_route_of_administration_phase`
(
`id` text NOT NULL,
`classification` text NOT NULL,
`lower_duration` text NULL,
`upper_duration` text NULL,
`routeOfAdministrationId` text NULL,
PRIMARY KEY (`id`),
CONSTRAINT `route_of_administration_phase_routeOfAdministrationId_fkey` FOREIGN KEY (`routeOfAdministrationId`) REFERENCES `substance_route_of_administration` (`id`) ON UPDATE CASCADE ON DELETE SET NULL
);
-- Create index "route_of_administration_phase_routeOfAdministrationId_classification_key" to table: "substance_route_of_administration_phase"
CREATE UNIQUE INDEX `route_of_administration_phase_routeOfAdministrationId_classification_key` ON `substance_route_of_administration_phase` (`routeOfAdministrationId`, `classification`);
-- Create "substance_route_of_administration_dosage" table
CREATE TABLE `substance_route_of_administration_dosage`
(
`id` text NOT NULL,
`intensity` text NOT NULL,
`lower_bound_amount` real NULL,
`upper_bound_amount` real NULL,
`unit` text NOT NULL,
`routeOfAdministrationId` text NULL,
PRIMARY KEY (`id`),
CONSTRAINT `route_of_administration_dosage_routeOfAdministrationId_fkey` FOREIGN KEY (`routeOfAdministrationId`) REFERENCES `substance_route_of_administration` (`id`) ON UPDATE CASCADE ON DELETE SET NULL
);
-- Create index "route_of_administration_dosage_intensivity_routeOfAdministrationId_key" to table: "substance_route_of_administration_dosage"
CREATE UNIQUE INDEX `route_of_administration_dosage_intensivity_routeOfAdministrationId_key` ON `substance_route_of_administration_dosage` (`intensity`, `routeOfAdministrationId`);
-- Disable the enforcement of foreign-keys constraints
PRAGMA foreign_keys = off;
-- Create "new_substance_route_of_administration_phase" table
Expand Down Expand Up @@ -54,7 +210,6 @@ DELETE
FROM "substance_route_of_administration";
DELETE
FROM "substance";
BEGIN;
INSERT INTO substance
VALUES ('3ab37fdea136ae2c01e5d7670e7ee0d7ea1c700367f9d4dfb65d4249fc7c0282f6fe70443f2506c6a5de71bda8e220b1c94de53ff0d4e34e697341e2728c4259',
'1,3-dimethylbutylamine', '', '', NULL, '4-methylpentan-2-amine', 7908, NULL, NULL,
Expand Down Expand Up @@ -13499,5 +13654,21 @@ INSERT INTO substance_route_of_administration_dosage
VALUES ('3b54f9aead9bf6a954607ca9314b57461b19ec95a0681499d5acad2547d11122d5cc9e6374c3df018a6c11964f3742d6bdeab47a4051ea354872f3beacee5a10',
'heavy', 15.0, 0.0, 'mg',
'319bdcc6327775a15fbce77e9fc1a3bb22a2a62acca3fe71f00b57c5d1094607047975ae4e88c548a8d6711be13d82c27bb45dba92e061df92feb834aeb3a8b7');
END;
PRAGMA foreign_keys = on;
PRAGMA foreign_keys = on;
-- Create "atlas_schema_revisions" table
CREATE TABLE IF NOT EXISTS `atlas_schema_revisions`
(
`version` text NOT NULL,
`description` text NOT NULL,
`type` integer NOT NULL DEFAULT 2,
`applied` integer NOT NULL DEFAULT 0,
`total` integer NOT NULL DEFAULT 0,
`executed_at` datetime NOT NULL,
`execution_time` integer NOT NULL,
`error` text NULL,
`error_stmt` text NULL,
`hash` text NOT NULL,
`partial_hashes` json NULL,
`operator_version` text NOT NULL,
PRIMARY KEY (`version`)
);
Loading

0 comments on commit dbb7f2d

Please sign in to comment.