rpbertp13-dm-core 0.9.11.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.autotest +26 -0
- data/.gitignore +18 -0
- data/CONTRIBUTING +51 -0
- data/FAQ +92 -0
- data/History.txt +52 -0
- data/MIT-LICENSE +22 -0
- data/Manifest.txt +130 -0
- data/QUICKLINKS +11 -0
- data/README.txt +143 -0
- data/Rakefile +32 -0
- data/SPECS +62 -0
- data/TODO +1 -0
- data/dm-core.gemspec +40 -0
- data/lib/dm-core.rb +217 -0
- data/lib/dm-core/adapters.rb +16 -0
- data/lib/dm-core/adapters/abstract_adapter.rb +209 -0
- data/lib/dm-core/adapters/data_objects_adapter.rb +716 -0
- data/lib/dm-core/adapters/in_memory_adapter.rb +87 -0
- data/lib/dm-core/adapters/mysql_adapter.rb +138 -0
- data/lib/dm-core/adapters/postgres_adapter.rb +189 -0
- data/lib/dm-core/adapters/sqlite3_adapter.rb +105 -0
- data/lib/dm-core/associations.rb +207 -0
- data/lib/dm-core/associations/many_to_many.rb +147 -0
- data/lib/dm-core/associations/many_to_one.rb +107 -0
- data/lib/dm-core/associations/one_to_many.rb +315 -0
- data/lib/dm-core/associations/one_to_one.rb +61 -0
- data/lib/dm-core/associations/relationship.rb +221 -0
- data/lib/dm-core/associations/relationship_chain.rb +81 -0
- data/lib/dm-core/auto_migrations.rb +105 -0
- data/lib/dm-core/collection.rb +670 -0
- data/lib/dm-core/dependency_queue.rb +32 -0
- data/lib/dm-core/hook.rb +11 -0
- data/lib/dm-core/identity_map.rb +42 -0
- data/lib/dm-core/is.rb +16 -0
- data/lib/dm-core/logger.rb +232 -0
- data/lib/dm-core/migrations/destructive_migrations.rb +17 -0
- data/lib/dm-core/migrator.rb +29 -0
- data/lib/dm-core/model.rb +526 -0
- data/lib/dm-core/naming_conventions.rb +84 -0
- data/lib/dm-core/property.rb +676 -0
- data/lib/dm-core/property_set.rb +169 -0
- data/lib/dm-core/query.rb +676 -0
- data/lib/dm-core/repository.rb +167 -0
- data/lib/dm-core/resource.rb +671 -0
- data/lib/dm-core/scope.rb +58 -0
- data/lib/dm-core/support.rb +7 -0
- data/lib/dm-core/support/array.rb +13 -0
- data/lib/dm-core/support/assertions.rb +8 -0
- data/lib/dm-core/support/errors.rb +23 -0
- data/lib/dm-core/support/kernel.rb +11 -0
- data/lib/dm-core/support/symbol.rb +41 -0
- data/lib/dm-core/transaction.rb +252 -0
- data/lib/dm-core/type.rb +160 -0
- data/lib/dm-core/type_map.rb +80 -0
- data/lib/dm-core/types.rb +19 -0
- data/lib/dm-core/types/boolean.rb +7 -0
- data/lib/dm-core/types/discriminator.rb +34 -0
- data/lib/dm-core/types/object.rb +24 -0
- data/lib/dm-core/types/paranoid_boolean.rb +34 -0
- data/lib/dm-core/types/paranoid_datetime.rb +33 -0
- data/lib/dm-core/types/serial.rb +9 -0
- data/lib/dm-core/types/text.rb +10 -0
- data/lib/dm-core/version.rb +3 -0
- data/script/all +4 -0
- data/script/performance.rb +282 -0
- data/script/profile.rb +87 -0
- data/spec/integration/association_spec.rb +1382 -0
- data/spec/integration/association_through_spec.rb +203 -0
- data/spec/integration/associations/many_to_many_spec.rb +449 -0
- data/spec/integration/associations/many_to_one_spec.rb +163 -0
- data/spec/integration/associations/one_to_many_spec.rb +188 -0
- data/spec/integration/auto_migrations_spec.rb +413 -0
- data/spec/integration/collection_spec.rb +1073 -0
- data/spec/integration/data_objects_adapter_spec.rb +32 -0
- data/spec/integration/dependency_queue_spec.rb +46 -0
- data/spec/integration/model_spec.rb +197 -0
- data/spec/integration/mysql_adapter_spec.rb +85 -0
- data/spec/integration/postgres_adapter_spec.rb +731 -0
- data/spec/integration/property_spec.rb +253 -0
- data/spec/integration/query_spec.rb +514 -0
- data/spec/integration/repository_spec.rb +61 -0
- data/spec/integration/resource_spec.rb +513 -0
- data/spec/integration/sqlite3_adapter_spec.rb +352 -0
- data/spec/integration/sti_spec.rb +273 -0
- data/spec/integration/strategic_eager_loading_spec.rb +156 -0
- data/spec/integration/transaction_spec.rb +60 -0
- data/spec/integration/type_spec.rb +275 -0
- data/spec/lib/logging_helper.rb +18 -0
- data/spec/lib/mock_adapter.rb +27 -0
- data/spec/lib/model_loader.rb +100 -0
- data/spec/lib/publicize_methods.rb +28 -0
- data/spec/models/content.rb +16 -0
- data/spec/models/vehicles.rb +34 -0
- data/spec/models/zoo.rb +48 -0
- data/spec/spec.opts +3 -0
- data/spec/spec_helper.rb +91 -0
- data/spec/unit/adapters/abstract_adapter_spec.rb +133 -0
- data/spec/unit/adapters/adapter_shared_spec.rb +15 -0
- data/spec/unit/adapters/data_objects_adapter_spec.rb +632 -0
- data/spec/unit/adapters/in_memory_adapter_spec.rb +98 -0
- data/spec/unit/adapters/postgres_adapter_spec.rb +133 -0
- data/spec/unit/associations/many_to_many_spec.rb +32 -0
- data/spec/unit/associations/many_to_one_spec.rb +159 -0
- data/spec/unit/associations/one_to_many_spec.rb +393 -0
- data/spec/unit/associations/one_to_one_spec.rb +7 -0
- data/spec/unit/associations/relationship_spec.rb +71 -0
- data/spec/unit/associations_spec.rb +242 -0
- data/spec/unit/auto_migrations_spec.rb +111 -0
- data/spec/unit/collection_spec.rb +182 -0
- data/spec/unit/data_mapper_spec.rb +35 -0
- data/spec/unit/identity_map_spec.rb +126 -0
- data/spec/unit/is_spec.rb +80 -0
- data/spec/unit/migrator_spec.rb +33 -0
- data/spec/unit/model_spec.rb +321 -0
- data/spec/unit/naming_conventions_spec.rb +36 -0
- data/spec/unit/property_set_spec.rb +90 -0
- data/spec/unit/property_spec.rb +753 -0
- data/spec/unit/query_spec.rb +571 -0
- data/spec/unit/repository_spec.rb +93 -0
- data/spec/unit/resource_spec.rb +649 -0
- data/spec/unit/scope_spec.rb +142 -0
- data/spec/unit/transaction_spec.rb +469 -0
- data/spec/unit/type_map_spec.rb +114 -0
- data/spec/unit/type_spec.rb +119 -0
- data/tasks/ci.rb +36 -0
- data/tasks/dm.rb +63 -0
- data/tasks/doc.rb +20 -0
- data/tasks/gemspec.rb +23 -0
- data/tasks/hoe.rb +46 -0
- data/tasks/install.rb +20 -0
- metadata +215 -0
@@ -0,0 +1,80 @@
|
|
1
|
+
# TODO: move to dm-more/dm-migrations
|
2
|
+
|
3
|
+
module DataMapper
|
4
|
+
class TypeMap
|
5
|
+
|
6
|
+
attr_accessor :parent, :chains
|
7
|
+
|
8
|
+
def initialize(parent = nil, &blk)
|
9
|
+
@parent, @chains = parent, {}
|
10
|
+
|
11
|
+
blk.call(self) unless blk.nil?
|
12
|
+
end
|
13
|
+
|
14
|
+
def map(type)
|
15
|
+
@chains[type] ||= TypeChain.new
|
16
|
+
end
|
17
|
+
|
18
|
+
def lookup(type)
|
19
|
+
if type_mapped?(type)
|
20
|
+
lookup_from_map(type)
|
21
|
+
else
|
22
|
+
lookup_by_type(type)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def lookup_from_map(type)
|
27
|
+
lookup_from_parent(type).merge(map(type).translate)
|
28
|
+
end
|
29
|
+
|
30
|
+
def lookup_from_parent(type)
|
31
|
+
if !@parent.nil? && @parent.type_mapped?(type)
|
32
|
+
@parent[type]
|
33
|
+
else
|
34
|
+
{}
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
# @raise <DataMapper::TypeMap::Error> if the type is not a default primitive or has a type map entry.
|
39
|
+
def lookup_by_type(type)
|
40
|
+
raise DataMapper::TypeMap::Error.new(type) unless type.respond_to?(:primitive) && !type.primitive.nil?
|
41
|
+
|
42
|
+
lookup(type.primitive).merge(Type::PROPERTY_OPTIONS.inject({}) {|h, k| h[k] = type.send(k); h})
|
43
|
+
end
|
44
|
+
|
45
|
+
alias [] lookup
|
46
|
+
|
47
|
+
def type_mapped?(type)
|
48
|
+
@chains.has_key?(type) || (@parent.nil? ? false : @parent.type_mapped?(type))
|
49
|
+
end
|
50
|
+
|
51
|
+
class TypeChain
|
52
|
+
attr_accessor :primitive, :attributes
|
53
|
+
|
54
|
+
def initialize
|
55
|
+
@attributes = {}
|
56
|
+
end
|
57
|
+
|
58
|
+
def to(primitive)
|
59
|
+
@primitive = primitive
|
60
|
+
self
|
61
|
+
end
|
62
|
+
|
63
|
+
def with(attributes)
|
64
|
+
raise "method 'with' expects a hash" unless attributes.kind_of?(Hash)
|
65
|
+
@attributes.merge!(attributes)
|
66
|
+
self
|
67
|
+
end
|
68
|
+
|
69
|
+
def translate
|
70
|
+
@attributes.merge((@primitive.nil? ? {} : {:primitive => @primitive}))
|
71
|
+
end
|
72
|
+
end # class TypeChain
|
73
|
+
|
74
|
+
class Error < StandardError
|
75
|
+
def initialize(type)
|
76
|
+
super("Type #{type} must have a default primitive or type map entry")
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end # class TypeMap
|
80
|
+
end # module DataMapper
|
@@ -0,0 +1,19 @@
|
|
1
|
+
dir = Pathname(__FILE__).dirname.expand_path / 'types'
|
2
|
+
|
3
|
+
require dir / 'boolean'
|
4
|
+
require dir / 'discriminator'
|
5
|
+
require dir / 'text'
|
6
|
+
require dir / 'paranoid_datetime'
|
7
|
+
require dir / 'paranoid_boolean'
|
8
|
+
require dir / 'object'
|
9
|
+
require dir / 'serial'
|
10
|
+
|
11
|
+
unless defined?(DM)
|
12
|
+
DM = DataMapper::Types
|
13
|
+
end
|
14
|
+
|
15
|
+
module DataMapper
|
16
|
+
module Resource
|
17
|
+
include Types
|
18
|
+
end # module Resource
|
19
|
+
end # module DataMapper
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module DataMapper
|
2
|
+
module Types
|
3
|
+
class Discriminator < DataMapper::Type
|
4
|
+
primitive Class
|
5
|
+
track :set
|
6
|
+
default lambda { |r,p| p.model }
|
7
|
+
nullable false
|
8
|
+
|
9
|
+
def self.bind(property)
|
10
|
+
model = property.model
|
11
|
+
|
12
|
+
model.class_eval <<-EOS, __FILE__, __LINE__
|
13
|
+
def self.descendants
|
14
|
+
(@descendants ||= []).uniq!
|
15
|
+
@descendants
|
16
|
+
end
|
17
|
+
|
18
|
+
after_class_method :inherited, :add_scope_for_discriminator
|
19
|
+
|
20
|
+
def self.add_scope_for_discriminator(retval, target)
|
21
|
+
target.descendants << target
|
22
|
+
target.default_scope.update(#{property.name.inspect} => target.descendants)
|
23
|
+
propagate_descendants(target)
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.propagate_descendants(target)
|
27
|
+
descendants << target
|
28
|
+
superclass.propagate_descendants(target) if superclass.respond_to?(:propagate_descendants)
|
29
|
+
end
|
30
|
+
EOS
|
31
|
+
end
|
32
|
+
end # class Discriminator
|
33
|
+
end # module Types
|
34
|
+
end # module DataMapper
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require "base64"
|
2
|
+
|
3
|
+
module DataMapper
|
4
|
+
module Types
|
5
|
+
class Object < DataMapper::Type
|
6
|
+
primitive String
|
7
|
+
size 65535
|
8
|
+
lazy true
|
9
|
+
track :hash
|
10
|
+
|
11
|
+
def self.typecast(value, property)
|
12
|
+
value
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.dump(value, property)
|
16
|
+
Base64.encode64(Marshal.dump(value))
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.load(value, property)
|
20
|
+
value.nil? ? nil : Marshal.load(Base64.decode64(value))
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module DataMapper
|
2
|
+
module Types
|
3
|
+
class ParanoidBoolean < DataMapper::Type(Boolean)
|
4
|
+
primitive TrueClass
|
5
|
+
default false
|
6
|
+
lazy true
|
7
|
+
|
8
|
+
def self.bind(property)
|
9
|
+
model = property.model
|
10
|
+
repository = property.repository
|
11
|
+
|
12
|
+
model.send(:set_paranoid_property, property.name){true}
|
13
|
+
|
14
|
+
model.class_eval <<-EOS, __FILE__, __LINE__
|
15
|
+
|
16
|
+
def self.with_deleted
|
17
|
+
with_exclusive_scope(#{property.name.inspect} => true) do
|
18
|
+
yield
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def destroy
|
23
|
+
self.class.paranoid_properties.each do |name, blk|
|
24
|
+
attribute_set(name, blk.call(self))
|
25
|
+
end
|
26
|
+
save
|
27
|
+
end
|
28
|
+
EOS
|
29
|
+
|
30
|
+
model.default_scope(repository.name).update(property.name => false)
|
31
|
+
end
|
32
|
+
end # class ParanoidBoolean
|
33
|
+
end # module Types
|
34
|
+
end # module DataMapper
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module DataMapper
|
2
|
+
module Types
|
3
|
+
class ParanoidDateTime < DataMapper::Type(DateTime)
|
4
|
+
primitive DateTime
|
5
|
+
lazy true
|
6
|
+
|
7
|
+
def self.bind(property)
|
8
|
+
model = property.model
|
9
|
+
repository = property.repository
|
10
|
+
|
11
|
+
model.send(:set_paranoid_property, property.name){DateTime.now}
|
12
|
+
|
13
|
+
model.class_eval <<-EOS, __FILE__, __LINE__
|
14
|
+
|
15
|
+
def self.with_deleted
|
16
|
+
with_exclusive_scope(#{property.name.inspect}.not => nil) do
|
17
|
+
yield
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def destroy
|
22
|
+
self.class.paranoid_properties.each do |name, blk|
|
23
|
+
attribute_set(name, blk.call(self))
|
24
|
+
end
|
25
|
+
save
|
26
|
+
end
|
27
|
+
EOS
|
28
|
+
|
29
|
+
model.default_scope(repository.name).update(property.name => nil)
|
30
|
+
end
|
31
|
+
end # class ParanoidDateTime
|
32
|
+
end # module Types
|
33
|
+
end # module DataMapper
|
data/script/all
ADDED
@@ -0,0 +1,282 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require File.join(File.dirname(__FILE__), '..', 'lib', 'dm-core')
|
4
|
+
require File.join(File.dirname(__FILE__), '..', 'lib', 'dm-core', 'version')
|
5
|
+
|
6
|
+
require 'ftools'
|
7
|
+
require 'rubygems'
|
8
|
+
|
9
|
+
gem 'rbench', '~>0.2.3'
|
10
|
+
require 'rbench'
|
11
|
+
|
12
|
+
gem 'faker', '~>0.3.1'
|
13
|
+
require 'faker'
|
14
|
+
|
15
|
+
gem 'activerecord', '~>2.3.2'
|
16
|
+
require 'active_record'
|
17
|
+
|
18
|
+
socket_file = Pathname.glob(%w[
|
19
|
+
/opt/local/var/run/mysql5/mysqld.sock
|
20
|
+
tmp/mysqld.sock
|
21
|
+
/tmp/mysqld.sock
|
22
|
+
tmp/mysql.sock
|
23
|
+
/tmp/mysql.sock
|
24
|
+
/var/mysql/mysql.sock
|
25
|
+
/var/run/mysqld/mysqld.sock
|
26
|
+
]).find { |path| path.socket? }
|
27
|
+
|
28
|
+
configuration_options = {
|
29
|
+
:adapter => 'mysql',
|
30
|
+
:username => 'root',
|
31
|
+
:password => '',
|
32
|
+
:database => 'data_mapper_1',
|
33
|
+
}
|
34
|
+
|
35
|
+
configuration_options[:socket] = socket_file unless socket_file.nil?
|
36
|
+
|
37
|
+
log_dir = DataMapper.root / 'log'
|
38
|
+
log_dir.mkdir unless log_dir.directory?
|
39
|
+
|
40
|
+
DataMapper::Logger.new(log_dir / 'dm.log', :off)
|
41
|
+
adapter = DataMapper.setup(:default, "mysql://root@localhost/data_mapper_1?socket=#{socket_file}")
|
42
|
+
|
43
|
+
if configuration_options[:adapter]
|
44
|
+
sqlfile = File.join(File.dirname(__FILE__),'..','tmp','performance.sql')
|
45
|
+
mysql_bin = %w[mysql mysql5].select{|bin| `which #{bin}`.length > 0 }
|
46
|
+
mysqldump_bin = %w[mysqldump mysqldump5].select{|bin| `which #{bin}`.length > 0 }
|
47
|
+
end
|
48
|
+
|
49
|
+
ActiveRecord::Base.logger = Logger.new(log_dir / 'ar.log')
|
50
|
+
ActiveRecord::Base.logger.level = 0
|
51
|
+
|
52
|
+
ActiveRecord::Base.establish_connection(configuration_options)
|
53
|
+
|
54
|
+
class ARExhibit < ActiveRecord::Base #:nodoc:
|
55
|
+
set_table_name 'exhibits'
|
56
|
+
|
57
|
+
belongs_to :user, :class_name => 'ARUser', :foreign_key => 'user_id'
|
58
|
+
end
|
59
|
+
|
60
|
+
class ARUser < ActiveRecord::Base #:nodoc:
|
61
|
+
set_table_name 'users'
|
62
|
+
|
63
|
+
has_many :exhibits, :foreign_key => 'user_id'
|
64
|
+
|
65
|
+
end
|
66
|
+
|
67
|
+
ARExhibit.find_by_sql('SELECT 1')
|
68
|
+
|
69
|
+
class Exhibit
|
70
|
+
include DataMapper::Resource
|
71
|
+
|
72
|
+
property :id, Serial
|
73
|
+
property :name, String
|
74
|
+
property :zoo_id, Integer
|
75
|
+
property :user_id, Integer
|
76
|
+
property :notes, Text, :lazy => true
|
77
|
+
property :created_on, Date
|
78
|
+
|
79
|
+
belongs_to :user
|
80
|
+
# property :updated_at, DateTime
|
81
|
+
end
|
82
|
+
|
83
|
+
class User
|
84
|
+
include DataMapper::Resource
|
85
|
+
|
86
|
+
property :id, Serial
|
87
|
+
property :name, String
|
88
|
+
property :email, String
|
89
|
+
property :about, Text, :lazy => true
|
90
|
+
property :created_on, Date
|
91
|
+
|
92
|
+
end
|
93
|
+
|
94
|
+
touch_attributes = lambda do |exhibits|
|
95
|
+
[*exhibits].each do |exhibit|
|
96
|
+
exhibit.id
|
97
|
+
exhibit.name
|
98
|
+
exhibit.created_on
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
touch_relationships = lambda do |exhibits|
|
103
|
+
[*exhibits].each do |exhibit|
|
104
|
+
exhibit.id
|
105
|
+
exhibit.name
|
106
|
+
exhibit.created_on
|
107
|
+
exhibit.user
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
|
112
|
+
c = configuration_options
|
113
|
+
|
114
|
+
if sqlfile && File.exists?(sqlfile)
|
115
|
+
puts "Found data-file. Importing from #{sqlfile}"
|
116
|
+
#adapter.execute("LOAD DATA LOCAL INFILE '#{sqlfile}' INTO TABLE exhibits")
|
117
|
+
`#{mysql_bin} -u #{c[:username]} #{"-p#{c[:password]}" unless c[:password].blank?} #{c[:database]} < #{sqlfile}`
|
118
|
+
else
|
119
|
+
|
120
|
+
puts "Generating data for benchmarking..."
|
121
|
+
|
122
|
+
User.auto_migrate!
|
123
|
+
Exhibit.auto_migrate!
|
124
|
+
|
125
|
+
users = []
|
126
|
+
exhibits = []
|
127
|
+
|
128
|
+
# pre-compute the insert statements and fake data compilation,
|
129
|
+
# so the benchmarks below show the actual runtime for the execute
|
130
|
+
# method, minus the setup steps
|
131
|
+
|
132
|
+
# Using the same paragraph for all exhibits because it is very slow
|
133
|
+
# to generate unique paragraphs for all exhibits.
|
134
|
+
paragraph = Faker::Lorem.paragraphs.join($/)
|
135
|
+
|
136
|
+
10_000.times do |i|
|
137
|
+
users << [
|
138
|
+
'INSERT INTO `users` (`name`,`email`,`created_on`) VALUES (?, ?, ?)',
|
139
|
+
Faker::Name.name,
|
140
|
+
Faker::Internet.email,
|
141
|
+
Date.today
|
142
|
+
]
|
143
|
+
|
144
|
+
exhibits << [
|
145
|
+
'INSERT INTO `exhibits` (`name`, `zoo_id`, `user_id`, `notes`, `created_on`) VALUES (?, ?, ?, ?, ?)',
|
146
|
+
Faker::Company.name,
|
147
|
+
rand(10).ceil,
|
148
|
+
i,
|
149
|
+
paragraph,#Faker::Lorem.paragraphs.join($/),
|
150
|
+
Date.today
|
151
|
+
]
|
152
|
+
end
|
153
|
+
|
154
|
+
puts "Inserting 10,000 users..."
|
155
|
+
10_000.times { |i| adapter.execute(*users.at(i)) }
|
156
|
+
puts "Inserting 10,000 exhibits..."
|
157
|
+
10_000.times { |i| adapter.execute(*exhibits.at(i)) }
|
158
|
+
|
159
|
+
if sqlfile
|
160
|
+
answer = nil
|
161
|
+
until answer && answer[/^$|y|yes|n|no/]
|
162
|
+
print("Would you like to dump data into tmp/performance.sql (for faster setup)? [Yn]");
|
163
|
+
STDOUT.flush
|
164
|
+
answer = gets
|
165
|
+
end
|
166
|
+
|
167
|
+
if answer[/^$|y|yes/]
|
168
|
+
File.makedirs(File.dirname(sqlfile))
|
169
|
+
#adapter.execute("SELECT * INTO OUTFILE '#{sqlfile}' FROM exhibits;")
|
170
|
+
`#{mysqldump_bin} -u #{c[:username]} #{"-p#{c[:password]}" unless c[:password].blank?} #{c[:database]} exhibits users > #{sqlfile}`
|
171
|
+
puts "File saved\n"
|
172
|
+
end
|
173
|
+
end
|
174
|
+
|
175
|
+
end
|
176
|
+
|
177
|
+
TIMES = ENV['x'] ? ENV['x'].to_i : 10_000
|
178
|
+
|
179
|
+
puts "You can specify how many times you want to run the benchmarks with rake:perf x=(number)"
|
180
|
+
puts "Some tasks will be run 10 and 1000 times less than (number)"
|
181
|
+
puts "Benchmarks will now run #{TIMES} times"
|
182
|
+
# Inform about slow benchmark
|
183
|
+
# answer = nil
|
184
|
+
# until answer && answer[/^$|y|yes|n|no/]
|
185
|
+
# print("A slow benchmark exposing problems with SEL is newly added. It takes approx. 20s\n");
|
186
|
+
# print("you have scheduled it to run #{TIMES / 100} times.\nWould you still include the particular benchmark? [Yn]")
|
187
|
+
# STDOUT.flush
|
188
|
+
# answer = gets
|
189
|
+
# end
|
190
|
+
# run_rel_bench = answer[/^$|y|yes/] ? true : false
|
191
|
+
|
192
|
+
|
193
|
+
RBench.run(TIMES) do
|
194
|
+
|
195
|
+
column :times
|
196
|
+
column :ar, :title => "AR 2.1"
|
197
|
+
column :dm, :title => "DM #{DataMapper::VERSION}"
|
198
|
+
column :diff, :compare => [:ar,:dm]
|
199
|
+
|
200
|
+
report "Model.new (instantiation)" do
|
201
|
+
ar { ARExhibit.new }
|
202
|
+
dm { Exhibit.new }
|
203
|
+
end
|
204
|
+
|
205
|
+
report "Model.new (setting attributes)" do
|
206
|
+
attrs = {:name => 'sam', :zoo_id => 1}
|
207
|
+
ar { ARExhibit.new(attrs) }
|
208
|
+
dm { Exhibit.new(attrs) }
|
209
|
+
end
|
210
|
+
|
211
|
+
report "Model.get specific (not cached)" do
|
212
|
+
ActiveRecord::Base.uncached { ar { touch_attributes[ARExhibit.find(1)] } }
|
213
|
+
dm { touch_attributes[Exhibit.get(1)] }
|
214
|
+
end
|
215
|
+
|
216
|
+
report "Model.get specific (cached)" do
|
217
|
+
ActiveRecord::Base.cache { ar { touch_attributes[ARExhibit.find(1)] } }
|
218
|
+
Exhibit.repository(:default) { dm { touch_attributes[Exhibit.get(1)] } }
|
219
|
+
end
|
220
|
+
|
221
|
+
report "Model.first" do
|
222
|
+
ar { touch_attributes[ARExhibit.first] }
|
223
|
+
dm { touch_attributes[Exhibit.first] }
|
224
|
+
end
|
225
|
+
|
226
|
+
report "Model.all limit(100)", (TIMES / 10.0).ceil do
|
227
|
+
ar { touch_attributes[ARExhibit.find(:all, :limit => 100)] }
|
228
|
+
dm { touch_attributes[Exhibit.all(:limit => 100)] }
|
229
|
+
end
|
230
|
+
|
231
|
+
report "Model.all limit(100) with relationship", (TIMES / 10.0).ceil do
|
232
|
+
ar { touch_relationships[ARExhibit.all(:limit => 100, :include => [:user])] }
|
233
|
+
dm { touch_relationships[Exhibit.all(:limit => 100)] }
|
234
|
+
end
|
235
|
+
|
236
|
+
report "Model.all limit(10,000)", (TIMES / 1000.0).ceil do
|
237
|
+
ar { touch_attributes[ARExhibit.find(:all, :limit => 10_000)] }
|
238
|
+
dm { touch_attributes[Exhibit.all(:limit => 10_000)] }
|
239
|
+
end
|
240
|
+
|
241
|
+
create_exhibit = {
|
242
|
+
:name => Faker::Company.name,
|
243
|
+
:zoo_id => rand(10).ceil,
|
244
|
+
:notes => Faker::Lorem.paragraphs.join($/),
|
245
|
+
:created_on => Date.today
|
246
|
+
}
|
247
|
+
|
248
|
+
report "Model.create" do
|
249
|
+
ar { ARExhibit.create(create_exhibit) }
|
250
|
+
dm { Exhibit.create(create_exhibit) }
|
251
|
+
end
|
252
|
+
|
253
|
+
report "Resource#attributes" do
|
254
|
+
attrs_first = {:name => 'sam', :zoo_id => 1}
|
255
|
+
attrs_second = {:name => 'tom', :zoo_id => 1}
|
256
|
+
ar { e = ARExhibit.new(attrs_first); e.attributes = attrs_second }
|
257
|
+
dm { e = Exhibit.new(attrs_first); e.attributes = attrs_second }
|
258
|
+
end
|
259
|
+
|
260
|
+
report "Resource#update" do
|
261
|
+
ar { e = ARExhibit.find(1); e.name = 'bob'; e.save }
|
262
|
+
dm { e = Exhibit.get(1); e.name = 'bob'; e.save }
|
263
|
+
end
|
264
|
+
|
265
|
+
report "Resource#destroy" do
|
266
|
+
ar { ARExhibit.first.destroy }
|
267
|
+
dm { Exhibit.first.destroy }
|
268
|
+
end
|
269
|
+
|
270
|
+
report "Model.transaction" do
|
271
|
+
ar { ARExhibit.transaction { ARExhibit.new } }
|
272
|
+
dm { Exhibit.transaction { Exhibit.new } }
|
273
|
+
end
|
274
|
+
|
275
|
+
summary "Total"
|
276
|
+
end
|
277
|
+
|
278
|
+
connection = adapter.send(:create_connection)
|
279
|
+
command = connection.create_command("DROP TABLE exhibits")
|
280
|
+
command = connection.create_command("DROP TABLE users")
|
281
|
+
command.execute_non_query rescue nil
|
282
|
+
connection.close
|