Class | DataMapper::Adapters::DataObjectAdapter |
In: |
lib/data_mapper/adapters/data_object_adapter.rb
lib/data_mapper/adapters/data_object_adapter.rb |
Parent: | AbstractAdapter |
You must inherit from the DoAdapter, and implement the required methods to adapt a database library for use with the DataMapper.
NOTE: By inheriting from DoAdapter, you get a copy of all the standard sub-modules (Quoting, Coersion and Queries) in your own Adapter. You can extend and overwrite these copies without affecting the originals.
FIND_OPTIONS | = | [ :select, :offset, :limit, :class, :include, :shallow_include, :reload, :conditions, :order, :intercept_load |
TABLE_QUOTING_CHARACTER | = | '`'.freeze |
COLUMN_QUOTING_CHARACTER | = | '`'.freeze |
SYNTAX | = | { :now => 'NOW()'.freeze |
MAGIC_PROPERTIES | = | { :updated_at => lambda { self.updated_at = Time::now }, :updated_on => lambda { self.updated_on = Date::today }, :created_at => lambda { self.created_at ||= Time::now }, :created_on => lambda { self.created_on ||= Date::today } |
TYPES | = | { :integer => 'int'.freeze, :string => 'varchar'.freeze, :text => 'text'.freeze, :class => 'varchar'.freeze, :decimal => 'decimal'.freeze, :float => 'float'.freeze, :datetime => 'datetime'.freeze, :date => 'date'.freeze, :boolean => 'boolean'.freeze, :object => 'text'.freeze |
FIND_OPTIONS | = | [ :select, :offset, :limit, :class, :include, :shallow_include, :reload, :conditions, :order, :intercept_load |
TABLE_QUOTING_CHARACTER | = | '`'.freeze |
COLUMN_QUOTING_CHARACTER | = | '`'.freeze |
SYNTAX | = | { :now => 'NOW()'.freeze |
MAGIC_PROPERTIES | = | { :updated_at => lambda { self.updated_at = Time::now }, :updated_on => lambda { self.updated_on = Date::today }, :created_at => lambda { self.created_at ||= Time::now }, :created_on => lambda { self.created_on ||= Date::today } |
TYPES | = | { :integer => 'int'.freeze, :string => 'varchar'.freeze, :text => 'text'.freeze, :class => 'varchar'.freeze, :decimal => 'decimal'.freeze, :float => 'float'.freeze, :datetime => 'datetime'.freeze, :date => 'date'.freeze, :boolean => 'boolean'.freeze, :object => 'text'.freeze |
This callback copies and sub-classes modules and classes in the DoAdapter to the inherited class so you don‘t have to copy and paste large blocks of code from the DoAdapter.
Basically, when inheriting from the DoAdapter, you aren‘t just inheriting a single class, you‘re inheriting a whole graph of Types. For convenience.
# File lib/data_mapper/adapters/data_object_adapter.rb, line 439 439: def self.inherited(base) 440: 441: commands = base.const_set('Commands', Module.new) 442: 443: Sql::Commands.constants.each do |name| 444: commands.const_set(name, Class.new(Sql::Commands.const_get(name))) 445: end 446: 447: mappings = base.const_set('Mappings', Module.new) 448: 449: Sql::Mappings.constants.each do |name| 450: mappings.const_set(name, Class.new(Sql::Mappings.const_get(name))) 451: end 452: 453: base.const_set('TYPES', TYPES.dup) 454: base.const_set('FIND_OPTIONS', FIND_OPTIONS.dup) 455: base.const_set('SYNTAX', SYNTAX.dup) 456: 457: super 458: end
This callback copies and sub-classes modules and classes in the DoAdapter to the inherited class so you don‘t have to copy and paste large blocks of code from the DoAdapter.
Basically, when inheriting from the DoAdapter, you aren‘t just inheriting a single class, you‘re inheriting a whole graph of Types. For convenience.
# File lib/data_mapper/adapters/data_object_adapter.rb, line 439 439: def self.inherited(base) 440: 441: commands = base.const_set('Commands', Module.new) 442: 443: Sql::Commands.constants.each do |name| 444: commands.const_set(name, Class.new(Sql::Commands.const_get(name))) 445: end 446: 447: mappings = base.const_set('Mappings', Module.new) 448: 449: Sql::Mappings.constants.each do |name| 450: mappings.const_set(name, Class.new(Sql::Mappings.const_get(name))) 451: end 452: 453: base.const_set('TYPES', TYPES.dup) 454: base.const_set('FIND_OPTIONS', FIND_OPTIONS.dup) 455: base.const_set('SYNTAX', SYNTAX.dup) 456: 457: super 458: end
# File lib/data_mapper/adapters/data_object_adapter.rb, line 55 55: def initialize(configuration) 56: super 57: @connection_pool = Support::ConnectionPool.new { create_connection } 58: end
# File lib/data_mapper/adapters/data_object_adapter.rb, line 55 55: def initialize(configuration) 56: super 57: @connection_pool = Support::ConnectionPool.new { create_connection } 58: end
# File lib/data_mapper/adapters/data_object_adapter.rb, line 64 64: def activate! 65: @activated = true 66: schema.activate! 67: end
# File lib/data_mapper/adapters/data_object_adapter.rb, line 64 64: def activate! 65: @activated = true 66: schema.activate! 67: end
# File lib/data_mapper/adapters/data_object_adapter.rb, line 60 60: def activated? 61: @activated 62: end
# File lib/data_mapper/adapters/data_object_adapter.rb, line 60 60: def activated? 61: @activated 62: end
# File lib/data_mapper/adapters/data_object_adapter.rb, line 73 73: def batch_insertable? 74: true 75: end
# File lib/data_mapper/adapters/data_object_adapter.rb, line 73 73: def batch_insertable? 74: true 75: end
# File lib/data_mapper/adapters/data_object_adapter.rb, line 427 427: def callback(instance, callback_name) 428: instance.class.callbacks.execute(callback_name, instance) 429: end
# File lib/data_mapper/adapters/data_object_adapter.rb, line 427 427: def callback(instance, callback_name) 428: instance.class.callbacks.execute(callback_name, instance) 429: end
# File lib/data_mapper/adapters/data_object_adapter.rb, line 166 166: def column_exists_for_table?(table_name, column_name) 167: connection do |db| 168: table = self.table(table_name) 169: command = db.create_command(table.to_column_exists_sql) 170: command.execute_reader(table.name, column_name, table.schema.name) do |reader| 171: reader.any? { reader.item(1) == column_name.to_s } 172: end 173: end 174: end
# File lib/data_mapper/adapters/data_object_adapter.rb, line 166 166: def column_exists_for_table?(table_name, column_name) 167: connection do |db| 168: table = self.table(table_name) 169: command = db.create_command(table.to_column_exists_sql) 170: command.execute_reader(table.name, column_name, table.schema.name) do |reader| 171: reader.any? { reader.item(1) == column_name.to_s } 172: end 173: end 174: end
Yields an available connection. Flushes the connection-pool and reconnects if the connection returns an error.
# File lib/data_mapper/adapters/data_object_adapter.rb, line 79 79: def connection 80: begin 81: # Yield the appropriate connection 82: @connection_pool.hold { |active_connection| yield(active_connection) } 83: rescue => execution_error 84: # Log error on failure 85: logger.error { execution_error } 86: 87: # Close all open connections, assuming that if one 88: # had an error, it's likely due to a lost connection, 89: # in which case all connections are likely broken. 90: flush_connections! 91: 92: raise execution_error 93: end 94: end
Yields an available connection. Flushes the connection-pool and reconnects if the connection returns an error.
# File lib/data_mapper/adapters/data_object_adapter.rb, line 79 79: def connection 80: begin 81: # Yield the appropriate connection 82: @connection_pool.hold { |active_connection| yield(active_connection) } 83: rescue => execution_error 84: # Log error on failure 85: logger.error { execution_error } 86: 87: # Close all open connections, assuming that if one 88: # had an error, it's likely due to a lost connection, 89: # in which case all connections are likely broken. 90: flush_connections! 91: 92: raise execution_error 93: end 94: end
# File lib/data_mapper/adapters/data_object_adapter.rb, line 285 285: def create(database_context, instance) 286: callback(instance, :before_create) 287: 288: instance = update_magic_properties(database_context, instance) 289: 290: table = self.table(instance) 291: attributes = instance.dirty_attributes 292: 293: if table.multi_class? 294: instance.instance_variable_set( 295: table[:type].instance_variable_name, 296: attributes[:type] = instance.class.name 297: ) 298: end 299: 300: keys = [] 301: values = [] 302: attributes.each_pair do |key, value| 303: raise ArgumentError.new("#{value.inspect} is not a valid value for #{key.inspect}") if value.is_a?(Array) 304: 305: keys << table[key].to_sql 306: values << value 307: end 308: 309: sql = if keys.size > 0 310: "INSERT INTO #{table.to_sql} (#{keys.join(', ')}) VALUES ?" 311: else 312: "INSERT INTO #{table.to_sql} #{self.empty_insert_sql}" 313: end 314: 315: result = connection do |db| 316: db.create_command(sql).execute_non_query(values) 317: end 318: 319: if result.to_i > 0 320: instance.instance_variable_set(:@new_record, false) 321: instance.key = result.last_insert_row if table.key.serial? && !attributes.include?(table.key.name) 322: database_context.identity_map.set(instance) 323: callback(instance, :after_create) 324: return true 325: else 326: return false 327: end 328: end
# File lib/data_mapper/adapters/data_object_adapter.rb, line 285 285: def create(database_context, instance) 286: callback(instance, :before_create) 287: 288: instance = update_magic_properties(database_context, instance) 289: 290: table = self.table(instance) 291: attributes = instance.dirty_attributes 292: 293: if table.multi_class? 294: instance.instance_variable_set( 295: table[:type].instance_variable_name, 296: attributes[:type] = instance.class.name 297: ) 298: end 299: 300: keys = [] 301: values = [] 302: attributes.each_pair do |key, value| 303: raise ArgumentError.new("#{value.inspect} is not a valid value for #{key.inspect}") if value.is_a?(Array) 304: 305: keys << table[key].to_sql 306: values << value 307: end 308: 309: sql = if keys.size > 0 310: "INSERT INTO #{table.to_sql} (#{keys.join(', ')}) VALUES ?" 311: else 312: "INSERT INTO #{table.to_sql} #{self.empty_insert_sql}" 313: end 314: 315: result = connection do |db| 316: db.create_command(sql).execute_non_query(values) 317: end 318: 319: if result.to_i > 0 320: instance.instance_variable_set(:@new_record, false) 321: instance.key = result.last_insert_row if table.key.serial? && !attributes.include?(table.key.name) 322: database_context.identity_map.set(instance) 323: callback(instance, :after_create) 324: return true 325: else 326: return false 327: end 328: end
# File lib/data_mapper/adapters/data_object_adapter.rb, line 69 69: def create_connection 70: raise NotImplementedError.new 71: end
# File lib/data_mapper/adapters/data_object_adapter.rb, line 69 69: def create_connection 70: raise NotImplementedError.new 71: end
# File lib/data_mapper/adapters/data_object_adapter.rb, line 176 176: def delete(database_context, instance) 177: table = self.table(instance) 178: 179: if instance.is_a?(Class) 180: table.delete_all! 181: else 182: callback(instance, :before_destroy) 183: 184: table.associations.each do |association| 185: instance.send(association.name).deactivate unless association.is_a?(::DataMapper::Associations::BelongsToAssociation) 186: end 187: 188: if table.paranoid? 189: instance.instance_variable_set(table.paranoid_column.instance_variable_name, Time::now) 190: instance.save 191: else 192: if connection do |db| 193: command = db.create_command("DELETE FROM #{table.to_sql} WHERE #{table.key.to_sql} = ?") 194: command.execute_non_query(instance.key).to_i > 0 195: end # connection do...end # if continued below: 196: instance.instance_variable_set(:@new_record, true) 197: instance.database_context = database_context 198: instance.original_values.clear 199: database_context.identity_map.delete(instance) 200: callback(instance, :after_destroy) 201: end 202: end 203: end 204: end
# File lib/data_mapper/adapters/data_object_adapter.rb, line 176 176: def delete(database_context, instance) 177: table = self.table(instance) 178: 179: if instance.is_a?(Class) 180: table.delete_all! 181: else 182: callback(instance, :before_destroy) 183: 184: table.associations.each do |association| 185: instance.send(association.name).deactivate unless association.is_a?(::DataMapper::Associations::BelongsToAssociation) 186: end 187: 188: if table.paranoid? 189: instance.instance_variable_set(table.paranoid_column.instance_variable_name, Time::now) 190: instance.save 191: else 192: if connection do |db| 193: command = db.create_command("DELETE FROM #{table.to_sql} WHERE #{table.key.to_sql} = ?") 194: command.execute_non_query(instance.key).to_i > 0 195: end # connection do...end # if continued below: 196: instance.instance_variable_set(:@new_record, true) 197: instance.database_context = database_context 198: instance.original_values.clear 199: database_context.identity_map.delete(instance) 200: callback(instance, :after_destroy) 201: end 202: end 203: end 204: end
# File lib/data_mapper/adapters/data_object_adapter.rb, line 281 281: def empty_insert_sql 282: "DEFAULT VALUES" 283: end
# File lib/data_mapper/adapters/data_object_adapter.rb, line 281 281: def empty_insert_sql 282: "DEFAULT VALUES" 283: end
# File lib/data_mapper/adapters/data_object_adapter.rb, line 147 147: def execute(*args) 148: db = create_connection 149: command = db.create_command(args.shift) 150: return command.execute_non_query(*args) 151: rescue => e 152: logger.error { e } 153: raise e 154: ensure 155: db.close 156: end
# File lib/data_mapper/adapters/data_object_adapter.rb, line 147 147: def execute(*args) 148: db = create_connection 149: command = db.create_command(args.shift) 150: return command.execute_non_query(*args) 151: rescue => e 152: logger.error { e } 153: raise e 154: ensure 155: db.close 156: end
Close any open connections.
# File lib/data_mapper/adapters/data_object_adapter.rb, line 97 97: def flush_connections! 98: @connection_pool.available_connections.each do |active_connection| 99: begin 100: active_connection.close 101: rescue => close_connection_error 102: # An error on closing the connection is almost expected 103: # if the socket is broken. 104: logger.warn { close_connection_error } 105: end 106: end 107: 108: # Reopen fresh connections. 109: @connection_pool.instance_variable_set('@created_count', 0) 110: @connection_pool.available_connections.clear 111: end
Close any open connections.
# File lib/data_mapper/adapters/data_object_adapter.rb, line 97 97: def flush_connections! 98: @connection_pool.available_connections.each do |active_connection| 99: begin 100: active_connection.close 101: rescue => close_connection_error 102: # An error on closing the connection is almost expected 103: # if the socket is broken. 104: logger.warn { close_connection_error } 105: end 106: end 107: 108: # Reopen fresh connections. 109: @connection_pool.instance_variable_set('@created_count', 0) 110: @connection_pool.available_connections.clear 111: end
# File lib/data_mapper/adapters/data_object_adapter.rb, line 348 348: def get(database_context, klass, keys) 349: table = self.table(klass) 350: instance_id = table.key.type_cast_value(keys.first) 351: instance = database_context.identity_map.get(klass, instance_id) 352: 353: return instance if instance 354: 355: column_indexes = {} 356: select_columns = [] 357: 358: table.columns.each_with_index do |column, i| 359: column_indexes[column] = i 360: select_columns << column.to_sql 361: end 362: 363: sql = "SELECT #{select_columns.join(', ')} FROM #{table.to_sql} WHERE #{table.keys.map { |key| "#{key.to_sql} = ?" }.join(' AND ')}" 364: 365: connection do |db| 366: reader = nil 367: begin 368: reader = db.create_command(sql).execute_reader(*keys) 369: 370: if reader.has_rows? 371: 372: instance_type = klass 373: 374: if table.multi_class? && table.type_column 375: value = reader.item(column_indexes[table.type_column]) 376: instance_type = table.type_column.type_cast_value(value) unless value.blank? 377: end 378: 379: if instance.nil? 380: instance = instance_type.allocate() 381: instance.instance_variable_set(:@__key, instance_id) 382: instance.instance_variable_set(:@new_record, false) 383: database_context.identity_map.set(instance) 384: elsif instance.new_record? 385: instance.instance_variable_set(:@__key, instance_id) 386: instance.instance_variable_set(:@new_record, false) 387: database_context.identity_map.set(instance) 388: end 389: 390: instance.database_context = database_context 391: 392: instance_type.callbacks.execute(:before_materialize, instance) 393: 394: originals = instance.original_values 395: 396: column_indexes.each_pair do |column, i| 397: value = column.type_cast_value(reader.item(i)) 398: instance.instance_variable_set(column.instance_variable_name, value) 399: 400: case value 401: when String, Date, Time then originals[column.name] = value.dup 402: else originals[column.name] = value 403: end 404: end 405: 406: instance.loaded_set = [instance] 407: 408: instance_type.callbacks.execute(:after_materialize, instance) 409: end # if reader.has_rows? 410: ensure 411: reader.close if reader && reader.open? 412: end 413: end # connection 414: 415: return instance 416: end
# File lib/data_mapper/adapters/data_object_adapter.rb, line 348 348: def get(database_context, klass, keys) 349: table = self.table(klass) 350: instance_id = table.key.type_cast_value(keys.first) 351: instance = database_context.identity_map.get(klass, instance_id) 352: 353: return instance if instance 354: 355: column_indexes = {} 356: select_columns = [] 357: 358: table.columns.each_with_index do |column, i| 359: column_indexes[column] = i 360: select_columns << column.to_sql 361: end 362: 363: sql = "SELECT #{select_columns.join(', ')} FROM #{table.to_sql} WHERE #{table.keys.map { |key| "#{key.to_sql} = ?" }.join(' AND ')}" 364: 365: connection do |db| 366: reader = nil 367: begin 368: reader = db.create_command(sql).execute_reader(*keys) 369: 370: if reader.has_rows? 371: 372: instance_type = klass 373: 374: if table.multi_class? && table.type_column 375: value = reader.item(column_indexes[table.type_column]) 376: instance_type = table.type_column.type_cast_value(value) unless value.blank? 377: end 378: 379: if instance.nil? 380: instance = instance_type.allocate() 381: instance.instance_variable_set(:@__key, instance_id) 382: instance.instance_variable_set(:@new_record, false) 383: database_context.identity_map.set(instance) 384: elsif instance.new_record? 385: instance.instance_variable_set(:@__key, instance_id) 386: instance.instance_variable_set(:@new_record, false) 387: database_context.identity_map.set(instance) 388: end 389: 390: instance.database_context = database_context 391: 392: instance_type.callbacks.execute(:before_materialize, instance) 393: 394: originals = instance.original_values 395: 396: column_indexes.each_pair do |column, i| 397: value = column.type_cast_value(reader.item(i)) 398: instance.instance_variable_set(column.instance_variable_name, value) 399: 400: case value 401: when String, Date, Time then originals[column.name] = value.dup 402: else originals[column.name] = value 403: end 404: end 405: 406: instance.loaded_set = [instance] 407: 408: instance_type.callbacks.execute(:after_materialize, instance) 409: end # if reader.has_rows? 410: ensure 411: reader.close if reader && reader.open? 412: end 413: end # connection 414: 415: return instance 416: end
# File lib/data_mapper/adapters/data_object_adapter.rb, line 158 158: def handle_error(error) 159: raise error 160: end
# File lib/data_mapper/adapters/data_object_adapter.rb, line 158 158: def handle_error(error) 159: raise error 160: end
# File lib/data_mapper/adapters/data_object_adapter.rb, line 344 344: def load(database_context, klass, options) 345: self.class::Commands::LoadCommand.new(self, database_context, klass, options).call 346: end
# File lib/data_mapper/adapters/data_object_adapter.rb, line 344 344: def load(database_context, klass, options) 345: self.class::Commands::LoadCommand.new(self, database_context, klass, options).call 346: end
# File lib/data_mapper/adapters/data_object_adapter.rb, line 117 117: def query(*args) 118: db = create_connection 119: 120: command = db.create_command(args.shift) 121: 122: reader = command.execute_reader(*args) 123: fields = reader.fields.map { |field| Inflector.underscore(field).to_sym } 124: results = [] 125: 126: if fields.size > 1 127: struct = Struct.new(*fields) 128: 129: reader.each do 130: results << struct.new(*reader.current_row) 131: end 132: else 133: reader.each do 134: results << reader.item(0) 135: end 136: end 137: 138: return results 139: rescue => e 140: logger.error { e } 141: raise e 142: ensure 143: reader.close if reader 144: db.close 145: end
# File lib/data_mapper/adapters/data_object_adapter.rb, line 117 117: def query(*args) 118: db = create_connection 119: 120: command = db.create_command(args.shift) 121: 122: reader = command.execute_reader(*args) 123: fields = reader.fields.map { |field| Inflector.underscore(field).to_sym } 124: results = [] 125: 126: if fields.size > 1 127: struct = Struct.new(*fields) 128: 129: reader.each do 130: results << struct.new(*reader.current_row) 131: end 132: else 133: reader.each do 134: results << reader.item(0) 135: end 136: end 137: 138: return results 139: rescue => e 140: logger.error { e } 141: raise e 142: ensure 143: reader.close if reader 144: db.close 145: end
# File lib/data_mapper/adapters/data_object_adapter.rb, line 206 206: def save(database_context, instance, validate = true, cleared = Set.new) 207: case instance 208: when Class then 209: table(instance).create! 210: table(instance).activate_associations! 211: when Mappings::Table then instance.create! 212: when DataMapper::Persistence then 213: event = instance.new_record? ? :create : :update 214: 215: return false if (validate && !instance.validate_recursively(event, Set.new)) || cleared.include?(instance) 216: cleared << instance 217: 218: callback(instance, :before_save) 219: 220: return true unless instance.new_record? || instance.dirty? 221: 222: result = send(event, database_context, instance) 223: 224: instance.database_context = database_context 225: instance.attributes.each_pair do |name, value| 226: instance.original_values[name] = value 227: end 228: 229: instance.loaded_associations.each do |association| 230: association.save_without_validation(database_context, cleared) if association.dirty? 231: end 232: 233: callback(instance, :after_save) 234: result 235: end 236: rescue => error 237: logger.error(error) 238: raise error 239: end
# File lib/data_mapper/adapters/data_object_adapter.rb, line 206 206: def save(database_context, instance, validate = true, cleared = Set.new) 207: case instance 208: when Class then 209: table(instance).create! 210: table(instance).activate_associations! 211: when Mappings::Table then instance.create! 212: when DataMapper::Persistence then 213: event = instance.new_record? ? :create : :update 214: 215: return false if (validate && !instance.validate_recursively(event, Set.new)) || cleared.include?(instance) 216: cleared << instance 217: 218: callback(instance, :before_save) 219: 220: return true unless instance.new_record? || instance.dirty? 221: 222: result = send(event, database_context, instance) 223: 224: instance.database_context = database_context 225: instance.attributes.each_pair do |name, value| 226: instance.original_values[name] = value 227: end 228: 229: instance.loaded_associations.each do |association| 230: association.save_without_validation(database_context, cleared) if association.dirty? 231: end 232: 233: callback(instance, :after_save) 234: result 235: end 236: rescue => error 237: logger.error(error) 238: raise error 239: end
# File lib/data_mapper/adapters/data_object_adapter.rb, line 241 241: def save_without_validation(database_context, instance, cleared = Set.new) 242: save(database_context, instance, false, cleared) 243: end
# File lib/data_mapper/adapters/data_object_adapter.rb, line 241 241: def save_without_validation(database_context, instance, cleared = Set.new) 242: save(database_context, instance, false, cleared) 243: end
# File lib/data_mapper/adapters/data_object_adapter.rb, line 162 162: def schema 163: @schema || ( @schema = self.class::Mappings::Schema.new(self, @configuration.database) ) 164: end
# File lib/data_mapper/adapters/data_object_adapter.rb, line 162 162: def schema 163: @schema || ( @schema = self.class::Mappings::Schema.new(self, @configuration.database) ) 164: end
# File lib/data_mapper/adapters/data_object_adapter.rb, line 418 418: def table(instance) 419: case instance 420: when DataMapper::Adapters::Sql::Mappings::Table then instance 421: when DataMapper::Persistence then schema[instance.class] 422: when Class, String then schema[instance] 423: else raise "Don't know how to map #{instance.inspect} to a table." 424: end 425: end
# File lib/data_mapper/adapters/data_object_adapter.rb, line 418 418: def table(instance) 419: case instance 420: when DataMapper::Adapters::Sql::Mappings::Table then instance 421: when DataMapper::Persistence then schema[instance.class] 422: when Class, String then schema[instance] 423: else raise "Don't know how to map #{instance.inspect} to a table." 424: end 425: end
# File lib/data_mapper/adapters/data_object_adapter.rb, line 113 113: def transaction(&block) 114: raise NotImplementedError.new 115: end
# File lib/data_mapper/adapters/data_object_adapter.rb, line 113 113: def transaction(&block) 114: raise NotImplementedError.new 115: end
# File lib/data_mapper/adapters/data_object_adapter.rb, line 245 245: def update(database_context, instance) 246: callback(instance, :before_update) 247: 248: instance = update_magic_properties(database_context, instance) 249: 250: table = self.table(instance) 251: attributes = instance.dirty_attributes 252: parameters = [] 253: 254: unless attributes.empty? 255: sql = "UPDATE " << table.to_sql << " SET " 256: 257: sql << attributes.map do |key, value| 258: parameters << value 259: "#{table[key].to_sql} = ?" 260: end.join(', ') 261: 262: sql << " WHERE #{table.key.to_sql} = ?" 263: parameters << instance.key 264: 265: result = connection do |db| 266: db.create_command(sql).execute_non_query(*parameters) 267: end 268: 269: # BUG: do_mysql returns inaccurate affected row counts for UPDATE statements. 270: if true || result.to_i > 0 271: callback(instance, :after_update) 272: return true 273: else 274: return false 275: end 276: else 277: true 278: end 279: end
# File lib/data_mapper/adapters/data_object_adapter.rb, line 245 245: def update(database_context, instance) 246: callback(instance, :before_update) 247: 248: instance = update_magic_properties(database_context, instance) 249: 250: table = self.table(instance) 251: attributes = instance.dirty_attributes 252: parameters = [] 253: 254: unless attributes.empty? 255: sql = "UPDATE " << table.to_sql << " SET " 256: 257: sql << attributes.map do |key, value| 258: parameters << value 259: "#{table[key].to_sql} = ?" 260: end.join(', ') 261: 262: sql << " WHERE #{table.key.to_sql} = ?" 263: parameters << instance.key 264: 265: result = connection do |db| 266: db.create_command(sql).execute_non_query(*parameters) 267: end 268: 269: # BUG: do_mysql returns inaccurate affected row counts for UPDATE statements. 270: if true || result.to_i > 0 271: callback(instance, :after_update) 272: return true 273: else 274: return false 275: end 276: else 277: true 278: end 279: end
# File lib/data_mapper/adapters/data_object_adapter.rb, line 337 337: def update_magic_properties(database_context, instance) 338: instance.class.properties.find_all { |property| MAGIC_PROPERTIES.has_key?(property.name) }.each do |property| 339: instance.instance_eval(&MAGIC_PROPERTIES[property.name]) 340: end 341: instance 342: end
# File lib/data_mapper/adapters/data_object_adapter.rb, line 337 337: def update_magic_properties(database_context, instance) 338: instance.class.properties.find_all { |property| MAGIC_PROPERTIES.has_key?(property.name) }.each do |property| 339: instance.instance_eval(&MAGIC_PROPERTIES[property.name]) 340: end 341: instance 342: end