multiple_dbs 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/MIT-LICENSE +20 -0
- data/README.md +341 -0
- data/Rakefile +34 -0
- data/lib/generators/multiple_dbs_initializer/USAGE +23 -0
- data/lib/generators/multiple_dbs_initializer/multiple_dbs_initializer_generator.rb +131 -0
- data/lib/generators/multiple_dbs_initializer/templates/config_db.yml +24 -0
- data/lib/generators/multiple_dbs_initializer/templates/initializer.rb +8 -0
- data/lib/generators/multiple_dbs_migration/USAGE +14 -0
- data/lib/generators/multiple_dbs_migration/multiple_dbs_migration_generator.rb +25 -0
- data/lib/generators/multiple_dbs_model/USAGE +14 -0
- data/lib/generators/multiple_dbs_model/multiple_dbs_model_generator.rb +26 -0
- data/lib/multiple_dbs.rb +7 -0
- data/lib/multiple_dbs/multi_connectable.rb +207 -0
- data/lib/multiple_dbs/railtie.rb +9 -0
- data/lib/multiple_dbs/version.rb +3 -0
- data/lib/tasks/multiple_dbs_tasks.rake +227 -0
- metadata +88 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: af9c0af78926a4506ef7eeb69316619bc61c35f0
|
4
|
+
data.tar.gz: de2bfdfa8fdc35f92efdaa58f69ff0a3b8eeb256
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: d036f11d65f5637c5d4c6a01cec12573d6fa23875309e43be5a606b6593c0d3269bd3a9fd54bfe7e529985d5b4c3579ae0741d8b038f21a39355295af257dfed
|
7
|
+
data.tar.gz: 93a80a61c13648cf9ec5d13c690649cf1318fca6f8714b5e2d1b1f7ebd29850bc4626596997862759bf4196ed1cc4913a6b1646df48ebdeb53be25871ea1ac3a
|
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright 2017 Yonga
|
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.md
ADDED
@@ -0,0 +1,341 @@
|
|
1
|
+
# MultipleDbs
|
2
|
+
So, your rails application needs to handle n databases. Well my friend,
|
3
|
+
this is your solution. This gem allows you to handle all your databases
|
4
|
+
connections, either for different databases that share the same entity
|
5
|
+
relationship model or for different databases with different entity
|
6
|
+
relationship models.
|
7
|
+
|
8
|
+
## Usage
|
9
|
+
|
10
|
+
multiple_dbs creates a subclass for the models you want to handle in multiple
|
11
|
+
databases and one subclass for each connection. By doing this, each connection is
|
12
|
+
handled by it's own subclass, preventing switching between connections, which add a high computational cost.
|
13
|
+
|
14
|
+
#### IMPORTANT.
|
15
|
+
The following examples assume that you define 3 databases: db1, db2 and db3.
|
16
|
+
|
17
|
+
Before you start, follow the installation instructions [here](https://github.com/yonga9121/multiple_dbs#installation) and please read all this
|
18
|
+
document, especially if your project is already running or
|
19
|
+
already has a database with migrations and stuff.
|
20
|
+
|
21
|
+
### Generate models.
|
22
|
+
|
23
|
+
If you want to generate a model for all the databases, run
|
24
|
+
```bash
|
25
|
+
$ rails g multiple_dbs_model user email:string
|
26
|
+
```
|
27
|
+
|
28
|
+
If you want to generate a model for a specific databases, run
|
29
|
+
```bash
|
30
|
+
$ rails g multiple_dbs_model user email:string --only=db1 db3
|
31
|
+
```
|
32
|
+
|
33
|
+
If you want to generate a model skipping a specific databases, run
|
34
|
+
```bash
|
35
|
+
$ rails g multiple_dbs_model user email:string --skip=db1 db3
|
36
|
+
```
|
37
|
+
|
38
|
+
You will find all migrations in the folder db/your_database/migrate.
|
39
|
+
The schema and seed files can be found in the folder db/your_database.
|
40
|
+
|
41
|
+
#### NOTE:
|
42
|
+
If you already have models, migrations and a schema file, and want to manage that
|
43
|
+
initial database with the multiple_dbs gem (recommended), you should create the database using the multiple_dbs_initializer generator and pass said database name as an argument. Check the ["How to start if already have a database ?"](https://github.com/yonga9121/multiple_dbs#how-to-start-if-already-have-a-database-) section for more information.
|
44
|
+
|
45
|
+
If you DO NOT want to override the default database.yml file, add as an option
|
46
|
+
--not_override=true
|
47
|
+
|
48
|
+
|
49
|
+
### Generate Migrations
|
50
|
+
|
51
|
+
If you want to generate a migration for all the databases, run
|
52
|
+
```bash
|
53
|
+
$ rails g multiple_dbs_migration add_column_password_to_users password:string
|
54
|
+
```
|
55
|
+
|
56
|
+
If you want to a generate migration for a specific database, run
|
57
|
+
```bash
|
58
|
+
$ rails g multiple_dbs_migration add_column_password_to_users password:string --only=db1 db3
|
59
|
+
```
|
60
|
+
|
61
|
+
If you want to generate a migration skipping a specific database, run
|
62
|
+
```bash
|
63
|
+
$ rails g multiple_dbs_migration add_column_password_to_users password:string --skip=db1 db2
|
64
|
+
```
|
65
|
+
|
66
|
+
#### NOTE:
|
67
|
+
If you already have models, migrations and a schema file, and want to manage that
|
68
|
+
initial database with the multiple_dbs gem (recommended), you should create the database using the multiple_dbs_initializer generator and pass said database name as an argument. Check the ["How to start if already have a database ?"](https://github.com/yonga9121/multiple_dbs#how-to-start-if-already-have-a-database-) section for more information.
|
69
|
+
|
70
|
+
If you DO NOT want to override the default database.yml file, add as an option
|
71
|
+
--not_override=true
|
72
|
+
|
73
|
+
### Setting up your application_controller
|
74
|
+
|
75
|
+
Add this tou your controller. Be sure to specify the database_name in the method mdb_name.
|
76
|
+
|
77
|
+
This will turn on the connection to the specified database.
|
78
|
+
|
79
|
+
```ruby
|
80
|
+
def mdb_name
|
81
|
+
Thread.current[:mdb_name] ||= nil # ...change this for somthing that gives you the database name, like: 'db1' or 'client1_database'. You can use the request headers or the params or an object in the database or the request domain...
|
82
|
+
end
|
83
|
+
|
84
|
+
before_filter do
|
85
|
+
MultipleDbs.validate_connection(mdb_name)
|
86
|
+
end
|
87
|
+
```
|
88
|
+
|
89
|
+
### Setting up your models
|
90
|
+
|
91
|
+
Assuming that you create a User model and it has many Posts.
|
92
|
+
|
93
|
+
The User and Post models should look like this:
|
94
|
+
```ruby
|
95
|
+
# app/models/user.rb
|
96
|
+
class User < ApplicationRecord
|
97
|
+
make_connectable_class do |db|
|
98
|
+
has_many :posts, class_name: "Post#{db}"
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
# app/models/post.rb
|
103
|
+
class Post < ApplicationRecord
|
104
|
+
make_connectable_class do |db|
|
105
|
+
belongs_to :user, foreign_key: "user_id", class_name: "User#{db}"
|
106
|
+
end
|
107
|
+
end
|
108
|
+
```
|
109
|
+
Here, you associate the models between databases, by using classes PostDb1, PostDb2 and PostDb3 associated with classes UserDb1, UserDb2 and UserDb3 respectively.
|
110
|
+
|
111
|
+
In case you don't need the association through all the databases, for example, the
|
112
|
+
database db1, your models should look like this.
|
113
|
+
|
114
|
+
```ruby
|
115
|
+
# app/models/user.rb
|
116
|
+
class User < ApplicationRecord
|
117
|
+
make_connectable_class do |db|
|
118
|
+
has_many :posts, class_name: "PostDb1"
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
# app/models/post.rb
|
123
|
+
class Post < ApplicationRecord
|
124
|
+
make_connectable_class do |db|
|
125
|
+
belongs_to :user, foreign_key: "user_id", class_name: "UserDb1"
|
126
|
+
end
|
127
|
+
end
|
128
|
+
```
|
129
|
+
Here, you associate the models between databases, by using class PostDb1 associated with classes UserDb1, UserDb2 and UserDb3.
|
130
|
+
|
131
|
+
In case you don't need to define a class for all your databases, your models should look like this.
|
132
|
+
```ruby
|
133
|
+
# app/models/user.rb
|
134
|
+
class User < ApplicationRecord
|
135
|
+
make_connectable_class(only: [:db1,:db3]) do |db|
|
136
|
+
has_many :posts, class_name: "Post#{db}"
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
# app/models/post.rb
|
141
|
+
class Post < ApplicationRecord
|
142
|
+
make_connectable_class(only: [:db1,:db3]) do |db|
|
143
|
+
belongs_to :user, foreign_key: "user_id", class_name: "User#{db}"
|
144
|
+
end
|
145
|
+
end
|
146
|
+
```
|
147
|
+
|
148
|
+
Here, you associate the models between databases, by using classes PostDb1, PostDb2 and PostDb3 associated with classes UserDb1 and UserDb3.
|
149
|
+
|
150
|
+
### Using the subclasses
|
151
|
+
|
152
|
+
You have two options for using a subclass that handles a connection.
|
153
|
+
|
154
|
+
- 1. Get the class from the base model
|
155
|
+
|
156
|
+
Use the model User to get the desired class.
|
157
|
+
|
158
|
+
```ruby
|
159
|
+
user_class = User.multiple_class(:db1) # or User.mdb(:db1)
|
160
|
+
user_class.create(email: "someone@email.com")
|
161
|
+
```
|
162
|
+
This is useful if your client sends you the database for data storage or transaction runs.
|
163
|
+
|
164
|
+
- 2. Using the raw constant
|
165
|
+
|
166
|
+
Before you can use the raw constant you must be sure that the connection to the database is on.
|
167
|
+
You can do this using MultipleDbs.validate_connection(dat_name) passing the database name as a parameter.
|
168
|
+
|
169
|
+
Use the UserDb1 class as usual
|
170
|
+
```ruby
|
171
|
+
UserDb1.create(email: "someone@email.com")
|
172
|
+
```
|
173
|
+
|
174
|
+
- 3. Using classes from different connections
|
175
|
+
|
176
|
+
In order to use different connections you must be sure that the connection from each database is on.
|
177
|
+
```ruby
|
178
|
+
# somewhere in your code before you use the classes
|
179
|
+
|
180
|
+
MultipleDbs.validate_connection(:db1)
|
181
|
+
MultipleDbs.validate_connection(:db2)
|
182
|
+
|
183
|
+
|
184
|
+
# using the raw classes
|
185
|
+
|
186
|
+
puts UserDb1.first.inspect
|
187
|
+
puts UserDb2.first.inspect
|
188
|
+
|
189
|
+
# using the model to get the desired class
|
190
|
+
|
191
|
+
puts User.mdb(:db1).first.inspect
|
192
|
+
puts User.mdb(:db2).first.inspect
|
193
|
+
```
|
194
|
+
|
195
|
+
## Installation
|
196
|
+
|
197
|
+
Add this line to your application's Gemfile:
|
198
|
+
```ruby
|
199
|
+
gem 'multiple_dbs'
|
200
|
+
```
|
201
|
+
|
202
|
+
And then execute:
|
203
|
+
```bash
|
204
|
+
$ bundle
|
205
|
+
```
|
206
|
+
|
207
|
+
Or install it yourself as:
|
208
|
+
```bash
|
209
|
+
$ gem install multiple_dbs
|
210
|
+
```
|
211
|
+
|
212
|
+
Let's setup our connections. We are going to create all our configuration files
|
213
|
+
and all the stuff needed. Call the multiple_dbs_initializer generator and pass
|
214
|
+
as an argument the databases names. You can also pass as options the specific
|
215
|
+
database configuration.
|
216
|
+
|
217
|
+
Run in your terminal
|
218
|
+
```bash
|
219
|
+
$ rails g multiple_dbs_initializer my_database1 my_database2
|
220
|
+
```
|
221
|
+
|
222
|
+
If you need to configure the database connections (adapter, username,
|
223
|
+
etc), pass the options you want. Allowed options are: adapter,encoding,pool,username,password
|
224
|
+
|
225
|
+
Run in your terminal
|
226
|
+
```bash
|
227
|
+
$ rails g multiple_dbs_initializer my_database1 my_database2
|
228
|
+
--development=username:goku password:ukog adapter:mysql2
|
229
|
+
--test=username:gohan password:nahog adapter:postgresql pool:2
|
230
|
+
--production=username:seriusname password:enviromentvariablepls pool:20
|
231
|
+
```
|
232
|
+
|
233
|
+
Run the help command for more information
|
234
|
+
```bash
|
235
|
+
$ rails g multiple_dbs_initializer --help
|
236
|
+
```
|
237
|
+
|
238
|
+
We just need one more thing... Read the section according to your rails version
|
239
|
+
|
240
|
+
### Rails >= 5.x.x
|
241
|
+
|
242
|
+
Add this line to your application_record.rb file so you ApplicationRecord class
|
243
|
+
looks like this.
|
244
|
+
```ruby
|
245
|
+
# app/models/application_record.rb
|
246
|
+
class ApplicationRecord < ActiveRecord::Base
|
247
|
+
include MultipleDbs::MultiConnectable # this line
|
248
|
+
self.abstract_class = true
|
249
|
+
end
|
250
|
+
|
251
|
+
```
|
252
|
+
|
253
|
+
### How to start if already have a database ?.
|
254
|
+
|
255
|
+
If you already have a database and want to replicate the entity relationship model in your new databases you can do the following:
|
256
|
+
|
257
|
+
- Install the gem.
|
258
|
+
- Run the multiple_dbs_initializer and configure your database connections.
|
259
|
+
- If you want to copy the migrations from the default folder db/migrate into all your new databases, run in your terminal
|
260
|
+
```bash
|
261
|
+
$ rails "mdbs:replicate_default_database"
|
262
|
+
```
|
263
|
+
|
264
|
+
This command will copy your db/migrate folder into each of your databases folders, like db/your_database.
|
265
|
+
|
266
|
+
- If you want to copy the migrations from the default folder db/migrate into an specific database, run in your terminal:
|
267
|
+
```bash
|
268
|
+
$ rails "mdbs:replicate_default_database_into[your_database]"
|
269
|
+
```
|
270
|
+
|
271
|
+
This command will copy your db/migrate folder into db/your_database
|
272
|
+
|
273
|
+
- If you want to copy a specific migration from the default folder db/migrate into all your databases, run in your terminal:
|
274
|
+
```bash
|
275
|
+
$ rails "mdbs:copy_migration_from_default[file_name.rb]"
|
276
|
+
```
|
277
|
+
|
278
|
+
- If you want to copy a specific migration from the default folder db/migrate into an specific database, run in your terminal:
|
279
|
+
```bash
|
280
|
+
$ rails "mdbs:copy_migration_from_default_into[file_name.rb, database_name]"
|
281
|
+
```
|
282
|
+
|
283
|
+
- after you copy the migrations you want into the databases you want, migrate your databases, run in your terminal:
|
284
|
+
```bash
|
285
|
+
$ rails mdbs:migrate
|
286
|
+
```
|
287
|
+
|
288
|
+
|
289
|
+
### Manage the databases
|
290
|
+
multiple_dbs comes with a list of useful tasks that you can find in your project
|
291
|
+
after the gem was installed.
|
292
|
+
|
293
|
+
Run in your terminal
|
294
|
+
```bash
|
295
|
+
$ rake --tasks
|
296
|
+
```
|
297
|
+
|
298
|
+
You will find all the tasks under the namespace "mdbs"
|
299
|
+
|
300
|
+
To create all the databases.
|
301
|
+
```bash
|
302
|
+
$ rails mdbs:create
|
303
|
+
```
|
304
|
+
|
305
|
+
To create a specific database
|
306
|
+
```bash
|
307
|
+
$ rails mdbs:your_database_name:create
|
308
|
+
```
|
309
|
+
|
310
|
+
To setup all the databases.
|
311
|
+
```bash
|
312
|
+
$ rails mdbs:setup
|
313
|
+
```
|
314
|
+
|
315
|
+
To setup a specific database.
|
316
|
+
```bash
|
317
|
+
$ rails mdbs:your_database_name:setup
|
318
|
+
```
|
319
|
+
|
320
|
+
To migrate all the databases.
|
321
|
+
```bash
|
322
|
+
$ rails mdbs:migrate
|
323
|
+
```
|
324
|
+
|
325
|
+
To migrate a specific database.
|
326
|
+
```bash
|
327
|
+
$ rails mdbs:your_database_name:migrate
|
328
|
+
```
|
329
|
+
|
330
|
+
You can pass the standard rails options as arguments to the tasks.
|
331
|
+
|
332
|
+
Please. Please! check the tasks under the namespace "mdbs"
|
333
|
+
Run in your terminal
|
334
|
+
```bash
|
335
|
+
$ rake --tasks
|
336
|
+
```
|
337
|
+
|
338
|
+
|
339
|
+
|
340
|
+
## License
|
341
|
+
The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
|
data/Rakefile
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
begin
|
2
|
+
require 'bundler/setup'
|
3
|
+
rescue LoadError
|
4
|
+
puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
|
5
|
+
end
|
6
|
+
|
7
|
+
require 'rdoc/task'
|
8
|
+
|
9
|
+
RDoc::Task.new(:rdoc) do |rdoc|
|
10
|
+
rdoc.rdoc_dir = 'rdoc'
|
11
|
+
rdoc.title = 'MultipleDbs'
|
12
|
+
rdoc.options << '--line-numbers'
|
13
|
+
rdoc.rdoc_files.include('README.md')
|
14
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
15
|
+
end
|
16
|
+
|
17
|
+
|
18
|
+
|
19
|
+
|
20
|
+
|
21
|
+
|
22
|
+
require 'bundler/gem_tasks'
|
23
|
+
|
24
|
+
require 'rake/testtask'
|
25
|
+
|
26
|
+
Rake::TestTask.new(:test) do |t|
|
27
|
+
t.libs << 'lib'
|
28
|
+
t.libs << 'test'
|
29
|
+
t.pattern = 'test/**/*_test.rb'
|
30
|
+
t.verbose = false
|
31
|
+
end
|
32
|
+
|
33
|
+
|
34
|
+
task default: :test
|
@@ -0,0 +1,23 @@
|
|
1
|
+
Description:
|
2
|
+
You must use this generator to start using the multiple_dbs gem .
|
3
|
+
It creates the files needed to work with your databases.
|
4
|
+
Those files are:
|
5
|
+
- An initializer that define a constant with the databases names that you
|
6
|
+
give as an argument and the constants that store the databases configuration.
|
7
|
+
- the DBNAME_database.yml configuration files for each one of the databases.
|
8
|
+
- the database.yml. This file is needed by rails as default.
|
9
|
+
You can pass as options the configuration for each environment
|
10
|
+
(development, production, test).
|
11
|
+
|
12
|
+
Example:
|
13
|
+
rails generate multiple_dbs_initializer your_database your_database2 your_database3
|
14
|
+
|
15
|
+
This will create and override if exist the following files:
|
16
|
+
config/initializers/multiple_dbs_initializer.rb
|
17
|
+
config/multiple_dbs/your_database_database.yml
|
18
|
+
config/multiple_dbs/your_database2_database.yml
|
19
|
+
config/multiple_dbs/your_database3_database.yml
|
20
|
+
config/database.yml
|
21
|
+
|
22
|
+
Example with Options:
|
23
|
+
rails generate multiple_dbs_initializer your_database your_database2 your_database3 --development=username:super password:cool --test=adapter:mysql2 pool:2 --production=username:imsecure
|
@@ -0,0 +1,131 @@
|
|
1
|
+
class MultipleDbsInitializerGenerator < Rails::Generators::Base
|
2
|
+
source_root File.expand_path("../templates", __FILE__)
|
3
|
+
|
4
|
+
## @@default_db_config
|
5
|
+
# default database configuration
|
6
|
+
@@default_db_config = {
|
7
|
+
"adapter"=> "postgresql",
|
8
|
+
"encoding"=> "unicode",
|
9
|
+
"pool"=> 5,
|
10
|
+
"username"=> "root",
|
11
|
+
"password"=> "toor",
|
12
|
+
}
|
13
|
+
|
14
|
+
## databases = [:db1, :db2]
|
15
|
+
# an array that stores the databases names.
|
16
|
+
argument :databases, type: :array, default: [:db1, :db2]
|
17
|
+
|
18
|
+
## development = @@default_db_config
|
19
|
+
# a hash that allows the user to change the default database configuration
|
20
|
+
# for the development environment through the options
|
21
|
+
class_option :development, type: :hash, default: @@default_db_config
|
22
|
+
## production = @@default_db_config
|
23
|
+
# a hash that allows the user to change the default database configuration
|
24
|
+
# for the production environment through the options
|
25
|
+
class_option :production, type: :hash, default: @@default_db_config
|
26
|
+
## test = @@default_db_config
|
27
|
+
# a hash that allows the user to change the default database configuration
|
28
|
+
# for the test environment through the options
|
29
|
+
class_option :test, type: :hash, default: @@default_db_config
|
30
|
+
|
31
|
+
## not_override
|
32
|
+
# If false override the config/database.yml otherwise not override it
|
33
|
+
class_option :not_override, type: :boolean, default: true
|
34
|
+
|
35
|
+
## define_multiple_dbs_constant
|
36
|
+
# Create the multiple_dbs_initializer.rb file.
|
37
|
+
# This file define the MultipleDbs::DBS constant
|
38
|
+
# and the MultipleDbs::DbConnection per database.
|
39
|
+
# Also delete the config/multiple_dbs folder and
|
40
|
+
# create the ymls files that store the database
|
41
|
+
# configuration
|
42
|
+
def define_multiple_dbs_constant
|
43
|
+
copy_file "initializer.rb", "config/initializers/multiple_dbs_initializer.rb"
|
44
|
+
insert_into_file "config/initializers/multiple_dbs_initializer.rb",
|
45
|
+
%Q{\tDBS=#{databases.map{|db| db.to_s.underscore.to_sym}}
|
46
|
+
run_setup\n}, after: "# Your databases.\n", verbose: false
|
47
|
+
remove_file "config/multiple_dbs", verbose: false
|
48
|
+
inject_into_class "app/controllers/application_controller.rb", ApplicationController,
|
49
|
+
%Q{\t\t# def mdb_name
|
50
|
+
# Thread.current[:mdb_name] ||= ... somthing that gives you the database name, like: 'db1' or 'client1_database'
|
51
|
+
# end
|
52
|
+
# before_filter do
|
53
|
+
# MultipleDbs.validate_connection(mdb_name)
|
54
|
+
# end\n}
|
55
|
+
databases.each do |db|
|
56
|
+
create_database_config_file db
|
57
|
+
end
|
58
|
+
create_database_config_file if !options.not_override
|
59
|
+
end
|
60
|
+
|
61
|
+
private
|
62
|
+
|
63
|
+
|
64
|
+
## create_database_config_file
|
65
|
+
# create the configuration yml file for the given database name
|
66
|
+
# if the database name is null then the default rails configuration file is
|
67
|
+
# Overwritten
|
68
|
+
def create_database_config_file(db = nil)
|
69
|
+
fpath = db ? "/multiple_dbs/#{db}_database.yml" : "/database.yml"
|
70
|
+
db ||= databases.first
|
71
|
+
copy_file "config_db.yml", "config#{fpath}"
|
72
|
+
|
73
|
+
insert_into_file "config#{fpath}",
|
74
|
+
%Q{#{options.development["adapter"] ? options.development["adapter"] : @@default_db_config["adapter"] } },
|
75
|
+
before: "#development_adapter", verbose: false, force: true
|
76
|
+
insert_into_file "config#{fpath}",
|
77
|
+
%Q{#{options.development["encoding"] ? options.development["encoding"] : @@default_db_config["encoding"] } },
|
78
|
+
before: "#development_encoding", verbose: false, force: true
|
79
|
+
insert_into_file "config#{fpath}",
|
80
|
+
%Q{#{options.development["pool"] ? options.development["pool"] : @@default_db_config["pool"] } },
|
81
|
+
before: "#development_pool", verbose: false, force: true
|
82
|
+
insert_into_file "config#{fpath}",
|
83
|
+
%Q{#{db}_development },
|
84
|
+
before: "#development_database", verbose: false, force: true
|
85
|
+
insert_into_file "config#{fpath}",
|
86
|
+
%Q{#{options.development["username"] ? options.development["username"] : @@default_db_config["username"] } },
|
87
|
+
before: "#development_username", verbose: false, force: true
|
88
|
+
insert_into_file "config#{fpath}",
|
89
|
+
%Q{#{options.development["password"] ? options.development["password"] : @@default_db_config["password"] } },
|
90
|
+
before: "#development_psw", verbose: false, force: true
|
91
|
+
|
92
|
+
insert_into_file "config#{fpath}",
|
93
|
+
%Q{#{options.production["adapter"] ? options.production["adapter"] : @@default_db_config["adapter"] } },
|
94
|
+
before: "#production_adapter", verbose: false, force: true
|
95
|
+
insert_into_file "config#{fpath}",
|
96
|
+
%Q{#{options.production["encoding"] ? options.production["encoding"] : @@default_db_config["encoding"] } },
|
97
|
+
before: "#production_encoding", verbose: false, force: true
|
98
|
+
insert_into_file "config#{fpath}",
|
99
|
+
%Q{#{options.production["pool"] ? options.production["pool"] : @@default_db_config["pool"] } },
|
100
|
+
before: "#production_pool", verbose: false, force: true
|
101
|
+
insert_into_file "config#{fpath}",
|
102
|
+
%Q{#{db}_production },
|
103
|
+
before: "#production_database", verbose: false, force: true
|
104
|
+
insert_into_file "config#{fpath}",
|
105
|
+
%Q{#{options.production["username"] ? options.production["username"] : @@default_db_config["username"] } },
|
106
|
+
before: "#production_username", verbose: false, force: true
|
107
|
+
insert_into_file "config#{fpath}",
|
108
|
+
%Q{#{options.production["password"] ? options.production["password"] : @@default_db_config["password"] } },
|
109
|
+
before: "#production_psw", verbose: false, force: true
|
110
|
+
|
111
|
+
insert_into_file "config#{fpath}",
|
112
|
+
%Q{#{options.test["adapter"] ? options.test["adapter"] : @@default_db_config["adapter"] } },
|
113
|
+
before: "#test_adapter", verbose: false, force: true
|
114
|
+
insert_into_file "config#{fpath}",
|
115
|
+
%Q{#{options.test["encoding"] ? options.test["encoding"] : @@default_db_config["encoding"] } },
|
116
|
+
before: "#test_encoding", verbose: false, force: true
|
117
|
+
insert_into_file "config#{fpath}",
|
118
|
+
%Q{#{options.test["pool"] ? options.test["pool"] : @@default_db_config["pool"] } },
|
119
|
+
before: "#test_pool", verbose: false, force: true
|
120
|
+
insert_into_file "config#{fpath}",
|
121
|
+
%Q{#{db}_test },
|
122
|
+
before: "#test_database", verbose: false, force: true
|
123
|
+
insert_into_file "config#{fpath}",
|
124
|
+
%Q{#{options.test["username"] ? options.test["username"] : @@default_db_config["username"] } },
|
125
|
+
before: "#test_username", verbose: false, force: true
|
126
|
+
insert_into_file "config#{fpath}",
|
127
|
+
%Q{#{options.test["password"] ? options.test["password"] : @@default_db_config["password"] } },
|
128
|
+
before: "#test_psw", verbose: false, force: true
|
129
|
+
end
|
130
|
+
|
131
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
|
2
|
+
development:
|
3
|
+
adapter: #development_adapter
|
4
|
+
encoding: #development_encoding
|
5
|
+
pool: #development_pool
|
6
|
+
database: #development_database
|
7
|
+
password: #development_psw
|
8
|
+
username: #development_username
|
9
|
+
|
10
|
+
production:
|
11
|
+
adapter: #production_adapter
|
12
|
+
encoding: #production_encoding
|
13
|
+
pool: #production_pool
|
14
|
+
database: #production_database
|
15
|
+
username: #production_username
|
16
|
+
password: #production_psw
|
17
|
+
|
18
|
+
test:
|
19
|
+
adapter: #test_adapter
|
20
|
+
encoding: #test_encoding
|
21
|
+
pool: #test_pool
|
22
|
+
database: #test_database
|
23
|
+
username: #test_username
|
24
|
+
password: #test_psw
|
@@ -0,0 +1,14 @@
|
|
1
|
+
Description:
|
2
|
+
Generate the migrations like the migration generator from rails but
|
3
|
+
create the files in the multiple_dbs databases.
|
4
|
+
|
5
|
+
You can use it as you usually use the rails migration generator
|
6
|
+
|
7
|
+
You can use the options:
|
8
|
+
--only and pass the name of the databases space separated. This only create
|
9
|
+
the migration in the specified databases
|
10
|
+
--skip and pass the name of the databases space separated. This not create
|
11
|
+
the migration in the specified databases
|
12
|
+
|
13
|
+
Example:
|
14
|
+
rails g multiple_dbs_migration add_password_to_users password:string --only=db1 db3 --skip=db3
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'rails/generators/active_record/migration/migration_generator'
|
2
|
+
|
3
|
+
class MultipleDbsMigrationGenerator < ActiveRecord::Generators::MigrationGenerator
|
4
|
+
source_root File.join(File.dirname(ActiveRecord::Generators::MigrationGenerator.instance_method(:create_migration_file).source_location.first), "templates")
|
5
|
+
|
6
|
+
class_option :only, type: :array, default: []
|
7
|
+
class_option :skip, type: :array, default: []
|
8
|
+
|
9
|
+
def create_migration_file
|
10
|
+
if MultipleDbs and MultipleDbs::DBS
|
11
|
+
set_local_assigns!
|
12
|
+
validate_file_name!
|
13
|
+
only_arr = options[:only].map{|o| o.to_sym }.delete_if{ |o| !MultipleDbs::DBS.include?(o)} if options[:only] and options[:only].any?
|
14
|
+
skip_arr = options[:skip].map{|s| s.to_sym }.delete_if{ |s| !MultipleDbs::DBS.include?(s)} if options[:skip] and options[:skip].any?
|
15
|
+
databases_list = (MultipleDbs::DBS & only_arr) if only_arr and only_arr.any?
|
16
|
+
databases_list = databases_list - skip_arr if skip_arr and skip_arr.any?
|
17
|
+
databases_list ||= MultipleDbs::DBS
|
18
|
+
databases_list.each do |branch|
|
19
|
+
migration_template @migration_template, "db/#{branch}/migrate/#{file_name}.rb"
|
20
|
+
end if databases_list.any?
|
21
|
+
else
|
22
|
+
puts "The multiple_dbs constant is not defined. The multiple_dbs generator must be runned first. Type in your console: rails g multiple_dbs --help"
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
Description:
|
2
|
+
Generate the models like the model generator from rails but
|
3
|
+
create the files in the multiple_dbs databases.
|
4
|
+
|
5
|
+
You can use it as you usually use the rails model generator
|
6
|
+
|
7
|
+
You can use the options:
|
8
|
+
--only and pass the name of the databases space separated. This only create
|
9
|
+
the model in the specified databases
|
10
|
+
--skip and pass the name of the databases space separated. This not create
|
11
|
+
the model in the specified databases
|
12
|
+
|
13
|
+
Example:
|
14
|
+
rails g multiple_dbs_model User email:string --only=db1 db3 --skip=db3
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'rails/generators/active_record/model/model_generator'
|
2
|
+
|
3
|
+
class MultipleDbsModelGenerator < ActiveRecord::Generators::ModelGenerator
|
4
|
+
source_root File.join(File.dirname(ActiveRecord::Generators::ModelGenerator.instance_method(:create_migration_file).source_location.first), "templates")
|
5
|
+
|
6
|
+
class_option :only, type: :array, default: []
|
7
|
+
class_option :skip, type: :array, default: []
|
8
|
+
|
9
|
+
def create_migration_file
|
10
|
+
if MultipleDbs and MultipleDbs::DBS
|
11
|
+
return unless options[:migration] && options[:parent].nil?
|
12
|
+
attributes.each { |a| a.attr_options.delete(:index) if a.reference? && !a.has_index? } if options[:indexes] == false
|
13
|
+
only_arr = options[:only].map{|o| o.to_sym }.delete_if{ |o| !MultipleDbs::DBS.include?(o)} if options[:only] and options[:only].any?
|
14
|
+
skip_arr = options[:skip].map{|s| s.to_sym }.delete_if{ |s| !MultipleDbs::DBS.include?(s)} if options[:skip] and options[:skip].any?
|
15
|
+
databases_list = (MultipleDbs::DBS & only_arr) if only_arr and only_arr.any?
|
16
|
+
databases_list = databases_list - skip_arr if skip_arr and skip_arr.any?
|
17
|
+
databases_list ||= MultipleDbs::DBS
|
18
|
+
databases_list.each do |branch|
|
19
|
+
migration_template "../../migration/templates/create_table_migration.rb", "db/#{branch}/migrate/#{table_name}.rb"
|
20
|
+
end if databases_list.any?
|
21
|
+
else
|
22
|
+
puts "The multiple_dbs constant is not defined. The multiple_dbs generator must be runned first. Type in your console: rails g multiple_dbs --help"
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
data/lib/multiple_dbs.rb
ADDED
@@ -0,0 +1,207 @@
|
|
1
|
+
module MultipleDbs
|
2
|
+
|
3
|
+
def validate_connection(db)
|
4
|
+
conn_klass = const_get("Conn#{db.to_s.camelize}")
|
5
|
+
if conn_klass
|
6
|
+
ActiveRecord::Base.connection_handler.connection_pools.each do |pool|
|
7
|
+
Rails.logger.info "CONN FOUND" and return true if pool.spec.name == conn_klass.to_s
|
8
|
+
end
|
9
|
+
Rails.logger.info " CONN NOT FOUND. CONNECTION TO #{conn_klass}"
|
10
|
+
conn_klass.connection and return true
|
11
|
+
else
|
12
|
+
raise Exception.new("Undefined constant #{conn_klass}")
|
13
|
+
end
|
14
|
+
end
|
15
|
+
module_function :validate_connection
|
16
|
+
|
17
|
+
# This module should be included in your application ApplicationRecord.
|
18
|
+
# It define two class methods for your models. With this two
|
19
|
+
# methods you can setup and handle all the models from all the
|
20
|
+
# databases you defined.
|
21
|
+
module MultiConnectable
|
22
|
+
extend ActiveSupport::Concern
|
23
|
+
|
24
|
+
included do
|
25
|
+
end
|
26
|
+
|
27
|
+
module ClassMethods
|
28
|
+
|
29
|
+
# This method lookup for the subclass related to the database that you pass
|
30
|
+
# as an argument and the model in wich you are calling the method.
|
31
|
+
# It use Object.const_get to lookup for the constant and also call
|
32
|
+
# the method multiple_relations so the relations match the classes
|
33
|
+
# that must be matched.
|
34
|
+
def multiple_class(connectable_type)
|
35
|
+
klass = Object.const_get("#{self.name}#{connectable_type.capitalize}")
|
36
|
+
klass.muliple_relations
|
37
|
+
klass
|
38
|
+
end
|
39
|
+
alias :mdb :multiple_class
|
40
|
+
|
41
|
+
# This method define one subclass for each database you define. Why?
|
42
|
+
# becouse each subclass handle the connection with the specifyed database
|
43
|
+
# and becouse of that we does not have to turn off and on the connections
|
44
|
+
# between databases. It's simple, if you have a User model and 3 databases
|
45
|
+
# defined db1, db2, db3 this method set the constants UserDb1, UserDb2
|
46
|
+
# and UserDb3. UserDb1 handle the connection with the database db1 and so on.
|
47
|
+
#
|
48
|
+
# EXAMPLE:
|
49
|
+
# class User < ApplicationRecord
|
50
|
+
# make_connectable_class do |db|
|
51
|
+
# has_many :post, class_name: "Post#{db}"
|
52
|
+
# end
|
53
|
+
# end
|
54
|
+
#
|
55
|
+
def make_connectable_class(options = {},&block)
|
56
|
+
only = options[:only]
|
57
|
+
only = only.delete_if{ |o| !MultipleDbs::DBS.include?(o) } if only and only.any?
|
58
|
+
database_list = (MultipleDbs::DBS & only) if only and only.any?
|
59
|
+
database_list ||= MultipleDbs::DBS
|
60
|
+
database_list.each do |db|
|
61
|
+
class_eval do
|
62
|
+
Object.const_set("#{self.name}#{db.capitalize}", Class.new(self) do
|
63
|
+
class_eval do
|
64
|
+
# This constant store the name of the database that this subclass
|
65
|
+
# is handling
|
66
|
+
const_set("CONNECTABLE_TYPE",db.capitalize)
|
67
|
+
|
68
|
+
# This variable will store the connection_pool that is going to
|
69
|
+
# handle the connections for the database. Just initializing the constant
|
70
|
+
Thread.current[const_get("CONNECTABLE_TYPE").to_s.underscore + "_connection"] = nil
|
71
|
+
|
72
|
+
# This filter calls the method multiple_relations
|
73
|
+
# setting the relations to the database they should be set
|
74
|
+
before_validation :muliple_relations
|
75
|
+
# This filter calls the method multiple_relations
|
76
|
+
# setting the relations to the database they should be set
|
77
|
+
after_find :muliple_relations
|
78
|
+
|
79
|
+
|
80
|
+
# This variable store the block given by the user...
|
81
|
+
# It is thought to have the definition of the model relations
|
82
|
+
# and is used my the method multiple_relations to set them adequately
|
83
|
+
@connectable_relations = block_given? ? block : nil
|
84
|
+
|
85
|
+
# This method call the block given by the user. If that block contains
|
86
|
+
# the definition of the relations parametrized like this:
|
87
|
+
#
|
88
|
+
# class User < ApplicationRecord
|
89
|
+
# make_connectable_class do |db|
|
90
|
+
# has_many :post, class_name: "Post#{db}"
|
91
|
+
# end
|
92
|
+
# end
|
93
|
+
#
|
94
|
+
# it will set the :post relation to the database handle by this
|
95
|
+
# subclass
|
96
|
+
def self.muliple_relations
|
97
|
+
@connectable_relations.call( const_get("CONNECTABLE_TYPE") ) if @connectable_relations
|
98
|
+
end
|
99
|
+
|
100
|
+
# return the database name of the database that this subclass
|
101
|
+
# is related to
|
102
|
+
def self.connectable_type
|
103
|
+
const_get("CONNECTABLE_TYPE")
|
104
|
+
end
|
105
|
+
|
106
|
+
|
107
|
+
# Override the connection method. Search the connection_pool that
|
108
|
+
# is handle the database connection, assign it to the
|
109
|
+
# Thread.current[const_get("CONNECTABLE_TYPE").to_s.underscore + "_connection"]
|
110
|
+
# vairable
|
111
|
+
def self.connection
|
112
|
+
self.connection_handler.connection_pools.each do |pool|
|
113
|
+
if pool.spec.config[:database] == eval('DBConnection' + const_get("CONNECTABLE_TYPE").to_s).connection["database"]
|
114
|
+
return Thread.current[const_get("CONNECTABLE_TYPE").to_s.underscore + "_connection"] = pool.connection
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
private
|
120
|
+
|
121
|
+
# return the database name of the database that this subclass
|
122
|
+
# is related to
|
123
|
+
def connectable_type
|
124
|
+
const_get("CONNECTABLE_TYPE")
|
125
|
+
end
|
126
|
+
|
127
|
+
# Call the class method multiple_relations.
|
128
|
+
# This method call the block given by the user. If that block contains
|
129
|
+
# the definition of the relations parametrized like this:
|
130
|
+
#
|
131
|
+
# class User < ApplicationRecord
|
132
|
+
# make_connectable_class do |db|
|
133
|
+
# has_many :post, class_name: "Post#{db}"
|
134
|
+
# end
|
135
|
+
# end
|
136
|
+
#
|
137
|
+
# it will set the :post relation to the database handle by this
|
138
|
+
# subclass
|
139
|
+
def muliple_relations
|
140
|
+
self.class.muliple_relations
|
141
|
+
end
|
142
|
+
end
|
143
|
+
end)
|
144
|
+
# Set the relations for the current database
|
145
|
+
Object.const_get("#{self.name}#{db.capitalize}").muliple_relations
|
146
|
+
end
|
147
|
+
end if database_list.any?
|
148
|
+
end
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
|
153
|
+
private
|
154
|
+
|
155
|
+
def run_setup
|
156
|
+
Object.class_eval do
|
157
|
+
def self.const_missing(c)
|
158
|
+
matches = []
|
159
|
+
db_matches = []
|
160
|
+
MultipleDbs::DBS.each do |db|
|
161
|
+
matches << c.to_s.scan(
|
162
|
+
Regexp.new('(([A-Z]){1}([a-zA-Z]|[0-9])*)+' + db.to_s.camelize + '$')
|
163
|
+
)
|
164
|
+
db_matches << db
|
165
|
+
break if matches.flatten.any?
|
166
|
+
end
|
167
|
+
const_temp = Object.const_get(matches.first).mdb(db_matches.last) if matches.flatten!.any?
|
168
|
+
MultipleDbs.validate_connection(db_matches.last) if matches.any? and const_temp.to_s.eql?(c.to_s)
|
169
|
+
return const_temp if matches.any? and const_temp.to_s.eql?(c.to_s)
|
170
|
+
super
|
171
|
+
end
|
172
|
+
end if Rails.env.development? and defined? MultipleDbs and defined? MultipleDbs::DBS
|
173
|
+
|
174
|
+
DBS.each do |db|
|
175
|
+
Object.const_set("DBConnection" + db.to_s.camelize , Class.new do
|
176
|
+
attr_accessor :connection
|
177
|
+
@connection = YAML::load(ERB.new(File.read(Rails.root.join("config/multiple_dbs", db.to_s.downcase + "_database.yml"))).result)[Rails.env]
|
178
|
+
def self.connection
|
179
|
+
@connection
|
180
|
+
end
|
181
|
+
end)
|
182
|
+
end
|
183
|
+
|
184
|
+
DBS.each do |db|
|
185
|
+
conn_config = const_get("DBConnection" + db.to_s.camelize).connection
|
186
|
+
if conn_config["database"] != ActiveRecord::Base.connection_config[:database]
|
187
|
+
conn_klass = Object.const_set("Conn" + db.to_s.camelize, Class.new(ApplicationRecord))
|
188
|
+
conn_klass.establish_connection conn_config
|
189
|
+
conn_klass.connection
|
190
|
+
else
|
191
|
+
Object.const_set("Conn" + db.to_s.camelize, ActiveRecord::Base)
|
192
|
+
end
|
193
|
+
end
|
194
|
+
|
195
|
+
ActiveRecord::Base.clear_all_connections!
|
196
|
+
end
|
197
|
+
module_function :run_setup
|
198
|
+
|
199
|
+
end
|
200
|
+
|
201
|
+
# If running in development mode, rails use Kernel#load to load our code.
|
202
|
+
# Is good, it allows us to make changes in files and see the changes in our
|
203
|
+
# server/console instantly but the subclasses that we create for each one of
|
204
|
+
# your models will not be available until you call the model...
|
205
|
+
# So this piece of code override const_missing if you are running rails in
|
206
|
+
# development and find the constants that you are looking for
|
207
|
+
# (the multiple_dbs constants) behind the scenes
|
@@ -0,0 +1,227 @@
|
|
1
|
+
|
2
|
+
# Regexp used to find the databases list.
|
3
|
+
REGEX_MATCH_FILES_BY_NAME = /config\/multiple_dbs\/([a-zA-Z]+[0-9]*|[0-9]+[a-zA-Z]*)_database.yml/
|
4
|
+
|
5
|
+
# @dbs Store all the databases names
|
6
|
+
@dbs = []
|
7
|
+
|
8
|
+
# Search in the config/multiple_dbs directory and scan each filename looking for each database name
|
9
|
+
Dir["config/multiple_dbs/*"].each do |file|
|
10
|
+
@dbs << file.scan(REGEX_MATCH_FILES_BY_NAME)
|
11
|
+
end
|
12
|
+
@dbs.flatten!
|
13
|
+
|
14
|
+
|
15
|
+
# MultipleDbs namespace
|
16
|
+
namespace :mdbs do
|
17
|
+
# Looping all the databases
|
18
|
+
@dbs.each do |db|
|
19
|
+
desc "databases managment #{db} tasks"
|
20
|
+
# A namespace per database
|
21
|
+
namespace db.to_sym do |database|
|
22
|
+
desc "#{db} drop"
|
23
|
+
task :drop do
|
24
|
+
Rake::Task["db:drop"].invoke
|
25
|
+
end
|
26
|
+
desc "#{db} create"
|
27
|
+
task :create do
|
28
|
+
Rake::Task["db:create"].invoke
|
29
|
+
end
|
30
|
+
desc "#{db} setup"
|
31
|
+
task :setup do
|
32
|
+
Rake::Task["db:setup"].invoke
|
33
|
+
end
|
34
|
+
desc "#{db} migrate"
|
35
|
+
task :migrate do
|
36
|
+
Rake::Task["db:migrate"].invoke
|
37
|
+
end
|
38
|
+
desc "#{db} rollback"
|
39
|
+
task :rollback do
|
40
|
+
Rake::Task["db:rollback"].invoke
|
41
|
+
end
|
42
|
+
desc "#{db} seed"
|
43
|
+
task :seed do
|
44
|
+
Rake::Task["db:seed"].invoke
|
45
|
+
end
|
46
|
+
desc "#{db} version"
|
47
|
+
task :version do
|
48
|
+
Rake::Task["db:version"].invoke
|
49
|
+
end
|
50
|
+
|
51
|
+
namespace :schema do
|
52
|
+
desc "#{db} schema load"
|
53
|
+
task :load do
|
54
|
+
Rake::Task["db:schema:load"].invoke
|
55
|
+
end
|
56
|
+
desc "#{db} schema dump"
|
57
|
+
task :dump do
|
58
|
+
Rake::Task["db:schema:dump"].invoke
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
database.tasks.each do |task|
|
63
|
+
task.enhance ["mdbs:#{db}:set_custom_config"] do
|
64
|
+
Rake::Task["mdbs:#{db}:revert_to_original_config"].invoke
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
desc "#{db} set custom config"
|
69
|
+
task "set_custom_config".to_sym do
|
70
|
+
# save current vars
|
71
|
+
@original_config = {
|
72
|
+
env_schema: ENV['SCHEMA'],
|
73
|
+
config: Rails.application.config.dup
|
74
|
+
}
|
75
|
+
# set config variables for custom database
|
76
|
+
ENV['SCHEMA'] = "db/#{db}/schema.rb"
|
77
|
+
Rails.application.config.paths['db'] = ["db/#{db}"]
|
78
|
+
Rails.application.config.paths['db/migrate'] = ["db/#{db}/migrate"]
|
79
|
+
Rails.application.config.paths['db/seeds.rb'] = ["db/#{db}/seeds.rb"]
|
80
|
+
Rails.application.config.paths['config/database'] = ["config/multiple_dbs/#{db}_database.yml"]
|
81
|
+
end
|
82
|
+
desc "#{db} revert custom config"
|
83
|
+
task "revert_to_original_config".to_sym do
|
84
|
+
# reset config variables to original values
|
85
|
+
ENV['SCHEMA'] = @original_config[:env_schema]
|
86
|
+
Rails.application.config = @original_config[:config]
|
87
|
+
end
|
88
|
+
end #db tasks
|
89
|
+
|
90
|
+
end # looping dbes
|
91
|
+
|
92
|
+
desc "drop all dbs and delete their schema file"
|
93
|
+
task :hard_drop do
|
94
|
+
@dbs.each do |db|
|
95
|
+
puts "hard dropping #{db}"
|
96
|
+
puts system(" rake mdbs:#{db}:drop") ? "#{db} dropped" : "Error while dropping #{db}"
|
97
|
+
puts system(" rm -rf db/#{db}/schema.rb ") ? "schema from #{db} removed" : "Error while erasing the schema from #{db}"
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
desc "drop, delete the schema files, create, migrate and seed for all dbs"
|
102
|
+
task :hard_reset do
|
103
|
+
@dbs.each do |db|
|
104
|
+
puts "hard reset #{db}"
|
105
|
+
puts system(" rake mdbs:#{db}:drop") ? "#{db} dropped" : "Error while dropping #{db}"
|
106
|
+
puts system(" rm -rf db/#{db}/schema.rb ") ? "schema from #{db} removed" : "Error while erasing the schema from #{db}"
|
107
|
+
puts system(" rake mdbs:#{db}:create") ? "#{db} created" : "Error while creating #{db}"
|
108
|
+
puts system(" rake mdbs:#{db}:migrate") ? "#{db} migrated" : "Error while migrating #{db}"
|
109
|
+
puts system(" rake mdbs:#{db}:seed") ? "#{db} seeded" : "Error while seeding #{db}"
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
desc "copy the seeds from the db/seed.rb file to each dbs seed file."
|
114
|
+
task :copy_seeds do
|
115
|
+
@dbs.each do |db|
|
116
|
+
puts "Copy seed to #{db}. #{system('cp db/seeds.rb db/#{db}/seeds.rb')}"
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
desc "copy the specified migration to each dbs migrations folder. Parameters: full_path.rb, database_name"
|
121
|
+
task :copy_migration, [:file_name, :db_name] do |t, args|
|
122
|
+
@dbs.each do |db|
|
123
|
+
puts "Copy migration from db/#{args[:db_name].downcase}/migrate/#{args[:file_name]} to db/#{db}/migrate/#{args[:file_name]}."
|
124
|
+
puts system("cp db/#{args[:db_name].downcase}/migrate/#{args[:file_name]} db/#{db}/migrate/#{args[:file_name]} ")
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
desc "copy the specified migration to the specified db migrations folder. Parameters: full_path.rb, from_database_name, to_database_name"
|
129
|
+
task :copy_migration_into, [:file_name, :from_database_name, :to_database_name] do |t, args|
|
130
|
+
puts "Copy migration from db/#{args[:from_database_name].downcase}/migrate/#{args[:file_name]} to db/#{args[:to_database_name]}/migrate/#{args[:file_name]}."
|
131
|
+
puts system("cp db/#{args[:from_database_name].downcase}/migrate/#{args[:file_name]} db/#{args[:to_database_name]}/migrate/#{args[:file_name]} ")
|
132
|
+
end
|
133
|
+
|
134
|
+
desc "copy the specified migration from the default migrations folder db/migrate to each dbs migrations folder. Parameters: full_path.rb"
|
135
|
+
task :copy_migration_from_default, [:file_name] do |t, args|
|
136
|
+
@dbs.each do |db|
|
137
|
+
puts "Copy migration from db/migrate/#{args[:file_name]} to db/#{db}/migrate/#{args[:file_name]}."
|
138
|
+
system(" mkdir db/#{db}")
|
139
|
+
system(" mkdir db/#{db}/migrate")
|
140
|
+
puts system("cp db/migrate/#{args[:file_name]} db/#{db}/migrate/#{args[:file_name]} ")
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
desc "copy the db/migration folder into each of your databases"
|
145
|
+
task :replicate_default_database do
|
146
|
+
@dbs.each do |db|
|
147
|
+
puts "Copy folder db/migrate to db/#{db}"
|
148
|
+
system(" mkdir db/#{db}")
|
149
|
+
puts system("cp -r db/migrate db/#{db}")
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
desc "copy the db/migration folder into the specified database"
|
154
|
+
task :replicate_default_database_into,[:db_name] do |t, args|
|
155
|
+
puts "Copy folder db/migrate to db/#{args[:db_name]}/migrate"
|
156
|
+
system(" mkdir db/#{args[:db_name]}")
|
157
|
+
puts system("cp -r db/migrate db/#{args[:db_name]}/migrate")
|
158
|
+
end
|
159
|
+
|
160
|
+
desc "copy the specified migration from the default migrations folder db/migrate, to the specified db migrations folder. Parameters: full_path.rb, to_database_name"
|
161
|
+
task :copy_migration_from_default_into, [:file_name, :to_database_name] do |t, args|
|
162
|
+
puts "Copy migration from db/migrate/#{args[:file_name]} to db/#{args[:to_database_name]}/migrate/#{args[:file_name]}."
|
163
|
+
system(" mkdir db/#{args[:to_database_name]}")
|
164
|
+
system(" mkdir db/#{args[:to_database_name]}/migrate")
|
165
|
+
puts system("cp db/migrate/#{args[:file_name]} db/#{args[:to_database_name]}/migrate/#{args[:file_name]} ")
|
166
|
+
end
|
167
|
+
|
168
|
+
desc "drop all dbs"
|
169
|
+
task :drop do
|
170
|
+
puts "Droping #{@dbs.join(',')}."
|
171
|
+
@dbs.each do |db|
|
172
|
+
Rake::Task["mdbs:#{db}:drop"].invoke
|
173
|
+
Rake::Task["db:drop"].reenable
|
174
|
+
Rake::Task["db:load_config"].reenable
|
175
|
+
Rake::Task["db:drop:_unsafe"].reenable
|
176
|
+
puts "#{db} dropped"
|
177
|
+
end
|
178
|
+
end
|
179
|
+
desc "create all dbs"
|
180
|
+
task :create do
|
181
|
+
@dbs.each do |db|
|
182
|
+
puts system(" rake mdbs:#{db}:create") ? "#{db} created" : "Error while creating #{db}"
|
183
|
+
end
|
184
|
+
end
|
185
|
+
desc "setup all dbs"
|
186
|
+
task :setup do
|
187
|
+
@dbs.each do |db|
|
188
|
+
puts system(" rake mdbs:#{db}:setup") ? "#{db} setup completed" : "Error while setting up #{db}"
|
189
|
+
end
|
190
|
+
end
|
191
|
+
desc "migrate all dbs"
|
192
|
+
task :migrate do
|
193
|
+
@dbs.each do |db|
|
194
|
+
puts system( "rake mdbs:#{db}:migrate" ) ? "#{db} migrated" : "Error while migrating #{db}"
|
195
|
+
end
|
196
|
+
end
|
197
|
+
desc "rollback all dbs"
|
198
|
+
task :rollback do
|
199
|
+
@dbs.each do |db|
|
200
|
+
puts system( "rake mdbs:#{db}:migrate" ) ? "#{db} rollback completed" : "Error while executing rollback on #{db}"
|
201
|
+
end
|
202
|
+
end
|
203
|
+
desc "seed all dbs"
|
204
|
+
task :seed do
|
205
|
+
@dbs.each do |db|
|
206
|
+
puts system( "rake mdbs:#{db}:seed" ) ? "#{db} seeded" : "Error while seeding #{db}"
|
207
|
+
end
|
208
|
+
end
|
209
|
+
desc "version all dbs"
|
210
|
+
task :version do
|
211
|
+
puts "Please use specific task for each database. Ex mdbs:my_db:version"
|
212
|
+
end
|
213
|
+
namespace :schema do
|
214
|
+
desc "schema load all dbs"
|
215
|
+
task :load do
|
216
|
+
@dbs.each do |db|
|
217
|
+
puts system(" rake mdbs:#{db}:schema:load ") ? "#{db} schema loaded" : "Error while loading schema for #{db}"
|
218
|
+
end
|
219
|
+
end
|
220
|
+
desc "schema dump all dbs"
|
221
|
+
task :dump do
|
222
|
+
@dbs.each do |db|
|
223
|
+
puts system(" rake mdbs:#{db}:schema:dump ") ? "#{db} schema dumped" : "Error while dumping schema for #{db}"
|
224
|
+
end
|
225
|
+
end
|
226
|
+
end
|
227
|
+
end
|
metadata
ADDED
@@ -0,0 +1,88 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: multiple_dbs
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Yonga9121
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2017-09-22 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rails
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 5.0.0
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 5.0.0
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: pg
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
description: Management of multiple databases.
|
42
|
+
email:
|
43
|
+
- jorgeggayon@gmail.com
|
44
|
+
executables: []
|
45
|
+
extensions: []
|
46
|
+
extra_rdoc_files: []
|
47
|
+
files:
|
48
|
+
- MIT-LICENSE
|
49
|
+
- README.md
|
50
|
+
- Rakefile
|
51
|
+
- lib/generators/multiple_dbs_initializer/USAGE
|
52
|
+
- lib/generators/multiple_dbs_initializer/multiple_dbs_initializer_generator.rb
|
53
|
+
- lib/generators/multiple_dbs_initializer/templates/config_db.yml
|
54
|
+
- lib/generators/multiple_dbs_initializer/templates/initializer.rb
|
55
|
+
- lib/generators/multiple_dbs_migration/USAGE
|
56
|
+
- lib/generators/multiple_dbs_migration/multiple_dbs_migration_generator.rb
|
57
|
+
- lib/generators/multiple_dbs_model/USAGE
|
58
|
+
- lib/generators/multiple_dbs_model/multiple_dbs_model_generator.rb
|
59
|
+
- lib/multiple_dbs.rb
|
60
|
+
- lib/multiple_dbs/multi_connectable.rb
|
61
|
+
- lib/multiple_dbs/railtie.rb
|
62
|
+
- lib/multiple_dbs/version.rb
|
63
|
+
- lib/tasks/multiple_dbs_tasks.rake
|
64
|
+
homepage: https://yonga9121.github.io/multiple_dbs/
|
65
|
+
licenses:
|
66
|
+
- MIT
|
67
|
+
metadata: {}
|
68
|
+
post_install_message:
|
69
|
+
rdoc_options: []
|
70
|
+
require_paths:
|
71
|
+
- lib
|
72
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
73
|
+
requirements:
|
74
|
+
- - ">="
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
version: '0'
|
77
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
78
|
+
requirements:
|
79
|
+
- - ">="
|
80
|
+
- !ruby/object:Gem::Version
|
81
|
+
version: '0'
|
82
|
+
requirements: []
|
83
|
+
rubyforge_project:
|
84
|
+
rubygems_version: 2.5.1
|
85
|
+
signing_key:
|
86
|
+
specification_version: 4
|
87
|
+
summary: Management of multiple databases.
|
88
|
+
test_files: []
|