require 'local/command' require 'builder/node.rb' require 'builder/node_pool.rb' require 'builder/batch.rb' require 'builder/parser.rb' include Constrain module Prick module Build class Error < StandardError; end class PostgresError < Error; end class Builder # PgConn object attr_reader :conn # Root schema directory attr_reader :dir # Reflections YAML file attr_reader :reflections_file # True if database is initially clean - ie. all tables are empty attr_accessor :clean # Root build node attr_reader :root # Pool of nodes. Initialized by #load_pool attr_reader :pool forward_to :pool, :schemas, :nodes, :decl_nodes, :init_nodes, :term_nodes, :seed_nodes, :fox_seed_nodes, :sql_seed_nodes, :build_nodes, :pg_graph_ignore_schemas, :refresh_schemas, :keep_schemas def batches() @batches ||= group end def initialize(conn, dir, clean = true, touched: false) @conn = conn @dir = dir @reflections_file = REFLECTIONS_PATH @clean = clean @pool = NodePool.new @root = Parser.parse(conn, dir) load_pool(@root) # Collect nodes into pool @batches = nil # Initialized by #group end # Group sources into batches def group @batches = [] kind = nil batch = nil for node in [init_nodes, decl_nodes, fox_seed_nodes, sql_seed_nodes, term_nodes.reverse].flatten case node.kind when :module if batch&.kind != :module @batches << batch if batch batch = ModuleBatch.new(self) end when :exe # Exe sources always create a new batch @batches << batch if batch batch = SqlBatch.new(self) when batch&.kind ; when :sql || node.kind == :inline if batch&.kind != :exe @batches << batch if batch batch = SqlBatch.new(self) end when :inline @batches << batch if batch batch = SqlBatch.new(self) when :fox @batches << batch if batch batch = FoxBatch.new(self) when :yml next else raise Error, "Unexpected node kind: #{node.kind}" end batch.nodes << node end @batches << batch if batch end def execute(conn, create_schemas: schemas) group if batches.nil? conn.exec create_schemas.map { |schema| "create schema #{schema}" } for batch in batches batch.execute end end # def setup # end # def teardown # end def dump batches ? batches.each(&:dump) : pool.dump end private def load_pool(build_node) pool.add(build_node.init_nodes) build_node.decl_nodes.each { |node| pool.add node load_pool(node) if node.kind == :yml } pool.add(build_node.seed_nodes) pool.add(build_node.term_nodes) end end end end