From f7a360c2d8c785553952313e1ef2cd94c22a05fd Mon Sep 17 00:00:00 2001 From: Alex Ling Date: Sat, 16 Jan 2021 17:11:57 +0000 Subject: [PATCH] Proper DB migration --- migration/ids.2.cr | 19 ++++++++++++++++ migration/tags.4.cr | 19 ++++++++++++++++ migration/thumbnails.3.cr | 20 +++++++++++++++++ migration/users.1.cr | 20 +++++++++++++++++ shard.lock | 4 ++++ shard.yml | 2 ++ src/logger.cr | 37 ++++++++++++++++++------------ src/storage.cr | 47 ++++++++++----------------------------- 8 files changed, 119 insertions(+), 49 deletions(-) create mode 100644 migration/ids.2.cr create mode 100644 migration/tags.4.cr create mode 100644 migration/thumbnails.3.cr create mode 100644 migration/users.1.cr diff --git a/migration/ids.2.cr b/migration/ids.2.cr new file mode 100644 index 0000000..631c50d --- /dev/null +++ b/migration/ids.2.cr @@ -0,0 +1,19 @@ +class CreateIds < MG::Base + def up : String + <<-SQL + CREATE TABLE IF NOT EXISTS ids ( + path TEXT NOT NULL, + id TEXT NOT NULL, + is_title INTEGER NOT NULL + ); + CREATE UNIQUE INDEX IF NOT EXISTS path_idx ON ids (path); + CREATE UNIQUE INDEX IF NOT EXISTS id_idx ON ids (id); + SQL + end + + def down : String + <<-SQL + DROP TABLE ids; + SQL + end +end diff --git a/migration/tags.4.cr b/migration/tags.4.cr new file mode 100644 index 0000000..af9906c --- /dev/null +++ b/migration/tags.4.cr @@ -0,0 +1,19 @@ +class CreateTags < MG::Base + def up : String + <<-SQL + CREATE TABLE IF NOT EXISTS tags ( + id TEXT NOT NULL, + tag TEXT NOT NULL, + unique (id, tag) + ); + CREATE INDEX IF NOT EXISTS tags_id_idx ON tags (id); + CREATE INDEX IF NOT EXISTS tags_tag_idx ON tags (tag); + SQL + end + + def down : String + <<-SQL + DROP TABLE tags; + SQL + end +end diff --git a/migration/thumbnails.3.cr b/migration/thumbnails.3.cr new file mode 100644 index 0000000..4e94069 --- /dev/null +++ b/migration/thumbnails.3.cr @@ -0,0 +1,20 @@ +class CreateThumbnails < MG::Base + def up : String + <<-SQL + CREATE TABLE IF NOT EXISTS thumbnails ( + id TEXT NOT NULL, + data BLOB NOT NULL, + filename TEXT NOT NULL, + mime TEXT NOT NULL, + size INTEGER NOT NULL + ); + CREATE UNIQUE INDEX IF NOT EXISTS tn_index ON thumbnails (id); + SQL + end + + def down : String + <<-SQL + DROP TABLE thumbnails; + SQL + end +end diff --git a/migration/users.1.cr b/migration/users.1.cr new file mode 100644 index 0000000..78b699a --- /dev/null +++ b/migration/users.1.cr @@ -0,0 +1,20 @@ +class CreateUsers < MG::Base + def up : String + <<-SQL + CREATE TABLE IF NOT EXISTS users ( + username TEXT NOT NULL, + password TEXT NOT NULL, + token TEXT, + admin INTEGER NOT NULL + ); + CREATE UNIQUE INDEX IF NOT EXISTS username_idx ON users (username); + CREATE UNIQUE INDEX IF NOT EXISTS token_idx ON users (token); + SQL + end + + def down : String + <<-SQL + DROP TABLE users; + SQL + end +end diff --git a/shard.lock b/shard.lock index 61ded6a..90acc99 100644 --- a/shard.lock +++ b/shard.lock @@ -52,6 +52,10 @@ shards: git: https://github.com/hkalexling/koa.git version: 0.5.0 + mg: + git: https://github.com/hkalexling/mg.git + version: 0.1.0+git.commit.8d378bf58da442be2e5a27670233d43687d14121 + myhtml: git: https://github.com/kostya/myhtml.git version: 1.5.1 diff --git a/shard.yml b/shard.yml index 3395471..0c21e38 100644 --- a/shard.yml +++ b/shard.yml @@ -41,3 +41,5 @@ dependencies: github: hkalexling/koa tallboy: github: epoch/tallboy + mg: + github: hkalexling/mg diff --git a/src/logger.cr b/src/logger.cr index 92be20e..ba5aa31 100644 --- a/src/logger.cr +++ b/src/logger.cr @@ -11,20 +11,7 @@ class Logger use_default def initialize - level = Config.current.log_level - {% begin %} - case level.downcase - when "off" - @@severity = :none - {% for lvl, i in LEVELS %} - when {{lvl}} - @@severity = Log::Severity.new SEVERITY_IDS[{{i}}] - {% end %} - else - raise "Unknown log level #{level}" - end - {% end %} - + @@severity = Logger.get_severity @log = Log.for("") @backend = Log::IOBackend.new @@ -49,6 +36,28 @@ class Logger Log.setup @@severity, @backend end + def self.get_severity(level = "") : Log::Severity + if level.empty? + level = Config.current.log_level + end + {% begin %} + case level.downcase + when "off" + return Log::Severity::None + {% for lvl, i in LEVELS %} + when {{lvl}} + return Log::Severity.new SEVERITY_IDS[{{i}}] + {% end %} + else + raise "Unknown log level #{level}" + end + {% end %} + end + + def self.reset + @@default = Logger.new + end + # Ignores @@severity and always log msg def log(msg) @backend.write Log::Entry.new "", Log::Severity::None, msg, diff --git a/src/storage.cr b/src/storage.cr index 4818ebd..d2374f7 100644 --- a/src/storage.cr +++ b/src/storage.cr @@ -3,6 +3,8 @@ require "crypto/bcrypt" require "uuid" require "base64" require "./util/*" +require "mg" +require "../migration/*" def hash_password(pw) Crypto::Bcrypt::Password.create(pw).to_s @@ -35,44 +37,19 @@ class Storage MainFiber.run do DB.open "sqlite3://#{@path}" do |db| begin - # v0.18.0 - db.exec "create table tags (id text, tag text, unique (id, tag))" - db.exec "create index tags_id_idx on tags (id)" - db.exec "create index tags_tag_idx on tags (tag)" - - # v0.15.0 - db.exec "create table thumbnails " \ - "(id text, data blob, filename text, " \ - "mime text, size integer)" - db.exec "create unique index tn_index on thumbnails (id)" - - # v0.1.1 - db.exec "create table ids" \ - "(path text, id text, is_title integer)" - db.exec "create unique index path_idx on ids (path)" - db.exec "create unique index id_idx on ids (id)" - - # v0.1.0 - db.exec "create table users" \ - "(username text, password text, token text, admin integer)" + severity = Logger.get_severity + Log.setup "mg", severity + MG::Migration.new(db).migrate rescue e - unless e.message.not_nil!.ends_with? "already exists" - Logger.fatal "Error when checking tables in DB: #{e}" - raise e - end - - # If the DB is initialized through CLI but no user is added, we need - # to create the admin user when first starting the app - user_count = db.query_one "select count(*) from users", as: Int32 - init_admin if init_user && user_count == 0 - else - Logger.debug "Creating DB file at #{@path}" - db.exec "create unique index username_idx on users (username)" - db.exec "create unique index token_idx on users (token)" - - init_admin if init_user + Logger.fatal "DB migration failed. #{e}" + raise e + ensure + Logger.reset end + user_count = db.query_one "select count(*) from users", as: Int32 + init_admin if init_user && user_count == 0 + # Verifies that the default username in config is valid if Config.current.disable_login username = Config.current.default_username