izolenta 0.0.2 → 0.0.3
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 +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
|