-
-
Save Svenskunganka/27d7831187520bc63609ea6eceaed97c to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require "../migration" | |
module Project | |
ver = 1 | |
migration = Migration.new ver | |
migration.register_up { |db| | |
db.exec "create table version (version int)" | |
db.exec "insert into version values (?)", ver | |
true # TODO: Replace with error-checking | |
} | |
migration.register_down { |db| | |
db.exec "drop table version" | |
true # TODO: Replace with error-checking | |
} | |
migration.register | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require "db" | |
require "sqlite3" | |
require "./migration/migrations/*" | |
module Project | |
class Database | |
@conn : DB::Database | |
def initialize(path : String) | |
@conn = DB.open `sqlite3://#{path}` | |
cur_version = get_version() | |
Migration.migrate(cur_version, DB_VERSION, @conn) | |
end | |
def get_version() | |
begin | |
version = @conn.query_one("select version from version limit 1", as: Int32) | |
rescue | |
version = 0 | |
end | |
return version | |
end | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Error in src/project.cr:25: instantiating 'Project::Database:Class#new(String)' | |
db = Database.new(db_path) | |
^~~ | |
in src/project/database/database.cr:15: instantiating 'Project::Migration:Class#migrate(Int32, Int32, DB::Database)' | |
Migration.migrate(cur_version, DB_VERSION, @conn) | |
^~~~~~~ | |
in src/project/database/migration/migration.cr:22: instantiating 'Project::Migration#up(DB::Database)' | |
result = @@migrations[from_version += 1].up(conn) | |
^~ | |
in src/project/database/migration/migration.cr:58: undefined method 'call' for Nil (compile-time type is (Proc(DB::Database, Bool) | Nil)) | |
result = @up.call(conn) | |
^~~~ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require "db" | |
require "sqlite3" | |
module Project | |
class Migration | |
@@migrations = {} of Int32 => Migration | |
def initialize(@version : Int32) | |
end | |
# Registers the current instance and its version to | |
# the list of migrations | |
def register() | |
@@migrations[@version] = self | |
end | |
def self.migrate(from_version, to_version : Int32, conn : DB::Database) | |
while from_version < to_version | |
migration = @@migrations[from_version =+ 1] | |
migration.up(conn) unless migration == nil | |
end | |
end | |
# Registers a callback that will be called when the `up`-method is called. | |
# The callback must return either `true` for a successful migration, | |
# or `false` for a failed migration. If an `up` migration has | |
# failed, the `down` migration will be called to restore the database | |
# back to its previous state. | |
# The callback will receive an instance of `DB::Database` | |
# | |
# Example: | |
# | |
# ``` | |
# migration = Migration.new(1) | |
# | |
# migration.register_up |db| do | |
# # Advance migration | |
# end | |
# | |
# migration.register_down |db| do | |
# # Recede migration | |
# end | |
# ``` | |
def register_up(&block : DB::Database -> Bool) | |
@up = block | |
end | |
# Registers a callback that will be called when the `down`-method is called. | |
# See the `register_up` method for more information | |
def register_down(&block : DB::Database -> Bool) | |
@down = block | |
end | |
# Advances DB to the next version | |
def up(conn : DB::Database) | |
result = @up.call(conn) | |
unless result | |
# Failed migration, rollback | |
@down.call(conn) | |
raise Exception.new(`Failed to migrate database to version: #{@version}. Rolling back.`) | |
end | |
end | |
# Recedes DB to the previous version | |
def down(conn : DB::Database) | |
result = @down.call(conn) | |
unless result | |
# Failed migration, rollback | |
@up.call(conn) | |
raise Exception.new(`Failed to migrate database to version: #{@version - 1}. Rolling back.`) | |
end | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment