DataMapper

25,341 views
24,328 views

Published on

Learn all about the state of DataMapper.

Published in: Technology, Business
3 Comments
36 Likes
Statistics
Notes
No Downloads
Views
Total views
25,341
On SlideShare
0
From Embeds
0
Number of Embeds
752
Actions
Shares
0
Downloads
374
Comments
3
Likes
36
Embeds 0
No embeds

No notes for slide

DataMapper

  1. datamapper the persistence framework
  2. who am I?
  3. (Booth 501)
  4. DataMapper
  5. datamapper
  6. object relational mapper
  7. like activerecord
  8. like activerecord ★ DB adapters ★ many-to-many ★ migrations ★ -through ★ associations ★ polymorphic ★ one-to-one ★ lifecycle events ★ one-to-many ★ sti ★ many-to-one ★ etc.
  9. drops into Rails 1.0
  10. (or merb) 0.9
  11. architecture Application Merb Rails DataMapper Adapters DO.rb YAML IMAP Data Stores
  12. some caveats
  13. work in progress 0.9 1.0
  14. be prepared for code
  15. why did we build it?
  16. identity map
  17. Foo[1] Foo id = 1 Foo[1] ...
  18. foo[1] == foo[1] #=> true
  19. loadedset
  20. foo.all Foo Foo Foo Foo Foo Foo id = 1 id = 2 id = 3 id = 4 id = 5 id = 6 ... ... ... ... ... ... LoadedSet
  21. composite keys
  22. belongs_to :project, :child_key => [:name, :tag]
  23. legacy data
  24. naming conventions (yours)
  25. naming conventions underscored foo::barBaz => foo/bar_baz
  26. naming conventions underscoredandpluralized foo::barBaz => foo_bar_bazs
  27. naming conventions underscoredandpluralizedwithoutmodule foo::barBaz => bazs
  28. naming conventions yaml foo::Bar => foo/bars.yaml
  29. support for multiple databases (even in the same model)
  30. Post.all(:repository => :legacy) Post.all # :repository => :default
  31. prepared statements 1.0
  32. custom types
  33. embedded values 1.0
  34. Employments Employment id: int id<Integer> person_id: int person<Person> start: date end: date start<Date> salary_amt: dec end<Date> salary_cur: char salary<Money>
  35. declared properties property :id, :key => true
  36. robust queries
  37. Child.all( “mother.last_name.like” => “Jane%”, :name.like => “Jim” )
  38. dirty tracking
  39. modularity
  40. unified interface for drivers
  41. •connections • commands • readers • cursors (forward-only) • quoting • transactions
  42. Connection Connection Connection Connection Connection Connection Pool create_command “select * from foos where id = ?” Command execute_reader Reader next values next ... execute_reader(12) => select * from foos where id = 12
  43. works today on: mysql, sqlite, postgres
  44. fast, written in C
  45. simple interface for adapters
  46. •read by key • read by query • update by key • update set • delete • (optional: transactions)
  47. salesforce adapter in 200 LOC
  48. Errors Operators Naming Conventions ~/.salesforce Build Query Load Result Set Similar CRUD Demo
  49. what does it look like?
  50. Zoo.all( :age.gt => 30, :name.not => [“bob”, “jones”] )
  51. SELECT “age”, “name”, “description” FROM “zoos” WHERE (“age” > 30) AND (“name” NOT IN (“bob”, “jones”))
  52. Zoo.first.eql? Zoo.first #=> true
  53. Zoo.all.map {|x| x.animals } how many queries? 2
  54. we call this strategic eager loading.
  55. lazy loading
  56. class Post include DataMapper::Resource property :id, Fixnum, :serial => true property :title, String property :body, Text, :lazy => true end
  57. posts = Post.all SELECT “id”, “title” FROM “posts”
  58. return two objects ids 1 and 2
  59. posts.first.body SELECT “body” FROM “posts” WHERE (“id” IN (1,2))
  60. posts.map{|x| x.body} SELECT “body” FROM “posts” WHERE (“id” IN (1,2))
  61. lazy loaded grouping
  62. class Post include DataMapper::Resource property :id, Fixnum, :serial => true property :title, String, :lazy => [:details] property :body, Text, :lazy => [:details] end
  63. you can go off the golden path
  64. class Post include DataMapper::Resource property :title, String repository(:legacy) do property :title, String, :field => “T1tLz” end end
  65. Post.all(:repository => :legacy) repository(:legacy) do Post.all end
  66. Post.all Post.all(:repository => :default) repository(:default) do Post.all end
  67. naming conventions repository(:legacy).adapter. resource_naming_convention = DM:: NamingConventions:: Underscored AndPluralized
  68. naming conventions repository(:legacy).adapter. resource_naming_convention = lambda do |klass| “tbl#{klass.camel_case}” end
  69. default repository class Post include DataMapper::Resource def self.default_repository_name :legacy end end
  70. import data Post.copy(:legacy, :default) Post.copy(:legacy, :default, :created_at.gt => Date.today - 365) 1.0
  71. import data class Post property :title, String repository(:legacy) do property :title, String, :field => “TIT13” end end
  72. custom types
  73. primitives Trueclass, string, text, float, fixnum, bigdecimal, datetime, date, object, class
  74. custom types class Post include DataMapper::Resource property :title, String property :author, FullName property :details, Csv end
  75. class FullName < DM::Type primitive String size 100 def self.load(str) str.split(“, ”).reverse end def self.dump(ary) ary.reverse.join(“, ”) end end
  76. class Csv < DM::Type primitive String size 65355 def self.load(str) FasterCSV.parse(value) end def self.dump(ary) FasterCSV.generate do |csv| ary.each {|line| csv << line} end end end
  77. Post.create!( :title => “New Post”, :author => [“Yehuda”, “Katz”], :metadata => [ [“Some”, “Sample”, “Data”], [“More”, “Sample”, “Data”] ] )
  78. in the database Title “New Post” Author “Katz, Yehuda” “Some,Sample,Datan Metadata More,Sample,Datan”
  79. and it’s lazy-parsed
  80. custom stores
  81. stores are uris
  82. mysql://user@localhost
  83. setting up DataMapper.setup( :default, “mysql://user@localhost” )
  84. database.yml development: default: adapter: mysql database: app_dev user: person password: sekrit
  85. database.yml legacy: adapter: sqlite3 database: config/l3g.db
  86. yaml:///fixtures 1.0
  87. ssh+yaml:// fixtures.engineyard.com/ fixtures 1+
  88. database.yml test: default: adapter: yaml database: app_test.db legacy: adapter: yaml database: l3g_test.db
  89. making fixtures Post.copy(:default, :fixtures) rake db:copy_fixtures
  90. validations
  91. class Product include DataMapper::Resource property :title, String property :price, String, validates_length_of :nullable => false, :validation_context => validates_presence_of :purchase end valid_for_purchase?
  92. class Product include DataMapper::Resource property :title, String property :number, String, :format => /d{3}-[a-zA-Z]{9}-0/ end validates_format_of
  93. class Product include DataMapper::Resource property :title, String property :number, String, :format => proc {|n| n.split(“-”).size == 2} validates_format_of end
  94. class Product include DataMapper::Resource property :title, String property :number, String, :length => 2..10, :validation_context => validates_length_of :import valid_for_import? save(:import) end
  95. class Product include DataMapper::Resource property :title, String property :number, String, validates_length_of :number, :in => (2..10), :when => :import end valid_for_import?
  96. thank you.
  97. any questions?
  98. </railsconf>

×