multitenancy_tools 0.1.12 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
- data/Dockerfile +8 -0
- data/README.md +23 -0
- data/lib/multitenancy_tools.rb +2 -0
- data/lib/multitenancy_tools/dump/data_only.rb +38 -0
- data/lib/multitenancy_tools/dump/schema_only.rb +36 -0
- data/lib/multitenancy_tools/dump_cleaner.rb +24 -1
- data/lib/multitenancy_tools/schema_dumper.rb +10 -11
- data/lib/multitenancy_tools/table_dumper.rb +11 -12
- data/lib/multitenancy_tools/version.rb +1 -1
- data/multitenancy_tools.gemspec +1 -1
- data/scripts/bash +37 -0
- data/scripts/setup +5 -0
- metadata +12 -9
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 29487300a4a2beaeeb630c17072466accc69b6c1a9b66be2a1860027174be30e
|
4
|
+
data.tar.gz: 33309996f228140ccbbcb81f3ef01bfec3d11290e5af40a8e2f717ccf6f07bda
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 346288f4a1b022de75b601a2638fa772e6f69ded6ede08fc56a1219e9ca63f4d9d606479b145110dee3f2898ee095581a4f4f52ea117befe6f4b5929cfb15c32
|
7
|
+
data.tar.gz: 348d188521cd848777b2246974c3456edd3bd479dd51d0dd8374b55f86292fff2d37df30774f9a471188720a6dde49952891cbf41b7d115ee6de2f8f4b993296
|
data/Dockerfile
ADDED
data/README.md
CHANGED
@@ -40,6 +40,13 @@ dumper = MultitenancyTools::SchemaDumper.new('database name', 'schema name')
|
|
40
40
|
dumper.dump_to('path/to/file.sql')
|
41
41
|
```
|
42
42
|
|
43
|
+
#### Dumping from a different host and using a different username
|
44
|
+
```ruby
|
45
|
+
options = { host: 'db-on-docker', username: 'non-root-user' }
|
46
|
+
dumper = MultitenancyTools::SchemaDumper.new('database name', 'schema name', options)
|
47
|
+
dupmer.dump_to('path/to/file.sql')
|
48
|
+
```
|
49
|
+
|
43
50
|
### Dumping the content of a table to a SQL file
|
44
51
|
|
45
52
|
Like `SchemaDumper`, this tool also requires `pg_dump` to be on the `PATH`:
|
@@ -49,6 +56,13 @@ dumper = MultitenancyTools::TableDumper.new('database name', 'schema name', 'tab
|
|
49
56
|
dumper.dump_to('path/to/file.sql')
|
50
57
|
```
|
51
58
|
|
59
|
+
#### Dumping from a different host and using a different username
|
60
|
+
```ruby
|
61
|
+
options = { host: 'db-on-docker', username: 'non-root-user' }
|
62
|
+
dumper = MultitenancyTools::TableDumper.new('database name', 'schema name', 'table_name', options)
|
63
|
+
dupmer.dump_to('path/to/file.sql')
|
64
|
+
```
|
65
|
+
|
52
66
|
### Creating a new PostgreSQL schema using a SQL file as template
|
53
67
|
|
54
68
|
After using `SchemaDumper` to create the SQL template, you can use the following
|
@@ -72,6 +86,15 @@ this database *will be destroyed and recreated* on test execution.
|
|
72
86
|
You can use `bin/console` to get an interactive prompt that will allow you to
|
73
87
|
experiment.
|
74
88
|
|
89
|
+
You can also run this project using docker in your local environment. Just
|
90
|
+
ensure that you have:
|
91
|
+
|
92
|
+
* Docker equal or greater than 18.09.1
|
93
|
+
|
94
|
+
Then, build *Multitenancy Tools* image running `scripts/setup`
|
95
|
+
|
96
|
+
In order to access it's console, run `scripts/bash`
|
97
|
+
|
75
98
|
## Releasing a new version
|
76
99
|
|
77
100
|
If you are the maintainer of this project:
|
data/lib/multitenancy_tools.rb
CHANGED
@@ -1,6 +1,8 @@
|
|
1
1
|
require 'multitenancy_tools/version'
|
2
2
|
require 'multitenancy_tools/errors'
|
3
3
|
require 'multitenancy_tools/dump_cleaner'
|
4
|
+
require 'multitenancy_tools/dump/data_only'
|
5
|
+
require 'multitenancy_tools/dump/schema_only'
|
4
6
|
require 'multitenancy_tools/schema_dumper'
|
5
7
|
require 'multitenancy_tools/schema_creator'
|
6
8
|
require 'multitenancy_tools/table_dumper'
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require 'open3'
|
2
|
+
|
3
|
+
module MultitenancyTools
|
4
|
+
module Dump
|
5
|
+
class DataOnly
|
6
|
+
def initialize(options)
|
7
|
+
@schema = options.fetch(:schema)
|
8
|
+
@db = options.fetch(:database)
|
9
|
+
@host = options.fetch(:host, nil)
|
10
|
+
@user = options.fetch(:username, nil)
|
11
|
+
@table = options.fetch(:table)
|
12
|
+
end
|
13
|
+
|
14
|
+
def dump
|
15
|
+
Open3.capture3(dump_args.shelljoin)
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
def dump_args
|
21
|
+
args = [
|
22
|
+
'pg_dump',
|
23
|
+
'--table', "#{@schema}.#{@table}",
|
24
|
+
'--no-privileges',
|
25
|
+
'--no-tablespaces',
|
26
|
+
'--no-owner',
|
27
|
+
'--dbname', @db,
|
28
|
+
'--data-only',
|
29
|
+
'--inserts'
|
30
|
+
]
|
31
|
+
|
32
|
+
args << ['--host', @host] if @host.present?
|
33
|
+
args << ['--username', @user] if @user.present?
|
34
|
+
args.flatten
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'open3'
|
2
|
+
|
3
|
+
module MultitenancyTools
|
4
|
+
module Dump
|
5
|
+
class SchemaOnly
|
6
|
+
def initialize(options)
|
7
|
+
@schema = options.fetch(:schema)
|
8
|
+
@database = options.fetch(:database)
|
9
|
+
@host = options.fetch(:host, nil)
|
10
|
+
@user = options.fetch(:username, nil)
|
11
|
+
end
|
12
|
+
|
13
|
+
def dump
|
14
|
+
Open3.capture3(dump_args.shelljoin)
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
def dump_args
|
20
|
+
args = [
|
21
|
+
'pg_dump',
|
22
|
+
'--schema', @schema,
|
23
|
+
'--schema-only',
|
24
|
+
'--no-privileges',
|
25
|
+
'--no-tablespaces',
|
26
|
+
'--no-owner',
|
27
|
+
'--dbname', @database,
|
28
|
+
]
|
29
|
+
|
30
|
+
args << ['--host', @host] if @host.present?
|
31
|
+
args << ['--username', @user] if @user.present?
|
32
|
+
args.flatten
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -3,7 +3,8 @@ module MultitenancyTools
|
|
3
3
|
# be present on dumps generated by {SchemaDumper} and {TableDumper}.
|
4
4
|
class DumpCleaner
|
5
5
|
# @param [String] sql
|
6
|
-
def initialize(sql)
|
6
|
+
def initialize(sql, schema_name = '')
|
7
|
+
@schema_name = schema_name
|
7
8
|
@sql = sql.dup
|
8
9
|
end
|
9
10
|
|
@@ -17,7 +18,29 @@ module MultitenancyTools
|
|
17
18
|
@sql.gsub!(/SET lock_timeout .*;\n/, '')
|
18
19
|
@sql.gsub!(/^--(?:.*)\n+/, '')
|
19
20
|
@sql.gsub!(/\n+/, "\n")
|
21
|
+
clean_schema_names!
|
22
|
+
clean_catalog_overwrites!
|
20
23
|
@sql
|
21
24
|
end
|
25
|
+
|
26
|
+
private
|
27
|
+
|
28
|
+
# Matches namespaces containing the given schema_name
|
29
|
+
#
|
30
|
+
# For instance:
|
31
|
+
# CREATE TABLE schema1.posts ();
|
32
|
+
#
|
33
|
+
# Will be replaced by:
|
34
|
+
# CREATE TABLE posts ();
|
35
|
+
def clean_schema_names!
|
36
|
+
return if @schema_name.blank?
|
37
|
+
|
38
|
+
@sql.gsub!(/\b#{@schema_name}\.([\S\D]*)/, '\1')
|
39
|
+
end
|
40
|
+
|
41
|
+
# Removes system administrators configs overwrites
|
42
|
+
def clean_catalog_overwrites!
|
43
|
+
@sql.gsub!(/SELECT pg_catalog\.set_config.*;\n/, '')
|
44
|
+
end
|
22
45
|
end
|
23
46
|
end
|
@@ -21,9 +21,11 @@ module MultitenancyTools
|
|
21
21
|
class SchemaDumper
|
22
22
|
# @param database [String] database name
|
23
23
|
# @param schema [String] schema name
|
24
|
-
def initialize(database, schema)
|
24
|
+
def initialize(database, schema, options = {})
|
25
25
|
@database = database
|
26
26
|
@schema = schema
|
27
|
+
@host = options.fetch(:host, '')
|
28
|
+
@username = options.fetch(:username, '')
|
27
29
|
end
|
28
30
|
|
29
31
|
# Generates a dump an writes it into a file. Please see {IO.new} for open
|
@@ -34,20 +36,17 @@ module MultitenancyTools
|
|
34
36
|
# @param file [String] file path
|
35
37
|
# @param mode [String] IO open mode
|
36
38
|
def dump_to(file, mode: 'w')
|
37
|
-
stdout, stderr, status =
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
'--no-owner',
|
44
|
-
'--dbname', @database
|
45
|
-
)
|
39
|
+
stdout, stderr, status = Dump::SchemaOnly.new(
|
40
|
+
schema: @schema,
|
41
|
+
host: @host,
|
42
|
+
username: @username,
|
43
|
+
database: @database
|
44
|
+
).dump
|
46
45
|
|
47
46
|
fail(PgDumpError, stderr) unless status.success?
|
48
47
|
|
49
48
|
File.open(file, mode) do |f|
|
50
|
-
f.write DumpCleaner.new(stdout).clean
|
49
|
+
f.write DumpCleaner.new(stdout, @schema).clean
|
51
50
|
end
|
52
51
|
end
|
53
52
|
end
|
@@ -20,10 +20,12 @@ module MultitenancyTools
|
|
20
20
|
# @param database [String] database name
|
21
21
|
# @param schema [String] schema name
|
22
22
|
# @param table [String] table name
|
23
|
-
def initialize(database, schema, table)
|
23
|
+
def initialize(database, schema, table, options = {})
|
24
24
|
@database = database
|
25
25
|
@schema = schema
|
26
26
|
@table = table
|
27
|
+
@host = options.fetch(:host, '')
|
28
|
+
@username = options.fetch(:username, '')
|
27
29
|
end
|
28
30
|
|
29
31
|
# Generates a dump an writes it into a file. Please see {IO.new} for open
|
@@ -34,21 +36,18 @@ module MultitenancyTools
|
|
34
36
|
# @param file [String] file path
|
35
37
|
# @param mode [String] IO open mode
|
36
38
|
def dump_to(file, mode: 'w')
|
37
|
-
stdout, stderr, status =
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
'--inserts',
|
45
|
-
'--dbname', @database
|
46
|
-
)
|
39
|
+
stdout, stderr, status = Dump::DataOnly.new(
|
40
|
+
table: @table,
|
41
|
+
schema: @schema,
|
42
|
+
database: @database,
|
43
|
+
host: @host,
|
44
|
+
username: @username
|
45
|
+
).dump
|
47
46
|
|
48
47
|
fail(PgDumpError, stderr) unless status.success?
|
49
48
|
|
50
49
|
File.open(file, mode) do |f|
|
51
|
-
f.write DumpCleaner.new(stdout).clean
|
50
|
+
f.write DumpCleaner.new(stdout, @schema).clean
|
52
51
|
end
|
53
52
|
end
|
54
53
|
end
|
data/multitenancy_tools.gemspec
CHANGED
@@ -22,7 +22,7 @@ Gem::Specification.new do |spec|
|
|
22
22
|
|
23
23
|
spec.add_dependency 'activerecord', '~> 4.2.0'
|
24
24
|
spec.add_dependency 'activesupport', '~> 4.2.0'
|
25
|
-
spec.add_dependency 'pg'
|
25
|
+
spec.add_dependency 'pg', '< 1'
|
26
26
|
|
27
27
|
spec.add_development_dependency 'bundler', '~> 1.10'
|
28
28
|
spec.add_development_dependency 'rake', '~> 10.0'
|
data/scripts/bash
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
#!/bin/bash
|
2
|
+
|
3
|
+
set -e
|
4
|
+
|
5
|
+
export POSTGRES_CONTAINER_NAME="postgres"
|
6
|
+
|
7
|
+
# removed old pg containers running in your machine
|
8
|
+
# searches for containers with name "postgres"
|
9
|
+
remove_old_pg_container() {
|
10
|
+
container_id=$(docker ps -a --filter name="^$POSTGRES_CONTAINER_NAME$" --format {{.ID}})
|
11
|
+
|
12
|
+
if [ "$container_id" ]; then
|
13
|
+
docker stop $container_id
|
14
|
+
docker rm $container_id
|
15
|
+
fi
|
16
|
+
}
|
17
|
+
|
18
|
+
# destroys previous postgres containers and starts a new one
|
19
|
+
# with fresh data. This prevents problems in running it with
|
20
|
+
# a prepoulated volume containing old tables.
|
21
|
+
setup_db_container() {
|
22
|
+
remove_old_pg_container
|
23
|
+
|
24
|
+
docker run --detach \
|
25
|
+
--publish 5432:5432 \
|
26
|
+
--hostname $POSTGRES_CONTAINER_NAME \
|
27
|
+
--name $POSTGRES_CONTAINER_NAME postgres:9.3
|
28
|
+
}
|
29
|
+
|
30
|
+
# ignores docker containers IDs outputs to stdout
|
31
|
+
setup_db_container &>/dev/null
|
32
|
+
|
33
|
+
# brings up main container with multitenancy tools environment
|
34
|
+
docker run -it \
|
35
|
+
-v $PWD:/mtools \
|
36
|
+
--workdir /mtools --user $EUID \
|
37
|
+
--link $POSTGRES_CONTAINER_NAME mtools bash
|
data/scripts/setup
ADDED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: multitenancy_tools
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1
|
4
|
+
version: 0.2.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Lenon Marcel
|
@@ -11,7 +11,7 @@ authors:
|
|
11
11
|
autorequire:
|
12
12
|
bindir: exe
|
13
13
|
cert_chain: []
|
14
|
-
date:
|
14
|
+
date: 2019-02-15 00:00:00.000000000 Z
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
17
17
|
name: activerecord
|
@@ -45,16 +45,16 @@ dependencies:
|
|
45
45
|
name: pg
|
46
46
|
requirement: !ruby/object:Gem::Requirement
|
47
47
|
requirements:
|
48
|
-
- - "
|
48
|
+
- - "<"
|
49
49
|
- !ruby/object:Gem::Version
|
50
|
-
version: '
|
50
|
+
version: '1'
|
51
51
|
type: :runtime
|
52
52
|
prerelease: false
|
53
53
|
version_requirements: !ruby/object:Gem::Requirement
|
54
54
|
requirements:
|
55
|
-
- - "
|
55
|
+
- - "<"
|
56
56
|
- !ruby/object:Gem::Version
|
57
|
-
version: '
|
57
|
+
version: '1'
|
58
58
|
- !ruby/object:Gem::Dependency
|
59
59
|
name: bundler
|
60
60
|
requirement: !ruby/object:Gem::Requirement
|
@@ -138,6 +138,7 @@ files:
|
|
138
138
|
- ".gitignore"
|
139
139
|
- ".rspec"
|
140
140
|
- ".travis.yml"
|
141
|
+
- Dockerfile
|
141
142
|
- Gemfile
|
142
143
|
- LICENSE.txt
|
143
144
|
- README.md
|
@@ -145,6 +146,8 @@ files:
|
|
145
146
|
- bin/console
|
146
147
|
- bin/setup
|
147
148
|
- lib/multitenancy_tools.rb
|
149
|
+
- lib/multitenancy_tools/dump/data_only.rb
|
150
|
+
- lib/multitenancy_tools/dump/schema_only.rb
|
148
151
|
- lib/multitenancy_tools/dump_cleaner.rb
|
149
152
|
- lib/multitenancy_tools/errors.rb
|
150
153
|
- lib/multitenancy_tools/extensions_dumper.rb
|
@@ -157,6 +160,8 @@ files:
|
|
157
160
|
- lib/multitenancy_tools/table_dumper.rb
|
158
161
|
- lib/multitenancy_tools/version.rb
|
159
162
|
- multitenancy_tools.gemspec
|
163
|
+
- scripts/bash
|
164
|
+
- scripts/setup
|
160
165
|
homepage: https://github.com/locaweb/multitenancy_tools
|
161
166
|
licenses:
|
162
167
|
- MIT
|
@@ -176,10 +181,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
176
181
|
- !ruby/object:Gem::Version
|
177
182
|
version: '0'
|
178
183
|
requirements: []
|
179
|
-
|
180
|
-
rubygems_version: 2.4.5.1
|
184
|
+
rubygems_version: 3.0.2
|
181
185
|
signing_key:
|
182
186
|
specification_version: 4
|
183
187
|
summary: A collection of tools for multitenant Ruby/Rails apps
|
184
188
|
test_files: []
|
185
|
-
has_rdoc:
|