arcopy 0.0.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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: ba25896eb10e1027cf4021ea88ba0fb5517c630907d442bfc5b27ed861f41677
4
+ data.tar.gz: d035b464d641f563962a1b3040e9fe894c848a0625e458f0e6385c92ffa78a4d
5
+ SHA512:
6
+ metadata.gz: 7f784501bd721c2be2ccfe16c740f84da92a43edd2b0a02ffe356de940e8db4a0906d701dafc643e1ee5e9d571e10916f46e3f5e2bedb595df4e63e44acfa695
7
+ data.tar.gz: d856708d946dacd3366015d7d4d11bd3e7aa2e87562b97367b2fd67627e5ccb551b17c719e4b3a526cc8f2f646d0d9c9f6699c547d31eaec2f94438c4f778e25
data/COPYING ADDED
@@ -0,0 +1,18 @@
1
+ Copyright (c) 2011 Ryan Tomayko <http://tomayko.com/about>
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ of this software and associated documentation files (the "Software"), to
5
+ deal in the Software without restriction, including without limitation the
6
+ rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
7
+ sell copies of the Software, and to permit persons to whom the Software is
8
+ furnished to do so, subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in
11
+ all copies or substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
16
+ THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
17
+ IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
18
+ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/HACKING ADDED
@@ -0,0 +1,61 @@
1
+ Grab a local clone of rtomayko/replicate:
2
+
3
+ git clone git://github.com/rtomayko/replicate.git
4
+ cd replicate
5
+
6
+ The default rake task installs the latest supported activerecord
7
+ version to a project local GEM_HOME=./vendor and runs the unit
8
+ tests:
9
+
10
+ $ rake
11
+ installing activerecord-3.1.0 to ./vendor/1.8
12
+ installing sqlite3 to ./vendor/1.8
13
+ Using activerecord 3.1.0
14
+ Loaded suite ...
15
+ Started
16
+ ....................
17
+ Finished in 0.150186 seconds.
18
+
19
+ 20 tests, 106 assertions, 0 failures, 0 errors
20
+
21
+ Use `rake test:all' to run tests under all activerecord versions:
22
+
23
+ $ rake test:all
24
+ installing activerecord ~> 2.2.3 to ./vendor
25
+ installing activerecord ~> 2.3.14 to ./vendor
26
+ installing activerecord ~> 3.0.10 to ./vendor
27
+ installing activerecord ~> 3.1.0 to ./vendor
28
+ ==> testing activerecord ~> 2.2.3
29
+ Started
30
+ ....................
31
+ Finished in 0.119517 seconds.
32
+
33
+ 20 tests, 106 assertions, 0 failures, 0 errors
34
+ ==> testing activerecord ~> 2.3.14
35
+ Started
36
+ ....................
37
+ Finished in 0.119517 seconds.
38
+
39
+ 20 tests, 106 assertions, 0 failures, 0 errors
40
+ <snip>
41
+
42
+ rake test:all should always be passing under latest stable MRI
43
+ 1.8.7 and MRI 1.9.x.
44
+
45
+ Running individual test files directly requires setting the
46
+ GEM_HOME environment variable and ensuring ./lib is on the load
47
+ path:
48
+
49
+ export GEM_HOME=vendor/1.9 # or 1.8.7
50
+ ruby -Ilib test/active_record_test.rb
51
+
52
+ You can also control which activerecord version is used in the
53
+ test with the AR_VERSION environment variable:
54
+
55
+ rake setup:all
56
+ export GEM_HOME=vendor/1.8.7
57
+ AR_VERSION=3.1.0 ruby -rubygems -Ilib test/active_record_test.rb
58
+
59
+ If you have something worth sharing, please send a pull request:
60
+
61
+ https://github.com/rtomayko/replicate
data/README.md ADDED
@@ -0,0 +1,285 @@
1
+ Dump and load relational objects between Ruby environments.
2
+ ===========================================================
3
+
4
+ *This repository is archived and no longer actively maintained by @rtomayko as of 2017-11-08. Issues and PRs documenting current issues have been intentionally left open for informational purposes.*
5
+
6
+ The project started at GitHub to simplify the process of getting real production
7
+ data into development and staging environments. We use it to replicate entire
8
+ repository data (including associated issue, pull request, commit comment, etc.
9
+ records) from production to our development environments with a single command.
10
+ It's excessively useful for troubleshooting issues, support requests, and
11
+ exception reports as well as for establishing real data for evaluating design
12
+ concepts.
13
+
14
+ Synopsis
15
+ --------
16
+
17
+ ### Installing
18
+
19
+ $ gem install replicate
20
+
21
+ ### Dumping objects
22
+
23
+ Evaluate a Ruby expression, dumping all resulting objects to standard output:
24
+
25
+ $ replicate -r ./config/environment -d "User.find(1)" > user.dump
26
+ ==> dumped 4 total objects:
27
+ Profile 1
28
+ User 1
29
+ UserEmail 2
30
+
31
+ The `-r ./config/environment` option is used to require environment setup and
32
+ model instantiation code needed by the ruby expression.
33
+
34
+ ### Dumping many objects with a dump script
35
+
36
+ Dump scripts are normal ruby source files evaluated in the context of the
37
+ dumper. The `dump(object)` method is used to put objects into the dump stream.
38
+
39
+ ```ruby
40
+ # config/replicate/dump-stuff.rb
41
+ require 'config/environment'
42
+
43
+ %w[rtomayko/tilt rtomayko/bcat].each do |repo_name|
44
+ repo = Repository.find_by_name_with_owner(repo_name)
45
+ dump repo
46
+ dump repo.commit_comments
47
+ dump repo.issues
48
+ end
49
+ ```
50
+
51
+ Run the dump script:
52
+
53
+ $ replicate -d config/replicate/dump-stuff.rb > repos.dump
54
+ ==> dumped 1479 total objects:
55
+ AR::Habtm 101
56
+ CommitComment 95
57
+ Issue 101
58
+ IssueComment 427
59
+ IssueEvent 308
60
+ Label 5
61
+ Language 19
62
+ LanguageName 1
63
+ Milestone 3
64
+ Organization 4
65
+ Profile 82
66
+ PullRequest 44
67
+ PullRequestReviewComment 8
68
+ Repository 20
69
+ Team 4
70
+ TeamMember 6
71
+ User 89
72
+ UserEmail 162
73
+
74
+ ### Loading many objects:
75
+
76
+ $ replicate -r ./config/environment -l < repos.dump
77
+ ==> loaded 1479 total objects:
78
+ AR::Habtm 101
79
+ CommitComment 95
80
+ Issue 101
81
+ IssueComment 427
82
+ IssueEvent 308
83
+ Label 5
84
+ Language 19
85
+ LanguageName 1
86
+ Milestone 3
87
+ Organization 4
88
+ Profile 82
89
+ PullRequest 44
90
+ PullRequestReviewComment 8
91
+ Repository 20
92
+ Team 4
93
+ TeamMember 6
94
+ User 89
95
+ UserEmail 162
96
+
97
+ ### Dumping and loading over ssh
98
+
99
+ $ remote_command="replicate -r /app/config/environment -d 'User.find(1234)'"
100
+ $ ssh example.org "$remote_command" |replicate -r ./config/environment -l
101
+
102
+ ActiveRecord
103
+ ------------
104
+
105
+ Basic support for dumping and loading ActiveRecord objects is included. The
106
+ tests pass under ActiveRecord versions 2.2.3, 2.3.5, 2.3.14, 3.0.10, 3.1.0, and 3.2.0 under
107
+ MRI 1.8.7 as well as under MRI 1.9.2.
108
+
109
+ To use customization macros in your models, require the replicate library after
110
+ ActiveRecord (in e.g., `config/initializers/libraries.rb`):
111
+
112
+ ```ruby
113
+ require 'active_record'
114
+ require 'replicate'
115
+ ```
116
+
117
+ ActiveRecord support works sensibly without customization so this isn't strictly
118
+ necessary to use the `replicate` command. The following sections document the
119
+ available customization macros.
120
+
121
+ ### Association Dumping
122
+
123
+ The baked in support adds some more or less sensible default behavior for all
124
+ subclasses of `ActiveRecord::Base` such that dumping an object will bring in
125
+ objects related via `belongs_to` and `has_one` associations.
126
+
127
+ Unlike 1:1 associations, `has_many` and `has_and_belongs_to_many` associations
128
+ are not automatically included. Doing so would quickly lead to the entire
129
+ database being sucked in. It can be useful to mark specific associations for
130
+ automatic inclusion using the `replicate_associations` macro. For instance,
131
+ to always include `EmailAddress` records belonging to a `User`:
132
+
133
+ ```ruby
134
+ class User < ActiveRecord::Base
135
+ belongs_to :profile
136
+ has_many :email_addresses
137
+
138
+ replicate_associations :email_addresses
139
+ end
140
+ ```
141
+
142
+ You may also do this by passing an option in your dump script:
143
+
144
+ ```ruby
145
+ dump User.all, :associations => [:email_addresses]
146
+ ```
147
+
148
+ ### Natural Keys
149
+
150
+ By default, the loader attempts to create a new record with a new primary key id
151
+ for all objects. This can lead to unique constraint errors when a record already
152
+ exists with matching attributes. To update existing records instead of
153
+ creating new ones, define a natural key for the model using the `replicate_natural_key`
154
+ macro:
155
+
156
+ ```ruby
157
+ class User < ActiveRecord::Base
158
+ belongs_to :profile
159
+ has_many :email_addresses
160
+
161
+ replicate_natural_key :login
162
+ replicate_associations :email_addresses
163
+ end
164
+
165
+ class EmailAddress < ActiveRecord::Base
166
+ belongs_to :user
167
+ replicate_natural_key :user_id, :email
168
+ end
169
+ ```
170
+
171
+ Multiple attribute names may be specified to define a compound key. Foreign key
172
+ column attributes (`user_id`) are often included in natural keys.
173
+
174
+ ### Omission of attributes and associations
175
+
176
+ You might want to exclude some attributes or associations from being dumped. For
177
+ this, use the replicate_omit_attributes macro:
178
+
179
+ ```ruby
180
+ class User < ActiveRecord::Base
181
+ has_one :profile
182
+
183
+ replicate_omit_attributes :created_at, :profile
184
+ end
185
+ ```
186
+
187
+ You can omit belongs_to associations by omitting the foreign key column.
188
+
189
+ You may also do this by passing an option in your dump script:
190
+
191
+ ```ruby
192
+ dump User.all, :omit => [:profile]
193
+ ```
194
+
195
+ ### Validations and Callbacks
196
+
197
+ __IMPORTANT:__ All ActiveRecord validations and callbacks are disabled on the
198
+ loading side. While replicate piggybacks on AR for relationship information and
199
+ uses `ActiveRecord::Base#save` to write objects to the database, it's designed
200
+ to act as a simple dump / load tool.
201
+
202
+ It's sometimes useful to run certain types of callbacks on replicate. For
203
+ instance, you might want to create files on disk or load information into a
204
+ separate data store any time an object enters the database. The best way to go
205
+ about this currently is to override the model's `load_replicant` class method:
206
+
207
+ ```ruby
208
+ class User < ActiveRecord::Base
209
+ def self.load_replicant(type, id, attrs)
210
+ id, object = super
211
+ object.register_in_redis
212
+ object.some_other_callback
213
+ [id, object]
214
+ end
215
+ end
216
+ ```
217
+
218
+ This interface will be improved in future versions.
219
+
220
+ Custom Objects
221
+ --------------
222
+
223
+ Other object types may be included in the dump stream so long as they implement
224
+ the `dump_replicant` and `load_replicant` methods.
225
+
226
+ ### dump_replicant
227
+
228
+ The dump side calls `#dump_replicant(dumper, opts={})` on each object. The method must
229
+ call `dumper.write()` with the class name, id, and hash of primitively typed
230
+ attributes for the object:
231
+
232
+ ```ruby
233
+ class User
234
+ attr_reader :id
235
+ attr_accessor :name, :email
236
+
237
+ def dump_replicant(dumper, opts={})
238
+ attributes = { 'name' => name, 'email' => email }
239
+ dumper.write self.class, id, attributes, self
240
+ end
241
+ end
242
+ ```
243
+
244
+ ### load_replicant
245
+
246
+ The load side calls `::load_replicant(type, id, attributes)` on the class to
247
+ load each object into the current environment. The method must return an
248
+ `[id, object]` tuple:
249
+
250
+ ```ruby
251
+ class User
252
+ def self.load_replicant(type, id, attributes)
253
+ user = User.new
254
+ user.name = attributes['name']
255
+ user.email = attributes['email']
256
+ user.save!
257
+ [user.id, user]
258
+ end
259
+ end
260
+ ```
261
+
262
+ How it works
263
+ ------------
264
+
265
+ The dump format is designed for streaming relational data. Each object is
266
+ encoded as a `[type, id, attributes]` tuple and marshalled directly onto the
267
+ stream. The `type` (class name string) and `id` must form a distinct key when
268
+ combined, `attributes` must consist of only string keys and simply typed values.
269
+
270
+ Relationships between objects in the stream are managed as follows:
271
+
272
+ - An object's attributes may encode references to objects that precede it
273
+ in the stream using a simple tuple format: `[:id, 'User', 1234]`.
274
+
275
+ - The dump side ensures that objects are written to the dump stream in
276
+ "reference order" such that when an object A includes a reference attribute
277
+ to an object B, B is guaranteed to arrive before A.
278
+
279
+ - The load side maintains a mapping of ids from the dumping system to the newly
280
+ replicated objects on the loading system. When the loader encounters a
281
+ reference value `[:id, 'User', 1234]` in an object's attributes, it converts it
282
+ to the load side id value.
283
+
284
+ Dumping and loading happens in a streaming fashion. There is no limit on the
285
+ number of objects included in the stream.
data/Rakefile ADDED
@@ -0,0 +1,16 @@
1
+ require 'rake/clean'
2
+ require 'rake/testtask'
3
+
4
+ task :default => :test
5
+
6
+ desc "Run tests"
7
+ Rake::TestTask.new do |t|
8
+ t.test_files = FileList['test/*_test.rb']
9
+ end
10
+
11
+ CLEAN.include 'test/db'
12
+
13
+ desc "Build gem"
14
+ task :build do
15
+ sh "gem build replicate.gemspec"
16
+ end
data/bin/replicate ADDED
@@ -0,0 +1,100 @@
1
+ #!/usr/bin/env ruby
2
+ #/ Usage: replicate --dump dumpscript.rb > objects.dump
3
+ #/ replicate [-r <lib>] --dump "<ruby>" [-- <argv>...] > objects.dump
4
+ #/ replicate [-r <lib>] --load < objects.dump
5
+ #/ Dump and load objects between environments.
6
+ #
7
+ #/ The --dump form writes to stdout the objects dumped by the script or
8
+ #/ ruby expression(s) given. Dump scripts are normal Ruby source files but
9
+ #/ must call dump(object) on one or more objects. When a Ruby expression is
10
+ #/ given, all resulting objects are dumped automatically.
11
+ #/
12
+ #/ Dump scripts have access to any additional <argv> provided via the normal
13
+ #/ system ARGV array. This can be used to pass arguments to dump scripts.
14
+ #/
15
+ #/ The --load form reads dump data from stdin and creates objects under the
16
+ #/ current environment.
17
+ #/
18
+ #/ Mode selection:
19
+ #/ -d, --dump Dump the repository and all related objects to stdout.
20
+ #/ -l, --load Load dump file data from stdin.
21
+ #/
22
+ #/ Options:
23
+ #/ -r, --require Require the library. Often used with 'config/environment'.
24
+ #/ -i, --keep-id Use replicated ids when loading dump file.
25
+ #/ -f, --force Allow loading in production environments.
26
+ #/ -v, --verbose Write more status output.
27
+ #/ -q, --quiet Write less status output.
28
+ $stderr.sync = true
29
+ $stdout = $stderr
30
+
31
+ require 'optparse'
32
+
33
+ # default options
34
+ mode = nil
35
+ verbose = false
36
+ quiet = false
37
+ keep_id = false
38
+ out = STDOUT
39
+ force = false
40
+
41
+ # parse arguments
42
+ file = __FILE__
43
+ usage = lambda { exec "grep ^#/<'#{file}'|cut -c4-" }
44
+ original_argv = ARGV.dup
45
+ ARGV.options do |opts|
46
+ opts.on("-d", "--dump") { mode = :dump }
47
+ opts.on("-l", "--load") { mode = :load }
48
+ opts.on("-r", "--require=f") { |file| require file }
49
+ opts.on("-v", "--verbose") { verbose = true }
50
+ opts.on("-q", "--quiet") { quiet = true }
51
+ opts.on("-i", "--keep-id") { keep_id = true }
52
+ opts.on("--force") { force = true }
53
+ opts.on_tail("-h", "--help", &usage)
54
+ opts.parse!
55
+ end
56
+
57
+ # load replicate lib and setup AR
58
+ require 'replicate'
59
+ if defined?(ActiveRecord::Base)
60
+ require 'replicate/active_record'
61
+ ActiveRecord::Base.replicate_id = keep_id
62
+ ActiveRecord::Base.connection.enable_query_cache!
63
+ end
64
+
65
+ # dump mode means we're reading records from the database here and writing to
66
+ # stdout. the database should not be modified at all by this operation.
67
+ if mode == :dump
68
+ script = ARGV.shift
69
+ usage.call if script.empty?
70
+ Replicate::Dumper.new do |dumper|
71
+ dumper.marshal_to out
72
+ dumper.log_to $stderr, verbose, quiet
73
+ if script == '-'
74
+ code = $stdin.read
75
+ objects = dumper.instance_eval(code, '<stdin>', 0)
76
+ elsif File.exist?(script)
77
+ dumper.load_script script
78
+ else
79
+ objects = dumper.instance_eval(script, '<argv>', 0)
80
+ dumper.dump objects
81
+ end
82
+ end
83
+
84
+ # load mode means we're reading objects from stdin and creating them under
85
+ # the current environment.
86
+ elsif mode == :load
87
+ if Replicate.production_environment? && !force
88
+ abort "error: refusing to load in production environment\n" +
89
+ " manual override: #{File.basename($0)} --force #{original_argv.join(' ')}"
90
+ else
91
+ Replicate::Loader.new do |loader|
92
+ loader.log_to $stderr, verbose, quiet
93
+ loader.read $stdin
94
+ end
95
+ end
96
+
97
+ # mode not set means no -l or -d arg was given. show usage and bail.
98
+ else
99
+ usage.call
100
+ end