Upload
paul-klipp
View
1.060
Download
1
Embed Size (px)
DESCRIPTION
Piotr's presentation on Datamapper and Merb at the Krakow Ruby User Group
Citation preview
BYPIOTR SOLNICA
Plan Prezentacji
1. Istniejące Implementacje ORM2. Architektura
1. Repozytoria2. Adaptery3. Zasoby
3. Podstawy4. Key Features 5. Status projektu
2
November 19, 2008© Piotr Solnica
DataMapper3
Istniejące Implementacje ORM
November 19, 2008© Piotr Solnica
Istniejące Implementacje ORM4
ActiveRecord & Sequel
November 19, 2008© Piotr Solnica
Istniejące Implementacje ORM5
Po co trzeci zawodnik…?
November 19, 2008© Piotr Solnica
Istniejące Implementacje ORM6
ActiveRecord:
• Kiepska architektura – obsługuje tylko relacyjne bazy danych i do tego nie wie czym jest klucz złożony…
• Dużo wtyczek, przy czym każdy update powoduje, że połowa przestaje działać
• Szybki kosztem pamięci• Frustrujące API!
November 19, 2008© Piotr Solnica
Istniejące Implementacje ORM7
Sequel:
• Trochę lepszy ActiveRecord
November 19, 2008© Piotr Solnica
Istniejące implementacje ORM8
November 19, 2008© Piotr Solnica
Istniejące Implementacje ORM9
Poza tym wszystkim…
November 19, 2008© Piotr Solnica
Istniejące Implementacje ORM10
…ActiveRecord & Sequel używają…
November 19, 2008© Piotr Solnica
Istniejące Implementacje ORM11
MIGRACJI!
November 19, 2008© Piotr Solnica
Istniejące Implementacje ORM12
DataMapper
November 19, 2008© Piotr Solnica
DataMapper13
Architektura
November 19, 2008© Piotr Solnica
DataMapper / Architektura14
Repozytoria
MySQL
CauchDB
SimpleDB
Adaptery Zasoby
November 19, 2008© Piotr Solnica
DataMapper / Architektura 15
Repozytoria
November 19, 2008© Piotr Solnica
DataMapper / Architektura / Repozytoria
16
Repozytoria są to źródła danych, na przykład:
• relacyjne bazy danych (doooh!)• obiektowe bazy danych• systemy plików• YAML, JSON, XML itd.• Amazon SimpleDB• REST-based
November 19, 2008© Piotr Solnica
DataMapper / Architektura / Repozytoria
17
Każdy system udostępniający dane za
pomocą swojego interfejsu może stać się repozytorium
DataMappera
November 19, 2008© Piotr Solnica
DataMapper / Architektura 18
Adaptery
November 19, 2008© Piotr Solnica
DataMapper / Architektura / Adaptery19
Adaptery zapewniają transparentny dostęp do danych z repozytoriów
November 19, 2008© Piotr Solnica
DataMapper / Architektura / Adaptery20
Istniejące adaptery:• MySQL / Postgres / SQLite• YAML• CSV• CouchDB• Amazon SimpleDB• Ferret• IMAP• …masa innych under development
November 19, 2008© Piotr Solnica
DataMapper / Architetura21
Zasoby
November 19, 2008© Piotr Solnica
DataMapper / Architektura / Zasoby22
Zasoby reprezentują dane z repozytoriów, za ich
pośrednictwem wykonujemy operacje CRUD
November 19, 2008© Piotr Solnica
DataMapper / Architektura / Zasoby23
Każdy zasób charakteryzuje się różnymi własnościami,
przy czym własności te mogą być związane z różnymi
repozytoriami…
November 19, 2008© Piotr Solnica
DataMapper / Architektura / Zasoby24
…to my decydujemy jakie własności zasobów nas
interesują, a nie zautomatyzowany do bólu
ORM!
November 19, 2008© Piotr Solnica
DataMapper / Architektura / Zasoby25
Pomiędzy zasobami mogą istnieć powiązania typowe dla relacyjnych baz danych (one-
to-one, one-to-many etc.)
November 19, 2008© Piotr Solnica
DataMapper26
Podstawy
November 19, 2008© Piotr Solnica
DataMapper / Podstawy27
dm-core & dm-more
November 19, 2008© Piotr Solnica
DataMapper / Podstawy28
Trzy poziomy API:
• public• semi-public• private
November 19, 2008© Piotr Solnica
DataMapper / Podstawy29
Własności modelu deklaruje się na poziomie jego klasy!
class Zoo include DataMapper::Resource property :id, Serial property :name, Stringend
November 19, 2008© Piotr Solnica
DataMapper / Podstawy30
Relacjeclass Zoo include DataMapper::Resource
property :id, Serial property :name, String
has n, :animals has 1..10, :young_animals, :class_name => ‘Animal’, :age => 1..3end
class Animal include DataMapper::Resource
property :id, Serial property :name, String property :age, Integer
belongs_to :zooend
November 19, 2008© Piotr Solnica
DataMapper / Podstawy31
Automigracje
Zoo.auto_migrate!Zoo.auto_upgrade!
November 19, 2008© Piotr Solnica
DataMapper / Podstawy32
Tworzenie nowych zasobów
some_zoo = Zoo.create(:name => ‘Some Zoo’)
some_zoo.animals.create(:name => ‘Marty’)
another_zoo = Zoo.new(:name => ‘Another Zoo’)
another_animal = Animal.new( :name => ‘Alex’, :zoo => another_zoo)
another_zoo.saveanother_animal.save
November 19, 2008© Piotr Solnica
DataMapper / Podstawy33
Pobieranie zasobów
zoo = Zoo.get(1)
zoo.animals.get(1)
zoo = Zoo.first(:name => ‘Some Zoo’)
zoo.animals.all(:name => ‘Marty’)
November 19, 2008© Piotr Solnica
DataMapper / Podstawy34
Callbacks
class Zoo include DataMapper::Resource
property :id, Serial property :name, String
before :save do name = ‘Default Name’ if name.blank? endend
November 19, 2008© Piotr Solnica
DataMapper35
Key Features
November 19, 2008© Piotr Solnica
DataMapper / Key Features36
IdentityMap
repository do marty1 = Zoo.get(1) marty2 = Zoo.get(1)
marty1.object_id == marty2.object_id # trueend
November 19, 2008© Piotr Solnica
DataMapper / Key Features37
Animal.create(:name => ‘Marty’, :age => 12)
marty = Animal.first(:name => 'Marty')
marty.attribute_dirty?(:age) # false
marty.age = 21
marty.attribute_dirty?(:age) # false
marty.save # UPDATE `animals` SET `age` = 21 WHERE (`id` = 1)
Dirty Properties Tracking
November 19, 2008© Piotr Solnica
DataMapper / Key Features38
class Zoo include DataMapper::Resource
property :id, Serial property :description, Textend
Zoo.create(:description => ‘This is a very nice zoo’)
# SELECT `id` FROM `zoos` WHERE (`id` = 1) ORDER BY `id` LIMIT 1zoo = Zoo.get(zoo1.id)
# SELECT `description`, `id` FROM `zoos` WHERE (`id` = 1) ORDER BY `id`zoo.description
Lazy Loading
November 19, 2008© Piotr Solnica
DataMapper / Key Features39
zoos = Zoo.all # nie wykonuje się żadne zapytanie!
zoos.each do |zoo| # dopiero tutaj zostaną pobrane wszystkie zoo zoo.animals.each do |animal| # a tutaj wszystkie animals należące do zoos! puts "Animal #{animal.name} from #{zoo.name}" end
end
Strategic Eager Loading
November 19, 2008© Piotr Solnica
DataMapper / Key Features40
class Zoo include DataMapper::Resource
property :id, Serialend
class Cage include DataMapper::Resource
property :id, Serialend
class Animal include DataMapper::Resource
property :zoo_id, :key => true property :cage_id, :key => trueend
Composite Keys
November 19, 2008© Piotr Solnica
DataMapper / Key Features41
zoo = Zoo.create
cage = Cage.create(:zoo => zoo)
Animal.create(:zoo => zoo, :cage => cage)
animal = Animal.get(zoo.id, cage.id)
Composite Keys
November 19, 2008© Piotr Solnica
DataMapper / Key Features42
class Zoo include DataMapper::Resource
property :id, Serial property :name, String, :length => 12..64end
zoo = Zoo.new(:name => ‘Too short’)
# ["Name must be between 12 and 64 characters long"]zoo.errors[:name]
Auto-Validations
November 19, 2008© Piotr Solnica
DataMapper / Key Features43
class Article include DataMapper::Resource property :id, Serial property :title, String property :body, Text validates_present :title, :when => [:publish] validates_length :body, :minimum => 1000, :when => [:publish]end
article = Article.new
article.valid_for_publish? # falsearticle.title = 'Hello World'article.valid_for_publish? # falsearticle.body = '...some 1000 chars text...'article.valid_for_publish? # true!
Contextual Validations
November 19, 2008© Piotr Solnica
DataMapper / Key Features44
class User include DataMapper::Resource
property :id, Serial property :postal_code, PostalCodeend
user = User.new(:postal_code => '12-34')
user.valid? # falseuser.errors[:postal_code] # ["Postal code has an invalid format"]
user.postal_code = '12-345'
user.valid? # true
Custom Data Types
November 19, 2008© Piotr Solnica
DataMapper / Key Features45
module DataMapper module Types class PostalCode < DataMapper::Type primitive String format(/^\d{2}\-\d{3}$/) end endend
Custom Data Types
November 19, 2008© Piotr Solnica
DataMapper46
Status Projektu
November 19, 2008© Piotr Solnica
DataMapper / Status Projektu47
CURRENT VERSION: 0.9.6
November 19, 2008© Piotr Solnica
DataMapper48
Pytania?
November 19, 2008© Piotr Solnica
DataMapper49
Dziękuję
November 19, 2008© Piotr Solnica