require 'active_support/concern' require 'neo4j/migration' if !defined?(Rails) && !Rake::Task.task_defined?('environment') desc 'Run a script against the database to perform system-wide changes' task :environment do require 'neo4j/session_manager' require 'ostruct' neo4j_url = ENV['NEO4J_URL'] || 'http://localhost:7474' $LOAD_PATH.unshift File.dirname('./') Neo4j::ActiveBase.on_establish_session do type = neo4j_url =~ /^bolt/ ? :bolt : :http Neo4j::SessionManager.open_neo4j_session(type, neo4j_url) end end end namespace :neo4j do task :allow_migrations do Neo4j::Migrations.currently_running_migrations = true end desc 'Run a script against the database to perform system-wide changes' task :legacy_migrate, [:task_name, :subtask] => :environment do |_, args| path = Rake.original_dir migration_task = args[:task_name] task_name_constant = migration_task.split('_').map(&:capitalize).join('') begin migration_class = "Neo4j::Migration::#{task_name_constant}".constantize rescue NameError load File.join(path, 'db', 'neo4j-migrate', "#{migration_task}.rb") migration_class = task_name_constant.to_s.constantize end migration = migration_class.new(path) subtask = args[:subtask] if subtask migration.send(subtask) else migration.migrate end end desc 'A shortcut for neo4j::migrate::all' task :migrate do Rake::Task['neo4j:migrate:all'].invoke end # TODO: Make sure these tasks don't run in versions of Neo4j before 3.0 namespace :schema do SCHEMA_YAML_PATH = 'db/neo4j/schema.yml' SCHEMA_YAML_COMMENT = < '3.0.0' yield else puts 'WARNING: This task does not work for versions of Neo4j before 3.0.0' end end desc 'Creates a db/neo4j/schema.yml file which represents the indexes / constraints in the Neo4j DB' task dump: :environment do check_neo4j_version_3 do require 'neo4j/migrations/schema' schema_data = Neo4j::Migrations::Schema.fetch_schema_data(Neo4j::ActiveBase.current_session) runner = Neo4j::Migrations::Runner.new schema_data[:versions] = runner.complete_migration_versions.sort FileUtils.mkdir_p(File.dirname(SCHEMA_YAML_PATH)) File.open(SCHEMA_YAML_PATH, 'w') { |file| file << SCHEMA_YAML_COMMENT + schema_data.to_yaml } puts "Dumped updated schema file to #{SCHEMA_YAML_PATH}" end end desc "Loads a db/neo4j/schema.yml file into the database\nOptionally removes schema elements which aren't in the schema.yml file (defaults to false)" task :load, [:remove_missing] => :environment do |_t, args| check_neo4j_version_3 do require 'neo4j/migrations/schema' args.with_defaults(remove_missing: false) schema_data = YAML.load(File.read(SCHEMA_YAML_PATH)) Neo4j::Core::CypherSession::Adaptors::Base.subscribe_to_query(&method(:puts)) Neo4j::ActiveBase.run_transaction do Neo4j::Migrations::Schema.synchronize_schema_data(Neo4j::ActiveBase.current_session, schema_data, args[:remove_missing]) runner = Neo4j::Migrations::Runner.new runner.mark_versions_as_complete(schema_data[:versions]) # Run in test mode? end end end end namespace :migrate do desc 'Run all pending migrations' task all: [:allow_migrations, :environment] do runner = Neo4j::Migrations::Runner.new runner.all Rake::Task['neo4j:schema:dump'].invoke end desc 'Run a migration given its VERSION' task up: [:allow_migrations, :environment] do version = ENV['VERSION'] || fail(ArgumentError, 'VERSION is required') runner = Neo4j::Migrations::Runner.new runner.up version Rake::Task['neo4j:schema:dump'].invoke end desc 'Revert a migration given its VERSION' task down: [:allow_migrations, :environment] do version = ENV['VERSION'] || fail(ArgumentError, 'VERSION is required') runner = Neo4j::Migrations::Runner.new runner.down version Rake::Task['neo4j:schema:dump'].invoke end desc 'Print a report of migrations status' task status: [:allow_migrations, :environment] do runner = Neo4j::Migrations::Runner.new runner.status end desc 'Resolve an incomplete version state' task resolve: [:allow_migrations, :environment] do version = ENV['VERSION'] || fail(ArgumentError, 'VERSION is required') runner = Neo4j::Migrations::Runner.new runner.resolve version end desc 'Resolve an incomplete version state' task reset: [:allow_migrations, :environment] do version = ENV['VERSION'] || fail(ArgumentError, 'VERSION is required') runner = Neo4j::Migrations::Runner.new runner.reset version end end desc 'Rollbacks migrations given a STEP number' task rollback: [:allow_migrations, :environment] do steps = (ENV['STEP'] || 1).to_i runner = Neo4j::Migrations::Runner.new runner.rollback(steps) Rake::Task['neo4j:schema:dump'].invoke end # Temporary to help people change to 8.0 desc 'Generates a migration for the specified constraint/index and label/property combination.' task :generate_schema_migration, :index_or_constraint, :label, :property_name do |_t, args| index_or_constraint, label, property_name = args.values_at(:index_or_constraint, :label, :property_name) if !%w(index constraint).include?(index_or_constraint) fail "Invalid schema element type: #{index_or_constraint} (should be either `index` or `constraint`)" end fail 'Label must be specified' if label.blank? fail 'Property name must be specified' if property_name.blank? migration_class_name = "ForceCreate#{label.camelize}#{property_name.camelize}#{index_or_constraint.capitalize}".gsub('::', '').underscore.camelize require 'fileutils' FileUtils.mkdir_p('db/neo4j/migrate') path = File.join('db/neo4j/migrate', "#{DateTime.now.utc.strftime('%Y%m%d%H%M%S')}_#{migration_class_name.underscore}.rb") content = <<-CONTENT class #{migration_class_name} < Neo4j::Migrations::Base def up add_#{index_or_constraint} #{label.to_sym.inspect}, #{property_name.to_sym.inspect}, force: true end def down drop_#{index_or_constraint} #{label.to_sym.inspect}, #{property_name.to_sym.inspect} end end CONTENT File.open(path, 'w') { |f| f << content } puts "Generated #{path}" end end