aboutsummaryrefslogtreecommitdiff
path: root/src/guff/database-updater.cr
diff options
context:
space:
mode:
Diffstat (limited to 'src/guff/database-updater.cr')
-rw-r--r--src/guff/database-updater.cr131
1 files changed, 131 insertions, 0 deletions
diff --git a/src/guff/database-updater.cr b/src/guff/database-updater.cr
new file mode 100644
index 0000000..e06aff3
--- /dev/null
+++ b/src/guff/database-updater.cr
@@ -0,0 +1,131 @@
+require "./database"
+
+module Guff
+ class DatabaseUpdater
+ CURRENT_VERSION = 2_i64
+
+ SQL = {
+ :get_version => "
+ SELECT value
+ FROM metadata
+ WHERE name = 'version'
+ ",
+ }
+
+ MIGRATION_IDS = %w{
+ 0-null
+ 1-create-tables
+ 2-create-indices
+ }
+
+ MIGRATIONS = {
+ "1-create-tables": {
+ backup: false,
+ sql: [%{
+ CREATE TABLE metadata (
+ name TEXT PRIMARY KEY,
+ value TEXT NOT NULL
+ )
+ }, %{
+ INSERT INTO metadata(name, value) VALUES ('version', '1')
+ }, %{
+ CREATE TABLE tags (
+ tag_id INTEGER PRIMARY KEY,
+ name TEXT UNIQUE NOT NULL
+ )
+ }, %{
+ CREATE TABLE posts (
+ -- unique id
+ post_id INTEGER PRIMARY KEY,
+
+ -- false if this post has been deleted
+ is_active BOOLEAN NOT NULL
+ DEFAULT true,
+
+ -- when this post was created
+ created_at TIMESTAMP WITH TIME ZONE
+ NOT NULL DEFAULT CURRENT_TIMESTAMP,
+
+ -- when this post was posted
+ -- (that is, the draft status was removed)
+ posted_at TIMESTAMP WITH TIME ZONE
+ NOT NULL DEFAULT CURRENT_TIMESTAMP,
+
+ -- title of post
+ name TEXT NOT NULL
+ CHECK (LENGTH(name) > 0)
+
+ -- slug of post (url fragment)
+ slug TEXT NOT NULL
+ CHECK (LENGTH(slug) > 0)
+
+ -- body (raw text before filters)
+ body TEXT NOT NULL
+ CHECK (LENGTH(body) > 0)
+
+ -- generated html (after filters)
+ html TEXT NOT NULL
+ CHECK (LENGTH(html) > 0)
+ )
+ }],
+ },
+
+ "2-create-indices": {
+ backup: false,
+ sql: [%{
+ CREATE INDEX ON tags(name)
+ }, %{
+ CREATE INDEX ON posts(slug)
+ }, %{
+ UPDATE metadata
+ SET value = '2'
+ WHERE name = 'version'
+ }],
+ },
+ }
+
+ def self.run(path, config)
+ new(path, config).run
+ end
+
+ def initialize(
+ @path : String,
+ @config : Config
+ )
+ @db = Database.new(path)
+ end
+
+ def run
+ version = 0_i64
+
+ if @db.table_exists?("metadata")
+ version = @db.one(SQL[:get_version]) as Int64
+ end
+
+ puts "versions: db = %d, code = %d" % [
+ version,
+ CURRENT_VERSION,
+ ]
+
+ if version < CURRENT_VERSION
+ (version + 1).upto(CURRENT_VERSION) do |v|
+ migrate_to(v)
+ end
+ end
+ end
+
+ private def migrate_to(version : Int64)
+ id = MIGRATION_IDS[version]
+ m = MIGRATIONS[id]
+ puts "migrating: %s" % [id]
+
+ (m[:sql] as Array(String)).each do |sql|
+ @db.query(sql)
+ end
+ end
+
+ private def get_version
+ @db.one(:get_version) as Int64
+ end
+ end
+end