Class: DataMapper::Adapters::DataObjectsAdapter
- Object
- DataMapper::Adapters::AbstractAdapter
- DataMapper::Adapters::DataObjectsAdapter
Included Modules
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 DataObjectsAdapter, 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.
Constructor Summary
340 341 342 343 344 345 346 347 348 349 350 351
# File 'dm-core/lib/dm-core/adapters/data_objects_adapter.rb', line 340 def initialize(name, uri_or_options) super # Default the driver-specifc logger to DataMapper's logger if driver_module = DataObjects.const_get(@uri.scheme.capitalize) rescue nil driver_module.logger = DataMapper.logger if driver_module.respond_to?(:logger=) end end
Public Visibility
Public Class Method Summary
| type_map |
Default TypeMap for all data object based adapters. Returns: |
|---|
Public Instance Method Summary
| #avg(respository, property, query) | |
|---|---|
| #count(repository, property, query) | |
| #create(repository, resource) |
all of our CRUD Methods dealing with a single resource object. |
| #create_model_storage(repository, model) |
TODO: move to dm-more/dm-migrations. |
| #delete(repository, resource) | |
| #destroy_model_storage(repository, model) |
TODO: move to dm-more/dm-migrations. |
| #execute(statement, *args) |
Database-specific method. |
| #max(respository, property, query) | |
| #min(respository, property, query) | |
| #query(statement, *args) | |
| #read_set(repository, query) |
Methods dealing with finding stuff by some query parameters. |
| #sum(respository, property, query) | |
| #transaction_primitive |
TODO: move to dm-more/dm-transactions. |
| #update(repository, resource) |
def read(repository, model, bind_values) properties = model. |
| #upgrade_model_storage(repository, model) |
TODO: move to dm-more/dm-migrations. |
Public Instance Methods Inherited from DataMapper::Adapters::AbstractAdapter
alter_model_storage, alter_property_storage, create_property_storage, current_transaction, delete_set, destroy_property_storage, field_exists?, pop_transaction, push_transaction, read, read_one, storage_exists?, within_transaction?
Public Instance Methods Inherited from Object
Public Class Method Details
type_map
Default TypeMap for all data object based adapters.
109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127
# File 'dm-core/lib/dm-core/adapters/data_objects_adapter.rb', line 109 def self.type_map @type_map ||= TypeMap.new(super) do |tm| tm.map(Integer).to('INT') tm.map(String).to('VARCHAR').with(:size => Property::DEFAULT_LENGTH) tm.map(Class).to('VARCHAR').with(:size => Property::DEFAULT_LENGTH) tm.map(DM::Discriminator).to('VARCHAR').with(:size => Property::DEFAULT_LENGTH) tm.map(BigDecimal).to('DECIMAL').with(:scale => Property::DEFAULT_SCALE, :precision => Property::DEFAULT_PRECISION) tm.map(Float).to('FLOAT').with(:scale => Property::DEFAULT_SCALE, :precision => Property::DEFAULT_PRECISION) tm.map(DateTime).to('DATETIME') tm.map(Date).to('DATE') tm.map(Time).to('TIMESTAMP') tm.map(TrueClass).to('BOOLEAN') tm.map(Object).to('TEXT') tm.map(DM::Text).to('TEXT') end end
Public Instance Method Details
avg
21 22 23 24 25
# File 'dm-more/dm-aggregates/lib/dm-aggregates/adapters/data_objects_adapter.rb', line 21 def avg(respository, property, query) parameters = query.parameters avg = query(aggregate_value_statement(:avg, property, query), *parameters).first property.type == Integer ? avg.to_f : property.typecast(avg) end
count
4 5 6 7
# File 'dm-more/dm-aggregates/lib/dm-aggregates/adapters/data_objects_adapter.rb', line 4 def count(repository, property, query) parameters = query.parameters query(aggregate_value_statement(:count, property, query), *parameters).first end
create
all of our CRUD Methods dealing with a single resource object
128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152
# File 'dm-core/lib/dm-core/adapters/data_objects_adapter.rb', line 128 def create(repository, resource) dirty_attributes = resource.dirty_attributes identity_field = begin key = resource.class.key(name) key.first if key.size == 1 && key.first.serial? end statement = create_statement(resource.class, dirty_attributes, identity_field) bind_values = dirty_attributes.map { |p| resource.instance_variable_get(p.instance_variable_name) } result = execute(statement, *bind_values) return false if result.to_i != 1 if identity_field resource.instance_variable_set(identity_field.instance_variable_name, result.insert_id) end true end
create_model_storage
TODO: move to dm-more/dm-migrations
275 276 277 278 279 280 281 282 283 284 285
# File 'dm-core/lib/dm-core/adapters/data_objects_adapter.rb', line 275 def create_model_storage(repository, model) return false if storage_exists?(model.storage_name(name)) execute(create_table_statement(model)) (create_index_statements(model) + create_unique_index_statements(model)).each do |sql| execute(sql) end true end
delete
193 194 195 196 197 198 199 200
# File 'dm-core/lib/dm-core/adapters/data_objects_adapter.rb', line 193 def delete(repository, resource) key = resource.class.key(name) statement = delete_statement(resource.class, key) bind_values = key.map { |p| resource.instance_variable_get(p.instance_variable_name) } execute(statement, *bind_values).to_i == 1 end
destroy_model_storage
TODO: move to dm-more/dm-migrations
288 289 290 291
# File 'dm-core/lib/dm-core/adapters/data_objects_adapter.rb', line 288 def destroy_model_storage(repository, model) execute(drop_table_statement(model)) true end
execute
Database-specific method
225 226 227 228 229 230
# File 'dm-core/lib/dm-core/adapters/data_objects_adapter.rb', line 225 def execute(statement, *args) with_connection do |connection| command = connection.create_command(statement) command.execute_non_query(*args) end end
max
15 16 17 18 19
# File 'dm-more/dm-aggregates/lib/dm-aggregates/adapters/data_objects_adapter.rb', line 15 def max(respository, property, query) parameters = query.parameters max = query(aggregate_value_statement(:max, property, query), *parameters).first property.typecast(max) end
min
9 10 11 12 13
# File 'dm-more/dm-aggregates/lib/dm-aggregates/adapters/data_objects_adapter.rb', line 9 def min(respository, property, query) parameters = query.parameters min = query(aggregate_value_statement(:min, property, query), *parameters).first property.typecast(min) end
query
232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255
# File 'dm-core/lib/dm-core/adapters/data_objects_adapter.rb', line 232 def query(statement, *args) with_reader(statement, *args) do |reader| results = [] if (fields = reader.fields).size > 1 fields = fields.map { |field| Extlib::Inflection.underscore(field).to_sym } struct = Struct.new(*fields) while(reader.next!) do results << struct.new(*reader.values) end else while(reader.next!) do results << reader.values.at(0) end end results end end
read_set
Methods dealing with finding stuff by some query parameters
203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226
# File 'dm-core/lib/dm-core/adapters/data_objects_adapter.rb', line 203 def read_set(repository, query) Collection.new(query) do |set| with_connection do |connection| begin command = connection.create_command(query_read_statement(query)) command.set_types(query.fields.map { |p| p.primitive }) reader = command.execute_reader(*query.parameters) do_reload = query.reload? while(reader.next!) set.load(reader.values, do_reload) end ensure reader.close if reader end end end end
sum
27 28 29 30 31
# File 'dm-more/dm-aggregates/lib/dm-aggregates/adapters/data_objects_adapter.rb', line 27 def sum(respository, property, query) parameters = query.parameters sum = query(aggregate_value_statement(:sum, property, query), *parameters).first property.typecast(sum) end
transaction_primitive
TODO: move to dm-more/dm-transactions
294 295 296 297 298 299
# File 'dm-core/lib/dm-core/adapters/data_objects_adapter.rb', line 294 def transaction_primitive DataObjects::Transaction.create_for_uri(@uri) end
update
def read(repository, model, bind_values)
properties = model.properties(name).defaults
key = model.key(name)
set = Collection.new(Query.new(repository, model, model.key(name) => bind_values))
statement = read_statement(model, properties, key)
with_connection do |connection|
command = connection.create_command(statement)
command.set_types(properties.map { |p| p.primitive })
begin
reader = command.execute_reader(*bind_values)
set.load(reader.values) if reader.next!
set.first
ensure
reader.close if reader
end
end
end
177 178 179 180 181 182 183 184 185 186 187 188 189 190 191
# File 'dm-core/lib/dm-core/adapters/data_objects_adapter.rb', line 177 def update(repository, resource) # FIXME: if the properties are in different repositories # won't this cause problems? dirty_attributes = resource.dirty_attributes return false if dirty_attributes.empty? key = resource.class.key(name) statement = update_statement(resource.class, dirty_attributes, key) bind_values = dirty_attributes.map { |p| resource.instance_variable_get(p.instance_variable_name) } key.each { |p| bind_values << resource.instance_variable_get(p.instance_variable_name) } execute(statement, *bind_values).to_i == 1 end
upgrade_model_storage
TODO: move to dm-more/dm-migrations
254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276
# File 'dm-core/lib/dm-core/adapters/data_objects_adapter.rb', line 254 def upgrade_model_storage(repository, model) table_name = model.storage_name(name) if success = create_model_storage(repository, model) return model.properties(name) end properties = [] model.properties(name).each do |property| schema_hash = property_schema_hash(property, model) next if field_exists?(table_name, schema_hash[:name]) statement = alter_table_add_column_statement(table_name, schema_hash) execute(statement) properties << property end properties end
Protected Visibility
Protected Instance Method Summary
| #close_connection(connection) |
TODO: clean up once transaction related methods move to dm-more/dm-transactions. |
|---|---|
| #create_connection |
TODO: clean up once transaction related methods move to dm-more/dm-transactions. |
| #normalize_uri(uri_or_options) |
Protected Instance Method Details
close_connection
TODO: clean up once transaction related methods move to dm-more/dm-transactions
334 335 336
# File 'dm-core/lib/dm-core/adapters/data_objects_adapter.rb', line 334 def close_connection(connection) connection.close unless within_transaction? && current_transaction.primitive_for(self).connection == connection end
create_connection
TODO: clean up once transaction related methods move to dm-more/dm-transactions
323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338
# File 'dm-core/lib/dm-core/adapters/data_objects_adapter.rb', line 323 def create_connection if within_transaction? current_transaction.primitive_for(self).connection else # DataObjects::Connection.new(uri) will give you back the right # driver based on the Uri#scheme. DataObjects::Connection.new(@uri) end end
normalize_uri
300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328
# File 'dm-core/lib/dm-core/adapters/data_objects_adapter.rb', line 300 def normalize_uri(uri_or_options) if String === uri_or_options uri_or_options = Addressable::URI.parse(uri_or_options) end if Addressable::URI === uri_or_options return uri_or_options.normalize end adapter = uri_or_options.delete(:adapter) user = uri_or_options.delete(:username) password = uri_or_options.delete(:password) host = (uri_or_options.delete(:host) || "") port = uri_or_options.delete(:port) database = uri_or_options.delete(:database) query = uri_or_options.to_a.map { |pair| pair.join('=') }.join('&') query = nil if query == "" return Addressable::URI.new( adapter, user, password, host, port, database, query, nil ) end