SlideShare a Scribd company logo
Custom DataMapper
     Adapters
    By Josh Moore (   )
About Me
• Josh Moore

• Optimis Dev

• github.com/joshsmoore

• twitter.com/codingforrent

• www.codingforrent.com

• joshsmoore@gmail.com
DataMapper seams to be losing
 popularity why talk about it?
I enjoy non standard
       things...
It still has features
ActiveRecord/ActiveModel does
                 not...
Try something new...
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

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'})




comments = Comment.all(:body => 'hi')
post_ids = comments.collect { |c| c.post_id }
Post.all(:id => post_ids)
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|
  ...   Array of properties
  case condition.class.to_s
        * property - subclass of DataMapper::Property
        * ex. Post#id
  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)}}
    elseArray of properties
        * property - subclass of DataMapper::Property
...     * ex Coment#post_id
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




              end

More Related Content

What's hot

Tutorial, Part 3: SharePoint 101: Jump-Starting the Developer by Rob Windsor ...
Tutorial, Part 3: SharePoint 101: Jump-Starting the Developer by Rob Windsor ...Tutorial, Part 3: SharePoint 101: Jump-Starting the Developer by Rob Windsor ...
Tutorial, Part 3: SharePoint 101: Jump-Starting the Developer by Rob Windsor ...
SPTechCon
 
Apache pig
Apache pigApache pig
Apache pig
Jigar Parekh
 
Perforce Object and Record Model
Perforce Object and Record Model  Perforce Object and Record Model
Perforce Object and Record Model
Perforce
 
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
Eric Normand
 
Database API, your new friend
Database API, your new friendDatabase API, your new friend
Database API, your new friendkikoalonsob
 
Lithium: The Framework for People Who Hate Frameworks, Tokyo Edition
Lithium: The Framework for People Who Hate Frameworks, Tokyo EditionLithium: The Framework for People Who Hate Frameworks, Tokyo Edition
Lithium: The Framework for People Who Hate Frameworks, Tokyo Edition
Nate Abele
 
GORM
GORMGORM
The State of Lithium
The State of LithiumThe State of Lithium
The State of Lithium
Nate Abele
 
Developer Testing Tools Roundup
Developer Testing Tools RoundupDeveloper Testing Tools Roundup
Developer Testing Tools Roundup
John Ferguson Smart Limited
 
The Zen of Lithium
The Zen of LithiumThe Zen of Lithium
The Zen of Lithium
Nate Abele
 
Bioinformatics p5-bioperlv2014
Bioinformatics p5-bioperlv2014Bioinformatics p5-bioperlv2014
Bioinformatics p5-bioperlv2014
Prof. Wim Van Criekinge
 
DBIx-DataModel v2.0 in detail
DBIx-DataModel v2.0 in detail DBIx-DataModel v2.0 in detail
DBIx-DataModel v2.0 in detail
Laurent Dami
 
Syntactic sugar in Postgre SQL
Syntactic sugar in Postgre SQLSyntactic sugar in Postgre SQL
Syntactic sugar in Postgre SQL
Antony Abramchenko
 
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
Howard Lewis Ship
 
MTDDC 2010.2.5 Tokyo - Brand new API
MTDDC 2010.2.5 Tokyo - Brand new APIMTDDC 2010.2.5 Tokyo - Brand new API
MTDDC 2010.2.5 Tokyo - Brand new APISix Apart KK
 
SPL: The Missing Link in Development
SPL: The Missing Link in DevelopmentSPL: The Missing Link in Development
SPL: The Missing Link in Developmentjsmith92
 
Resource Routing in ExpressionEngine
Resource Routing in ExpressionEngineResource Routing in ExpressionEngine
Resource Routing in ExpressionEngine
MichaelRog
 
Lithium: The Framework for People Who Hate Frameworks
Lithium: The Framework for People Who Hate FrameworksLithium: The Framework for People Who Hate Frameworks
Lithium: The Framework for People Who Hate Frameworks
Nate Abele
 
Array operators
Array operatorsArray operators
Array operators
RamakrishnaChava5
 
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
Michelangelo van Dam
 

What's hot (20)

Tutorial, Part 3: SharePoint 101: Jump-Starting the Developer by Rob Windsor ...
Tutorial, Part 3: SharePoint 101: Jump-Starting the Developer by Rob Windsor ...Tutorial, Part 3: SharePoint 101: Jump-Starting the Developer by Rob Windsor ...
Tutorial, Part 3: SharePoint 101: Jump-Starting the Developer by Rob Windsor ...
 
Apache pig
Apache pigApache pig
Apache pig
 
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
 
Lithium: The Framework for People Who Hate Frameworks, Tokyo Edition
Lithium: The Framework for People Who Hate Frameworks, Tokyo EditionLithium: The Framework for People Who Hate Frameworks, Tokyo Edition
Lithium: The Framework for People Who Hate Frameworks, Tokyo Edition
 
GORM
GORMGORM
GORM
 
The State of Lithium
The State of LithiumThe State of Lithium
The State of Lithium
 
Developer Testing Tools Roundup
Developer Testing Tools RoundupDeveloper Testing Tools Roundup
Developer Testing Tools Roundup
 
The Zen of Lithium
The Zen of LithiumThe Zen of Lithium
The Zen of Lithium
 
Bioinformatics p5-bioperlv2014
Bioinformatics p5-bioperlv2014Bioinformatics p5-bioperlv2014
Bioinformatics p5-bioperlv2014
 
DBIx-DataModel v2.0 in detail
DBIx-DataModel v2.0 in detail DBIx-DataModel v2.0 in detail
DBIx-DataModel v2.0 in detail
 
Syntactic sugar in Postgre SQL
Syntactic sugar in Postgre SQLSyntactic sugar in Postgre SQL
Syntactic sugar in Postgre SQL
 
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
 
MTDDC 2010.2.5 Tokyo - Brand new API
MTDDC 2010.2.5 Tokyo - Brand new APIMTDDC 2010.2.5 Tokyo - Brand new API
MTDDC 2010.2.5 Tokyo - Brand new API
 
SPL: The Missing Link in Development
SPL: The Missing Link in DevelopmentSPL: The Missing Link in Development
SPL: The Missing Link in Development
 
Resource Routing in ExpressionEngine
Resource Routing in ExpressionEngineResource Routing in ExpressionEngine
Resource Routing in ExpressionEngine
 
Lithium: The Framework for People Who Hate Frameworks
Lithium: The Framework for People Who Hate FrameworksLithium: The Framework for People Who Hate Frameworks
Lithium: The Framework for People Who Hate Frameworks
 
Array operators
Array operatorsArray operators
Array operators
 
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
 

Similar to Dm adapter RubyConf.TW

DataMapper
DataMapperDataMapper
DataMapper
Yehuda Katz
 
Spring data iii
Spring data iiiSpring data iii
Spring data iii
명철 강
 
第49回Php勉強会@関東 Datasource
第49回Php勉強会@関東 Datasource第49回Php勉強会@関東 Datasource
第49回Php勉強会@関東 DatasourceKaz Watanabe
 
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
IMC Institute
 
From mysql to MongoDB(MongoDB2011北京交流会)
From mysql to MongoDB(MongoDB2011北京交流会)From mysql to MongoDB(MongoDB2011北京交流会)
From mysql to MongoDB(MongoDB2011北京交流会)Night Sailer
 
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
Fabio Akita
 
Zend Framework Study@Tokyo #2
Zend Framework Study@Tokyo #2Zend Framework Study@Tokyo #2
Zend Framework Study@Tokyo #2
Shinya Ohyanagi
 
Metaprogramovanie #1
Metaprogramovanie #1Metaprogramovanie #1
Metaprogramovanie #1Jano Suchal
 
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
Ben Scofield
 
mongodb-introduction
mongodb-introductionmongodb-introduction
mongodb-introduction
Tse-Ching Ho
 
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
ManageIQ
 
Introducing DataWave
Introducing DataWaveIntroducing DataWave
Introducing DataWave
Data Works MD
 
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
DataWorks Summit
 
Shooting the Rapids
Shooting the RapidsShooting the Rapids
Shooting the Rapids
Maurice Naftalin
 
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
Chetan Khatri
 
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
Jacob Park
 
I Phone On Rails
I Phone On RailsI Phone On Rails
I Phone On Rails
John Wilker
 
Hadoop Integration in Cassandra
Hadoop Integration in CassandraHadoop Integration in Cassandra
Hadoop Integration in Cassandra
Jairam Chandar
 
Tools for Making Machine Learning more Reactive
Tools for Making Machine Learning more ReactiveTools for Making Machine Learning more Reactive
Tools for Making Machine Learning more Reactive
Jeff Smith
 

Similar to Dm adapter RubyConf.TW (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
 
From mysql to MongoDB(MongoDB2011北京交流会)
From mysql to MongoDB(MongoDB2011北京交流会)From mysql to MongoDB(MongoDB2011北京交流会)
From mysql to MongoDB(MongoDB2011北京交流会)
 
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
 
Metaprogramovanie #1
Metaprogramovanie #1Metaprogramovanie #1
Metaprogramovanie #1
 
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
 
mongodb-introduction
mongodb-introductionmongodb-introduction
mongodb-introduction
 
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
 
Introducing DataWave
Introducing DataWaveIntroducing DataWave
Introducing DataWave
 
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
 
Shooting the Rapids
Shooting the RapidsShooting the Rapids
Shooting the Rapids
 
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
 
Jquery 4
Jquery 4Jquery 4
Jquery 4
 
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
 
I Phone On Rails
I Phone On RailsI Phone On Rails
I Phone On Rails
 
Hadoop Integration in Cassandra
Hadoop Integration in CassandraHadoop Integration in Cassandra
Hadoop Integration in Cassandra
 
Tools for Making Machine Learning more Reactive
Tools for Making Machine Learning more ReactiveTools for Making Machine Learning more Reactive
Tools for Making Machine Learning more Reactive
 

Recently uploaded

Essentials of Automations: The Art of Triggers and Actions in FME
Essentials of Automations: The Art of Triggers and Actions in FMEEssentials of Automations: The Art of Triggers and Actions in FME
Essentials of Automations: The Art of Triggers and Actions in FME
Safe Software
 
LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
DanBrown980551
 
By Design, not by Accident - Agile Venture Bolzano 2024
By Design, not by Accident - Agile Venture Bolzano 2024By Design, not by Accident - Agile Venture Bolzano 2024
By Design, not by Accident - Agile Venture Bolzano 2024
Pierluigi Pugliese
 
GraphSummit Singapore | Enhancing Changi Airport Group's Passenger Experience...
GraphSummit Singapore | Enhancing Changi Airport Group's Passenger Experience...GraphSummit Singapore | Enhancing Changi Airport Group's Passenger Experience...
GraphSummit Singapore | Enhancing Changi Airport Group's Passenger Experience...
Neo4j
 
How to Get CNIC Information System with Paksim Ga.pptx
How to Get CNIC Information System with Paksim Ga.pptxHow to Get CNIC Information System with Paksim Ga.pptx
How to Get CNIC Information System with Paksim Ga.pptx
danishmna97
 
Video Streaming: Then, Now, and in the Future
Video Streaming: Then, Now, and in the FutureVideo Streaming: Then, Now, and in the Future
Video Streaming: Then, Now, and in the Future
Alpen-Adria-Universität
 
Why You Should Replace Windows 11 with Nitrux Linux 3.5.0 for enhanced perfor...
Why You Should Replace Windows 11 with Nitrux Linux 3.5.0 for enhanced perfor...Why You Should Replace Windows 11 with Nitrux Linux 3.5.0 for enhanced perfor...
Why You Should Replace Windows 11 with Nitrux Linux 3.5.0 for enhanced perfor...
SOFTTECHHUB
 
Removing Uninteresting Bytes in Software Fuzzing
Removing Uninteresting Bytes in Software FuzzingRemoving Uninteresting Bytes in Software Fuzzing
Removing Uninteresting Bytes in Software Fuzzing
Aftab Hussain
 
Artificial Intelligence for XMLDevelopment
Artificial Intelligence for XMLDevelopmentArtificial Intelligence for XMLDevelopment
Artificial Intelligence for XMLDevelopment
Octavian Nadolu
 
PCI PIN Basics Webinar from the Controlcase Team
PCI PIN Basics Webinar from the Controlcase TeamPCI PIN Basics Webinar from the Controlcase Team
PCI PIN Basics Webinar from the Controlcase Team
ControlCase
 
Monitoring Java Application Security with JDK Tools and JFR Events
Monitoring Java Application Security with JDK Tools and JFR EventsMonitoring Java Application Security with JDK Tools and JFR Events
Monitoring Java Application Security with JDK Tools and JFR Events
Ana-Maria Mihalceanu
 
みなさんこんにちはこれ何文字まで入るの?40文字以下不可とか本当に意味わからないけどこれ限界文字数書いてないからマジでやばい文字数いけるんじゃないの?えこ...
みなさんこんにちはこれ何文字まで入るの?40文字以下不可とか本当に意味わからないけどこれ限界文字数書いてないからマジでやばい文字数いけるんじゃないの?えこ...みなさんこんにちはこれ何文字まで入るの?40文字以下不可とか本当に意味わからないけどこれ限界文字数書いてないからマジでやばい文字数いけるんじゃないの?えこ...
みなさんこんにちはこれ何文字まで入るの?40文字以下不可とか本当に意味わからないけどこれ限界文字数書いてないからマジでやばい文字数いけるんじゃないの?えこ...
名前 です男
 
Observability Concepts EVERY Developer Should Know -- DeveloperWeek Europe.pdf
Observability Concepts EVERY Developer Should Know -- DeveloperWeek Europe.pdfObservability Concepts EVERY Developer Should Know -- DeveloperWeek Europe.pdf
Observability Concepts EVERY Developer Should Know -- DeveloperWeek Europe.pdf
Paige Cruz
 
zkStudyClub - Reef: Fast Succinct Non-Interactive Zero-Knowledge Regex Proofs
zkStudyClub - Reef: Fast Succinct Non-Interactive Zero-Knowledge Regex ProofszkStudyClub - Reef: Fast Succinct Non-Interactive Zero-Knowledge Regex Proofs
zkStudyClub - Reef: Fast Succinct Non-Interactive Zero-Knowledge Regex Proofs
Alex Pruden
 
Epistemic Interaction - tuning interfaces to provide information for AI support
Epistemic Interaction - tuning interfaces to provide information for AI supportEpistemic Interaction - tuning interfaces to provide information for AI support
Epistemic Interaction - tuning interfaces to provide information for AI support
Alan Dix
 
Secstrike : Reverse Engineering & Pwnable tools for CTF.pptx
Secstrike : Reverse Engineering & Pwnable tools for CTF.pptxSecstrike : Reverse Engineering & Pwnable tools for CTF.pptx
Secstrike : Reverse Engineering & Pwnable tools for CTF.pptx
nkrafacyberclub
 
GraphSummit Singapore | Neo4j Product Vision & Roadmap - Q2 2024
GraphSummit Singapore | Neo4j Product Vision & Roadmap - Q2 2024GraphSummit Singapore | Neo4j Product Vision & Roadmap - Q2 2024
GraphSummit Singapore | Neo4j Product Vision & Roadmap - Q2 2024
Neo4j
 
Encryption in Microsoft 365 - ExpertsLive Netherlands 2024
Encryption in Microsoft 365 - ExpertsLive Netherlands 2024Encryption in Microsoft 365 - ExpertsLive Netherlands 2024
Encryption in Microsoft 365 - ExpertsLive Netherlands 2024
Albert Hoitingh
 
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdfFIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
FIDO Alliance
 
Microsoft - Power Platform_G.Aspiotis.pdf
Microsoft - Power Platform_G.Aspiotis.pdfMicrosoft - Power Platform_G.Aspiotis.pdf
Microsoft - Power Platform_G.Aspiotis.pdf
Uni Systems S.M.S.A.
 

Recently uploaded (20)

Essentials of Automations: The Art of Triggers and Actions in FME
Essentials of Automations: The Art of Triggers and Actions in FMEEssentials of Automations: The Art of Triggers and Actions in FME
Essentials of Automations: The Art of Triggers and Actions in FME
 
LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
 
By Design, not by Accident - Agile Venture Bolzano 2024
By Design, not by Accident - Agile Venture Bolzano 2024By Design, not by Accident - Agile Venture Bolzano 2024
By Design, not by Accident - Agile Venture Bolzano 2024
 
GraphSummit Singapore | Enhancing Changi Airport Group's Passenger Experience...
GraphSummit Singapore | Enhancing Changi Airport Group's Passenger Experience...GraphSummit Singapore | Enhancing Changi Airport Group's Passenger Experience...
GraphSummit Singapore | Enhancing Changi Airport Group's Passenger Experience...
 
How to Get CNIC Information System with Paksim Ga.pptx
How to Get CNIC Information System with Paksim Ga.pptxHow to Get CNIC Information System with Paksim Ga.pptx
How to Get CNIC Information System with Paksim Ga.pptx
 
Video Streaming: Then, Now, and in the Future
Video Streaming: Then, Now, and in the FutureVideo Streaming: Then, Now, and in the Future
Video Streaming: Then, Now, and in the Future
 
Why You Should Replace Windows 11 with Nitrux Linux 3.5.0 for enhanced perfor...
Why You Should Replace Windows 11 with Nitrux Linux 3.5.0 for enhanced perfor...Why You Should Replace Windows 11 with Nitrux Linux 3.5.0 for enhanced perfor...
Why You Should Replace Windows 11 with Nitrux Linux 3.5.0 for enhanced perfor...
 
Removing Uninteresting Bytes in Software Fuzzing
Removing Uninteresting Bytes in Software FuzzingRemoving Uninteresting Bytes in Software Fuzzing
Removing Uninteresting Bytes in Software Fuzzing
 
Artificial Intelligence for XMLDevelopment
Artificial Intelligence for XMLDevelopmentArtificial Intelligence for XMLDevelopment
Artificial Intelligence for XMLDevelopment
 
PCI PIN Basics Webinar from the Controlcase Team
PCI PIN Basics Webinar from the Controlcase TeamPCI PIN Basics Webinar from the Controlcase Team
PCI PIN Basics Webinar from the Controlcase Team
 
Monitoring Java Application Security with JDK Tools and JFR Events
Monitoring Java Application Security with JDK Tools and JFR EventsMonitoring Java Application Security with JDK Tools and JFR Events
Monitoring Java Application Security with JDK Tools and JFR Events
 
みなさんこんにちはこれ何文字まで入るの?40文字以下不可とか本当に意味わからないけどこれ限界文字数書いてないからマジでやばい文字数いけるんじゃないの?えこ...
みなさんこんにちはこれ何文字まで入るの?40文字以下不可とか本当に意味わからないけどこれ限界文字数書いてないからマジでやばい文字数いけるんじゃないの?えこ...みなさんこんにちはこれ何文字まで入るの?40文字以下不可とか本当に意味わからないけどこれ限界文字数書いてないからマジでやばい文字数いけるんじゃないの?えこ...
みなさんこんにちはこれ何文字まで入るの?40文字以下不可とか本当に意味わからないけどこれ限界文字数書いてないからマジでやばい文字数いけるんじゃないの?えこ...
 
Observability Concepts EVERY Developer Should Know -- DeveloperWeek Europe.pdf
Observability Concepts EVERY Developer Should Know -- DeveloperWeek Europe.pdfObservability Concepts EVERY Developer Should Know -- DeveloperWeek Europe.pdf
Observability Concepts EVERY Developer Should Know -- DeveloperWeek Europe.pdf
 
zkStudyClub - Reef: Fast Succinct Non-Interactive Zero-Knowledge Regex Proofs
zkStudyClub - Reef: Fast Succinct Non-Interactive Zero-Knowledge Regex ProofszkStudyClub - Reef: Fast Succinct Non-Interactive Zero-Knowledge Regex Proofs
zkStudyClub - Reef: Fast Succinct Non-Interactive Zero-Knowledge Regex Proofs
 
Epistemic Interaction - tuning interfaces to provide information for AI support
Epistemic Interaction - tuning interfaces to provide information for AI supportEpistemic Interaction - tuning interfaces to provide information for AI support
Epistemic Interaction - tuning interfaces to provide information for AI support
 
Secstrike : Reverse Engineering & Pwnable tools for CTF.pptx
Secstrike : Reverse Engineering & Pwnable tools for CTF.pptxSecstrike : Reverse Engineering & Pwnable tools for CTF.pptx
Secstrike : Reverse Engineering & Pwnable tools for CTF.pptx
 
GraphSummit Singapore | Neo4j Product Vision & Roadmap - Q2 2024
GraphSummit Singapore | Neo4j Product Vision & Roadmap - Q2 2024GraphSummit Singapore | Neo4j Product Vision & Roadmap - Q2 2024
GraphSummit Singapore | Neo4j Product Vision & Roadmap - Q2 2024
 
Encryption in Microsoft 365 - ExpertsLive Netherlands 2024
Encryption in Microsoft 365 - ExpertsLive Netherlands 2024Encryption in Microsoft 365 - ExpertsLive Netherlands 2024
Encryption in Microsoft 365 - ExpertsLive Netherlands 2024
 
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdfFIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
 
Microsoft - Power Platform_G.Aspiotis.pdf
Microsoft - Power Platform_G.Aspiotis.pdfMicrosoft - Power Platform_G.Aspiotis.pdf
Microsoft - Power Platform_G.Aspiotis.pdf
 

Dm adapter RubyConf.TW

  • 1. Custom DataMapper Adapters By Josh Moore ( )
  • 2. About Me • Josh Moore • Optimis Dev • github.com/joshsmoore • twitter.com/codingforrent • www.codingforrent.com • joshsmoore@gmail.com
  • 3.
  • 4. DataMapper seams to be losing popularity why talk about it?
  • 5. I enjoy non standard things...
  • 6. It still has features ActiveRecord/ActiveModel does not...
  • 8. 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
  • 9.
  • 10. Terms term meaning Resource A model field A property on a model Repository DataMapper term for the storage engine
  • 11.
  • 12. 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
  • 13.
  • 14.
  • 15. Symbol Hash def initialize(name, options) end
  • 16. def initialize(name, options) Just do it super end
  • 18. Connect to your def initialize(name, options) adapter super @conn = Mongo::Connection.new( options[:host], options[:port]) @adapter = @conn[options[:database]] end
  • 19. 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
  • 20. 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
  • 21. 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
  • 22.
  • 23.
  • 24. Array of Resources def create(resources) end Return number of resources created
  • 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
  • 27. 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"}
  • 28. 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
  • 29. 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
  • 30.
  • 31.
  • 32. DataMapper::Query def read(query) end Return a Array of Hashes key: field name value: unmarshed value {field_name => value}
  • 33. def read(query) conditions = parse_query_conditions(query) @adapter[query.model.storage_name].find( conditions) end
  • 34. Query Structure DataMapper::Query #conditions Operation #operands Set Operation Condition Array #subject Field Association
  • 35. Query Structure DataMapper::Query #conditions Operation #operands Set Operation Condition Array #subject Field Association :conditions => ["updated_at > ?", Time.now]
  • 36. 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}}
  • 37. 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}}
  • 38.
  • 39. DataMapper::Query def parse_query_conditions(query) mongo_conditions = {} Return a hash mongo_conditions
  • 40. 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
  • 41. 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
  • 42. 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
  • 43. 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
  • 44. Post.all(:comments => {:body => 'hi'}) comments = Comment.all(:body => 'hi') post_ids = comments.collect { |c| c.post_id } Post.all(:id => post_ids)
  • 45. 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 ...
  • 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| ... Array of properties case condition.class.to_s * property - subclass of DataMapper::Property * ex. Post#id 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)}} elseArray of properties * property - subclass of DataMapper::Property ... * ex Coment#post_id
  • 48. 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 ...
  • 49. 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 ...
  • 50. 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 ...
  • 52. 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
  • 53. What is not covered • Nested Operands
  • 54. 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
  • 55.
  • 56. def delete(resources) conditions = parse_query_conditions(resources.query) record_count = read(resources.query).count @adapter[resources.storage_name].remove(conditions) record_count end
  • 57. 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)
  • 58. 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
  • 59.
  • 60. 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
  • 61. 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)
  • 62. 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
  • 63. Be Kind log • DataMapper.logger
  • 64. You can stop now end

Editor's Notes

  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. \n
  4. \n
  5. * About the little ruby Code in the middle\n* Will not focus on either DB OR DM\n
  6. * last commit was almost a month ago\n* It is true\n* ActiveRecord lots of improvements\n
  7. \n
  8. \n
  9. * Associations across multiple repositories\n
  10. * &amp;#x738B;&amp;#x5EFA;&amp;#x8208; talked about picking different things from different languages... Why not learn different ORMs to?\n
  11. \n
  12. * xdite will think it is stupid\n
  13. \n
  14. * With the addition of the initialization mostly just CRUD operations\n* CRUD\n
  15. \n
  16. \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. * Raw Access to connection through adapter\n* Persisted through entire instance, so if time out need to reconnect\n
  35. * Raw Access to connection through adapter\n* Persisted through entire instance, so if time out need to reconnect\n
  36. * Raw Access to connection through adapter\n* Persisted through entire instance, so if time out need to reconnect\n
  37. * Raw Access to connection through adapter\n* Persisted through entire instance, so if time out need to reconnect\n
  38. * Raw Access to connection through adapter\n* Persisted through entire instance, so if time out need to reconnect\n
  39. * Raw Access to connection through adapter\n* Persisted through entire instance, so if time out need to reconnect\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. \n
  74. \n
  75. \n
  76. \n
  77. \n
  78. \n
  79. * Association - subclass of DataMapper::Associations::*::Relationship\n* Field - subclass of DataMapper::Property\n
  80. * Association - subclass of DataMapper::Associations::*::Relationship\n* Field - subclass of DataMapper::Property\n
  81. * Association - subclass of DataMapper::Associations::*::Relationship\n* Field - subclass of DataMapper::Property\n
  82. * Association - subclass of DataMapper::Associations::*::Relationship\n* Field - subclass of DataMapper::Property\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. * Only top level Operation\n* own your own for recursive solution\n
  97. * Only top level Operation\n* own your own for recursive solution\n
  98. * Only top level Operation\n* own your own for recursive solution\n
  99. * Only top level Operation\n* own your own for recursive solution\n
  100. * Only top level Operation\n* own your own for recursive solution\n
  101. * Only top level Operation\n* own your own for recursive solution\n
  102. \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. * .field - the repository name\n* .name - the resource name\n* value IS UNMARSHALED \n
  110. * .field - the repository name\n* .name - the resource name\n* value IS UNMARSHALED \n
  111. * .field - the repository name\n* .name - the resource name\n* value IS UNMARSHALED \n
  112. * .field - the repository name\n* .name - the resource name\n* value IS UNMARSHALED \n
  113. * .field - the repository name\n* .name - the resource name\n* value IS UNMARSHALED \n
  114. * .field - the repository name\n* .name - the resource name\n* value IS UNMARSHALED \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. \n
  142. \n
  143. \n
  144. \n
  145. \n
  146. \n
  147. * info - used for logging what you are sending to the repository\n
  148. \n
  149. * 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
  150. * Mongo specific example \n* But demonstrates the process of modifying a models\n
  151. \n
  152. \n
  153. \n
  154. \n
  155. \n
  156. \n
  157. \n
  158. \n
  159. \n
  160. \n
  161. \n
  162. \n
  163. \n
  164. \n
  165. \n
  166. * Be kind log\n* at info log the query parameters that are being passed to repository\n* Mongo supports Array and Hash natively\n
  167. \n
  168. \n
  169. \n
  170. \n
  171. \n