SlideShare une entreprise Scribd logo
1  sur  77
Custom DataMapper
     Adapters
     By Josh Moore
About Me
• Josh Moore

• Optimis International

• github.com/joshsmoore

• twitter.com/codingforrent

• www.codingforrent.com
About this
          presentation

• Not an introduction to DataMapper

• Mostly Code

• Why?
Examples
class Comment                class Post
  include                      include
      DataMapper::Resource         DataMapper::Resource

 property :id, Serial         property :id, Serial
 property :body, String       property :title, String

  belongs_to :post            has n, :comments
end                          end
Terms
    term                        meaning

Storage Engine       Whatever is persisting the data


  Resource                      A model


     field               A property on a model


  Repository     DataMapper term for the storage engine
Preamble
require 'dm-core'
                        Just do it
module DataMapper
                     Just do it
  module Adapters
    class TestAdapter < AbstractAdapter
       ...
    end
                                   Just do it
    const_added(:TestAdapter)
  end
end
Symbol
                                Hash



def initialize(name, options)




end
def initialize(name, options)
          Just do it
 super




end
def initialize(name, options)
 super




end
Connect
                                    to your
def initialize(name, options)      adapter
 super
 @conn = Mongo::Connection.new(
            options[:host], options[:port])
 @adapter = @conn[options[:database]]




end
def initialize(name, options)
 super
 @conn = Mongo::Connection.new(
                  Sub class of: DataMapper::Property
            options[:host], options[:port])
 @adapter = @conn[options[:database]]
 @field_naming_convention = Proc.new do |field|
   field.model.storage_name + '_' + field.name.to_s
 end
                   Return a String




end
def initialize(name, options)
 super
 @conn = Mongo::Connection.new(
             options[:host], options[:port])
 @adapter = @conn[options[:database]]
 @field_naming_convention = Proc.new do |field|
    field.model.storage_name String (class.to_s)
                                    + '_' + field.name.to_s
 end
 @resource_naming_convention = Proc.new do |resource|
    resource.downcase
 end                Return a String
end
def initialize(name, options)
 super
 @conn = Mongo::Connection.new(
             options[:host], options[:port])
 @adapter = @conn[options[:database]]
 @field_naming_convention = Proc.new do |field|
    field.model.storage_name + '_' + field.name.to_s
 end
 @resource_naming_convention = Proc.new do |resource|
    resource.downcase
 end
end
Array of Resources
def create(resources)




end
           Return number of resources created
def create(resources)
 resources.collect do |resource|
   initialize_serial(resource,
      @adapter[resource.class.storage_name].find.count)
   fields = attributes_as_fields(
                 resource.attributes(:property))
   @adapter[resource.class.storage_name].insert(fields)
 end.size

end
def create(resources)
 resources.collect do |resource|
   initialize_serial(resource,
      @adapter[resource.class.storage_name].find.count)
   fields = attributes_as_fields(
                 resource.attributes(:property))
   @adapter[resource.class.storage_name].insert(fields)
 end.size

end
•   Accepts: Hash
                     •   Key: Sub class of: DataMapper::Property
                     •   Value: non marshaled data
                     •   example:

                     {<DataMapper::Property::String(title)>   =>
                     "hasdf"}
def create(resources)
 resources.collect do |resource|
   initialize_serial(resource,
      @adapter[resource.class.storage_name].find.count)
   fields = attributes_as_fields(
                 resource.attributes(:property))
   @adapter[resource.class.storage_name].insert(fields)
 end.size
             • Return: Hash
             • Key: @field_naming_convention result
end          • Value: Marshaled data
             • Only values that are set
             •Example:
             {"post_title" => "hasdf"}
def create(resources)
 resources.collect do |resource|
   initialize_serial(resource,
      @adapter[resource.class.storage_name].find.count)
   fields = attributes_as_fields(
                 resource.attributes(:property))
   @adapter[resource.class.storage_name].insert(fields)
 end.size

end
def create(resources)
 resources.collect do |resource|
   initialize_serial(resource,
      @adapter[resource.class.storage_name].find.count)
   fields = attributes_as_fields(
                 resource.attributes(:property))
   @adapter[resource.class.storage_name].insert(fields)
 end.size

end         Unless an Exception is raised the
           resource will be considered saved
DataMapper::Query

def read(query)




end
              Return a Array of Hashes
                    key: field name
              value: unmarshed value
               {field_name => value}
def read(query)

 conditions = parse_query_conditions(query)
 @adapter[query.model.storage_name].find(
                                 conditions)
end
Query Structure
               DataMapper::Query

                  #conditions


                   Operation

                  #operands


                     Set




 Operation         Condition              Array

                   #subject
       Field                       Association
Query Structure
                          DataMapper::Query

                             #conditions


                              Operation

                             #operands


                                Set




            Operation         Condition              Array

                              #subject
                  Field                       Association



:conditions => ["updated_at > ?", Time.now]
Query Structure
                            DataMapper::Query

                               #conditions


                                Operation

                               #operands


                                  Set




              Operation         Condition              Array

                                #subject
                    Field                       Association



  :conditions => ["updated_at > ?", Time.now]
:conditions => {:updated_at => {"$gte" => Time.now}}
Query Structure
                            DataMapper::Query

                               #conditions


                                Operation

                               #operands


                                  Set




              Operation         Condition
                                                     Hash
                                                      Array

                                #subject
                    Field                       Association



  :conditions => ["updated_at > ?", Time.now]
:conditions => {:updated_at => {"$gte" => Time.now}}
DataMapper::Query

def parse_query_conditions(query)
  mongo_conditions = {}




                                    Return a hash

 mongo_conditions
query.conditions.operands.each do |condition|
         def parse_query_conditions(query)
           mongo_conditions = {}
  case condition.class.to_s
  when 'DataMapper::Query::Conditions::GreaterThanComparison'
    mongo_conditions[condition.subject.field] =
      { "$gt" => condition.value}
  when 'DataMapper::Query::Conditions::LessThanComparison'
    mongo_conditions[condition.subject.field] =
      { "$lt" => condition.value}
  else
    mongo_conditions[condition.subject.field] =
      condition.value
  end      mongo_conditions
end      end
query.conditions.operands.each do |condition|
         def parse_query_conditions(query)
           mongo_conditions = {}
  case condition.class.to_s
  when 'DataMapper::Query::Conditions::GreaterThanComparison'
    mongo_conditions[condition.subject.field] =
      { "$gt" => condition.value}
  when 'DataMapper::Query::Conditions::LessThanComparison'
    mongo_conditions[condition.subject.field] =
      { "$lt" => condition.value}
  else
    mongo_conditions[condition.subject.field] =
      condition.value
  end      mongo_conditions
end      end
query.conditions.operands.each do |condition|
         def parse_query_conditions(query)
           mongo_conditions = {}
  case condition.class.to_s
  when 'DataMapper::Query::Conditions::GreaterThanComparison'
    mongo_conditions[condition.subject.field] =
      { "$gt" => condition.value}
  when 'DataMapper::Query::Conditions::LessThanComparison'
    mongo_conditions[condition.subject.field] =
      { "$lt" => condition.value}
  else
    mongo_conditions[condition.subject.field] =
      condition.value
  end      mongo_conditions
end      end
def parse_query_conditions(query)
  mongo_conditions = {}

 query.conditions.operands.each do |condition|
   case condition.class.to_s
   when 'DataMapper::Query::Conditions::GreaterThanComparison'
     mongo_conditions[condition.subject.field] =
       { "$gt" => condition.value}
   when 'DataMapper::Query::Conditions::LessThanComparison'
     mongo_conditions[condition.subject.field] =
       { "$lt" => condition.value}
   else
     mongo_conditions[condition.subject.field] =
       condition.value
   end
 end

  mongo_conditions
end
Post.all(:comments => {:body => 'hi 2'})
conditions.operands.each do |condition|
  ...
  case condition.class.to_s
  when '...InclusionComparison'
    if condition.subject.instance_of?
DataMapper::Associations::OneToMany::Relationship
      pk = condition.subject.parent_key.first.field
      ck = condition.subject.child_key.first.name
      mongo_conditions[pk] = {"$in" =>
        condition.value.collect {|r| r.send(ck)}}
    else
...
conditions.operands.each do |condition|
  ...
  case condition.class.to_s
  when '...InclusionComparison'
    if condition.subject.instance_of?
DataMapper::Associations::OneToMany::Relationship
      pk = condition.subject.parent_key.first.field
      ck = condition.subject.child_key.first.name
      mongo_conditions[pk] = {"$in" =>
        condition.value.collect {|r| r.send(ck)}}
    else
...
conditions.operands.each do |condition|
  ...
  case condition.class.to_s
        Array of properties
  when '...InclusionComparison'
        * property - subclass of DataMapper::Property

    if condition.subject.instance_of?
DataMapper::Associations::OneToMany::Relationship
      pk = condition.subject.parent_key.first.field
      ck = condition.subject.child_key.first.name
      mongo_conditions[pk] = {"$in" =>
        condition.value.collect {|r| r.send(ck)}}
    elseArray of properties
        * property - subclass of DataMapper::Property
...
conditions.operands.each do |condition|
  ...
  case condition.class.to_s
  when '...InclusionComparison'
    if condition.subject.instance_of?
DataMapper::Associations::OneToMany::Relationship
     Array of resources
        pk = condition.subject.parent_key.first.field
     * [#<Comment..>, #<Comment..>,...]

        ck = condition.subject.child_key.first.name
        mongo_conditions[pk] = {"$in" =>
          condition.value.collect {|r| r.send(ck)}}
    else
...
conditions.operands.each do |condition|
  ...
  case condition.class.to_s
  when '...InclusionComparison'
    if condition.subject.instance_of?
DataMapper::Associations::OneToMany::Relationship
      pk = condition.subject.parent_key.first.field
      ck = condition.subject.child_key.first.name
      mongo_conditions[pk] = {"$in" =>
        condition.value.collect {|r| r.send(ck)}}
    else
...
conditions.operands.each do |condition|
  ...
  case condition.class.to_s
  when '...InclusionComparison'
    if condition.subject.instance_of?
DataMapper::Associations::OneToMany::Relationship
      pk = condition.subject.parent_key.first.field
      ck = condition.subject.child_key.first.name
      mongo_conditions[pk] = {"$in" =>
        condition.value.collect {|r| r.send(ck)}}
    else
...
Operation

• DataMapper::Query::Conditions::AndOperation

• DataMapper::Query::Conditions::OrOperation

• DataMapper::Query::Conditions::NotOperation
Condition
• DataMapper::Query::Conditions::EqualToComparison

• DataMapper::Query::Conditions::InclusionComparison

• DataMapper::Query::Conditions::RegexpComparison

• DataMapper::Query::Conditions::LikeComparison

• DataMapper::Query::Conditions::GreaterThanComparison

• DataMapper::Query::Conditions::LessThanComparison

• DataMapper::Query::Conditions::GreaterThanOrEqualToComparison

• DataMapper::Query::Conditions::LessThanOrEqualToComparison
What is not covered


• Nested Operands
If your backed does not
 have a query language
                      A Array of Hashes
                        key: field name
                  value: unmarshed value
                  [{field_name => value}]




def read(query)
  query.filter_records(records)
end
def delete(resources)
  conditions = parse_query_conditions(resources.query)
  record_count = read(resources.query).count
  @adapter[resources.storage_name].remove(conditions)
  record_count
end
DataMapper::Collection

def delete(resources)
  conditions = parse_query_conditions(resources.query)
  record_count = read(resources.query).count
  @adapter[resources.storage_name].remove(conditions)
  record_count
end     Number of resources deleted (int)
def delete(resources)
  conditions = parse_query_conditions(resources.query)
  record_count = read(resources.query).count
  @adapter[resources.storage_name].remove(conditions)
  record_count
end



           Unless an Exception is raised the
          resource will be considered saved
def update(changes, resources)
  conditions = parse_query_conditions(resources.query)
  @adapter[resources.storage_name].update(conditions,
     {"$set" => attributes_as_fields(changes)},
     {:multi => true})
  read(resources.query).count
end
Unmarshaled hash of changes

        {<DataMapper::Property::String(title)>
             => "hasdf"}



                                            DataMapper::Collection

def update(changes, resources)
  conditions = parse_query_conditions(resources.query)
  @adapter[resources.storage_name].update(conditions,
     {"$set" => attributes_as_fields(changes)},
     {:multi => true})
  read(resources.query).count
end
       Number of resources updated (int)
def update(changes, resources)
  conditions = parse_query_conditions(resources.query)
  @adapter[resources.storage_name].update(conditions,
     {"$set" => attributes_as_fields(changes)},
     {:multi => true})
  read(resources.query).count
end
            Unless an Exception is raised the
           resource will be considered saved
Be Kind log


• DataMapper.logger
You can stop now
80/20 rule
But, if you want to
  keep going...
Post.create.key
Post.create.key

 ["4e15cab882034dc7f7000002"]
Post.create.key
Just do it
module DataMapper
                      Just do it
  module Is
    module Mongo
      def is_mongo(options={})
        property :_id, String,
            :key => true, :default => ''
      end
    end
  end
                                           Just do it
  Model.append_extensions(Is::Mongo)
end
class Post
  include DataMapper::Resource

 property :title, String

 has n, :comments

  is :mongo
end
class Post
  include DataMapper::Resource

 property :title, String

 has n, :comments

  is :mongo
end

     Post.create.key

                 [""]
def create(resources)
  resources.collect do |resource|
    fields =
attributes_as_fields(resource.attributes(:property))
    fields.delete '_id'
    b_id = @adapter[resource.class.storage_name].insert
                          fields
    resource._id = b_id.to_s

    if resource.instance_variables.include? '@_key'
      resource.send :remove_instance_variable, :@_key
    end
  end.size
end                 Post.create.key
def create(resources)
  resources.collect do |resource|
    fields =
attributes_as_fields(resource.attributes(:property))
    fields.delete '_id'
    b_id = @adapter[resource.class.storage_name].insert
                          fields
    resource._id = b_id.to_s

    if resource.instance_variables.include? '@_key'
      resource.send :remove_instance_variable, :@_key
    end
  end.size
end                 Post.create.key
def create(resources)
  resources.collect do |resource|
    fields =
attributes_as_fields(resource.attributes(:property))
    fields.delete '_id'
    b_id = @adapter[resource.class.storage_name].insert
                          fields
    resource._id = b_id.to_s

    if resource.instance_variables.include? '@_key'
      resource.send :remove_instance_variable, :@_key
    end
  end.size
end                 Post.create.key
def create(resources)
  resources.collect do |resource|
    fields =
attributes_as_fields(resource.attributes(:property))
    fields.delete '_id'
    b_id = @adapter[resource.class.storage_name].insert
                          fields
    resource._id = b_id.to_s

    if resource.instance_variables.include? '@_key'
      resource.send :remove_instance_variable, :@_key
    end
  end.size
end                 Post.create.key
def create(resources)
  resources.collect do |resource|
    fields =
attributes_as_fields(resource.attributes(:property))
    fields.delete '_id'
    b_id = @adapter[resource.class.storage_name].insert
                          fields
    resource._id = b_id.to_s

    if resource.instance_variables.include? '@_key'
      resource.send :remove_instance_variable, :@_key
    end
  end.size
end                 Post.create.key
def create(resources)
  resources.collect do |resource|
    fields =
attributes_as_fields(resource.attributes(:property))
    fields.delete '_id'
    b_id = @adapter[resource.class.storage_name].insert
                          fields
    resource._id = b_id.to_s

    if resource.instance_variables.include? '@_key'
      resource.send :remove_instance_variable, :@_key
    end
  end.size
end                 Post.create.key

                       ["4e15cab882034dc7f7000002"]
def create(resources)
  resources.collect do |resource|
    fields =
attributes_as_fields(resource.attributes(:property))
    fields.delete '_id'
    b_id = @adapter[resource.class.storage_name].insert
                          fields
    resource._id = b_id.to_s

    if resource.instance_variables.include? '@_key'
      resource.send :remove_instance_variable, :@_key
    end
  end.size
end                 Post.create.key
Whats left

• Aggregation

• Native types

• DataMapper.logger

Contenu connexe

Tendances

Database API, your new friend
Database API, your new friendDatabase API, your new friend
Database API, your new friend
kikoalonsob
 
SPL: The Missing Link in Development
SPL: The Missing Link in DevelopmentSPL: The Missing Link in Development
SPL: The Missing Link in Development
jsmith92
 
vfsStream - effective filesystem mocking
vfsStream - effective filesystem mocking vfsStream - effective filesystem mocking
vfsStream - effective filesystem mocking
Sebastian Marek
 
Wordcamp Fayetteville Pods Presentation (PDF)
Wordcamp Fayetteville Pods Presentation (PDF)Wordcamp Fayetteville Pods Presentation (PDF)
Wordcamp Fayetteville Pods Presentation (PDF)
mpvanwinkle
 

Tendances (20)

Perforce Object and Record Model
Perforce Object and Record Model  Perforce Object and Record Model
Perforce Object and Record Model
 
Testing stateful, concurrent, and async systems using test.check
Testing stateful, concurrent, and async systems using test.checkTesting stateful, concurrent, and async systems using test.check
Testing stateful, concurrent, and async systems using test.check
 
Database API, your new friend
Database API, your new friendDatabase API, your new friend
Database API, your new friend
 
Syntactic sugar in Postgre SQL
Syntactic sugar in Postgre SQLSyntactic sugar in Postgre SQL
Syntactic sugar in Postgre SQL
 
Bioinformatics p5-bioperlv2014
Bioinformatics p5-bioperlv2014Bioinformatics p5-bioperlv2014
Bioinformatics p5-bioperlv2014
 
Resource Routing in ExpressionEngine
Resource Routing in ExpressionEngineResource Routing in ExpressionEngine
Resource Routing in ExpressionEngine
 
Backbone.js: Run your Application Inside The Browser
Backbone.js: Run your Application Inside The BrowserBackbone.js: Run your Application Inside The Browser
Backbone.js: Run your Application Inside The Browser
 
SPL: The Missing Link in Development
SPL: The Missing Link in DevelopmentSPL: The Missing Link in Development
SPL: The Missing Link in Development
 
Apache Spark - Key-Value RDD | Big Data Hadoop Spark Tutorial | CloudxLab
Apache Spark - Key-Value RDD | Big Data Hadoop Spark Tutorial | CloudxLabApache Spark - Key-Value RDD | Big Data Hadoop Spark Tutorial | CloudxLab
Apache Spark - Key-Value RDD | Big Data Hadoop Spark Tutorial | CloudxLab
 
Node js mongodriver
Node js mongodriverNode js mongodriver
Node js mongodriver
 
Spl Not A Bridge Too Far phpNW09
Spl Not A Bridge Too Far phpNW09Spl Not A Bridge Too Far phpNW09
Spl Not A Bridge Too Far phpNW09
 
New SPL Features in PHP 5.3
New SPL Features in PHP 5.3New SPL Features in PHP 5.3
New SPL Features in PHP 5.3
 
Drupal 8 database api
Drupal 8 database apiDrupal 8 database api
Drupal 8 database api
 
vfsStream - a better approach for file system dependent tests
vfsStream - a better approach for file system dependent testsvfsStream - a better approach for file system dependent tests
vfsStream - a better approach for file system dependent tests
 
vfsStream - effective filesystem mocking
vfsStream - effective filesystem mocking vfsStream - effective filesystem mocking
vfsStream - effective filesystem mocking
 
Scaling modern JVM applications with Akka toolkit
Scaling modern JVM applications with Akka toolkitScaling modern JVM applications with Akka toolkit
Scaling modern JVM applications with Akka toolkit
 
Wordcamp Fayetteville Pods Presentation (PDF)
Wordcamp Fayetteville Pods Presentation (PDF)Wordcamp Fayetteville Pods Presentation (PDF)
Wordcamp Fayetteville Pods Presentation (PDF)
 
Marc’s (bio)perl course
Marc’s (bio)perl courseMarc’s (bio)perl course
Marc’s (bio)perl course
 
G*ワークショップ in 仙台 Grails(とことん)入門
G*ワークショップ in 仙台 Grails(とことん)入門G*ワークショップ in 仙台 Grails(とことん)入門
G*ワークショップ in 仙台 Grails(とことん)入門
 
WP_Query, pre_get_posts, and eliminating query_posts()
WP_Query, pre_get_posts, and eliminating query_posts()WP_Query, pre_get_posts, and eliminating query_posts()
WP_Query, pre_get_posts, and eliminating query_posts()
 

Similaire à Dm adapter

第49回Php勉強会@関東 Datasource
第49回Php勉強会@関東 Datasource第49回Php勉強会@関東 Datasource
第49回Php勉強会@関東 Datasource
Kaz Watanabe
 
From mysql to MongoDB(MongoDB2011北京交流会)
From mysql to MongoDB(MongoDB2011北京交流会)From mysql to MongoDB(MongoDB2011北京交流会)
From mysql to MongoDB(MongoDB2011北京交流会)
Night Sailer
 
Introducing DataWave
Introducing DataWaveIntroducing DataWave
Introducing DataWave
Data Works MD
 
Metaprogramovanie #1
Metaprogramovanie #1Metaprogramovanie #1
Metaprogramovanie #1
Jano Suchal
 

Similaire à Dm adapter (20)

DataMapper
DataMapperDataMapper
DataMapper
 
Spring data iii
Spring data iiiSpring data iii
Spring data iii
 
第49回Php勉強会@関東 Datasource
第49回Php勉強会@関東 Datasource第49回Php勉強会@関東 Datasource
第49回Php勉強会@関東 Datasource
 
Java Web Programming [5/9] : EL, JSTL and Custom Tags
Java Web Programming [5/9] : EL, JSTL and Custom TagsJava Web Programming [5/9] : EL, JSTL and Custom Tags
Java Web Programming [5/9] : EL, JSTL and Custom Tags
 
TDC 2012 - Patterns e Anti-Patterns em Ruby
TDC 2012 - Patterns e Anti-Patterns em RubyTDC 2012 - Patterns e Anti-Patterns em Ruby
TDC 2012 - Patterns e Anti-Patterns em Ruby
 
Zend Framework Study@Tokyo #2
Zend Framework Study@Tokyo #2Zend Framework Study@Tokyo #2
Zend Framework Study@Tokyo #2
 
From mysql to MongoDB(MongoDB2011北京交流会)
From mysql to MongoDB(MongoDB2011北京交流会)From mysql to MongoDB(MongoDB2011北京交流会)
From mysql to MongoDB(MongoDB2011北京交流会)
 
Introducing DataWave
Introducing DataWaveIntroducing DataWave
Introducing DataWave
 
mongodb-introduction
mongodb-introductionmongodb-introduction
mongodb-introduction
 
All I Need to Know I Learned by Writing My Own Web Framework
All I Need to Know I Learned by Writing My Own Web FrameworkAll I Need to Know I Learned by Writing My Own Web Framework
All I Need to Know I Learned by Writing My Own Web Framework
 
Design Summit - Rails 4 Migration - Aaron Patterson
Design Summit - Rails 4 Migration - Aaron PattersonDesign Summit - Rails 4 Migration - Aaron Patterson
Design Summit - Rails 4 Migration - Aaron Patterson
 
Metaprogramovanie #1
Metaprogramovanie #1Metaprogramovanie #1
Metaprogramovanie #1
 
Shooting the Rapids
Shooting the RapidsShooting the Rapids
Shooting the Rapids
 
Developing a Real-time Engine with Akka, Cassandra, and Spray
Developing a Real-time Engine with Akka, Cassandra, and SprayDeveloping a Real-time Engine with Akka, Cassandra, and Spray
Developing a Real-time Engine with Akka, Cassandra, and Spray
 
From docker to kubernetes: running Apache Hadoop in a cloud native way
From docker to kubernetes: running Apache Hadoop in a cloud native wayFrom docker to kubernetes: running Apache Hadoop in a cloud native way
From docker to kubernetes: running Apache Hadoop in a cloud native way
 
I Phone On Rails
I Phone On RailsI Phone On Rails
I Phone On Rails
 
No more struggles with Apache Spark workloads in production
No more struggles with Apache Spark workloads in productionNo more struggles with Apache Spark workloads in production
No more struggles with Apache Spark workloads in production
 
Jdbc Java Programming
Jdbc Java ProgrammingJdbc Java Programming
Jdbc Java Programming
 
Jquery 4
Jquery 4Jquery 4
Jquery 4
 
Hadoop Integration in Cassandra
Hadoop Integration in CassandraHadoop Integration in Cassandra
Hadoop Integration in Cassandra
 

Dernier

Call Girls in Delhi, Escort Service Available 24x7 in Delhi 959961-/-3876
Call Girls in Delhi, Escort Service Available 24x7 in Delhi 959961-/-3876Call Girls in Delhi, Escort Service Available 24x7 in Delhi 959961-/-3876
Call Girls in Delhi, Escort Service Available 24x7 in Delhi 959961-/-3876
dlhescort
 
Call Girls From Pari Chowk Greater Noida ❤️8448577510 ⊹Best Escorts Service I...
Call Girls From Pari Chowk Greater Noida ❤️8448577510 ⊹Best Escorts Service I...Call Girls From Pari Chowk Greater Noida ❤️8448577510 ⊹Best Escorts Service I...
Call Girls From Pari Chowk Greater Noida ❤️8448577510 ⊹Best Escorts Service I...
lizamodels9
 
Call Girls Jp Nagar Just Call 👗 7737669865 👗 Top Class Call Girl Service Bang...
Call Girls Jp Nagar Just Call 👗 7737669865 👗 Top Class Call Girl Service Bang...Call Girls Jp Nagar Just Call 👗 7737669865 👗 Top Class Call Girl Service Bang...
Call Girls Jp Nagar Just Call 👗 7737669865 👗 Top Class Call Girl Service Bang...
amitlee9823
 
Call Girls Kengeri Satellite Town Just Call 👗 7737669865 👗 Top Class Call Gir...
Call Girls Kengeri Satellite Town Just Call 👗 7737669865 👗 Top Class Call Gir...Call Girls Kengeri Satellite Town Just Call 👗 7737669865 👗 Top Class Call Gir...
Call Girls Kengeri Satellite Town Just Call 👗 7737669865 👗 Top Class Call Gir...
amitlee9823
 
Nelamangala Call Girls: 🍓 7737669865 🍓 High Profile Model Escorts | Bangalore...
Nelamangala Call Girls: 🍓 7737669865 🍓 High Profile Model Escorts | Bangalore...Nelamangala Call Girls: 🍓 7737669865 🍓 High Profile Model Escorts | Bangalore...
Nelamangala Call Girls: 🍓 7737669865 🍓 High Profile Model Escorts | Bangalore...
amitlee9823
 
FULL ENJOY Call Girls In Mahipalpur Delhi Contact Us 8377877756
FULL ENJOY Call Girls In Mahipalpur Delhi Contact Us 8377877756FULL ENJOY Call Girls In Mahipalpur Delhi Contact Us 8377877756
FULL ENJOY Call Girls In Mahipalpur Delhi Contact Us 8377877756
dollysharma2066
 
The Abortion pills for sale in Qatar@Doha [+27737758557] []Deira Dubai Kuwait
The Abortion pills for sale in Qatar@Doha [+27737758557] []Deira Dubai KuwaitThe Abortion pills for sale in Qatar@Doha [+27737758557] []Deira Dubai Kuwait
The Abortion pills for sale in Qatar@Doha [+27737758557] []Deira Dubai Kuwait
daisycvs
 

Dernier (20)

Call Girls in Delhi, Escort Service Available 24x7 in Delhi 959961-/-3876
Call Girls in Delhi, Escort Service Available 24x7 in Delhi 959961-/-3876Call Girls in Delhi, Escort Service Available 24x7 in Delhi 959961-/-3876
Call Girls in Delhi, Escort Service Available 24x7 in Delhi 959961-/-3876
 
Lundin Gold - Q1 2024 Conference Call Presentation (Revised)
Lundin Gold - Q1 2024 Conference Call Presentation (Revised)Lundin Gold - Q1 2024 Conference Call Presentation (Revised)
Lundin Gold - Q1 2024 Conference Call Presentation (Revised)
 
Marel Q1 2024 Investor Presentation from May 8, 2024
Marel Q1 2024 Investor Presentation from May 8, 2024Marel Q1 2024 Investor Presentation from May 8, 2024
Marel Q1 2024 Investor Presentation from May 8, 2024
 
Falcon Invoice Discounting platform in india
Falcon Invoice Discounting platform in indiaFalcon Invoice Discounting platform in india
Falcon Invoice Discounting platform in india
 
Uneak White's Personal Brand Exploration Presentation
Uneak White's Personal Brand Exploration PresentationUneak White's Personal Brand Exploration Presentation
Uneak White's Personal Brand Exploration Presentation
 
Call Girls Ludhiana Just Call 98765-12871 Top Class Call Girl Service Available
Call Girls Ludhiana Just Call 98765-12871 Top Class Call Girl Service AvailableCall Girls Ludhiana Just Call 98765-12871 Top Class Call Girl Service Available
Call Girls Ludhiana Just Call 98765-12871 Top Class Call Girl Service Available
 
(Anamika) VIP Call Girls Napur Call Now 8617697112 Napur Escorts 24x7
(Anamika) VIP Call Girls Napur Call Now 8617697112 Napur Escorts 24x7(Anamika) VIP Call Girls Napur Call Now 8617697112 Napur Escorts 24x7
(Anamika) VIP Call Girls Napur Call Now 8617697112 Napur Escorts 24x7
 
Call Girls From Pari Chowk Greater Noida ❤️8448577510 ⊹Best Escorts Service I...
Call Girls From Pari Chowk Greater Noida ❤️8448577510 ⊹Best Escorts Service I...Call Girls From Pari Chowk Greater Noida ❤️8448577510 ⊹Best Escorts Service I...
Call Girls From Pari Chowk Greater Noida ❤️8448577510 ⊹Best Escorts Service I...
 
Call Girls Zirakpur👧 Book Now📱7837612180 📞👉Call Girl Service In Zirakpur No A...
Call Girls Zirakpur👧 Book Now📱7837612180 📞👉Call Girl Service In Zirakpur No A...Call Girls Zirakpur👧 Book Now📱7837612180 📞👉Call Girl Service In Zirakpur No A...
Call Girls Zirakpur👧 Book Now📱7837612180 📞👉Call Girl Service In Zirakpur No A...
 
Call Girls Jp Nagar Just Call 👗 7737669865 👗 Top Class Call Girl Service Bang...
Call Girls Jp Nagar Just Call 👗 7737669865 👗 Top Class Call Girl Service Bang...Call Girls Jp Nagar Just Call 👗 7737669865 👗 Top Class Call Girl Service Bang...
Call Girls Jp Nagar Just Call 👗 7737669865 👗 Top Class Call Girl Service Bang...
 
Call Girls Kengeri Satellite Town Just Call 👗 7737669865 👗 Top Class Call Gir...
Call Girls Kengeri Satellite Town Just Call 👗 7737669865 👗 Top Class Call Gir...Call Girls Kengeri Satellite Town Just Call 👗 7737669865 👗 Top Class Call Gir...
Call Girls Kengeri Satellite Town Just Call 👗 7737669865 👗 Top Class Call Gir...
 
Eluru Call Girls Service ☎ ️93326-06886 ❤️‍🔥 Enjoy 24/7 Escort Service
Eluru Call Girls Service ☎ ️93326-06886 ❤️‍🔥 Enjoy 24/7 Escort ServiceEluru Call Girls Service ☎ ️93326-06886 ❤️‍🔥 Enjoy 24/7 Escort Service
Eluru Call Girls Service ☎ ️93326-06886 ❤️‍🔥 Enjoy 24/7 Escort Service
 
How to Get Started in Social Media for Art League City
How to Get Started in Social Media for Art League CityHow to Get Started in Social Media for Art League City
How to Get Started in Social Media for Art League City
 
Nelamangala Call Girls: 🍓 7737669865 🍓 High Profile Model Escorts | Bangalore...
Nelamangala Call Girls: 🍓 7737669865 🍓 High Profile Model Escorts | Bangalore...Nelamangala Call Girls: 🍓 7737669865 🍓 High Profile Model Escorts | Bangalore...
Nelamangala Call Girls: 🍓 7737669865 🍓 High Profile Model Escorts | Bangalore...
 
FULL ENJOY Call Girls In Mahipalpur Delhi Contact Us 8377877756
FULL ENJOY Call Girls In Mahipalpur Delhi Contact Us 8377877756FULL ENJOY Call Girls In Mahipalpur Delhi Contact Us 8377877756
FULL ENJOY Call Girls In Mahipalpur Delhi Contact Us 8377877756
 
The Abortion pills for sale in Qatar@Doha [+27737758557] []Deira Dubai Kuwait
The Abortion pills for sale in Qatar@Doha [+27737758557] []Deira Dubai KuwaitThe Abortion pills for sale in Qatar@Doha [+27737758557] []Deira Dubai Kuwait
The Abortion pills for sale in Qatar@Doha [+27737758557] []Deira Dubai Kuwait
 
The Path to Product Excellence: Avoiding Common Pitfalls and Enhancing Commun...
The Path to Product Excellence: Avoiding Common Pitfalls and Enhancing Commun...The Path to Product Excellence: Avoiding Common Pitfalls and Enhancing Commun...
The Path to Product Excellence: Avoiding Common Pitfalls and Enhancing Commun...
 
Call Girls Service In Old Town Dubai ((0551707352)) Old Town Dubai Call Girl ...
Call Girls Service In Old Town Dubai ((0551707352)) Old Town Dubai Call Girl ...Call Girls Service In Old Town Dubai ((0551707352)) Old Town Dubai Call Girl ...
Call Girls Service In Old Town Dubai ((0551707352)) Old Town Dubai Call Girl ...
 
Dr. Admir Softic_ presentation_Green Club_ENG.pdf
Dr. Admir Softic_ presentation_Green Club_ENG.pdfDr. Admir Softic_ presentation_Green Club_ENG.pdf
Dr. Admir Softic_ presentation_Green Club_ENG.pdf
 
Falcon Invoice Discounting: Empowering Your Business Growth
Falcon Invoice Discounting: Empowering Your Business GrowthFalcon Invoice Discounting: Empowering Your Business Growth
Falcon Invoice Discounting: Empowering Your Business Growth
 

Dm adapter

  • 1. Custom DataMapper Adapters By Josh Moore
  • 2. About Me • Josh Moore • Optimis International • github.com/joshsmoore • twitter.com/codingforrent • www.codingforrent.com
  • 3.
  • 4. About this presentation • Not an introduction to DataMapper • Mostly Code • Why?
  • 5. Examples class Comment class Post include include DataMapper::Resource DataMapper::Resource property :id, Serial property :id, Serial property :body, String property :title, String belongs_to :post has n, :comments end end
  • 6.
  • 7. Terms term meaning Storage Engine Whatever is persisting the data Resource A model field A property on a model Repository DataMapper term for the storage engine
  • 8.
  • 9. Preamble require 'dm-core' Just do it module DataMapper Just do it module Adapters class TestAdapter < AbstractAdapter ... end Just do it const_added(:TestAdapter) end end
  • 10.
  • 11.
  • 12. Symbol Hash def initialize(name, options) end
  • 13. def initialize(name, options) Just do it super end
  • 15. Connect to your def initialize(name, options) adapter super @conn = Mongo::Connection.new( options[:host], options[:port]) @adapter = @conn[options[:database]] end
  • 16. def initialize(name, options) super @conn = Mongo::Connection.new( Sub class of: DataMapper::Property options[:host], options[:port]) @adapter = @conn[options[:database]] @field_naming_convention = Proc.new do |field| field.model.storage_name + '_' + field.name.to_s end Return a String end
  • 17. def initialize(name, options) super @conn = Mongo::Connection.new( options[:host], options[:port]) @adapter = @conn[options[:database]] @field_naming_convention = Proc.new do |field| field.model.storage_name String (class.to_s) + '_' + field.name.to_s end @resource_naming_convention = Proc.new do |resource| resource.downcase end Return a String end
  • 18. def initialize(name, options) super @conn = Mongo::Connection.new( options[:host], options[:port]) @adapter = @conn[options[:database]] @field_naming_convention = Proc.new do |field| field.model.storage_name + '_' + field.name.to_s end @resource_naming_convention = Proc.new do |resource| resource.downcase end end
  • 19.
  • 20.
  • 21. Array of Resources def create(resources) end Return number of resources created
  • 22. def create(resources) resources.collect do |resource| initialize_serial(resource, @adapter[resource.class.storage_name].find.count) fields = attributes_as_fields( resource.attributes(:property)) @adapter[resource.class.storage_name].insert(fields) end.size end
  • 23. def create(resources) resources.collect do |resource| initialize_serial(resource, @adapter[resource.class.storage_name].find.count) fields = attributes_as_fields( resource.attributes(:property)) @adapter[resource.class.storage_name].insert(fields) end.size end
  • 24. Accepts: Hash • Key: Sub class of: DataMapper::Property • Value: non marshaled data • example: {<DataMapper::Property::String(title)> => "hasdf"} def create(resources) resources.collect do |resource| initialize_serial(resource, @adapter[resource.class.storage_name].find.count) fields = attributes_as_fields( resource.attributes(:property)) @adapter[resource.class.storage_name].insert(fields) end.size • Return: Hash • Key: @field_naming_convention result end • Value: Marshaled data • Only values that are set •Example: {"post_title" => "hasdf"}
  • 25. def create(resources) resources.collect do |resource| initialize_serial(resource, @adapter[resource.class.storage_name].find.count) fields = attributes_as_fields( resource.attributes(:property)) @adapter[resource.class.storage_name].insert(fields) end.size end
  • 26. def create(resources) resources.collect do |resource| initialize_serial(resource, @adapter[resource.class.storage_name].find.count) fields = attributes_as_fields( resource.attributes(:property)) @adapter[resource.class.storage_name].insert(fields) end.size end Unless an Exception is raised the resource will be considered saved
  • 27.
  • 28.
  • 29. DataMapper::Query def read(query) end Return a Array of Hashes key: field name value: unmarshed value {field_name => value}
  • 30. def read(query) conditions = parse_query_conditions(query) @adapter[query.model.storage_name].find( conditions) end
  • 31. Query Structure DataMapper::Query #conditions Operation #operands Set Operation Condition Array #subject Field Association
  • 32. Query Structure DataMapper::Query #conditions Operation #operands Set Operation Condition Array #subject Field Association :conditions => ["updated_at > ?", Time.now]
  • 33. Query Structure DataMapper::Query #conditions Operation #operands Set Operation Condition Array #subject Field Association :conditions => ["updated_at > ?", Time.now] :conditions => {:updated_at => {"$gte" => Time.now}}
  • 34. Query Structure DataMapper::Query #conditions Operation #operands Set Operation Condition Hash Array #subject Field Association :conditions => ["updated_at > ?", Time.now] :conditions => {:updated_at => {"$gte" => Time.now}}
  • 35.
  • 36. DataMapper::Query def parse_query_conditions(query) mongo_conditions = {} Return a hash mongo_conditions
  • 37. query.conditions.operands.each do |condition| def parse_query_conditions(query) mongo_conditions = {} case condition.class.to_s when 'DataMapper::Query::Conditions::GreaterThanComparison' mongo_conditions[condition.subject.field] = { "$gt" => condition.value} when 'DataMapper::Query::Conditions::LessThanComparison' mongo_conditions[condition.subject.field] = { "$lt" => condition.value} else mongo_conditions[condition.subject.field] = condition.value end mongo_conditions end end
  • 38. query.conditions.operands.each do |condition| def parse_query_conditions(query) mongo_conditions = {} case condition.class.to_s when 'DataMapper::Query::Conditions::GreaterThanComparison' mongo_conditions[condition.subject.field] = { "$gt" => condition.value} when 'DataMapper::Query::Conditions::LessThanComparison' mongo_conditions[condition.subject.field] = { "$lt" => condition.value} else mongo_conditions[condition.subject.field] = condition.value end mongo_conditions end end
  • 39. query.conditions.operands.each do |condition| def parse_query_conditions(query) mongo_conditions = {} case condition.class.to_s when 'DataMapper::Query::Conditions::GreaterThanComparison' mongo_conditions[condition.subject.field] = { "$gt" => condition.value} when 'DataMapper::Query::Conditions::LessThanComparison' mongo_conditions[condition.subject.field] = { "$lt" => condition.value} else mongo_conditions[condition.subject.field] = condition.value end mongo_conditions end end
  • 40. def parse_query_conditions(query) mongo_conditions = {} query.conditions.operands.each do |condition| case condition.class.to_s when 'DataMapper::Query::Conditions::GreaterThanComparison' mongo_conditions[condition.subject.field] = { "$gt" => condition.value} when 'DataMapper::Query::Conditions::LessThanComparison' mongo_conditions[condition.subject.field] = { "$lt" => condition.value} else mongo_conditions[condition.subject.field] = condition.value end end mongo_conditions end
  • 42. conditions.operands.each do |condition| ... case condition.class.to_s when '...InclusionComparison' if condition.subject.instance_of? DataMapper::Associations::OneToMany::Relationship pk = condition.subject.parent_key.first.field ck = condition.subject.child_key.first.name mongo_conditions[pk] = {"$in" => condition.value.collect {|r| r.send(ck)}} else ...
  • 43. conditions.operands.each do |condition| ... case condition.class.to_s when '...InclusionComparison' if condition.subject.instance_of? DataMapper::Associations::OneToMany::Relationship pk = condition.subject.parent_key.first.field ck = condition.subject.child_key.first.name mongo_conditions[pk] = {"$in" => condition.value.collect {|r| r.send(ck)}} else ...
  • 44. conditions.operands.each do |condition| ... case condition.class.to_s Array of properties when '...InclusionComparison' * property - subclass of DataMapper::Property if condition.subject.instance_of? DataMapper::Associations::OneToMany::Relationship pk = condition.subject.parent_key.first.field ck = condition.subject.child_key.first.name mongo_conditions[pk] = {"$in" => condition.value.collect {|r| r.send(ck)}} elseArray of properties * property - subclass of DataMapper::Property ...
  • 45. conditions.operands.each do |condition| ... case condition.class.to_s when '...InclusionComparison' if condition.subject.instance_of? DataMapper::Associations::OneToMany::Relationship Array of resources pk = condition.subject.parent_key.first.field * [#<Comment..>, #<Comment..>,...] ck = condition.subject.child_key.first.name mongo_conditions[pk] = {"$in" => condition.value.collect {|r| r.send(ck)}} else ...
  • 46. conditions.operands.each do |condition| ... case condition.class.to_s when '...InclusionComparison' if condition.subject.instance_of? DataMapper::Associations::OneToMany::Relationship pk = condition.subject.parent_key.first.field ck = condition.subject.child_key.first.name mongo_conditions[pk] = {"$in" => condition.value.collect {|r| r.send(ck)}} else ...
  • 47. conditions.operands.each do |condition| ... case condition.class.to_s when '...InclusionComparison' if condition.subject.instance_of? DataMapper::Associations::OneToMany::Relationship pk = condition.subject.parent_key.first.field ck = condition.subject.child_key.first.name mongo_conditions[pk] = {"$in" => condition.value.collect {|r| r.send(ck)}} else ...
  • 49. Condition • DataMapper::Query::Conditions::EqualToComparison • DataMapper::Query::Conditions::InclusionComparison • DataMapper::Query::Conditions::RegexpComparison • DataMapper::Query::Conditions::LikeComparison • DataMapper::Query::Conditions::GreaterThanComparison • DataMapper::Query::Conditions::LessThanComparison • DataMapper::Query::Conditions::GreaterThanOrEqualToComparison • DataMapper::Query::Conditions::LessThanOrEqualToComparison
  • 50. What is not covered • Nested Operands
  • 51. If your backed does not have a query language A Array of Hashes key: field name value: unmarshed value [{field_name => value}] def read(query) query.filter_records(records) end
  • 52.
  • 53. def delete(resources) conditions = parse_query_conditions(resources.query) record_count = read(resources.query).count @adapter[resources.storage_name].remove(conditions) record_count end
  • 54. DataMapper::Collection def delete(resources) conditions = parse_query_conditions(resources.query) record_count = read(resources.query).count @adapter[resources.storage_name].remove(conditions) record_count end Number of resources deleted (int)
  • 55. def delete(resources) conditions = parse_query_conditions(resources.query) record_count = read(resources.query).count @adapter[resources.storage_name].remove(conditions) record_count end Unless an Exception is raised the resource will be considered saved
  • 56.
  • 57. def update(changes, resources) conditions = parse_query_conditions(resources.query) @adapter[resources.storage_name].update(conditions, {"$set" => attributes_as_fields(changes)}, {:multi => true}) read(resources.query).count end
  • 58. Unmarshaled hash of changes {<DataMapper::Property::String(title)> => "hasdf"} DataMapper::Collection def update(changes, resources) conditions = parse_query_conditions(resources.query) @adapter[resources.storage_name].update(conditions, {"$set" => attributes_as_fields(changes)}, {:multi => true}) read(resources.query).count end Number of resources updated (int)
  • 59. def update(changes, resources) conditions = parse_query_conditions(resources.query) @adapter[resources.storage_name].update(conditions, {"$set" => attributes_as_fields(changes)}, {:multi => true}) read(resources.query).count end Unless an Exception is raised the resource will be considered saved
  • 60. Be Kind log • DataMapper.logger
  • 63. But, if you want to keep going...
  • 67. Just do it module DataMapper Just do it module Is module Mongo def is_mongo(options={}) property :_id, String, :key => true, :default => '' end end end Just do it Model.append_extensions(Is::Mongo) end
  • 68. class Post include DataMapper::Resource property :title, String has n, :comments is :mongo end
  • 69. class Post include DataMapper::Resource property :title, String has n, :comments is :mongo end Post.create.key [""]
  • 70. def create(resources) resources.collect do |resource| fields = attributes_as_fields(resource.attributes(:property)) fields.delete '_id' b_id = @adapter[resource.class.storage_name].insert fields resource._id = b_id.to_s if resource.instance_variables.include? '@_key' resource.send :remove_instance_variable, :@_key end end.size end Post.create.key
  • 71. def create(resources) resources.collect do |resource| fields = attributes_as_fields(resource.attributes(:property)) fields.delete '_id' b_id = @adapter[resource.class.storage_name].insert fields resource._id = b_id.to_s if resource.instance_variables.include? '@_key' resource.send :remove_instance_variable, :@_key end end.size end Post.create.key
  • 72. def create(resources) resources.collect do |resource| fields = attributes_as_fields(resource.attributes(:property)) fields.delete '_id' b_id = @adapter[resource.class.storage_name].insert fields resource._id = b_id.to_s if resource.instance_variables.include? '@_key' resource.send :remove_instance_variable, :@_key end end.size end Post.create.key
  • 73. def create(resources) resources.collect do |resource| fields = attributes_as_fields(resource.attributes(:property)) fields.delete '_id' b_id = @adapter[resource.class.storage_name].insert fields resource._id = b_id.to_s if resource.instance_variables.include? '@_key' resource.send :remove_instance_variable, :@_key end end.size end Post.create.key
  • 74. def create(resources) resources.collect do |resource| fields = attributes_as_fields(resource.attributes(:property)) fields.delete '_id' b_id = @adapter[resource.class.storage_name].insert fields resource._id = b_id.to_s if resource.instance_variables.include? '@_key' resource.send :remove_instance_variable, :@_key end end.size end Post.create.key
  • 75. def create(resources) resources.collect do |resource| fields = attributes_as_fields(resource.attributes(:property)) fields.delete '_id' b_id = @adapter[resource.class.storage_name].insert fields resource._id = b_id.to_s if resource.instance_variables.include? '@_key' resource.send :remove_instance_variable, :@_key end end.size end Post.create.key ["4e15cab882034dc7f7000002"]
  • 76. def create(resources) resources.collect do |resource| fields = attributes_as_fields(resource.attributes(:property)) fields.delete '_id' b_id = @adapter[resource.class.storage_name].insert fields resource._id = b_id.to_s if resource.instance_variables.include? '@_key' resource.send :remove_instance_variable, :@_key end end.size end Post.create.key
  • 77. Whats left • Aggregation • Native types • DataMapper.logger

Notes de l'éditeur

  1. \n
  2. * Work mostly with backend data transformations from Transactional Database to Reporting datastore\n* When you have a child the blogging slows down\n* Talk quickly when I am nervous, let me know if to fast\n
  3. * About the little ruby Code in the middle\n* Will not focus on either DB OR DM\n
  4. \n
  5. \n
  6. \n
  7. \n
  8. * With the addition of the initialization mostly just CRUD operations\n* CRUD\n
  9. \n
  10. \n
  11. * Raw Access to connection through adapter\n* Persisted through entire instance, so if time out need to reconnect\n
  12. * Raw Access to connection through adapter\n* Persisted through entire instance, so if time out need to reconnect\n
  13. * Raw Access to connection through adapter\n* Persisted through entire instance, so if time out need to reconnect\n
  14. * Raw Access to connection through adapter\n* Persisted through entire instance, so if time out need to reconnect\n
  15. * Raw Access to connection through adapter\n* Persisted through entire instance, so if time out need to reconnect\n
  16. * Raw Access to connection through adapter\n* Persisted through entire instance, so if time out need to reconnect\n
  17. * Raw Access to connection through adapter\n* Persisted through entire instance, so if time out need to reconnect\n
  18. * Raw Access to connection through adapter\n* Persisted through entire instance, so if time out need to reconnect\n
  19. * Raw Access to connection through adapter\n* Persisted through entire instance, so if time out need to reconnect\n
  20. * Raw Access to connection through adapter\n* Persisted through entire instance, so if time out need to reconnect\n
  21. * Raw Access to connection through adapter\n* Persisted through entire instance, so if time out need to reconnect\n
  22. * Raw Access to connection through adapter\n* Persisted through entire instance, so if time out need to reconnect\n
  23. * Raw Access to connection through adapter\n* Persisted through entire instance, so if time out need to reconnect\n
  24. * Raw Access to connection through adapter\n* Persisted through entire instance, so if time out need to reconnect\n
  25. * Raw Access to connection through adapter\n* Persisted through entire instance, so if time out need to reconnect\n
  26. * Raw Access to connection through adapter\n* Persisted through entire instance, so if time out need to reconnect\n
  27. * Raw Access to connection through adapter\n* Persisted through entire instance, so if time out need to reconnect\n
  28. * Raw Access to connection through adapter\n* Persisted through entire instance, so if time out need to reconnect\n
  29. * Raw Access to connection through adapter\n* Persisted through entire instance, so if time out need to reconnect\n
  30. * Raw Access to connection through adapter\n* Persisted through entire instance, so if time out need to reconnect\n
  31. * Raw Access to connection through adapter\n* Persisted through entire instance, so if time out need to reconnect\n
  32. * Raw Access to connection through adapter\n* Persisted through entire instance, so if time out need to reconnect\n
  33. * Raw Access to connection through adapter\n* Persisted through entire instance, so if time out need to reconnect\n
  34. \n
  35. \n
  36. \n
  37. \n
  38. \n
  39. \n
  40. \n
  41. \n
  42. \n
  43. \n
  44. \n
  45. \n
  46. \n
  47. \n
  48. \n
  49. \n
  50. \n
  51. \n
  52. \n
  53. \n
  54. \n
  55. \n
  56. \n
  57. \n
  58. \n
  59. \n
  60. \n
  61. \n
  62. \n
  63. \n
  64. \n
  65. \n
  66. \n
  67. \n
  68. \n
  69. \n
  70. \n
  71. \n
  72. \n
  73. * Association - subclass of DataMapper::Associations::*::Relationship\n* Field - subclass of DataMapper::Property\n
  74. * Association - subclass of DataMapper::Associations::*::Relationship\n* Field - subclass of DataMapper::Property\n
  75. * Association - subclass of DataMapper::Associations::*::Relationship\n* Field - subclass of DataMapper::Property\n
  76. * Association - subclass of DataMapper::Associations::*::Relationship\n* Field - subclass of DataMapper::Property\n
  77. * Only top level Operation\n* own your own for recursive solution\n
  78. * Only top level Operation\n* own your own for recursive solution\n
  79. * Only top level Operation\n* own your own for recursive solution\n
  80. * Only top level Operation\n* own your own for recursive solution\n
  81. * Only top level Operation\n* own your own for recursive solution\n
  82. * Only top level Operation\n* own your own for recursive solution\n
  83. * Only top level Operation\n* own your own for recursive solution\n
  84. * Only top level Operation\n* own your own for recursive solution\n
  85. * Only top level Operation\n* own your own for recursive solution\n
  86. * Only top level Operation\n* own your own for recursive solution\n
  87. * Only top level Operation\n* own your own for recursive solution\n
  88. * Only top level Operation\n* own your own for recursive solution\n
  89. * Only top level Operation\n* own your own for recursive solution\n
  90. * Only top level Operation\n* own your own for recursive solution\n
  91. * Only top level Operation\n* own your own for recursive solution\n
  92. * Only top level Operation\n* own your own for recursive solution\n
  93. * Only top level Operation\n* own your own for recursive solution\n
  94. * Only top level Operation\n* own your own for recursive solution\n
  95. * Only top level Operation\n* own your own for recursive solution\n
  96. \n
  97. * .field - the repository name\n* .name - the resource name\n* value IS UNMARSHALED \n
  98. * .field - the repository name\n* .name - the resource name\n* value IS UNMARSHALED \n
  99. * .field - the repository name\n* .name - the resource name\n* value IS UNMARSHALED \n
  100. * .field - the repository name\n* .name - the resource name\n* value IS UNMARSHALED \n
  101. * .field - the repository name\n* .name - the resource name\n* value IS UNMARSHALED \n
  102. * .field - the repository name\n* .name - the resource name\n* value IS UNMARSHALED \n
  103. * .field - the repository name\n* .name - the resource name\n* value IS UNMARSHALED \n
  104. * .field - the repository name\n* .name - the resource name\n* value IS UNMARSHALED \n
  105. * .field - the repository name\n* .name - the resource name\n* value IS UNMARSHALED \n
  106. * .field - the repository name\n* .name - the resource name\n* value IS UNMARSHALED \n
  107. * .field - the repository name\n* .name - the resource name\n* value IS UNMARSHALED \n
  108. * .field - the repository name\n* .name - the resource name\n* value IS UNMARSHALED \n
  109. \n
  110. \n
  111. \n
  112. \n
  113. \n
  114. \n
  115. \n
  116. \n
  117. \n
  118. \n
  119. \n
  120. \n
  121. \n
  122. \n
  123. \n
  124. \n
  125. \n
  126. \n
  127. \n
  128. \n
  129. \n
  130. \n
  131. \n
  132. \n
  133. \n
  134. \n
  135. \n
  136. \n
  137. \n
  138. \n
  139. \n
  140. \n
  141. * info - used for logging what you are sending to the repository\n
  142. \n
  143. * The first part of the presentation is the 80 percent that makes the most difference\n* The last (more repository specific) part is the 20 percent\n
  144. * Mongo specific example \n* But demonstrates the process of modifying a models\n
  145. \n
  146. \n
  147. \n
  148. \n
  149. \n
  150. \n
  151. \n
  152. \n
  153. \n
  154. \n
  155. \n
  156. \n
  157. \n
  158. \n
  159. \n
  160. * Be kind log\n* at info log the query parameters that are being passed to repository\n
  161. \n
  162. \n
  163. \n
  164. \n