sskirby-activerecord 3.2.1
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.md +6749 -0
- data/MIT-LICENSE +20 -0
- data/README.rdoc +222 -0
- data/examples/associations.png +0 -0
- data/examples/performance.rb +177 -0
- data/examples/simple.rb +14 -0
- data/lib/active_record.rb +147 -0
- data/lib/active_record/aggregations.rb +255 -0
- data/lib/active_record/associations.rb +1604 -0
- data/lib/active_record/associations/alias_tracker.rb +79 -0
- data/lib/active_record/associations/association.rb +239 -0
- data/lib/active_record/associations/association_scope.rb +119 -0
- data/lib/active_record/associations/belongs_to_association.rb +79 -0
- data/lib/active_record/associations/belongs_to_polymorphic_association.rb +34 -0
- data/lib/active_record/associations/builder/association.rb +55 -0
- data/lib/active_record/associations/builder/belongs_to.rb +85 -0
- data/lib/active_record/associations/builder/collection_association.rb +75 -0
- data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +57 -0
- data/lib/active_record/associations/builder/has_many.rb +71 -0
- data/lib/active_record/associations/builder/has_one.rb +62 -0
- data/lib/active_record/associations/builder/singular_association.rb +32 -0
- data/lib/active_record/associations/collection_association.rb +574 -0
- data/lib/active_record/associations/collection_proxy.rb +132 -0
- data/lib/active_record/associations/has_and_belongs_to_many_association.rb +62 -0
- data/lib/active_record/associations/has_many_association.rb +108 -0
- data/lib/active_record/associations/has_many_through_association.rb +180 -0
- data/lib/active_record/associations/has_one_association.rb +73 -0
- data/lib/active_record/associations/has_one_through_association.rb +36 -0
- data/lib/active_record/associations/join_dependency.rb +214 -0
- data/lib/active_record/associations/join_dependency/join_association.rb +154 -0
- data/lib/active_record/associations/join_dependency/join_base.rb +24 -0
- data/lib/active_record/associations/join_dependency/join_part.rb +78 -0
- data/lib/active_record/associations/join_helper.rb +55 -0
- data/lib/active_record/associations/preloader.rb +177 -0
- data/lib/active_record/associations/preloader/association.rb +127 -0
- data/lib/active_record/associations/preloader/belongs_to.rb +17 -0
- data/lib/active_record/associations/preloader/collection_association.rb +24 -0
- data/lib/active_record/associations/preloader/has_and_belongs_to_many.rb +60 -0
- data/lib/active_record/associations/preloader/has_many.rb +17 -0
- data/lib/active_record/associations/preloader/has_many_through.rb +15 -0
- data/lib/active_record/associations/preloader/has_one.rb +23 -0
- data/lib/active_record/associations/preloader/has_one_through.rb +9 -0
- data/lib/active_record/associations/preloader/singular_association.rb +21 -0
- data/lib/active_record/associations/preloader/through_association.rb +67 -0
- data/lib/active_record/associations/singular_association.rb +64 -0
- data/lib/active_record/associations/through_association.rb +83 -0
- data/lib/active_record/attribute_assignment.rb +221 -0
- data/lib/active_record/attribute_methods.rb +272 -0
- data/lib/active_record/attribute_methods/before_type_cast.rb +31 -0
- data/lib/active_record/attribute_methods/deprecated_underscore_read.rb +32 -0
- data/lib/active_record/attribute_methods/dirty.rb +101 -0
- data/lib/active_record/attribute_methods/primary_key.rb +114 -0
- data/lib/active_record/attribute_methods/query.rb +39 -0
- data/lib/active_record/attribute_methods/read.rb +135 -0
- data/lib/active_record/attribute_methods/serialization.rb +93 -0
- data/lib/active_record/attribute_methods/time_zone_conversion.rb +62 -0
- data/lib/active_record/attribute_methods/write.rb +69 -0
- data/lib/active_record/autosave_association.rb +422 -0
- data/lib/active_record/base.rb +716 -0
- data/lib/active_record/callbacks.rb +275 -0
- data/lib/active_record/coders/yaml_column.rb +41 -0
- data/lib/active_record/connection_adapters/abstract/connection_pool.rb +452 -0
- data/lib/active_record/connection_adapters/abstract/connection_specification.rb +188 -0
- data/lib/active_record/connection_adapters/abstract/database_limits.rb +58 -0
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +388 -0
- data/lib/active_record/connection_adapters/abstract/query_cache.rb +82 -0
- data/lib/active_record/connection_adapters/abstract/quoting.rb +115 -0
- data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +492 -0
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +598 -0
- data/lib/active_record/connection_adapters/abstract_adapter.rb +296 -0
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +653 -0
- data/lib/active_record/connection_adapters/column.rb +270 -0
- data/lib/active_record/connection_adapters/mysql2_adapter.rb +288 -0
- data/lib/active_record/connection_adapters/mysql_adapter.rb +426 -0
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +1261 -0
- data/lib/active_record/connection_adapters/schema_cache.rb +50 -0
- data/lib/active_record/connection_adapters/sqlite3_adapter.rb +55 -0
- data/lib/active_record/connection_adapters/sqlite_adapter.rb +577 -0
- data/lib/active_record/connection_adapters/statement_pool.rb +40 -0
- data/lib/active_record/counter_cache.rb +119 -0
- data/lib/active_record/dynamic_finder_match.rb +56 -0
- data/lib/active_record/dynamic_matchers.rb +79 -0
- data/lib/active_record/dynamic_scope_match.rb +23 -0
- data/lib/active_record/errors.rb +195 -0
- data/lib/active_record/explain.rb +85 -0
- data/lib/active_record/explain_subscriber.rb +21 -0
- data/lib/active_record/fixtures.rb +906 -0
- data/lib/active_record/fixtures/file.rb +65 -0
- data/lib/active_record/identity_map.rb +156 -0
- data/lib/active_record/inheritance.rb +167 -0
- data/lib/active_record/integration.rb +49 -0
- data/lib/active_record/locale/en.yml +40 -0
- data/lib/active_record/locking/optimistic.rb +183 -0
- data/lib/active_record/locking/pessimistic.rb +77 -0
- data/lib/active_record/log_subscriber.rb +68 -0
- data/lib/active_record/migration.rb +765 -0
- data/lib/active_record/migration/command_recorder.rb +105 -0
- data/lib/active_record/model_schema.rb +366 -0
- data/lib/active_record/nested_attributes.rb +469 -0
- data/lib/active_record/observer.rb +121 -0
- data/lib/active_record/persistence.rb +372 -0
- data/lib/active_record/query_cache.rb +74 -0
- data/lib/active_record/querying.rb +58 -0
- data/lib/active_record/railtie.rb +119 -0
- data/lib/active_record/railties/console_sandbox.rb +6 -0
- data/lib/active_record/railties/controller_runtime.rb +49 -0
- data/lib/active_record/railties/databases.rake +620 -0
- data/lib/active_record/railties/jdbcmysql_error.rb +16 -0
- data/lib/active_record/readonly_attributes.rb +26 -0
- data/lib/active_record/reflection.rb +534 -0
- data/lib/active_record/relation.rb +534 -0
- data/lib/active_record/relation/batches.rb +90 -0
- data/lib/active_record/relation/calculations.rb +354 -0
- data/lib/active_record/relation/delegation.rb +49 -0
- data/lib/active_record/relation/finder_methods.rb +398 -0
- data/lib/active_record/relation/predicate_builder.rb +58 -0
- data/lib/active_record/relation/query_methods.rb +417 -0
- data/lib/active_record/relation/spawn_methods.rb +148 -0
- data/lib/active_record/result.rb +34 -0
- data/lib/active_record/sanitization.rb +194 -0
- data/lib/active_record/schema.rb +58 -0
- data/lib/active_record/schema_dumper.rb +204 -0
- data/lib/active_record/scoping.rb +152 -0
- data/lib/active_record/scoping/default.rb +142 -0
- data/lib/active_record/scoping/named.rb +202 -0
- data/lib/active_record/serialization.rb +18 -0
- data/lib/active_record/serializers/xml_serializer.rb +202 -0
- data/lib/active_record/session_store.rb +358 -0
- data/lib/active_record/store.rb +50 -0
- data/lib/active_record/test_case.rb +73 -0
- data/lib/active_record/timestamp.rb +113 -0
- data/lib/active_record/transactions.rb +360 -0
- data/lib/active_record/translation.rb +22 -0
- data/lib/active_record/validations.rb +83 -0
- data/lib/active_record/validations/associated.rb +43 -0
- data/lib/active_record/validations/uniqueness.rb +180 -0
- data/lib/active_record/version.rb +10 -0
- data/lib/rails/generators/active_record.rb +25 -0
- data/lib/rails/generators/active_record/migration.rb +15 -0
- data/lib/rails/generators/active_record/migration/migration_generator.rb +25 -0
- data/lib/rails/generators/active_record/migration/templates/migration.rb +31 -0
- data/lib/rails/generators/active_record/model/model_generator.rb +43 -0
- data/lib/rails/generators/active_record/model/templates/migration.rb +15 -0
- data/lib/rails/generators/active_record/model/templates/model.rb +7 -0
- data/lib/rails/generators/active_record/model/templates/module.rb +7 -0
- data/lib/rails/generators/active_record/observer/observer_generator.rb +15 -0
- data/lib/rails/generators/active_record/observer/templates/observer.rb +4 -0
- data/lib/rails/generators/active_record/session_migration/session_migration_generator.rb +25 -0
- data/lib/rails/generators/active_record/session_migration/templates/migration.rb +12 -0
- metadata +242 -0
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2004-2011 David Heinemeier Hansson
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.rdoc
ADDED
@@ -0,0 +1,222 @@
|
|
1
|
+
= Active Record -- Object-relational mapping put on rails
|
2
|
+
|
3
|
+
Active Record connects classes to relational database tables to establish an
|
4
|
+
almost zero-configuration persistence layer for applications. The library
|
5
|
+
provides a base class that, when subclassed, sets up a mapping between the new
|
6
|
+
class and an existing table in the database. In the context of an application,
|
7
|
+
these classes are commonly referred to as *models*. Models can also be
|
8
|
+
connected to other models; this is done by defining *associations*.
|
9
|
+
|
10
|
+
Active Record relies heavily on naming in that it uses class and association
|
11
|
+
names to establish mappings between respective database tables and foreign key
|
12
|
+
columns. Although these mappings can be defined explicitly, it's recommended
|
13
|
+
to follow naming conventions, especially when getting started with the
|
14
|
+
library.
|
15
|
+
|
16
|
+
A short rundown of some of the major features:
|
17
|
+
|
18
|
+
* Automated mapping between classes and tables, attributes and columns.
|
19
|
+
|
20
|
+
class Product < ActiveRecord::Base
|
21
|
+
end
|
22
|
+
|
23
|
+
The Product class is automatically mapped to the table named "products",
|
24
|
+
which might look like this:
|
25
|
+
|
26
|
+
CREATE TABLE products (
|
27
|
+
id int(11) NOT NULL auto_increment,
|
28
|
+
name varchar(255),
|
29
|
+
PRIMARY KEY (id)
|
30
|
+
);
|
31
|
+
|
32
|
+
This would also define the following accessors: `Product#name` and
|
33
|
+
`Product#name=(new_name)`
|
34
|
+
|
35
|
+
{Learn more}[link:classes/ActiveRecord/Base.html]
|
36
|
+
|
37
|
+
|
38
|
+
* Associations between objects defined by simple class methods.
|
39
|
+
|
40
|
+
class Firm < ActiveRecord::Base
|
41
|
+
has_many :clients
|
42
|
+
has_one :account
|
43
|
+
belongs_to :conglomerate
|
44
|
+
end
|
45
|
+
|
46
|
+
{Learn more}[link:classes/ActiveRecord/Associations/ClassMethods.html]
|
47
|
+
|
48
|
+
|
49
|
+
* Aggregations of value objects.
|
50
|
+
|
51
|
+
class Account < ActiveRecord::Base
|
52
|
+
composed_of :balance, :class_name => "Money",
|
53
|
+
:mapping => %w(balance amount)
|
54
|
+
composed_of :address,
|
55
|
+
:mapping => [%w(address_street street), %w(address_city city)]
|
56
|
+
end
|
57
|
+
|
58
|
+
{Learn more}[link:classes/ActiveRecord/Aggregations/ClassMethods.html]
|
59
|
+
|
60
|
+
|
61
|
+
* Validation rules that can differ for new or existing objects.
|
62
|
+
|
63
|
+
class Account < ActiveRecord::Base
|
64
|
+
validates_presence_of :subdomain, :name, :email_address, :password
|
65
|
+
validates_uniqueness_of :subdomain
|
66
|
+
validates_acceptance_of :terms_of_service, :on => :create
|
67
|
+
validates_confirmation_of :password, :email_address, :on => :create
|
68
|
+
end
|
69
|
+
|
70
|
+
{Learn more}[link:classes/ActiveRecord/Validations.html]
|
71
|
+
|
72
|
+
|
73
|
+
* Callbacks available for the entire life cycle (instantiation, saving, destroying, validating, etc.).
|
74
|
+
|
75
|
+
class Person < ActiveRecord::Base
|
76
|
+
before_destroy :invalidate_payment_plan
|
77
|
+
# the `invalidate_payment_plan` method gets called just before Person#destroy
|
78
|
+
end
|
79
|
+
|
80
|
+
{Learn more}[link:classes/ActiveRecord/Callbacks.html]
|
81
|
+
|
82
|
+
|
83
|
+
* Observers that react to changes in a model.
|
84
|
+
|
85
|
+
class CommentObserver < ActiveRecord::Observer
|
86
|
+
def after_create(comment) # is called just after Comment#save
|
87
|
+
CommentMailer.new_comment_email("david@loudthinking.com", comment).deliver
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
{Learn more}[link:classes/ActiveRecord/Observer.html]
|
92
|
+
|
93
|
+
|
94
|
+
* Inheritance hierarchies.
|
95
|
+
|
96
|
+
class Company < ActiveRecord::Base; end
|
97
|
+
class Firm < Company; end
|
98
|
+
class Client < Company; end
|
99
|
+
class PriorityClient < Client; end
|
100
|
+
|
101
|
+
{Learn more}[link:classes/ActiveRecord/Base.html]
|
102
|
+
|
103
|
+
|
104
|
+
* Transactions.
|
105
|
+
|
106
|
+
# Database transaction
|
107
|
+
Account.transaction do
|
108
|
+
david.withdrawal(100)
|
109
|
+
mary.deposit(100)
|
110
|
+
end
|
111
|
+
|
112
|
+
{Learn more}[link:classes/ActiveRecord/Transactions/ClassMethods.html]
|
113
|
+
|
114
|
+
|
115
|
+
* Reflections on columns, associations, and aggregations.
|
116
|
+
|
117
|
+
reflection = Firm.reflect_on_association(:clients)
|
118
|
+
reflection.klass # => Client (class)
|
119
|
+
Firm.columns # Returns an array of column descriptors for the firms table
|
120
|
+
|
121
|
+
{Learn more}[link:classes/ActiveRecord/Reflection/ClassMethods.html]
|
122
|
+
|
123
|
+
|
124
|
+
* Database abstraction through simple adapters.
|
125
|
+
|
126
|
+
# connect to SQLite3
|
127
|
+
ActiveRecord::Base.establish_connection(:adapter => "sqlite3", :database => "dbfile.sqlite3")
|
128
|
+
|
129
|
+
# connect to MySQL with authentication
|
130
|
+
ActiveRecord::Base.establish_connection(
|
131
|
+
:adapter => "mysql2",
|
132
|
+
:host => "localhost",
|
133
|
+
:username => "me",
|
134
|
+
:password => "secret",
|
135
|
+
:database => "activerecord"
|
136
|
+
)
|
137
|
+
|
138
|
+
{Learn more}[link:classes/ActiveRecord/Base.html] and read about the built-in support for
|
139
|
+
MySQL[link:classes/ActiveRecord/ConnectionAdapters/MysqlAdapter.html],
|
140
|
+
PostgreSQL[link:classes/ActiveRecord/ConnectionAdapters/PostgreSQLAdapter.html], and
|
141
|
+
SQLite3[link:classes/ActiveRecord/ConnectionAdapters/SQLite3Adapter.html].
|
142
|
+
|
143
|
+
|
144
|
+
* Logging support for Log4r[http://log4r.sourceforge.net] and Logger[http://www.ruby-doc.org/stdlib/libdoc/logger/rdoc].
|
145
|
+
|
146
|
+
ActiveRecord::Base.logger = Logger.new(STDOUT)
|
147
|
+
ActiveRecord::Base.logger = Log4r::Logger.new("Application Log")
|
148
|
+
|
149
|
+
|
150
|
+
* Database agnostic schema management with Migrations.
|
151
|
+
|
152
|
+
class AddSystemSettings < ActiveRecord::Migration
|
153
|
+
def up
|
154
|
+
create_table :system_settings do |t|
|
155
|
+
t.string :name
|
156
|
+
t.string :label
|
157
|
+
t.text :value
|
158
|
+
t.string :type
|
159
|
+
t.integer :position
|
160
|
+
end
|
161
|
+
|
162
|
+
SystemSetting.create :name => "notice", :label => "Use notice?", :value => 1
|
163
|
+
end
|
164
|
+
|
165
|
+
def down
|
166
|
+
drop_table :system_settings
|
167
|
+
end
|
168
|
+
end
|
169
|
+
|
170
|
+
{Learn more}[link:classes/ActiveRecord/Migration.html]
|
171
|
+
|
172
|
+
|
173
|
+
== Philosophy
|
174
|
+
|
175
|
+
Active Record is an implementation of the object-relational mapping (ORM)
|
176
|
+
pattern[http://www.martinfowler.com/eaaCatalog/activeRecord.html] by the same
|
177
|
+
name described by Martin Fowler:
|
178
|
+
|
179
|
+
"An object that wraps a row in a database table or view,
|
180
|
+
encapsulates the database access, and adds domain logic on that data."
|
181
|
+
|
182
|
+
Active Record attempts to provide a coherent wrapper as a solution for the inconvenience that is
|
183
|
+
object-relational mapping. The prime directive for this mapping has been to minimize
|
184
|
+
the amount of code needed to build a real-world domain model. This is made possible
|
185
|
+
by relying on a number of conventions that make it easy for Active Record to infer
|
186
|
+
complex relations and structures from a minimal amount of explicit direction.
|
187
|
+
|
188
|
+
Convention over Configuration:
|
189
|
+
* No XML-files!
|
190
|
+
* Lots of reflection and run-time extension
|
191
|
+
* Magic is not inherently a bad word
|
192
|
+
|
193
|
+
Admit the Database:
|
194
|
+
* Lets you drop down to SQL for odd cases and performance
|
195
|
+
* Doesn't attempt to duplicate or replace data definitions
|
196
|
+
|
197
|
+
|
198
|
+
== Download and installation
|
199
|
+
|
200
|
+
The latest version of Active Record can be installed with RubyGems:
|
201
|
+
|
202
|
+
% [sudo] gem install activerecord
|
203
|
+
|
204
|
+
Source code can be downloaded as part of the Rails project on GitHub
|
205
|
+
|
206
|
+
* https://github.com/rails/rails/tree/master/activerecord
|
207
|
+
|
208
|
+
|
209
|
+
== License
|
210
|
+
|
211
|
+
Active Record is released under the MIT license.
|
212
|
+
|
213
|
+
|
214
|
+
== Support
|
215
|
+
|
216
|
+
API documentation is at
|
217
|
+
|
218
|
+
* http://api.rubyonrails.org
|
219
|
+
|
220
|
+
Bug reports and feature requests can be filed with the rest for the Ruby on Rails project here:
|
221
|
+
|
222
|
+
* https://github.com/rails/rails/issues
|
Binary file
|
@@ -0,0 +1,177 @@
|
|
1
|
+
TIMES = (ENV['N'] || 10000).to_i
|
2
|
+
|
3
|
+
require File.expand_path('../../../load_paths', __FILE__)
|
4
|
+
require "active_record"
|
5
|
+
|
6
|
+
conn = { :adapter => 'sqlite3', :database => ':memory:' }
|
7
|
+
|
8
|
+
ActiveRecord::Base.establish_connection(conn)
|
9
|
+
|
10
|
+
class User < ActiveRecord::Base
|
11
|
+
connection.create_table :users, :force => true do |t|
|
12
|
+
t.string :name, :email
|
13
|
+
t.timestamps
|
14
|
+
end
|
15
|
+
|
16
|
+
has_many :exhibits
|
17
|
+
end
|
18
|
+
|
19
|
+
class Exhibit < ActiveRecord::Base
|
20
|
+
connection.create_table :exhibits, :force => true do |t|
|
21
|
+
t.belongs_to :user
|
22
|
+
t.string :name
|
23
|
+
t.text :notes
|
24
|
+
t.timestamps
|
25
|
+
end
|
26
|
+
|
27
|
+
belongs_to :user
|
28
|
+
|
29
|
+
def look; attributes end
|
30
|
+
def feel; look; user.name end
|
31
|
+
|
32
|
+
def self.with_name
|
33
|
+
where("name IS NOT NULL")
|
34
|
+
end
|
35
|
+
|
36
|
+
def self.with_notes
|
37
|
+
where("notes IS NOT NULL")
|
38
|
+
end
|
39
|
+
|
40
|
+
def self.look(exhibits) exhibits.each { |e| e.look } end
|
41
|
+
def self.feel(exhibits) exhibits.each { |e| e.feel } end
|
42
|
+
end
|
43
|
+
|
44
|
+
puts 'Generating data...'
|
45
|
+
|
46
|
+
module ActiveRecord
|
47
|
+
class Faker
|
48
|
+
LOREM = %Q{Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse non aliquet diam. Curabitur vel urna metus, quis malesuada elit.
|
49
|
+
Integer consequat tincidunt felis. Etiam non erat dolor. Vivamus imperdiet nibh sit amet diam eleifend id posuere diam malesuada. Mauris at accumsan sem.
|
50
|
+
Donec id lorem neque. Fusce erat lorem, ornare eu congue vitae, malesuada quis neque. Maecenas vel urna a velit pretium fermentum. Donec tortor enim,
|
51
|
+
tempor venenatis egestas a, tempor sed ipsum. Ut arcu justo, faucibus non imperdiet ac, interdum at diam. Pellentesque ipsum enim, venenatis ut iaculis vitae,
|
52
|
+
varius vitae sem. Sed rutrum quam ac elit euismod bibendum. Donec ultricies ultricies magna, at lacinia libero mollis aliquam. Sed ac arcu in tortor elementum
|
53
|
+
tincidunt vel interdum sem. Curabitur eget erat arcu. Praesent eget eros leo. Nam magna enim, sollicitudin vehicula scelerisque in, vulputate ut libero.
|
54
|
+
Praesent varius tincidunt commodo}.split
|
55
|
+
|
56
|
+
def self.name
|
57
|
+
LOREM.grep(/^\w*$/).sort_by { rand }.first(2).join ' '
|
58
|
+
end
|
59
|
+
|
60
|
+
def self.email
|
61
|
+
LOREM.grep(/^\w*$/).sort_by { rand }.first(2).join('@') + ".com"
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
# pre-compute the insert statements and fake data compilation,
|
67
|
+
# so the benchmarks below show the actual runtime for the execute
|
68
|
+
# method, minus the setup steps
|
69
|
+
|
70
|
+
# Using the same paragraph for all exhibits because it is very slow
|
71
|
+
# to generate unique paragraphs for all exhibits.
|
72
|
+
notes = ActiveRecord::Faker::LOREM.join ' '
|
73
|
+
today = Date.today
|
74
|
+
|
75
|
+
puts 'Inserting 10,000 users and exhibits...'
|
76
|
+
10_000.times do
|
77
|
+
user = User.create(
|
78
|
+
:created_at => today,
|
79
|
+
:name => ActiveRecord::Faker.name,
|
80
|
+
:email => ActiveRecord::Faker.email
|
81
|
+
)
|
82
|
+
|
83
|
+
Exhibit.create(
|
84
|
+
:created_at => today,
|
85
|
+
:name => ActiveRecord::Faker.name,
|
86
|
+
:user => user,
|
87
|
+
:notes => notes
|
88
|
+
)
|
89
|
+
end
|
90
|
+
|
91
|
+
require 'benchmark'
|
92
|
+
|
93
|
+
Benchmark.bm(46) do |x|
|
94
|
+
ar_obj = Exhibit.find(1)
|
95
|
+
attrs = { :name => 'sam' }
|
96
|
+
attrs_first = { :name => 'sam' }
|
97
|
+
attrs_second = { :name => 'tom' }
|
98
|
+
exhibit = {
|
99
|
+
:name => ActiveRecord::Faker.name,
|
100
|
+
:notes => notes,
|
101
|
+
:created_at => Date.today
|
102
|
+
}
|
103
|
+
|
104
|
+
x.report("Model#id (x#{(TIMES * 100).ceil})") do
|
105
|
+
(TIMES * 100).ceil.times { ar_obj.id }
|
106
|
+
end
|
107
|
+
|
108
|
+
x.report 'Model.new (instantiation)' do
|
109
|
+
TIMES.times { Exhibit.new }
|
110
|
+
end
|
111
|
+
|
112
|
+
x.report 'Model.new (setting attributes)' do
|
113
|
+
TIMES.times { Exhibit.new(attrs) }
|
114
|
+
end
|
115
|
+
|
116
|
+
x.report 'Model.first' do
|
117
|
+
TIMES.times { Exhibit.first.look }
|
118
|
+
end
|
119
|
+
|
120
|
+
x.report 'Model.named_scope' do
|
121
|
+
TIMES.times { Exhibit.limit(10).with_name.with_notes }
|
122
|
+
end
|
123
|
+
|
124
|
+
x.report("Model.all limit(100) (x#{(TIMES / 10).ceil})") do
|
125
|
+
(TIMES / 10).ceil.times { Exhibit.look Exhibit.limit(100) }
|
126
|
+
end
|
127
|
+
|
128
|
+
x.report "Model.all limit(100) with relationship (x#{(TIMES / 10).ceil})" do
|
129
|
+
(TIMES / 10).ceil.times { Exhibit.feel Exhibit.limit(100).includes(:user) }
|
130
|
+
end
|
131
|
+
|
132
|
+
x.report "Model.all limit(10,000) x(#{(TIMES / 1000).ceil})" do
|
133
|
+
(TIMES / 1000).ceil.times { Exhibit.look Exhibit.limit(10000) }
|
134
|
+
end
|
135
|
+
|
136
|
+
x.report 'Model.create' do
|
137
|
+
TIMES.times { Exhibit.create(exhibit) }
|
138
|
+
end
|
139
|
+
|
140
|
+
x.report 'Resource#attributes=' do
|
141
|
+
TIMES.times {
|
142
|
+
exhibit = Exhibit.new(attrs_first)
|
143
|
+
exhibit.attributes = attrs_second
|
144
|
+
}
|
145
|
+
end
|
146
|
+
|
147
|
+
x.report 'Resource#update' do
|
148
|
+
TIMES.times { Exhibit.first.update_attributes(:name => 'bob') }
|
149
|
+
end
|
150
|
+
|
151
|
+
x.report 'Resource#destroy' do
|
152
|
+
TIMES.times { Exhibit.first.destroy }
|
153
|
+
end
|
154
|
+
|
155
|
+
x.report 'Model.transaction' do
|
156
|
+
TIMES.times { Exhibit.transaction { Exhibit.new } }
|
157
|
+
end
|
158
|
+
|
159
|
+
x.report 'Model.find(id)' do
|
160
|
+
id = Exhibit.first.id
|
161
|
+
TIMES.times { Exhibit.find(id) }
|
162
|
+
end
|
163
|
+
|
164
|
+
x.report 'Model.find_by_sql' do
|
165
|
+
TIMES.times {
|
166
|
+
Exhibit.find_by_sql("SELECT * FROM exhibits WHERE id = #{(rand * 1000 + 1).to_i}").first
|
167
|
+
}
|
168
|
+
end
|
169
|
+
|
170
|
+
x.report "Model.log x(#{TIMES * 10})" do
|
171
|
+
(TIMES * 10).times { Exhibit.connection.send(:log, "hello", "world") {} }
|
172
|
+
end
|
173
|
+
|
174
|
+
x.report "AR.execute(query) (#{TIMES / 2})" do
|
175
|
+
(TIMES / 2).times { ActiveRecord::Base.connection.execute("Select * from exhibits where id = #{(rand * 1000 + 1).to_i}") }
|
176
|
+
end
|
177
|
+
end
|
data/examples/simple.rb
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
$LOAD_PATH.unshift "#{File.dirname(__FILE__)}/../lib"
|
2
|
+
require 'active_record'
|
3
|
+
|
4
|
+
class Person < ActiveRecord::Base
|
5
|
+
establish_connection :adapter => 'sqlite3', :database => 'foobar.db'
|
6
|
+
connection.create_table table_name, :force => true do |t|
|
7
|
+
t.string :name
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
bob = Person.create!(:name => 'bob')
|
12
|
+
puts Person.all.inspect
|
13
|
+
bob.destroy
|
14
|
+
puts Person.all.inspect
|
@@ -0,0 +1,147 @@
|
|
1
|
+
#--
|
2
|
+
# Copyright (c) 2004-2011 David Heinemeier Hansson
|
3
|
+
#
|
4
|
+
# Permission is hereby granted, free of charge, to any person obtaining
|
5
|
+
# a copy of this software and associated documentation files (the
|
6
|
+
# "Software"), to deal in the Software without restriction, including
|
7
|
+
# without limitation the rights to use, copy, modify, merge, publish,
|
8
|
+
# distribute, sublicense, and/or sell copies of the Software, and to
|
9
|
+
# permit persons to whom the Software is furnished to do so, subject to
|
10
|
+
# the following conditions:
|
11
|
+
#
|
12
|
+
# The above copyright notice and this permission notice shall be
|
13
|
+
# included in all copies or substantial portions of the Software.
|
14
|
+
#
|
15
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
16
|
+
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
17
|
+
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
18
|
+
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
19
|
+
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
20
|
+
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
21
|
+
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
22
|
+
#++
|
23
|
+
|
24
|
+
require 'active_support'
|
25
|
+
require 'active_support/i18n'
|
26
|
+
require 'active_model'
|
27
|
+
require 'arel'
|
28
|
+
|
29
|
+
require 'active_record/version'
|
30
|
+
|
31
|
+
module ActiveRecord
|
32
|
+
extend ActiveSupport::Autoload
|
33
|
+
|
34
|
+
eager_autoload do
|
35
|
+
autoload :ActiveRecordError, 'active_record/errors'
|
36
|
+
autoload :ConnectionNotEstablished, 'active_record/errors'
|
37
|
+
autoload :ConnectionAdapters, 'active_record/connection_adapters/abstract_adapter'
|
38
|
+
|
39
|
+
autoload :Aggregations
|
40
|
+
autoload :Associations
|
41
|
+
autoload :AttributeMethods
|
42
|
+
autoload :AttributeAssignment
|
43
|
+
autoload :AutosaveAssociation
|
44
|
+
|
45
|
+
autoload :Relation
|
46
|
+
|
47
|
+
autoload_under 'relation' do
|
48
|
+
autoload :QueryMethods
|
49
|
+
autoload :FinderMethods
|
50
|
+
autoload :Calculations
|
51
|
+
autoload :PredicateBuilder
|
52
|
+
autoload :SpawnMethods
|
53
|
+
autoload :Batches
|
54
|
+
autoload :Explain
|
55
|
+
autoload :Delegation
|
56
|
+
end
|
57
|
+
|
58
|
+
autoload :Base
|
59
|
+
autoload :Callbacks
|
60
|
+
autoload :CounterCache
|
61
|
+
autoload :DynamicMatchers
|
62
|
+
autoload :DynamicFinderMatch
|
63
|
+
autoload :DynamicScopeMatch
|
64
|
+
autoload :Explain
|
65
|
+
autoload :IdentityMap
|
66
|
+
autoload :Inheritance
|
67
|
+
autoload :Integration
|
68
|
+
autoload :Migration
|
69
|
+
autoload :Migrator, 'active_record/migration'
|
70
|
+
autoload :ModelSchema
|
71
|
+
autoload :NestedAttributes
|
72
|
+
autoload :Observer
|
73
|
+
autoload :Persistence
|
74
|
+
autoload :QueryCache
|
75
|
+
autoload :Querying
|
76
|
+
autoload :ReadonlyAttributes
|
77
|
+
autoload :Reflection
|
78
|
+
autoload :Result
|
79
|
+
autoload :Sanitization
|
80
|
+
autoload :Schema
|
81
|
+
autoload :SchemaDumper
|
82
|
+
autoload :Scoping
|
83
|
+
autoload :Serialization
|
84
|
+
autoload :SessionStore
|
85
|
+
autoload :Store
|
86
|
+
autoload :Timestamp
|
87
|
+
autoload :Transactions
|
88
|
+
autoload :Translation
|
89
|
+
autoload :Validations
|
90
|
+
end
|
91
|
+
|
92
|
+
module Coders
|
93
|
+
autoload :YAMLColumn, 'active_record/coders/yaml_column'
|
94
|
+
end
|
95
|
+
|
96
|
+
module AttributeMethods
|
97
|
+
extend ActiveSupport::Autoload
|
98
|
+
|
99
|
+
eager_autoload do
|
100
|
+
autoload :BeforeTypeCast
|
101
|
+
autoload :Dirty
|
102
|
+
autoload :PrimaryKey
|
103
|
+
autoload :Query
|
104
|
+
autoload :Read
|
105
|
+
autoload :TimeZoneConversion
|
106
|
+
autoload :Write
|
107
|
+
autoload :Serialization
|
108
|
+
autoload :DeprecatedUnderscoreRead
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
module Locking
|
113
|
+
extend ActiveSupport::Autoload
|
114
|
+
|
115
|
+
eager_autoload do
|
116
|
+
autoload :Optimistic
|
117
|
+
autoload :Pessimistic
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
module ConnectionAdapters
|
122
|
+
extend ActiveSupport::Autoload
|
123
|
+
|
124
|
+
eager_autoload do
|
125
|
+
autoload :AbstractAdapter
|
126
|
+
autoload :ConnectionManagement, "active_record/connection_adapters/abstract/connection_pool"
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
module Scoping
|
131
|
+
extend ActiveSupport::Autoload
|
132
|
+
|
133
|
+
eager_autoload do
|
134
|
+
autoload :Named
|
135
|
+
autoload :Default
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
autoload :TestCase
|
140
|
+
autoload :TestFixtures, 'active_record/fixtures'
|
141
|
+
end
|
142
|
+
|
143
|
+
ActiveSupport.on_load(:active_record) do
|
144
|
+
Arel::Table.engine = self
|
145
|
+
end
|
146
|
+
|
147
|
+
I18n.load_path << File.dirname(__FILE__) + '/active_record/locale/en.yml'
|