diff --git a/Rakefile b/Rakefile index 981c69f..ac638d7 100644 --- a/Rakefile +++ b/Rakefile @@ -7,11 +7,12 @@ Minitest::TestTask.create namespace :db do desc "Run migrations" task :migrate, [:version] do |t, args| + require_relative "db" + require "sequel/core" Sequel.extension :migration + version = args[:version].to_i if args[:version] - Sequel.connect(ENV.fetch("DATABASE_URL"), logger: Logger.new($stderr)) do |db| - Sequel::Migrator.run(db, "db/migrations", target: version) - end + Sequel::Migrator.run(DB, "db/migrations", target: version, use_transactions: true) end end diff --git a/db.rb b/db.rb index c6f3a6c..1acbc3e 100644 --- a/db.rb +++ b/db.rb @@ -2,4 +2,8 @@ require "logger" require "sequel" -DB = Sequel.connect(ENV.fetch("DATABASE_URL"), loggers: [Logger.new($stdout)]) +Sequel.extension :sqlite_json_ops + +logger = Logger.new($stdout) +logger.level = Logger::WARN +DB = Sequel.connect(ENV.fetch("DATABASE_URL"), loggers: [logger]) diff --git a/db/migrations/004_create_tags.rb b/db/migrations/004_create_tags.rb new file mode 100644 index 0000000..2915204 --- /dev/null +++ b/db/migrations/004_create_tags.rb @@ -0,0 +1,48 @@ +Sequel.migration do + up do + create_table(:tags) do + primary_key :id + + String :name, unique: true, null: false + + DateTime :created_at, null: false + DateTime :modified_at, null: false + end + + create_table(:entities_tags) do + foreign_key :entity_id, :entities + foreign_key :tag_id, :tags + + DateTime :created_at, null: false + DateTime :modified_at, null: false + + unique [:entity_id, :tag_id] + end + + json = Sequel.sqlite_json_op(:json) + tags = json.extract("$.tags") + + DB[:pinboard] + .select_append(tags.as(:tags)) + .exclude(tags => "") + .each do |pin| + entity_id = pin.fetch(:entity_id) + tag_names = pin.fetch(:tags).split(/\s+/) + + tag_names.each do |tag_name| + tag_id = DB[:tags].where(name: tag_name).get(:id) + + created_at = modified_at = DateTime.now + tag_id ||= DB[:tags].insert(name: tag_name, created_at:, modified_at:) + + created_at = modified_at = DateTime.now + DB[:entities_tags].insert(entity_id:, tag_id:, created_at:, modified_at:) + end + end + end + + down do + drop_table(:tags) + drop_table(:entities_tags) + end +end