mack-data_mapper 0.8.1 → 0.8.2
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/lib/gems/addressable-2.0.0/lib/addressable/idna.rb +4867 -0
- data/lib/gems/addressable-2.0.0/lib/addressable/uri.rb +2469 -0
- data/lib/gems/addressable-2.0.0/lib/addressable/version.rb +35 -0
- data/lib/gems/dm-aggregates-0.9.7/lib/dm-aggregates/adapters/data_objects_adapter.rb +85 -0
- data/lib/gems/dm-aggregates-0.9.7/lib/dm-aggregates/aggregate_functions.rb +201 -0
- data/lib/gems/dm-aggregates-0.9.7/lib/dm-aggregates/collection.rb +11 -0
- data/lib/gems/dm-aggregates-0.9.7/lib/dm-aggregates/model.rb +11 -0
- data/lib/gems/dm-aggregates-0.9.7/lib/dm-aggregates/repository.rb +7 -0
- data/lib/gems/dm-aggregates-0.9.7/lib/dm-aggregates/support/symbol.rb +21 -0
- data/lib/gems/dm-aggregates-0.9.7/lib/dm-aggregates/version.rb +7 -0
- data/lib/gems/dm-aggregates-0.9.7/lib/dm-aggregates.rb +15 -0
- data/lib/gems/dm-core-0.9.7/lib/dm-core/adapters/abstract_adapter.rb +209 -0
- data/lib/gems/dm-core-0.9.7/lib/dm-core/adapters/data_objects_adapter.rb +709 -0
- data/lib/gems/dm-core-0.9.7/lib/dm-core/adapters/in_memory_adapter.rb +87 -0
- data/lib/gems/dm-core-0.9.7/lib/dm-core/adapters/mysql_adapter.rb +136 -0
- data/lib/gems/dm-core-0.9.7/lib/dm-core/adapters/postgres_adapter.rb +188 -0
- data/lib/gems/dm-core-0.9.7/lib/dm-core/adapters/sqlite3_adapter.rb +105 -0
- data/lib/gems/dm-core-0.9.7/lib/dm-core/adapters.rb +22 -0
- data/lib/gems/dm-core-0.9.7/lib/dm-core/associations/many_to_many.rb +147 -0
- data/lib/gems/dm-core-0.9.7/lib/dm-core/associations/many_to_one.rb +107 -0
- data/lib/gems/dm-core-0.9.7/lib/dm-core/associations/one_to_many.rb +318 -0
- data/lib/gems/dm-core-0.9.7/lib/dm-core/associations/one_to_one.rb +61 -0
- data/lib/gems/dm-core-0.9.7/lib/dm-core/associations/relationship.rb +223 -0
- data/lib/gems/dm-core-0.9.7/lib/dm-core/associations/relationship_chain.rb +81 -0
- data/lib/gems/dm-core-0.9.7/lib/dm-core/associations.rb +200 -0
- data/lib/gems/dm-core-0.9.7/lib/dm-core/auto_migrations.rb +105 -0
- data/lib/gems/dm-core-0.9.7/lib/dm-core/collection.rb +642 -0
- data/lib/gems/dm-core-0.9.7/lib/dm-core/dependency_queue.rb +32 -0
- data/lib/gems/dm-core-0.9.7/lib/dm-core/hook.rb +11 -0
- data/lib/gems/dm-core-0.9.7/lib/dm-core/identity_map.rb +42 -0
- data/lib/gems/dm-core-0.9.7/lib/dm-core/is.rb +16 -0
- data/lib/gems/dm-core-0.9.7/lib/dm-core/logger.rb +232 -0
- data/lib/gems/dm-core-0.9.7/lib/dm-core/migrations/destructive_migrations.rb +17 -0
- data/lib/gems/dm-core-0.9.7/lib/dm-core/migrator.rb +29 -0
- data/lib/gems/dm-core-0.9.7/lib/dm-core/model.rb +488 -0
- data/lib/gems/dm-core-0.9.7/lib/dm-core/naming_conventions.rb +84 -0
- data/lib/gems/dm-core-0.9.7/lib/dm-core/property.rb +663 -0
- data/lib/gems/dm-core-0.9.7/lib/dm-core/property_set.rb +169 -0
- data/lib/gems/dm-core-0.9.7/lib/dm-core/query.rb +628 -0
- data/lib/gems/dm-core-0.9.7/lib/dm-core/repository.rb +159 -0
- data/lib/gems/dm-core-0.9.7/lib/dm-core/resource.rb +637 -0
- data/lib/gems/dm-core-0.9.7/lib/dm-core/scope.rb +58 -0
- data/lib/gems/dm-core-0.9.7/lib/dm-core/support/array.rb +13 -0
- data/lib/gems/dm-core-0.9.7/lib/dm-core/support/assertions.rb +8 -0
- data/lib/gems/dm-core-0.9.7/lib/dm-core/support/errors.rb +23 -0
- data/lib/gems/dm-core-0.9.7/lib/dm-core/support/kernel.rb +11 -0
- data/lib/gems/dm-core-0.9.7/lib/dm-core/support/symbol.rb +41 -0
- data/lib/gems/dm-core-0.9.7/lib/dm-core/support.rb +7 -0
- data/lib/gems/dm-core-0.9.7/lib/dm-core/transaction.rb +267 -0
- data/lib/gems/dm-core-0.9.7/lib/dm-core/type.rb +160 -0
- data/lib/gems/dm-core-0.9.7/lib/dm-core/type_map.rb +80 -0
- data/lib/gems/dm-core-0.9.7/lib/dm-core/types/boolean.rb +7 -0
- data/lib/gems/dm-core-0.9.7/lib/dm-core/types/discriminator.rb +34 -0
- data/lib/gems/dm-core-0.9.7/lib/dm-core/types/object.rb +24 -0
- data/lib/gems/dm-core-0.9.7/lib/dm-core/types/paranoid_boolean.rb +34 -0
- data/lib/gems/dm-core-0.9.7/lib/dm-core/types/paranoid_datetime.rb +33 -0
- data/lib/gems/dm-core-0.9.7/lib/dm-core/types/serial.rb +9 -0
- data/lib/gems/dm-core-0.9.7/lib/dm-core/types/text.rb +10 -0
- data/lib/gems/dm-core-0.9.7/lib/dm-core/types.rb +19 -0
- data/lib/gems/dm-core-0.9.7/lib/dm-core/version.rb +3 -0
- data/lib/gems/dm-core-0.9.7/lib/dm-core.rb +217 -0
- data/lib/gems/dm-core-0.9.7/script/all +5 -0
- data/lib/gems/dm-core-0.9.7/script/performance.rb +284 -0
- data/lib/gems/dm-core-0.9.7/script/profile.rb +87 -0
- data/lib/gems/dm-migrations-0.9.7/lib/dm-migrations/version.rb +5 -0
- data/lib/gems/dm-migrations-0.9.7/lib/dm-migrations.rb +1 -0
- data/lib/gems/dm-migrations-0.9.7/lib/migration.rb +215 -0
- data/lib/gems/dm-migrations-0.9.7/lib/migration_runner.rb +88 -0
- data/lib/gems/dm-migrations-0.9.7/lib/spec/example/migration_example_group.rb +73 -0
- data/lib/gems/dm-migrations-0.9.7/lib/spec/matchers/migration_matchers.rb +107 -0
- data/lib/gems/dm-migrations-0.9.7/lib/sql/column.rb +9 -0
- data/lib/gems/dm-migrations-0.9.7/lib/sql/mysql.rb +52 -0
- data/lib/gems/dm-migrations-0.9.7/lib/sql/postgresql.rb +78 -0
- data/lib/gems/dm-migrations-0.9.7/lib/sql/sqlite3.rb +43 -0
- data/lib/gems/dm-migrations-0.9.7/lib/sql/table.rb +19 -0
- data/lib/gems/dm-migrations-0.9.7/lib/sql/table_creator.rb +81 -0
- data/lib/gems/dm-migrations-0.9.7/lib/sql/table_modifier.rb +53 -0
- data/lib/gems/dm-migrations-0.9.7/lib/sql.rb +10 -0
- data/lib/gems/dm-observer-0.9.7/lib/dm-observer/version.rb +5 -0
- data/lib/gems/dm-observer-0.9.7/lib/dm-observer.rb +91 -0
- data/lib/gems/dm-serializer-0.9.7/lib/dm-serializer/version.rb +5 -0
- data/lib/gems/dm-serializer-0.9.7/lib/dm-serializer.rb +183 -0
- data/lib/gems/dm-timestamps-0.9.7/lib/dm-timestamps/version.rb +5 -0
- data/lib/gems/dm-timestamps-0.9.7/lib/dm-timestamps.rb +57 -0
- data/lib/gems/dm-types-0.9.7/lib/dm-types/bcrypt_hash.rb +31 -0
- data/lib/gems/dm-types-0.9.7/lib/dm-types/csv.rb +28 -0
- data/lib/gems/dm-types-0.9.7/lib/dm-types/enum.rb +70 -0
- data/lib/gems/dm-types-0.9.7/lib/dm-types/epoch_time.rb +27 -0
- data/lib/gems/dm-types-0.9.7/lib/dm-types/file_path.rb +27 -0
- data/lib/gems/dm-types-0.9.7/lib/dm-types/flag.rb +61 -0
- data/lib/gems/dm-types-0.9.7/lib/dm-types/ip_address.rb +30 -0
- data/lib/gems/dm-types-0.9.7/lib/dm-types/json.rb +40 -0
- data/lib/gems/dm-types-0.9.7/lib/dm-types/regexp.rb +20 -0
- data/lib/gems/dm-types-0.9.7/lib/dm-types/serial.rb +8 -0
- data/lib/gems/dm-types-0.9.7/lib/dm-types/slug.rb +37 -0
- data/lib/gems/dm-types-0.9.7/lib/dm-types/uri.rb +29 -0
- data/lib/gems/dm-types-0.9.7/lib/dm-types/uuid.rb +64 -0
- data/lib/gems/dm-types-0.9.7/lib/dm-types/version.rb +5 -0
- data/lib/gems/dm-types-0.9.7/lib/dm-types/yaml.rb +36 -0
- data/lib/gems/dm-types-0.9.7/lib/dm-types.rb +28 -0
- data/lib/gems/dm-validations-0.9.7/lib/dm-validations/absent_field_validator.rb +60 -0
- data/lib/gems/dm-validations-0.9.7/lib/dm-validations/acceptance_validator.rb +76 -0
- data/lib/gems/dm-validations-0.9.7/lib/dm-validations/auto_validate.rb +153 -0
- data/lib/gems/dm-validations-0.9.7/lib/dm-validations/block_validator.rb +60 -0
- data/lib/gems/dm-validations-0.9.7/lib/dm-validations/confirmation_validator.rb +80 -0
- data/lib/gems/dm-validations-0.9.7/lib/dm-validations/contextual_validators.rb +56 -0
- data/lib/gems/dm-validations-0.9.7/lib/dm-validations/custom_validator.rb +72 -0
- data/lib/gems/dm-validations-0.9.7/lib/dm-validations/format_validator.rb +97 -0
- data/lib/gems/dm-validations-0.9.7/lib/dm-validations/formats/email.rb +40 -0
- data/lib/gems/dm-validations-0.9.7/lib/dm-validations/formats/url.rb +20 -0
- data/lib/gems/dm-validations-0.9.7/lib/dm-validations/generic_validator.rb +100 -0
- data/lib/gems/dm-validations-0.9.7/lib/dm-validations/length_validator.rb +113 -0
- data/lib/gems/dm-validations-0.9.7/lib/dm-validations/method_validator.rb +68 -0
- data/lib/gems/dm-validations-0.9.7/lib/dm-validations/numeric_validator.rb +83 -0
- data/lib/gems/dm-validations-0.9.7/lib/dm-validations/primitive_validator.rb +60 -0
- data/lib/gems/dm-validations-0.9.7/lib/dm-validations/required_field_validator.rb +88 -0
- data/lib/gems/dm-validations-0.9.7/lib/dm-validations/support/object.rb +5 -0
- data/lib/gems/dm-validations-0.9.7/lib/dm-validations/uniqueness_validator.rb +64 -0
- data/lib/gems/dm-validations-0.9.7/lib/dm-validations/validation_errors.rb +63 -0
- data/lib/gems/dm-validations-0.9.7/lib/dm-validations/version.rb +5 -0
- data/lib/gems/dm-validations-0.9.7/lib/dm-validations/within_validator.rb +53 -0
- data/lib/gems/dm-validations-0.9.7/lib/dm-validations.rb +234 -0
- data/lib/gems/json_pure-1.1.3/GPL +340 -0
- data/lib/gems/json_pure-1.1.3/VERSION +1 -0
- data/lib/gems/json_pure-1.1.3/bin/edit_json.rb +10 -0
- data/lib/gems/json_pure-1.1.3/bin/prettify_json.rb +76 -0
- data/lib/gems/json_pure-1.1.3/lib/json/Array.xpm +21 -0
- data/lib/gems/json_pure-1.1.3/lib/json/FalseClass.xpm +21 -0
- data/lib/gems/json_pure-1.1.3/lib/json/Hash.xpm +21 -0
- data/lib/gems/json_pure-1.1.3/lib/json/Key.xpm +73 -0
- data/lib/gems/json_pure-1.1.3/lib/json/NilClass.xpm +21 -0
- data/lib/gems/json_pure-1.1.3/lib/json/Numeric.xpm +28 -0
- data/lib/gems/json_pure-1.1.3/lib/json/String.xpm +96 -0
- data/lib/gems/json_pure-1.1.3/lib/json/TrueClass.xpm +21 -0
- data/lib/gems/json_pure-1.1.3/lib/json/add/core.rb +135 -0
- data/lib/gems/json_pure-1.1.3/lib/json/add/rails.rb +58 -0
- data/lib/gems/json_pure-1.1.3/lib/json/common.rb +354 -0
- data/lib/gems/json_pure-1.1.3/lib/json/editor.rb +1362 -0
- data/lib/gems/json_pure-1.1.3/lib/json/ext.rb +13 -0
- data/lib/gems/json_pure-1.1.3/lib/json/json.xpm +1499 -0
- data/lib/gems/json_pure-1.1.3/lib/json/pure/generator.rb +394 -0
- data/lib/gems/json_pure-1.1.3/lib/json/pure/parser.rb +259 -0
- data/lib/gems/json_pure-1.1.3/lib/json/pure.rb +75 -0
- data/lib/gems/json_pure-1.1.3/lib/json/version.rb +9 -0
- data/lib/gems/json_pure-1.1.3/lib/json.rb +235 -0
- data/lib/gems/launchy-0.3.2/bin/launchy +12 -0
- data/lib/gems/launchy-0.3.2/lib/launchy/application.rb +163 -0
- data/lib/gems/launchy-0.3.2/lib/launchy/browser.rb +85 -0
- data/lib/gems/launchy-0.3.2/lib/launchy/command_line.rb +48 -0
- data/lib/gems/launchy-0.3.2/lib/launchy/gemspec.rb +53 -0
- data/lib/gems/launchy-0.3.2/lib/launchy/specification.rb +133 -0
- data/lib/gems/launchy-0.3.2/lib/launchy/version.rb +18 -0
- data/lib/gems/launchy-0.3.2/lib/launchy.rb +58 -0
- data/lib/gems/uuidtools-1.0.3/lib/uuidtools/version.rb +32 -0
- data/lib/gems/uuidtools-1.0.3/lib/uuidtools.rb +648 -0
- data/lib/gems.rb +13 -0
- data/lib/mack-data_mapper/migration_generator/migration_generator.rb +5 -0
- data/lib/mack-data_mapper/migration_generator/templates/db/migrations/%=@migration_name%.rb.template +1 -1
- data/lib/mack-data_mapper/model_generator/manifest.yml +3 -3
- data/lib/mack-data_mapper/model_generator/model_generator.rb +8 -1
- data/lib/mack-data_mapper/model_generator/templates/model.rb.template +1 -1
- data/lib/mack-data_mapper/model_generator/templates/rspec.rb.template +1 -1
- data/lib/mack-data_mapper/model_generator/templates/test_case.rb.template +1 -1
- data/lib/mack-data_mapper.rb +3 -2
- data/lib/mack-data_mapper_tasks.rb +7 -0
- metadata +235 -86
|
@@ -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
|
|
@@ -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,217 @@
|
|
|
1
|
+
# This file begins the loading sequence.
|
|
2
|
+
#
|
|
3
|
+
# Quick Overview:
|
|
4
|
+
# * Requires fastthread, support libs, and base.
|
|
5
|
+
# * Sets the application root and environment for compatibility with frameworks
|
|
6
|
+
# such as Rails or Merb.
|
|
7
|
+
# * Checks for the database.yml and loads it if it exists.
|
|
8
|
+
# * Sets up the database using the config from the Yaml file or from the
|
|
9
|
+
# environment.
|
|
10
|
+
#
|
|
11
|
+
|
|
12
|
+
require 'date'
|
|
13
|
+
require 'pathname'
|
|
14
|
+
require 'set'
|
|
15
|
+
require 'time'
|
|
16
|
+
require 'yaml'
|
|
17
|
+
|
|
18
|
+
require 'rubygems'
|
|
19
|
+
|
|
20
|
+
gem 'addressable', '~>2.0'
|
|
21
|
+
require 'addressable/uri'
|
|
22
|
+
|
|
23
|
+
gem 'extlib', '~>0.9.8'
|
|
24
|
+
require 'extlib'
|
|
25
|
+
require "extlib/inflection"
|
|
26
|
+
|
|
27
|
+
begin
|
|
28
|
+
require 'fastthread'
|
|
29
|
+
rescue LoadError
|
|
30
|
+
# fastthread not installed
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
dir = Pathname(__FILE__).dirname.expand_path / 'dm-core'
|
|
34
|
+
|
|
35
|
+
require dir / 'support'
|
|
36
|
+
require dir / 'resource'
|
|
37
|
+
require dir / 'model'
|
|
38
|
+
|
|
39
|
+
require dir / 'dependency_queue'
|
|
40
|
+
require dir / 'type'
|
|
41
|
+
require dir / 'type_map'
|
|
42
|
+
require dir / 'types'
|
|
43
|
+
require dir / 'hook'
|
|
44
|
+
require dir / 'associations'
|
|
45
|
+
require dir / 'auto_migrations'
|
|
46
|
+
require dir / 'identity_map'
|
|
47
|
+
require dir / 'logger'
|
|
48
|
+
require dir / 'migrator'
|
|
49
|
+
require dir / 'naming_conventions'
|
|
50
|
+
require dir / 'property_set'
|
|
51
|
+
require dir / 'query'
|
|
52
|
+
require dir / 'transaction'
|
|
53
|
+
require dir / 'repository'
|
|
54
|
+
require dir / 'scope'
|
|
55
|
+
require dir / 'property'
|
|
56
|
+
require dir / 'adapters'
|
|
57
|
+
require dir / 'collection'
|
|
58
|
+
require dir / 'is'
|
|
59
|
+
|
|
60
|
+
# == Setup and Configuration
|
|
61
|
+
# DataMapper uses URIs or a connection hash to connect to your data-store.
|
|
62
|
+
# URI connections takes the form of:
|
|
63
|
+
# DataMapper.setup(:default, 'protocol://username:password@localhost:port/path/to/repo')
|
|
64
|
+
#
|
|
65
|
+
# Breaking this down, the first argument is the name you wish to give this
|
|
66
|
+
# connection. If you do not specify one, it will be assigned :default. If you
|
|
67
|
+
# would like to connect to more than one data-store, simply issue this command
|
|
68
|
+
# again, but with a different name specified.
|
|
69
|
+
#
|
|
70
|
+
# In order to issue ORM commands without specifying the repository context, you
|
|
71
|
+
# must define the :default database. Otherwise, you'll need to wrap your ORM
|
|
72
|
+
# calls in <tt>repository(:name) { }</tt>.
|
|
73
|
+
#
|
|
74
|
+
# Second, the URI breaks down into the access protocol, the username, the
|
|
75
|
+
# server, the password, and whatever path information is needed to properly
|
|
76
|
+
# address the data-store on the server.
|
|
77
|
+
#
|
|
78
|
+
# Here's some examples
|
|
79
|
+
# DataMapper.setup(:default, "sqlite3://path/to/your/project/db/development.db")
|
|
80
|
+
# DataMapper.setup(:default, "mysql://localhost/dm_core_test")
|
|
81
|
+
# # no auth-info
|
|
82
|
+
# DataMapper.setup(:default, "postgres://root:supahsekret@127.0.0.1/dm_core_test")
|
|
83
|
+
# # with auth-info
|
|
84
|
+
#
|
|
85
|
+
#
|
|
86
|
+
# Alternatively, you can supply a hash as the second parameter, which would
|
|
87
|
+
# take the form:
|
|
88
|
+
#
|
|
89
|
+
# DataMapper.setup(:default, {
|
|
90
|
+
# :adapter => 'adapter_name_here',
|
|
91
|
+
# :database => "path/to/repo",
|
|
92
|
+
# :username => 'username',
|
|
93
|
+
# :password => 'password',
|
|
94
|
+
# :host => 'hostname'
|
|
95
|
+
# })
|
|
96
|
+
#
|
|
97
|
+
# === Logging
|
|
98
|
+
# To turn on error logging to STDOUT, issue:
|
|
99
|
+
#
|
|
100
|
+
# DataMapper::Logger.new(STDOUT, 0)
|
|
101
|
+
#
|
|
102
|
+
# You can pass a file location ("/path/to/log/file.log") in place of STDOUT.
|
|
103
|
+
# see DataMapper::Logger for more information.
|
|
104
|
+
#
|
|
105
|
+
module DataMapper
|
|
106
|
+
extend Assertions
|
|
107
|
+
|
|
108
|
+
def self.root
|
|
109
|
+
@root ||= Pathname(__FILE__).dirname.parent.expand_path
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
##
|
|
113
|
+
# Setups up a connection to a data-store
|
|
114
|
+
#
|
|
115
|
+
# @param Symbol name a name for the context, defaults to :default
|
|
116
|
+
# @param [Hash{Symbol => String}, Addressable::URI, String] uri_or_options
|
|
117
|
+
# connection information
|
|
118
|
+
#
|
|
119
|
+
# @return Repository the resulting setup repository
|
|
120
|
+
#
|
|
121
|
+
# @raise ArgumentError "+name+ must be a Symbol, but was..." indicates that
|
|
122
|
+
# an invalid argument was passed for name[Symbol]
|
|
123
|
+
# @raise [ArgumentError] "+uri_or_options+ must be a Hash, URI or String,
|
|
124
|
+
# but was..." indicates that connection information could not be gleaned
|
|
125
|
+
# from the given uri_or_options<Hash, Addressable::URI, String>
|
|
126
|
+
#
|
|
127
|
+
# -
|
|
128
|
+
# @api public
|
|
129
|
+
def self.setup(name, uri_or_options)
|
|
130
|
+
assert_kind_of 'name', name, Symbol
|
|
131
|
+
assert_kind_of 'uri_or_options', uri_or_options, Addressable::URI, Hash, String
|
|
132
|
+
|
|
133
|
+
case uri_or_options
|
|
134
|
+
when Hash
|
|
135
|
+
adapter_name = uri_or_options[:adapter].to_s
|
|
136
|
+
when String, DataObjects::URI, Addressable::URI
|
|
137
|
+
uri_or_options = DataObjects::URI.parse(uri_or_options) if uri_or_options.kind_of?(String)
|
|
138
|
+
adapter_name = uri_or_options.scheme
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
class_name = Extlib::Inflection.classify(adapter_name) + 'Adapter'
|
|
142
|
+
|
|
143
|
+
unless Adapters::const_defined?(class_name)
|
|
144
|
+
lib_name = "#{Extlib::Inflection.underscore(adapter_name)}_adapter"
|
|
145
|
+
begin
|
|
146
|
+
require root / 'lib' / 'dm-core' / 'adapters' / lib_name
|
|
147
|
+
rescue LoadError => e
|
|
148
|
+
begin
|
|
149
|
+
require lib_name
|
|
150
|
+
rescue Exception
|
|
151
|
+
# library not found, raise the original error
|
|
152
|
+
raise e
|
|
153
|
+
end
|
|
154
|
+
end
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
Repository.adapters[name] = Adapters::const_get(class_name).new(name, uri_or_options)
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
##
|
|
161
|
+
# Block Syntax
|
|
162
|
+
# Pushes the named repository onto the context-stack,
|
|
163
|
+
# yields a new session, and pops the context-stack.
|
|
164
|
+
#
|
|
165
|
+
# Non-Block Syntax
|
|
166
|
+
# Returns the current session, or if there is none,
|
|
167
|
+
# a new Session.
|
|
168
|
+
#
|
|
169
|
+
# @param [Symbol] args the name of a repository to act within or return, :default is default
|
|
170
|
+
# @yield [Proc] (optional) block to execute within the context of the named repository
|
|
171
|
+
# @demo spec/integration/repository_spec.rb
|
|
172
|
+
def self.repository(name = nil) # :yields: current_context
|
|
173
|
+
current_repository = if name
|
|
174
|
+
raise ArgumentError, "First optional argument must be a Symbol, but was #{args.first.inspect}" unless name.is_a?(Symbol)
|
|
175
|
+
Repository.context.detect { |r| r.name == name } || Repository.new(name)
|
|
176
|
+
else
|
|
177
|
+
Repository.context.last || Repository.new(Repository.default_name)
|
|
178
|
+
end
|
|
179
|
+
|
|
180
|
+
if block_given?
|
|
181
|
+
current_repository.scope { |*block_args| yield(*block_args) }
|
|
182
|
+
else
|
|
183
|
+
current_repository
|
|
184
|
+
end
|
|
185
|
+
end
|
|
186
|
+
|
|
187
|
+
# A logger should always be present. Lets be consistent with DO
|
|
188
|
+
Logger.new(nil, :off)
|
|
189
|
+
|
|
190
|
+
##
|
|
191
|
+
# destructively migrates the repository upwards to match model definitions
|
|
192
|
+
#
|
|
193
|
+
# @param [Symbol] name repository to act on, :default is the default
|
|
194
|
+
def self.migrate!(name = Repository.default_name)
|
|
195
|
+
repository(name).migrate!
|
|
196
|
+
end
|
|
197
|
+
|
|
198
|
+
##
|
|
199
|
+
# drops and recreates the repository upwards to match model definitions
|
|
200
|
+
#
|
|
201
|
+
# @param [Symbol] name repository to act on, :default is the default
|
|
202
|
+
def self.auto_migrate!(repository_name = nil)
|
|
203
|
+
AutoMigrator.auto_migrate(repository_name)
|
|
204
|
+
end
|
|
205
|
+
|
|
206
|
+
def self.auto_upgrade!(repository_name = nil)
|
|
207
|
+
AutoMigrator.auto_upgrade(repository_name)
|
|
208
|
+
end
|
|
209
|
+
|
|
210
|
+
def self.prepare(*args, &blk)
|
|
211
|
+
yield repository(*args)
|
|
212
|
+
end
|
|
213
|
+
|
|
214
|
+
def self.dependency_queue
|
|
215
|
+
@dependency_queue ||= DependencyQueue.new
|
|
216
|
+
end
|
|
217
|
+
end
|
|
@@ -0,0 +1,284 @@
|
|
|
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 'rubygems'
|
|
7
|
+
require 'ftools'
|
|
8
|
+
|
|
9
|
+
# sudo gem install rbench
|
|
10
|
+
# OR git clone git://github.com/somebee/rbench.git , rake install
|
|
11
|
+
gem 'rbench', '>=0.2.2'
|
|
12
|
+
require 'rbench'
|
|
13
|
+
|
|
14
|
+
gem 'faker', '>=0.3.1'
|
|
15
|
+
require 'faker'
|
|
16
|
+
|
|
17
|
+
gem 'activerecord', '>=2.1.0'
|
|
18
|
+
require 'active_record'
|
|
19
|
+
|
|
20
|
+
socket_file = Pathname.glob(%w[
|
|
21
|
+
/opt/local/var/run/mysql5/mysqld.sock
|
|
22
|
+
tmp/mysqld.sock
|
|
23
|
+
/tmp/mysqld.sock
|
|
24
|
+
tmp/mysql.sock
|
|
25
|
+
/tmp/mysql.sock
|
|
26
|
+
/var/mysql/mysql.sock
|
|
27
|
+
/var/run/mysqld/mysqld.sock
|
|
28
|
+
]).find { |path| path.socket? }
|
|
29
|
+
|
|
30
|
+
configuration_options = {
|
|
31
|
+
:adapter => 'mysql',
|
|
32
|
+
:username => 'root',
|
|
33
|
+
:password => '',
|
|
34
|
+
:database => 'data_mapper_1',
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
configuration_options[:socket] = socket_file unless socket_file.nil?
|
|
38
|
+
|
|
39
|
+
log_dir = DataMapper.root / 'log'
|
|
40
|
+
log_dir.mkdir unless log_dir.directory?
|
|
41
|
+
|
|
42
|
+
DataMapper::Logger.new(log_dir / 'dm.log', :off)
|
|
43
|
+
adapter = DataMapper.setup(:default, "mysql://root@localhost/data_mapper_1?socket=#{socket_file}")
|
|
44
|
+
|
|
45
|
+
if configuration_options[:adapter]
|
|
46
|
+
sqlfile = File.join(File.dirname(__FILE__),'..','tmp','performance.sql')
|
|
47
|
+
mysql_bin = %w[mysql mysql5].select{|bin| `which #{bin}`.length > 0 }
|
|
48
|
+
mysqldump_bin = %w[mysqldump mysqldump5].select{|bin| `which #{bin}`.length > 0 }
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
ActiveRecord::Base.logger = Logger.new(log_dir / 'ar.log')
|
|
52
|
+
ActiveRecord::Base.logger.level = 0
|
|
53
|
+
|
|
54
|
+
ActiveRecord::Base.establish_connection(configuration_options)
|
|
55
|
+
|
|
56
|
+
class ARExhibit < ActiveRecord::Base #:nodoc:
|
|
57
|
+
set_table_name 'exhibits'
|
|
58
|
+
|
|
59
|
+
belongs_to :user, :class_name => 'ARUser', :foreign_key => 'user_id'
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
class ARUser < ActiveRecord::Base #:nodoc:
|
|
63
|
+
set_table_name 'users'
|
|
64
|
+
|
|
65
|
+
has_many :exhibits, :foreign_key => 'user_id'
|
|
66
|
+
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
ARExhibit.find_by_sql('SELECT 1')
|
|
70
|
+
|
|
71
|
+
class Exhibit
|
|
72
|
+
include DataMapper::Resource
|
|
73
|
+
|
|
74
|
+
property :id, Serial
|
|
75
|
+
property :name, String
|
|
76
|
+
property :zoo_id, Integer
|
|
77
|
+
property :user_id, Integer
|
|
78
|
+
property :notes, Text, :lazy => true
|
|
79
|
+
property :created_on, Date
|
|
80
|
+
|
|
81
|
+
belongs_to :user
|
|
82
|
+
# property :updated_at, DateTime
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
class User
|
|
86
|
+
include DataMapper::Resource
|
|
87
|
+
|
|
88
|
+
property :id, Serial
|
|
89
|
+
property :name, String
|
|
90
|
+
property :email, String
|
|
91
|
+
property :about, Text, :lazy => true
|
|
92
|
+
property :created_on, Date
|
|
93
|
+
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
touch_attributes = lambda do |exhibits|
|
|
97
|
+
[*exhibits].each do |exhibit|
|
|
98
|
+
exhibit.id
|
|
99
|
+
exhibit.name
|
|
100
|
+
exhibit.created_on
|
|
101
|
+
end
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
touch_relationships = lambda do |exhibits|
|
|
105
|
+
[*exhibits].each do |exhibit|
|
|
106
|
+
exhibit.id
|
|
107
|
+
exhibit.name
|
|
108
|
+
exhibit.created_on
|
|
109
|
+
exhibit.user
|
|
110
|
+
end
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
c = configuration_options
|
|
115
|
+
|
|
116
|
+
if sqlfile && File.exists?(sqlfile)
|
|
117
|
+
puts "Found data-file. Importing from #{sqlfile}"
|
|
118
|
+
#adapter.execute("LOAD DATA LOCAL INFILE '#{sqlfile}' INTO TABLE exhibits")
|
|
119
|
+
`#{mysql_bin} -u #{c[:username]} #{"-p#{c[:password]}" unless c[:password].blank?} #{c[:database]} < #{sqlfile}`
|
|
120
|
+
else
|
|
121
|
+
|
|
122
|
+
puts "Generating data for benchmarking..."
|
|
123
|
+
|
|
124
|
+
User.auto_migrate!
|
|
125
|
+
Exhibit.auto_migrate!
|
|
126
|
+
|
|
127
|
+
users = []
|
|
128
|
+
exhibits = []
|
|
129
|
+
|
|
130
|
+
# pre-compute the insert statements and fake data compilation,
|
|
131
|
+
# so the benchmarks below show the actual runtime for the execute
|
|
132
|
+
# method, minus the setup steps
|
|
133
|
+
|
|
134
|
+
# Using the same paragraph for all exhibits because it is very slow
|
|
135
|
+
# to generate unique paragraphs for all exhibits.
|
|
136
|
+
paragraph = Faker::Lorem.paragraphs.join($/)
|
|
137
|
+
|
|
138
|
+
10_000.times do |i|
|
|
139
|
+
users << [
|
|
140
|
+
'INSERT INTO `users` (`name`,`email`,`created_on`) VALUES (?, ?, ?)',
|
|
141
|
+
Faker::Name.name,
|
|
142
|
+
Faker::Internet.email,
|
|
143
|
+
Date.today
|
|
144
|
+
]
|
|
145
|
+
|
|
146
|
+
exhibits << [
|
|
147
|
+
'INSERT INTO `exhibits` (`name`, `zoo_id`, `user_id`, `notes`, `created_on`) VALUES (?, ?, ?, ?, ?)',
|
|
148
|
+
Faker::Company.name,
|
|
149
|
+
rand(10).ceil,
|
|
150
|
+
i,
|
|
151
|
+
paragraph,#Faker::Lorem.paragraphs.join($/),
|
|
152
|
+
Date.today
|
|
153
|
+
]
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
puts "Inserting 10,000 users..."
|
|
157
|
+
10_000.times { |i| adapter.execute(*users.at(i)) }
|
|
158
|
+
puts "Inserting 10,000 exhibits..."
|
|
159
|
+
10_000.times { |i| adapter.execute(*exhibits.at(i)) }
|
|
160
|
+
|
|
161
|
+
if sqlfile
|
|
162
|
+
answer = nil
|
|
163
|
+
until answer && answer[/^$|y|yes|n|no/]
|
|
164
|
+
print("Would you like to dump data into tmp/performance.sql (for faster setup)? [Yn]");
|
|
165
|
+
STDOUT.flush
|
|
166
|
+
answer = gets
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
if answer[/^$|y|yes/]
|
|
170
|
+
File.makedirs(File.dirname(sqlfile))
|
|
171
|
+
#adapter.execute("SELECT * INTO OUTFILE '#{sqlfile}' FROM exhibits;")
|
|
172
|
+
`#{mysqldump_bin} -u #{c[:username]} #{"-p#{c[:password]}" unless c[:password].blank?} #{c[:database]} exhibits users > #{sqlfile}`
|
|
173
|
+
puts "File saved\n"
|
|
174
|
+
end
|
|
175
|
+
end
|
|
176
|
+
|
|
177
|
+
end
|
|
178
|
+
|
|
179
|
+
TIMES = ENV['x'] ? ENV['x'].to_i : 10_000
|
|
180
|
+
|
|
181
|
+
puts "You can specify how many times you want to run the benchmarks with rake:perf x=(number)"
|
|
182
|
+
puts "Some tasks will be run 10 and 1000 times less than (number)"
|
|
183
|
+
puts "Benchmarks will now run #{TIMES} times"
|
|
184
|
+
# Inform about slow benchmark
|
|
185
|
+
# answer = nil
|
|
186
|
+
# until answer && answer[/^$|y|yes|n|no/]
|
|
187
|
+
# print("A slow benchmark exposing problems with SEL is newly added. It takes approx. 20s\n");
|
|
188
|
+
# print("you have scheduled it to run #{TIMES / 100} times.\nWould you still include the particular benchmark? [Yn]")
|
|
189
|
+
# STDOUT.flush
|
|
190
|
+
# answer = gets
|
|
191
|
+
# end
|
|
192
|
+
# run_rel_bench = answer[/^$|y|yes/] ? true : false
|
|
193
|
+
|
|
194
|
+
|
|
195
|
+
RBench.run(TIMES) do
|
|
196
|
+
|
|
197
|
+
column :times
|
|
198
|
+
column :ar, :title => "AR 2.1"
|
|
199
|
+
column :dm, :title => "DM #{DataMapper::VERSION}"
|
|
200
|
+
column :diff, :compare => [:ar,:dm]
|
|
201
|
+
|
|
202
|
+
report "Model.new (instantiation)" do
|
|
203
|
+
ar { ARExhibit.new }
|
|
204
|
+
dm { Exhibit.new }
|
|
205
|
+
end
|
|
206
|
+
|
|
207
|
+
report "Model.new (setting attributes)" do
|
|
208
|
+
attrs = {:name => 'sam', :zoo_id => 1}
|
|
209
|
+
ar { ARExhibit.new(attrs) }
|
|
210
|
+
dm { Exhibit.new(attrs) }
|
|
211
|
+
end
|
|
212
|
+
|
|
213
|
+
report "Model.get specific (not cached)" do
|
|
214
|
+
ActiveRecord::Base.uncached { ar { touch_attributes[ARExhibit.find(1)] } }
|
|
215
|
+
dm { touch_attributes[Exhibit.get(1)] }
|
|
216
|
+
end
|
|
217
|
+
|
|
218
|
+
report "Model.get specific (cached)" do
|
|
219
|
+
ActiveRecord::Base.cache { ar { touch_attributes[ARExhibit.find(1)] } }
|
|
220
|
+
Exhibit.repository(:default) { dm { touch_attributes[Exhibit.get(1)] } }
|
|
221
|
+
end
|
|
222
|
+
|
|
223
|
+
report "Model.first" do
|
|
224
|
+
ar { touch_attributes[ARExhibit.first] }
|
|
225
|
+
dm { touch_attributes[Exhibit.first] }
|
|
226
|
+
end
|
|
227
|
+
|
|
228
|
+
report "Model.all limit(100)", (TIMES / 10.0).ceil do
|
|
229
|
+
ar { touch_attributes[ARExhibit.find(:all, :limit => 100)] }
|
|
230
|
+
dm { touch_attributes[Exhibit.all(:limit => 100)] }
|
|
231
|
+
end
|
|
232
|
+
|
|
233
|
+
report "Model.all limit(100) with relationship", (TIMES / 10.0).ceil do
|
|
234
|
+
ar { touch_relationships[ARExhibit.all(:limit => 100, :include => [:user])] }
|
|
235
|
+
dm { touch_relationships[Exhibit.all(:limit => 100)] }
|
|
236
|
+
end
|
|
237
|
+
|
|
238
|
+
report "Model.all limit(10,000)", (TIMES / 1000.0).ceil do
|
|
239
|
+
ar { touch_attributes[ARExhibit.find(:all, :limit => 10_000)] }
|
|
240
|
+
dm { touch_attributes[Exhibit.all(:limit => 10_000)] }
|
|
241
|
+
end
|
|
242
|
+
|
|
243
|
+
create_exhibit = {
|
|
244
|
+
:name => Faker::Company.name,
|
|
245
|
+
:zoo_id => rand(10).ceil,
|
|
246
|
+
:notes => Faker::Lorem.paragraphs.join($/),
|
|
247
|
+
:created_on => Date.today
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
report "Model.create" do
|
|
251
|
+
ar { ARExhibit.create(create_exhibit) }
|
|
252
|
+
dm { Exhibit.create(create_exhibit) }
|
|
253
|
+
end
|
|
254
|
+
|
|
255
|
+
report "Resource#attributes" do
|
|
256
|
+
attrs_first = {:name => 'sam', :zoo_id => 1}
|
|
257
|
+
attrs_second = {:name => 'tom', :zoo_id => 1}
|
|
258
|
+
ar { e = ARExhibit.new(attrs_first); e.attributes = attrs_second }
|
|
259
|
+
dm { e = Exhibit.new(attrs_first); e.attributes = attrs_second }
|
|
260
|
+
end
|
|
261
|
+
|
|
262
|
+
report "Resource#update" do
|
|
263
|
+
ar { e = ARExhibit.find(1); e.name = 'bob'; e.save }
|
|
264
|
+
dm { e = Exhibit.get(1); e.name = 'bob'; e.save }
|
|
265
|
+
end
|
|
266
|
+
|
|
267
|
+
report "Resource#destroy" do
|
|
268
|
+
ar { ARExhibit.first.destroy }
|
|
269
|
+
dm { Exhibit.first.destroy }
|
|
270
|
+
end
|
|
271
|
+
|
|
272
|
+
report "Model.transaction" do
|
|
273
|
+
ar { ARExhibit.transaction { ARExhibit.new } }
|
|
274
|
+
dm { Exhibit.transaction { Exhibit.new } }
|
|
275
|
+
end
|
|
276
|
+
|
|
277
|
+
summary "Total"
|
|
278
|
+
end
|
|
279
|
+
|
|
280
|
+
connection = adapter.send(:create_connection)
|
|
281
|
+
command = connection.create_command("DROP TABLE exhibits")
|
|
282
|
+
command = connection.create_command("DROP TABLE users")
|
|
283
|
+
command.execute_non_query rescue nil
|
|
284
|
+
connection.close
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
|
|
3
|
+
require File.join(File.dirname(__FILE__), '..', 'lib', 'dm-core')
|
|
4
|
+
|
|
5
|
+
require 'rubygems'
|
|
6
|
+
|
|
7
|
+
gem 'ruby-prof', '>=0.6.0'
|
|
8
|
+
require 'ruby-prof'
|
|
9
|
+
|
|
10
|
+
gem 'faker', '>=0.3.1'
|
|
11
|
+
require 'faker'
|
|
12
|
+
|
|
13
|
+
OUTPUT = DataMapper.root / 'profile_results.txt'
|
|
14
|
+
#OUTPUT = DataMapper.root / 'profile_results.html'
|
|
15
|
+
|
|
16
|
+
SOCKET_FILE = Pathname.glob(%w[
|
|
17
|
+
/opt/local/var/run/mysql5/mysqld.sock
|
|
18
|
+
/tmp/mysqld.sock
|
|
19
|
+
/tmp/mysql.sock
|
|
20
|
+
/var/mysql/mysql.sock
|
|
21
|
+
/var/run/mysqld/mysqld.sock
|
|
22
|
+
]).find { |path| path.socket? }
|
|
23
|
+
|
|
24
|
+
DataMapper::Logger.new(DataMapper.root / 'log' / 'dm.log', :debug)
|
|
25
|
+
DataMapper.setup(:default, "mysql://root@localhost/data_mapper_1?socket=#{SOCKET_FILE}")
|
|
26
|
+
|
|
27
|
+
class Exhibit
|
|
28
|
+
include DataMapper::Resource
|
|
29
|
+
|
|
30
|
+
property :id, Serial
|
|
31
|
+
property :name, String
|
|
32
|
+
property :zoo_id, Integer
|
|
33
|
+
property :notes, Text, :lazy => true
|
|
34
|
+
property :created_on, Date
|
|
35
|
+
# property :updated_at, DateTime
|
|
36
|
+
|
|
37
|
+
auto_migrate!
|
|
38
|
+
create # create one row for testing
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
touch_attributes = lambda do |exhibits|
|
|
42
|
+
[*exhibits].each do |exhibit|
|
|
43
|
+
exhibit.id
|
|
44
|
+
exhibit.name
|
|
45
|
+
exhibit.created_on
|
|
46
|
+
exhibit.updated_at
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
# RubyProf, making profiling Ruby pretty since 1899!
|
|
51
|
+
def profile(&b)
|
|
52
|
+
result = RubyProf.profile &b
|
|
53
|
+
printer = RubyProf::FlatPrinter.new(result)
|
|
54
|
+
#printer = RubyProf::GraphHtmlPrinter.new(result)
|
|
55
|
+
printer.print(OUTPUT.open('w+'))
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
profile do
|
|
59
|
+
# 10_000.times { touch_attributes[Exhibit.get(1)] }
|
|
60
|
+
#
|
|
61
|
+
# repository(:default) do
|
|
62
|
+
# 10_000.times { touch_attributes[Exhibit.get(1)] }
|
|
63
|
+
# end
|
|
64
|
+
#
|
|
65
|
+
# 1000.times { touch_attributes[Exhibit.all(:limit => 100)] }
|
|
66
|
+
#
|
|
67
|
+
# repository(:default) do
|
|
68
|
+
# 1000.times { touch_attributes[Exhibit.all(:limit => 100)] }
|
|
69
|
+
# end
|
|
70
|
+
#
|
|
71
|
+
# 10.times { touch_attributes[Exhibit.all(:limit => 10_000)] }
|
|
72
|
+
#
|
|
73
|
+
# repository(:default) do
|
|
74
|
+
# 10.times { touch_attributes[Exhibit.all(:limit => 10_000)] }
|
|
75
|
+
# end
|
|
76
|
+
|
|
77
|
+
create_exhibit = {
|
|
78
|
+
:name => Faker::Company.name,
|
|
79
|
+
:zoo_id => rand(10).ceil,
|
|
80
|
+
:notes => Faker::Lorem.paragraphs.join($/),
|
|
81
|
+
:created_on => Date.today
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
1000.times { Exhibit.create(create_exhibit) }
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
puts "Done!"
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
require File.dirname(__FILE__) + '/migration'
|