multiple_dbs 1.0.0
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 +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: []
|