Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- class InsertQuery
- def initialize(model_class, column_names, returning = nil)
- @model_class = model_class
- @column_names = column_names
- @returning = returning
- @rows = []
- @executed = false
- end
- def insert(model_attributes)
- ensure_not_executed
- rows << prepare_model_attributes(model_attributes, Time.zone.now)
- end
- def prepare_model_attributes(model_attributes, now)
- column_names.map do |column_name|
- prepare_model_attribute(column_name, model_attributes, now)
- end
- end
- def prepare_model_attribute(column_name, model_attributes, now)
- column_name = column_name.to_sym
- if %i(created_at updated_at).include?(column_name)
- if model_attributes.include?(column_name)
- model_attributes[column_name]
- else
- now
- end
- else
- model_attributes.fetch(column_name, :default)
- end
- end
- def execute
- ensure_not_executed
- yield(self) if block_given?
- result = connection.execute(query).values unless rows.empty?
- self.executed = true
- result
- end
- def self.execute(*constructor_args, &block)
- new(*constructor_args).execute(&block)
- end
- private
- attr_reader :model_class, :column_names, :rows, :returning
- attr_accessor :executed
- delegate :connection, to: :model_class
- def ensure_not_executed
- fail("the query has been already executed") if executed
- end
- def query
- <<-SQL
- INSERT INTO
- #{model_class.table_name}
- (#{column_names.join(', ')})
- VALUES #{
- rows.map do |row|
- "(#{row.map { |datum| quote(datum) }.join(', ')})"
- end.join(', ')
- }
- #{returning_clause}
- SQL
- end
- def quote(datum)
- if datum == :default
- 'default'
- else
- connection.quote(datum)
- end
- end
- def returning_clause
- %(RETURNING #{returning}) if returning
- end
- end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement