izolenta 0.0.2 → 0.0.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +3 -0
- data/README.md +11 -0
- data/lib/izolenta/active_record_migration.rb +48 -31
- data/lib/izolenta/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: '09bc2895fc70a6c50727f81242f0f06e90c4492d3c1193ba4e1a1bffb83599ec'
|
4
|
+
data.tar.gz: 14d8e61fbd7bb788b05054274418d14b55e18117fc5793d5f0b4a67af1e85a41
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1d3fdb8446cd4698487c397bb7c8de99cdf1a44b911d84ce218c76d46f4aa98adc922813abfbbb231ad612bb0430137a538555d4620f77e813e2ac19e39c2d56
|
7
|
+
data.tar.gz: c9dc6ef925404436a15358c07a1c7a640f593a02f12fae1448b8b6429063c07629768e0f8f45dc78e44367ab482ade23bd53a5e5be926cf1f23d53910f13d62d
|
data/CHANGELOG.md
CHANGED
data/README.md
CHANGED
@@ -39,6 +39,13 @@ class YourMigration < ActiveRecord::Migration[5.0]
|
|
39
39
|
delegate_uniqueness( :your_table_name, :column_name )
|
40
40
|
end
|
41
41
|
end
|
42
|
+
|
43
|
+
class WithWrapperFunctionMigration < ActiveRecord::Migration[5.0]
|
44
|
+
# define some where before 'type_conversion_function' to use it later
|
45
|
+
def change
|
46
|
+
delegate_uniqueness( :your_table_name, :column_name, wrapper_function: 'type_conversion_function' )
|
47
|
+
end
|
48
|
+
end
|
42
49
|
```
|
43
50
|
|
44
51
|
## Development
|
@@ -50,6 +57,10 @@ docker-compose run test /bin/bash
|
|
50
57
|
> service postgresql start && rake test
|
51
58
|
```
|
52
59
|
|
60
|
+
## Future Features
|
61
|
+
- Sequel migration helpers
|
62
|
+
- Existing data sync
|
63
|
+
|
53
64
|
## Contributing
|
54
65
|
|
55
66
|
Bug reports and pull requests are welcome on GitHub at https://github.com/alekseyl/izolenta. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [code of conduct](https://github.com/[USERNAME]/izolenta/blob/master/CODE_OF_CONDUCT.md).
|
@@ -1,52 +1,69 @@
|
|
1
1
|
module Izolenta::ActiveRecordMigration
|
2
|
-
|
2
|
+
# options:
|
3
|
+
# wrapper_function: 'some_func' # some_func should be defined prior
|
3
4
|
def delegate_uniqueness(origin_table, column, options = {})
|
4
5
|
helper_table_name = "#{column}_#{origin_table}_uniqs"
|
6
|
+
|
5
7
|
reversible do |dir|
|
6
8
|
dir.up {
|
7
|
-
create_helper_table(helper_table_name, column,
|
8
|
-
|
9
|
+
Helpers.create_helper_table(helper_table_name, column, Helpers.get_new_column_type(origin_table, column, options))
|
10
|
+
add_index( helper_table_name, column, unique: true )
|
11
|
+
|
12
|
+
Helpers.create_sync_trigger( origin_table, column, helper_table_name, options )
|
9
13
|
}
|
10
14
|
|
11
15
|
dir.down {
|
12
16
|
drop_table( helper_table_name )
|
13
|
-
drop_sync_trigger( origin_table, column )
|
17
|
+
Helpers.drop_sync_trigger( origin_table, column )
|
14
18
|
}
|
15
19
|
end
|
16
20
|
end
|
17
21
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
add_index( helper_table, column_name, unique: true )
|
24
|
-
end
|
22
|
+
module Helpers
|
23
|
+
class << self
|
24
|
+
def create_helper_table(helper_table, column_name, column_type )
|
25
|
+
ActiveRecord::Base.connection.execute "CREATE TABLE #{helper_table} ( #{column_name} #{column_type} );"
|
26
|
+
end
|
25
27
|
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
28
|
+
def create_sync_trigger(table, column_name, helper_table_name, options )
|
29
|
+
trg_name = "#{table}_#{column_name}_trg"
|
30
|
+
insert_value = options[:wrapper_function] ? "#{options[:wrapper_function]}(NEW.#{column_name})"
|
31
|
+
: "NEW.#{column_name}"
|
32
|
+
ActiveRecord::Base.connection.execute <<~SYNC_TRIGGER
|
33
|
+
CREATE OR REPLACE FUNCTION #{trg_name}() RETURNS trigger AS $$
|
34
|
+
BEGIN
|
35
|
+
INSERT INTO #{helper_table_name} VALUES ( #{insert_value} );
|
36
|
+
RETURN NEW;
|
37
|
+
END $$ LANGUAGE plpgSQL;
|
38
|
+
|
39
|
+
CREATE OR REPLACE TRIGGER #{trg_name} BEFORE INSERT ON #{table} FOR EACH ROW
|
40
|
+
EXECUTE FUNCTION #{trg_name}();
|
41
|
+
SYNC_TRIGGER
|
42
|
+
end
|
39
43
|
|
40
|
-
|
41
|
-
|
44
|
+
def drop_sync_trigger(table, column_name)
|
45
|
+
trg_name = "#{table}_#{column_name}_trg"
|
42
46
|
|
43
|
-
|
47
|
+
ActiveRecord::Base.connection.execute <<~SYNC_TRIGGER
|
44
48
|
DROP TRIGGER IF EXISTS #{trg_name} ON #{table};
|
45
|
-
|
46
|
-
|
49
|
+
SYNC_TRIGGER
|
50
|
+
end
|
51
|
+
|
52
|
+
def get_new_column_type(origin_table, column, wrapper_function: nil)
|
53
|
+
wrapper_function ? get_function_type(wrapper_function) : get_column_type(origin_table, column)
|
54
|
+
end
|
47
55
|
|
48
|
-
|
49
|
-
|
56
|
+
def get_column_type(origin_table, column)
|
57
|
+
ActiveRecord::Base.connection.schema_cache.columns_hash(origin_table.to_s)[column.to_s]&.sql_type
|
58
|
+
end
|
59
|
+
|
60
|
+
def get_function_type(wrapper_function)
|
61
|
+
ActiveRecord::Base
|
62
|
+
.connection
|
63
|
+
.execute("SELECT typname FROM pg_type WHERE oid=(SELECT prorettype FROM pg_proc WHERE proname ='#{wrapper_function}')")
|
64
|
+
.first['typname']
|
65
|
+
end
|
66
|
+
end
|
50
67
|
end
|
51
68
|
|
52
69
|
end if defined? ActiveRecord
|
data/lib/izolenta/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: izolenta
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- alekseyl
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-12-
|
11
|
+
date: 2021-12-24 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: pg
|