Class: DataMapper::Adapters::DataObjectsAdapter

### Home Classes Methods

### In Files

- lib/dm-do-adapter/adapter.rb

### Parent

AbstractAdapter

### Methods

- ::new
- #close_connection
- #create
- #delete
- #execute
- #normalized_uri
- #open_connection
- #read
- #select
- #update

### Files

- LICENSE
- README.rdoc

### Class/Module Index

Quicksearch

- DataMapper
- DataMapper::Adapters
- DataMapper::Adapters::DataObjectsAdapter
- Article
- Author
- Object
- Publisher

No matching classes.

# DataMapper::Adapters::DataObjectsAdapter

DataObjectsAdapter is the base class for all adapers for relational databases. If you want to add support for a new RDBMS, it makes sense to make your adapter class inherit from this class.

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.

### Public Class Methods

new(name, uri_or_options) click to toggle source

@api public

    # File lib/dm-do-adapter/adapter.rb, line 265
    def initialize(name, uri_or_options)
      super

      # Default the driver-specific logger to DataMapper's logger
      if driver_module = DataObjects.const_get(normalized_uri.scheme.capitalize)
        driver_module.logger = DataMapper.logger if driver_module.respond_to?(:logger=)
      end
    end

### Public Instance Methods

create(resources) click to toggle source

For each model instance in resources, issues an SQL INSERT (or equivalent) statement to create a new record in the data store for the instance

Note that this method does not update the identity map. If a plugin needs to use an adapter directly, it is up to plugin developer to keep the identity map up to date.

@param [Enumerable(Resource)] resources

    The list of resources (model instances) to create

@return [Integer]

    The number of records that were actually saved into the database

@api semipublic

    # File lib/dm-do-adapter/adapter.rb, line 82
    def create(resources)
      name = self.name

      resources.each do |resource|
        model      = resource.model
        serial     = model.serial(name)
        attributes = resource.dirty_attributes

        properties  = []
        bind_values = []

        # make the order of the properties consistent
        model.properties(name).each do |property|
          next unless attributes.key?(property)

          bind_value = attributes[property]

          # skip insering NULL for columns that are serial or without a default
          next if bind_value.nil? && (property.serial? || !property.default?)

          # if serial is being set explicitly, do not set it again
          if property.equal?(serial)
            serial = nil
          end

          properties  << property
          bind_values << bind_value
        end

        statement = insert_statement(model, properties, serial)

        result = with_connection do |connection|
          connection.create_command(statement).execute_non_query(*bind_values)
        end

        if result.affected_rows == 1 && serial
          serial.set!(resource, result.insert_id)
        end
      end
    end

delete(collection) click to toggle source

Constructs and executes DELETE statement for given query

@param [Collection] collection

    collection of records to be deleted

@return [Integer]

    the number of records deleted

@api semipublic

    # File lib/dm-do-adapter/adapter.rb, line 207
    def delete(collection)
      query = collection.query
      statement, bind_values = delete_statement(query)

      with_connection do |connection|
        connection.create_command(statement).execute_non_query(*bind_values)
      end.affected_rows
    end

execute(statement, *bind_values) click to toggle source

Execute non-SELECT SQL query

@param [String] statement

    the SQL statement

@param [Array] *bind_values

    optional bind values to merge into the statement

@return [DataObjects::Result]

    result with number of affected rows, and insert id if any

@api public

    # File lib/dm-do-adapter/adapter.rb, line 60
    def execute(statement, *bind_values)
      with_connection do |connection|
        command = connection.create_command(statement)
        command.execute_non_query(*bind_values)
      end
    end

read(query) click to toggle source

Constructs and executes SELECT query, then instantiates one or many object from result set.

@param [Query] query

    composition of the query to perform

@return [Array]

    result set of the query

@api semipublic

    # File lib/dm-do-adapter/adapter.rb, line 133
    def read(query)
      fields = query.fields
      types  = fields.map { |property| property.primitive }

      statement, bind_values = select_statement(query)

      records = []

      with_connection do |connection|
        command = connection.create_command(statement)
        command.set_types(types)

        # Handle different splat semantics for nil on 1.8 and 1.9
        reader = if bind_values
          command.execute_reader(*bind_values)
        else
          command.execute_reader
        end

        begin
          while reader.next!
            records << Hash[ fields.zip(reader.values) ]
          end
        ensure
          reader.close
        end
      end

      records
    end

select(statement, *bind_values) click to toggle source

Retrieve results using an SQL SELECT statement

@param [String] statement

    the SQL SELECT statement

@param [Array] *bind_values

    optional bind values to merge into the statement

@return [Array]

    if fields > 1, return an Array of Struct objects
    if fields == 1, return an Array of objects

@api public

    # File lib/dm-do-adapter/adapter.rb, line 32
    def select(statement, *bind_values)
      with_connection do |connection|
        reader = connection.create_command(statement).execute_reader(*bind_values)
        fields = reader.fields

        begin
          if fields.size > 1
            select_fields(reader, fields)
          else
            select_field(reader)
          end
        ensure
          reader.close
        end
      end
    end

update(attributes, collection) click to toggle source

Constructs and executes UPDATE statement for given attributes and a query

@param [Hash(Property => Object)] attributes

    hash of attribute values to set, keyed by Property

@param [Collection] collection

    collection of records to be updated

@return [Integer]

    the number of records updated

@api semipublic

    # File lib/dm-do-adapter/adapter.rb, line 176
    def update(attributes, collection)
      query = collection.query

      properties  = []
      bind_values = []

      # make the order of the properties consistent
      query.model.properties(name).each do |property|
        next unless attributes.key?(property)
        properties  << property
        bind_values << attributes[property]
      end

      statement, conditions_bind_values = update_statement(properties, query)

      bind_values.concat(conditions_bind_values)

      with_connection do |connection|
        connection.create_command(statement).execute_non_query(*bind_values)
      end.affected_rows
    end

### Protected Instance Methods

close_connection(connection) click to toggle source

Takes connection and closes it

@api semipublic

    # File lib/dm-do-adapter/adapter.rb, line 257
    def close_connection(connection)
      connection.close if connection.respond_to?(:close)
    end

normalized_uri() click to toggle source

@api private

    # File lib/dm-do-adapter/adapter.rb, line 219
    def normalized_uri
      @normalized_uri ||=
        begin
          keys = [
            :adapter, :user, :password, :host, :port, :path, :fragment,
            :scheme, :query, :username, :database ]
          query = DataMapper::Ext::Hash.except(@options, keys)
          query = nil if query.empty?

          # Better error message in case port is no Numeric value
          port = @options[:port].nil? ? nil : @options[:port].to_int

          DataObjects::URI.new(
            :scheme     => @options[:adapter],
            :user       => @options[:user] || @options[:username],
            :password   => @options[:password],
            :host       => @options[:host],
            :port       => port,
            :path       => @options[:path] || @options[:database],
            :query      => query,
            :fragment   => @options[:fragment]
          ).freeze
        end
    end

open_connection() click to toggle source

Instantiates new connection object

@api semipublic

    # File lib/dm-do-adapter/adapter.rb, line 250
    def open_connection
      DataObjects::Connection.new(normalized_uri)
    end

[Validate]

Generated with the Darkfish Rdoc Generator 2.