#!/usr/bin/env ruby require 'builder/builder.rb' module Prick::SubCommand def self.make(database, username, schema, timer: nil, dump: nil) Timer.on! if timer time "Prick::Command#build" do begin super_conn = PgConn.new conn = nil builder = nil built_at = EPOCH clean = false create_schemas = [] time "Load build object" do if super_conn.rdbms.exist? database conn = PgConn.new(database, username) if conn.schema.exist_table? "prick", "versions" built_at = conn.value("select built_at from prick.versions") end else super_conn.rdbms.create database, owner: username conn = PgConn.new(database, username) clean = true end builder = Prick::Build::Builder.new(conn, "schema", clean) if schema builder.pool.after_schema(schema).each { |schema| conn.schema.drop(schema, cascade: true) builder.pool.delete_schema(schema) } end touched_nodes = builder.nodes.select { |node| File.mtime(node.path) > built_at } touched_phases = touched_nodes.map(&:phase).uniq.compact touched_kinds = touched_nodes.map(&:kind).uniq.compact touched_schema = touched_nodes.first&.schema missing_schema = builder.schemas.find { |schema| !conn.schema.exist?(schema) } build_schema = builder.schemas.find { |schema| [touched_schema, missing_schema].include? schema } if build_schema.nil? puts "#{database} is up to date" exit end if touched_phases.include?(:decl) || touched_phases.empty? create_schemas = [build_schema] + builder.pool.after_schema(build_schema) create_schemas.each { |schema| conn.schema.drop(schema, cascade: true) } builder.pool.delete_schema(builder.pool.before_schema(build_schema), exclude: [:seed]) elsif touched_phases.include?(:init) || touched_phases.include?(:term) builder.pool.clear(:decl, :seed) elsif touched_phases.include?(:seed) builder.pool.clear(:init, :decl, :term) end builder.group end case dump when :nodes; builder.nodes.reject { |node| node.is_a?(Build::BuildNode) }.map &:dump when :allnodes; builder.nodes.map &:dump when :batches; builder.dump when nil; else raise Prick::Error, "Illegal dump type: #{dump.inspect}" end exit if dump time "Execute build object" do builder.execute(conn, create_schemas: create_schemas) end rescue Prick::Build::Error => ex $stderr.puts ex.message exit 1 rescue Command::Error => ex $stderr.puts ex.message exit 1 end end end end __END__ require 'prick_build.rb' require 'pg_conn' require 'ruby-prof' DATABASE = "mikras" USERNAME = "mikras" #PROFILE = true PROFILE = false TIME = true #TIME = false EPOCH = Time.at(0).utc schema = ARGV.first time "Program" do RubyProf.start if PROFILE begin conn = nil builder = nil built_at = EPOCH clean = false create_schema = true time "Load build object" do PgConn.new { |super_conn| if super_conn.rdbms.exist? DATABASE conn = PgConn.new(DATABASE) if conn.schema.exist_table? "prick", "versions" built_at = conn.value("select built_at from prick.versions") end else super_conn.rdbms.create DATABASE, owner: USERNAME conn = PgConn.new(DATABASE) clean = true end } builder = Prick::Build::Builder.new(conn, "schema", clean) if schema builder.pool.after_schema(schema).each { |schema| conn.schema.drop(schema, cascade: true) builder.pool.delete_schema(schema) } end touched_nodes = builder.nodes.select { |node| File.mtime(node.path) > built_at } touched_phases = touched_nodes.map(&:phase).uniq.compact touched_schema = touched_nodes.first&.schema missing_schema = builder.schemas.find { |schema| !conn.schema.exist?(schema) } build_schema = builder.schemas.find { |schema| [touched_schema, missing_schema].include? schema } # puts "touched_nodes : #{touched_nodes.size} nodes" # puts "touched_phases: #{touched_phases.inspect}" # puts "touched_schema: #{touched_schema.inspect}" # puts "missing_schema: #{missing_schema.inspect}" # puts "build_schema : #{build_schema.inspect}" # builder.pool.dump if build_schema.nil? puts "#{DATABASE} is up to date" exit end if touched_phases.include?(:decl) || touched_phases.empty? schemas = [build_schema] + builder.pool.after_schema(build_schema) schemas.each { |schema| conn.schema.drop(schema, cascade: true) } builder.pool.delete_schema(builder.pool.before_schema(build_schema)) elsif touched_phases.include?(:init) || touched_phases.include?(:term) builder.pool.clear(:decl, :seed) create_schema = false elsif touched_phases.include?(:seed) builder.pool.clear(:init, :decl, :term) create_schema = false end # builder.pool.dump builder.group end # builder.dump # p builder.schemas # exit time "Execute build object" do builder.execute(conn, create_schema: create_schema) end rescue Prick::Build::Error => ex $stderr.puts ex.message exit 1 rescue Command::Error => ex $stderr.puts ex.message exit 1 end end if PROFILE profile = RubyProf.stop # printer = RubyProf::GraphHtmlPrinter.new(profile) printer = RubyProf::CallStackPrinter.new(profile) File.open("t.html", "w") { |file| printer.print(file, :min_percent => 2) } end