DataMapper

  • 20,940 views
Uploaded on

Learn all about the state of DataMapper.

Learn all about the state of DataMapper.

More in: Technology , Business
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
No Downloads

Views

Total Views
20,940
On Slideshare
0
From Embeds
0
Number of Embeds
3

Actions

Shares
Downloads
373
Comments
3
Likes
36

Embeds 0

No embeds

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
    No notes for slide

Transcript

  • 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>