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
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
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
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
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
...
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
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
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
* 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
\n
\n
* About the little ruby Code in the middle\n* Will not focus on either DB OR DM\n
* last commit was almost a month ago\n* It is true\n* ActiveRecord lots of improvements\n
\n
\n
* Associations across multiple repositories\n
* &#x738B;&#x5EFA;&#x8208; talked about picking different things from different languages... Why not learn different ORMs to?\n
\n
* xdite will think it is stupid\n
\n
* With the addition of the initialization mostly just CRUD operations\n* CRUD\n
\n
\n
* Raw Access to connection through adapter\n* Persisted through entire instance, so if time out need to reconnect\n
* Raw Access to connection through adapter\n* Persisted through entire instance, so if time out need to reconnect\n
* Raw Access to connection through adapter\n* Persisted through entire instance, so if time out need to reconnect\n
* Raw Access to connection through adapter\n* Persisted through entire instance, so if time out need to reconnect\n
* Raw Access to connection through adapter\n* Persisted through entire instance, so if time out need to reconnect\n
* Raw Access to connection through adapter\n* Persisted through entire instance, so if time out need to reconnect\n
* Raw Access to connection through adapter\n* Persisted through entire instance, so if time out need to reconnect\n
* Raw Access to connection through adapter\n* Persisted through entire instance, so if time out need to reconnect\n
* Raw Access to connection through adapter\n* Persisted through entire instance, so if time out need to reconnect\n
* Raw Access to connection through adapter\n* Persisted through entire instance, so if time out need to reconnect\n
* Raw Access to connection through adapter\n* Persisted through entire instance, so if time out need to reconnect\n
* Raw Access to connection through adapter\n* Persisted through entire instance, so if time out need to reconnect\n
* Raw Access to connection through adapter\n* Persisted through entire instance, so if time out need to reconnect\n
* Raw Access to connection through adapter\n* Persisted through entire instance, so if time out need to reconnect\n
* Raw Access to connection through adapter\n* Persisted through entire instance, so if time out need to reconnect\n
* Raw Access to connection through adapter\n* Persisted through entire instance, so if time out need to reconnect\n
* Raw Access to connection through adapter\n* Persisted through entire instance, so if time out need to reconnect\n
* Raw Access to connection through adapter\n* Persisted through entire instance, so if time out need to reconnect\n
* Raw Access to connection through adapter\n* Persisted through entire instance, so if time out need to reconnect\n
* Raw Access to connection through adapter\n* Persisted through entire instance, so if time out need to reconnect\n
* Raw Access to connection through adapter\n* Persisted through entire instance, so if time out need to reconnect\n
* Raw Access to connection through adapter\n* Persisted through entire instance, so if time out need to reconnect\n
* Raw Access to connection through adapter\n* Persisted through entire instance, so if time out need to reconnect\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
* Association - subclass of DataMapper::Associations::*::Relationship\n* Field - subclass of DataMapper::Property\n
* Association - subclass of DataMapper::Associations::*::Relationship\n* Field - subclass of DataMapper::Property\n
* Association - subclass of DataMapper::Associations::*::Relationship\n* Field - subclass of DataMapper::Property\n
* Association - subclass of DataMapper::Associations::*::Relationship\n* Field - subclass of DataMapper::Property\n
* Only top level Operation\n* own your own for recursive solution\n
* Only top level Operation\n* own your own for recursive solution\n
* Only top level Operation\n* own your own for recursive solution\n
* Only top level Operation\n* own your own for recursive solution\n
* Only top level Operation\n* own your own for recursive solution\n
* Only top level Operation\n* own your own for recursive solution\n
* Only top level Operation\n* own your own for recursive solution\n
* Only top level Operation\n* own your own for recursive solution\n
* Only top level Operation\n* own your own for recursive solution\n
* Only top level Operation\n* own your own for recursive solution\n
* Only top level Operation\n* own your own for recursive solution\n
* Only top level Operation\n* own your own for recursive solution\n
* Only top level Operation\n* own your own for recursive solution\n
* Only top level Operation\n* own your own for recursive solution\n
* Only top level Operation\n* own your own for recursive solution\n
* Only top level Operation\n* own your own for recursive solution\n
* Only top level Operation\n* own your own for recursive solution\n
* Only top level Operation\n* own your own for recursive solution\n
* Only top level Operation\n* own your own for recursive solution\n
\n
* .field - the repository name\n* .name - the resource name\n* value IS UNMARSHALED \n
* .field - the repository name\n* .name - the resource name\n* value IS UNMARSHALED \n
* .field - the repository name\n* .name - the resource name\n* value IS UNMARSHALED \n
* .field - the repository name\n* .name - the resource name\n* value IS UNMARSHALED \n
* .field - the repository name\n* .name - the resource name\n* value IS UNMARSHALED \n
* .field - the repository name\n* .name - the resource name\n* value IS UNMARSHALED \n
* .field - the repository name\n* .name - the resource name\n* value IS UNMARSHALED \n
* .field - the repository name\n* .name - the resource name\n* value IS UNMARSHALED \n
* .field - the repository name\n* .name - the resource name\n* value IS UNMARSHALED \n
* .field - the repository name\n* .name - the resource name\n* value IS UNMARSHALED \n
* .field - the repository name\n* .name - the resource name\n* value IS UNMARSHALED \n
* .field - the repository name\n* .name - the resource name\n* value IS UNMARSHALED \n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
* info - used for logging what you are sending to the repository\n
\n
* 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
* Mongo specific example \n* But demonstrates the process of modifying a models\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
* Be kind log\n* at info log the query parameters that are being passed to repository\n* Mongo supports Array and Hash natively\n