lib/pgslice.rb in pgslice-0.2.0 vs lib/pgslice.rb in pgslice-0.2.1

- old
+ new

@@ -77,11 +77,11 @@ sql_format = SQL_FORMAT[period.to_sym] queries << <<-SQL CREATE FUNCTION #{trigger_name}() RETURNS trigger AS $$ BEGIN - RAISE EXCEPTION 'Date out of range. Create partitions first.'; + RAISE EXCEPTION 'Create partitions first.'; END; $$ LANGUAGE plpgsql; SQL queries << <<-SQL @@ -131,20 +131,17 @@ index_defs = execute("select pg_get_indexdef(indexrelid) from pg_index where indrelid = $1::regclass AND indisprimary = 'f'", [original_table]).map { |r| r["pg_get_indexdef"] } primary_key = self.primary_key(table) queries = [] - comment = execute("SELECT obj_description(oid, 'pg_trigger') AS comment FROM pg_trigger WHERE tgname = $1 AND tgrelid = $2::regclass", [trigger_name, table]).first - if comment - field, period = comment["comment"].split(",").map { |v| v.split(":").last } rescue [nil, nil] - end + period, field, needs_comment = settings_from_trigger(original_table, table) + abort "Could not read settings" unless period - unless period - period, field = settings_from_table(original_table, table) + if needs_comment queries << "COMMENT ON TRIGGER #{trigger_name} ON #{table} is 'column:#{field},period:#{period}';" end - abort "Could not read settings" unless period + # today = utc date today = round_date(DateTime.now.new_offset(0).to_date, period) added_partitions = [] range.each do |n| day = advance_date(today, period, n) @@ -227,11 +224,11 @@ end abort "Table not found: #{source_table}" unless table_exists?(source_table) abort "Table not found: #{dest_table}" unless table_exists?(dest_table) - period, field = settings_from_table(table, dest_table) + period, field, needs_comment = settings_from_trigger(table, dest_table) if period name_format = self.name_format(period) existing_tables = self.existing_tables(like: "#{table}_%").select { |t| /#{Regexp.escape("#{table}_")}(\d{4,6})/.match(t) }.sort @@ -256,20 +253,23 @@ max_dest_id = min_source_id - 1 if min_source_id end end starting_id = max_dest_id - fields = columns(source_table).join(", ") + fields = columns(source_table).map { |c| PG::Connection.quote_ident(c) }.join(", ") batch_size = options[:batch_size] i = 1 batch_count = ((max_source_id - starting_id) / batch_size.to_f).ceil while starting_id < max_source_id where = "#{primary_key} > #{starting_id} AND #{primary_key} <= #{starting_id + batch_size}" if period where << " AND #{field} >= #{sql_date(starting_time)} AND #{field} < #{sql_date(ending_time)}" end + if options[:where] + where << " AND #{options[:where]}" + end query = <<-SQL /* #{i} of #{batch_count} */ INSERT INTO #{dest_table} (#{fields}) SELECT #{fields} FROM #{source_table} @@ -346,10 +346,11 @@ o.boolean "--dry-run", default: false o.boolean "--no-partition", default: false o.integer "--start" o.string "--url" o.string "--source-table" + o.string "--where" o.on "-v", "--version", "print the version" do log PgSlice::VERSION @exit = true end end @@ -525,18 +526,29 @@ else date.next_month(count) end end - def settings_from_table(original_table, table) + def settings_from_trigger(original_table, table) trigger_name = self.trigger_name(original_table) - function_def = execute("select pg_get_functiondef(oid) from pg_proc where proname = $1", [trigger_name])[0] - return [nil, nil] unless function_def - function_def = function_def["pg_get_functiondef"] - sql_format = SQL_FORMAT.find { |_, f| function_def.include?("'#{f}'") } - return [nil, nil] unless sql_format - period = sql_format[0] - field = /to_char\(NEW\.(\w+),/.match(function_def)[1] - [period, field] + + needs_comment = false + comment = execute("SELECT obj_description(oid, 'pg_trigger') AS comment FROM pg_trigger WHERE tgname = $1 AND tgrelid = $2::regclass", [trigger_name, table])[0] + if comment + field, period = comment["comment"].split(",").map { |v| v.split(":").last } rescue [nil, nil] + end + + unless period + needs_comment = true + function_def = execute("select pg_get_functiondef(oid) from pg_proc where proname = $1", [trigger_name])[0] + return [nil, nil] unless function_def + function_def = function_def["pg_get_functiondef"] + sql_format = SQL_FORMAT.find { |_, f| function_def.include?("'#{f}'") } + return [nil, nil] unless sql_format + period = sql_format[0] + field = /to_char\(NEW\.(\w+),/.match(function_def)[1] + end + + [period, field, needs_comment] end end end