feat: add charts table schema and migration with data backfill
- Add charts table with id, name (unique), created_at - Add chart_id FK to candles table with composite unique on (chart_id, time) - Add chart_id FK to annotations table - Custom migration handles existing data: creates 'Imported Data' chart and backfills chart_id - Recreates tables for NOT NULL constraint (SQLite limitation)
This commit is contained in:
parent
178834f3b2
commit
92d3339a48
14 changed files with 913 additions and 3 deletions
74
drizzle/0002_careful_synch.sql
Normal file
74
drizzle/0002_careful_synch.sql
Normal file
|
|
@ -0,0 +1,74 @@
|
|||
-- Create charts table
|
||||
CREATE TABLE `charts` (
|
||||
`id` integer PRIMARY KEY AUTOINCREMENT NOT NULL,
|
||||
`name` text NOT NULL,
|
||||
`created_at` integer NOT NULL
|
||||
);
|
||||
--> statement-breakpoint
|
||||
CREATE UNIQUE INDEX `charts_name_unique` ON `charts` (`name`);
|
||||
--> statement-breakpoint
|
||||
|
||||
-- Insert default chart if candles exist
|
||||
INSERT INTO `charts` (`name`, `created_at`)
|
||||
SELECT 'Imported Data', CAST(strftime('%s', 'now') AS INTEGER)
|
||||
WHERE EXISTS (SELECT 1 FROM `candles` LIMIT 1);
|
||||
--> statement-breakpoint
|
||||
|
||||
-- Drop old unique index on candles.time
|
||||
DROP INDEX IF EXISTS `candles_time_unique`;
|
||||
--> statement-breakpoint
|
||||
|
||||
-- Add chart_id column to candles (nullable first for backfill)
|
||||
ALTER TABLE `candles` ADD `chart_id` integer REFERENCES charts(id);
|
||||
--> statement-breakpoint
|
||||
|
||||
-- Backfill existing candles with the default chart id
|
||||
UPDATE `candles` SET `chart_id` = (SELECT `id` FROM `charts` WHERE `name` = 'Imported Data') WHERE `chart_id` IS NULL;
|
||||
--> statement-breakpoint
|
||||
|
||||
-- Add chart_id column to annotations (nullable first for backfill)
|
||||
ALTER TABLE `annotations` ADD `chart_id` integer REFERENCES charts(id);
|
||||
--> statement-breakpoint
|
||||
|
||||
-- Backfill existing annotations with the default chart id
|
||||
UPDATE `annotations` SET `chart_id` = (SELECT `id` FROM `charts` WHERE `name` = 'Imported Data') WHERE `chart_id` IS NULL;
|
||||
--> statement-breakpoint
|
||||
|
||||
-- Recreate candles table with NOT NULL constraint and composite unique index
|
||||
CREATE TABLE `candles_new` (
|
||||
`id` integer PRIMARY KEY AUTOINCREMENT NOT NULL,
|
||||
`chart_id` integer NOT NULL REFERENCES charts(id),
|
||||
`time` integer NOT NULL,
|
||||
`open` real NOT NULL,
|
||||
`high` real NOT NULL,
|
||||
`low` real NOT NULL,
|
||||
`close` real NOT NULL
|
||||
);
|
||||
--> statement-breakpoint
|
||||
INSERT INTO `candles_new` (`id`, `chart_id`, `time`, `open`, `high`, `low`, `close`)
|
||||
SELECT `id`, `chart_id`, `time`, `open`, `high`, `low`, `close` FROM `candles`;
|
||||
--> statement-breakpoint
|
||||
DROP TABLE `candles`;
|
||||
--> statement-breakpoint
|
||||
ALTER TABLE `candles_new` RENAME TO `candles`;
|
||||
--> statement-breakpoint
|
||||
CREATE UNIQUE INDEX `candles_chart_time_unique` ON `candles` (`chart_id`, `time`);
|
||||
--> statement-breakpoint
|
||||
|
||||
-- Recreate annotations table with NOT NULL constraint
|
||||
CREATE TABLE `annotations_new` (
|
||||
`id` integer PRIMARY KEY AUTOINCREMENT NOT NULL,
|
||||
`chart_id` integer NOT NULL REFERENCES charts(id),
|
||||
`timestamp` integer NOT NULL,
|
||||
`label_type` text NOT NULL,
|
||||
`geometry` text,
|
||||
`color` text DEFAULT '#3b82f6',
|
||||
`created_at` integer NOT NULL
|
||||
);
|
||||
--> statement-breakpoint
|
||||
INSERT INTO `annotations_new` (`id`, `chart_id`, `timestamp`, `label_type`, `geometry`, `color`, `created_at`)
|
||||
SELECT `id`, `chart_id`, `timestamp`, `label_type`, `geometry`, `color`, `created_at` FROM `annotations`;
|
||||
--> statement-breakpoint
|
||||
DROP TABLE `annotations`;
|
||||
--> statement-breakpoint
|
||||
ALTER TABLE `annotations_new` RENAME TO `annotations`;
|
||||
288
drizzle/meta/0002_snapshot.json
Normal file
288
drizzle/meta/0002_snapshot.json
Normal file
|
|
@ -0,0 +1,288 @@
|
|||
{
|
||||
"version": "6",
|
||||
"dialect": "sqlite",
|
||||
"id": "8eb771d5-6d44-473e-8bce-144d195ae2b5",
|
||||
"prevId": "111e1b91-6d7b-45e4-aeb9-9762725d6905",
|
||||
"tables": {
|
||||
"annotation_types": {
|
||||
"name": "annotation_types",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "integer",
|
||||
"primaryKey": true,
|
||||
"notNull": true,
|
||||
"autoincrement": true
|
||||
},
|
||||
"name": {
|
||||
"name": "name",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"display_name": {
|
||||
"name": "display_name",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"color": {
|
||||
"name": "color",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"category": {
|
||||
"name": "category",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"icon": {
|
||||
"name": "icon",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"is_active": {
|
||||
"name": "is_active",
|
||||
"type": "integer",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": 1
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "integer",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
}
|
||||
},
|
||||
"indexes": {
|
||||
"annotation_types_name_unique": {
|
||||
"name": "annotation_types_name_unique",
|
||||
"columns": [
|
||||
"name"
|
||||
],
|
||||
"isUnique": true
|
||||
}
|
||||
},
|
||||
"foreignKeys": {},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {},
|
||||
"checkConstraints": {}
|
||||
},
|
||||
"annotations": {
|
||||
"name": "annotations",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "integer",
|
||||
"primaryKey": true,
|
||||
"notNull": true,
|
||||
"autoincrement": true
|
||||
},
|
||||
"chart_id": {
|
||||
"name": "chart_id",
|
||||
"type": "integer",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"timestamp": {
|
||||
"name": "timestamp",
|
||||
"type": "integer",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"label_type": {
|
||||
"name": "label_type",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"geometry": {
|
||||
"name": "geometry",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"color": {
|
||||
"name": "color",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false,
|
||||
"default": "'#3b82f6'"
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "integer",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"annotations_chart_id_charts_id_fk": {
|
||||
"name": "annotations_chart_id_charts_id_fk",
|
||||
"tableFrom": "annotations",
|
||||
"tableTo": "charts",
|
||||
"columnsFrom": [
|
||||
"chart_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "no action",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {},
|
||||
"checkConstraints": {}
|
||||
},
|
||||
"candles": {
|
||||
"name": "candles",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "integer",
|
||||
"primaryKey": true,
|
||||
"notNull": true,
|
||||
"autoincrement": true
|
||||
},
|
||||
"chart_id": {
|
||||
"name": "chart_id",
|
||||
"type": "integer",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"time": {
|
||||
"name": "time",
|
||||
"type": "integer",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"open": {
|
||||
"name": "open",
|
||||
"type": "real",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"high": {
|
||||
"name": "high",
|
||||
"type": "real",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"low": {
|
||||
"name": "low",
|
||||
"type": "real",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"close": {
|
||||
"name": "close",
|
||||
"type": "real",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
}
|
||||
},
|
||||
"indexes": {
|
||||
"candles_chart_time_unique": {
|
||||
"name": "candles_chart_time_unique",
|
||||
"columns": [
|
||||
"chart_id",
|
||||
"time"
|
||||
],
|
||||
"isUnique": true
|
||||
}
|
||||
},
|
||||
"foreignKeys": {
|
||||
"candles_chart_id_charts_id_fk": {
|
||||
"name": "candles_chart_id_charts_id_fk",
|
||||
"tableFrom": "candles",
|
||||
"tableTo": "charts",
|
||||
"columnsFrom": [
|
||||
"chart_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "no action",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {},
|
||||
"checkConstraints": {}
|
||||
},
|
||||
"charts": {
|
||||
"name": "charts",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "integer",
|
||||
"primaryKey": true,
|
||||
"notNull": true,
|
||||
"autoincrement": true
|
||||
},
|
||||
"name": {
|
||||
"name": "name",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "integer",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
}
|
||||
},
|
||||
"indexes": {
|
||||
"charts_name_unique": {
|
||||
"name": "charts_name_unique",
|
||||
"columns": [
|
||||
"name"
|
||||
],
|
||||
"isUnique": true
|
||||
}
|
||||
},
|
||||
"foreignKeys": {},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {},
|
||||
"checkConstraints": {}
|
||||
}
|
||||
},
|
||||
"views": {},
|
||||
"enums": {},
|
||||
"_meta": {
|
||||
"schemas": {},
|
||||
"tables": {},
|
||||
"columns": {}
|
||||
},
|
||||
"internal": {
|
||||
"indexes": {}
|
||||
}
|
||||
}
|
||||
|
|
@ -15,6 +15,13 @@
|
|||
"when": 1770915891699,
|
||||
"tag": "0001_sticky_shinko_yamashiro",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 2,
|
||||
"version": "6",
|
||||
"when": 1770937855462,
|
||||
"tag": "0002_careful_synch",
|
||||
"breakpoints": true
|
||||
}
|
||||
]
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue