clickhouse-activerecord 1.0.4 → 1.0.6

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 194430a00c6f085ec0bf6b1cf18911c06b69ff2e87ef18fc50183b1d7d1f20c7
4
- data.tar.gz: 54e418ac9c841e6852e7e87e1ea169335f0c0940537eda3f95d645f3e63ed81e
3
+ metadata.gz: 01f256bfb493f9961b3c0268d7f71009468b7b28c00deba7901d064f74b91c5c
4
+ data.tar.gz: 13b366b2264636610baa3bde60b9c82930c80b13201ac41724d37d4430fa60dd
5
5
  SHA512:
6
- metadata.gz: 9d5a90636c9eaa390ce1b75f65581061312dd598fbaf64e0402a40d3e2a1ab6b8079a0ae438ac86e1b03d4df3a1d1ab6308db961cf988320a39b13cf65014cc5
7
- data.tar.gz: d961eaf6d2d5798cbf220dc7249330c91b43fe86a68d64ff0371bb0a0f7cba754dd5e95fb1fb666fadcbd74fe71fd89f6ea5b2d85a6d478e7c624e541f00b768
6
+ metadata.gz: 75bafd27ee374a30f8a519937591254f2f316e3bf477b6298da709652064853cc491f454950fefc1558e66b170c4773b167d1988aaa9dd38b583d79ba60b3c4d
7
+ data.tar.gz: 23709bae8fdf85dda4be2f70d41016be9e8cc10ba503ffc73dcc42e69ca0573f792f4635fa7d1b476b74e394ba1dd2f4fc6774c42d96821c13b55f798094666e
@@ -0,0 +1,117 @@
1
+ <?xml version="1.0"?>
2
+ <clickhouse>
3
+
4
+ <http_port>8123</http_port>
5
+ <interserver_http_port>9009</interserver_http_port>
6
+ <interserver_http_host>clickhouse1</interserver_http_host>
7
+
8
+ <users_config>users.xml</users_config>
9
+ <default_profile>default</default_profile>
10
+ <default_database>default</default_database>
11
+
12
+ <mark_cache_size>5368709120</mark_cache_size>
13
+
14
+ <path>/var/lib/clickhouse/</path>
15
+ <tmp_path>/var/lib/clickhouse/tmp/</tmp_path>
16
+ <user_files_path>/var/lib/clickhouse/user_files/</user_files_path>
17
+ <access_control_path>/var/lib/clickhouse/access/</access_control_path>
18
+ <keep_alive_timeout>3</keep_alive_timeout>
19
+
20
+ <logger>
21
+ <level>debug</level>
22
+ <log>/var/log/clickhouse-server/clickhouse-server.log</log>
23
+ <errorlog>/var/log/clickhouse-server/clickhouse-server.err.log</errorlog>
24
+ <size>1000M</size>
25
+ <count>10</count>
26
+ <console>1</console>
27
+ </logger>
28
+
29
+ <remote_servers>
30
+ <test_cluster>
31
+ <shard>
32
+ <replica>
33
+ <host>clickhouse1</host>
34
+ <port>9000</port>
35
+ </replica>
36
+ <replica>
37
+ <host>clickhouse2</host>
38
+ <port>9000</port>
39
+ </replica>
40
+ </shard>
41
+ </test_cluster>
42
+ </remote_servers>
43
+
44
+ <keeper_server>
45
+ <tcp_port>9181</tcp_port>
46
+ <server_id>1</server_id>
47
+ <log_storage_path>/var/lib/clickhouse/coordination/log</log_storage_path>
48
+ <snapshot_storage_path>/var/lib/clickhouse/coordination/snapshots</snapshot_storage_path>
49
+
50
+ <coordination_settings>
51
+ <operation_timeout_ms>10000</operation_timeout_ms>
52
+ <session_timeout_ms>30000</session_timeout_ms>
53
+ <raft_logs_level>trace</raft_logs_level>
54
+ <rotate_log_storage_interval>10000</rotate_log_storage_interval>
55
+ </coordination_settings>
56
+
57
+ <raft_configuration>
58
+ <server>
59
+ <id>1</id>
60
+ <hostname>clickhouse1</hostname>
61
+ <port>9000</port>
62
+ </server>
63
+ <server>
64
+ <id>2</id>
65
+ <hostname>clickhouse2</hostname>
66
+ <port>9000</port>
67
+ </server>
68
+ </raft_configuration>
69
+ </keeper_server>
70
+
71
+ <zookeeper>
72
+ <node>
73
+ <host>clickhouse1</host>
74
+ <port>9181</port>
75
+ </node>
76
+ <node>
77
+ <host>clickhouse2</host>
78
+ <port>9181</port>
79
+ </node>
80
+ </zookeeper>
81
+
82
+ <macros>
83
+ <cluster>test_cluster</cluster>
84
+ <replica>clickhouse1</replica>
85
+ <shard>1</shard>
86
+ </macros>
87
+
88
+ <distributed_ddl>
89
+ <path>/clickhouse/test_cluster/task_queue/ddl</path>
90
+ </distributed_ddl>
91
+
92
+ <query_log>
93
+ <database>system</database>
94
+ <table>query_log</table>
95
+ <partition_by>toYYYYMM(event_date)</partition_by>
96
+ <flush_interval_milliseconds>1000</flush_interval_milliseconds>
97
+ </query_log>
98
+
99
+ <http_options_response>
100
+ <header>
101
+ <name>Access-Control-Allow-Origin</name>
102
+ <value>*</value>
103
+ </header>
104
+ <header>
105
+ <name>Access-Control-Allow-Headers</name>
106
+ <value>accept, origin, x-requested-with, content-type, authorization</value>
107
+ </header>
108
+ <header>
109
+ <name>Access-Control-Allow-Methods</name>
110
+ <value>POST, GET, OPTIONS</value>
111
+ </header>
112
+ <header>
113
+ <name>Access-Control-Max-Age</name>
114
+ <value>86400</value>
115
+ </header>
116
+ </http_options_response>
117
+ </clickhouse>
@@ -0,0 +1,117 @@
1
+ <?xml version="1.0"?>
2
+ <clickhouse>
3
+
4
+ <http_port>8123</http_port>
5
+ <interserver_http_port>9009</interserver_http_port>
6
+ <interserver_http_host>clickhouse2</interserver_http_host>
7
+
8
+ <users_config>users.xml</users_config>
9
+ <default_profile>default</default_profile>
10
+ <default_database>default</default_database>
11
+
12
+ <mark_cache_size>5368709120</mark_cache_size>
13
+
14
+ <path>/var/lib/clickhouse/</path>
15
+ <tmp_path>/var/lib/clickhouse/tmp/</tmp_path>
16
+ <user_files_path>/var/lib/clickhouse/user_files/</user_files_path>
17
+ <access_control_path>/var/lib/clickhouse/access/</access_control_path>
18
+ <keep_alive_timeout>3</keep_alive_timeout>
19
+
20
+ <logger>
21
+ <level>debug</level>
22
+ <log>/var/log/clickhouse-server/clickhouse-server.log</log>
23
+ <errorlog>/var/log/clickhouse-server/clickhouse-server.err.log</errorlog>
24
+ <size>1000M</size>
25
+ <count>10</count>
26
+ <console>1</console>
27
+ </logger>
28
+
29
+ <remote_servers>
30
+ <test_cluster>
31
+ <shard>
32
+ <replica>
33
+ <host>clickhouse1</host>
34
+ <port>9000</port>
35
+ </replica>
36
+ <replica>
37
+ <host>clickhouse2</host>
38
+ <port>9000</port>
39
+ </replica>
40
+ </shard>
41
+ </test_cluster>
42
+ </remote_servers>
43
+
44
+ <keeper_server>
45
+ <tcp_port>9181</tcp_port>
46
+ <server_id>2</server_id>
47
+ <log_storage_path>/var/lib/clickhouse/coordination/log</log_storage_path>
48
+ <snapshot_storage_path>/var/lib/clickhouse/coordination/snapshots</snapshot_storage_path>
49
+
50
+ <coordination_settings>
51
+ <operation_timeout_ms>10000</operation_timeout_ms>
52
+ <session_timeout_ms>30000</session_timeout_ms>
53
+ <raft_logs_level>trace</raft_logs_level>
54
+ <rotate_log_storage_interval>10000</rotate_log_storage_interval>
55
+ </coordination_settings>
56
+
57
+ <raft_configuration>
58
+ <server>
59
+ <id>1</id>
60
+ <hostname>clickhouse1</hostname>
61
+ <port>9000</port>
62
+ </server>
63
+ <server>
64
+ <id>2</id>
65
+ <hostname>clickhouse2</hostname>
66
+ <port>9000</port>
67
+ </server>
68
+ </raft_configuration>
69
+ </keeper_server>
70
+
71
+ <zookeeper>
72
+ <node>
73
+ <host>clickhouse1</host>
74
+ <port>9181</port>
75
+ </node>
76
+ <node>
77
+ <host>clickhouse2</host>
78
+ <port>9181</port>
79
+ </node>
80
+ </zookeeper>
81
+
82
+ <macros>
83
+ <cluster>test_cluster</cluster>
84
+ <replica>clickhouse2</replica>
85
+ <shard>1</shard>
86
+ </macros>
87
+
88
+ <distributed_ddl>
89
+ <path>/clickhouse/test_cluster/task_queue/ddl</path>
90
+ </distributed_ddl>
91
+
92
+ <query_log>
93
+ <database>system</database>
94
+ <table>query_log</table>
95
+ <partition_by>toYYYYMM(event_date)</partition_by>
96
+ <flush_interval_milliseconds>1000</flush_interval_milliseconds>
97
+ </query_log>
98
+
99
+ <http_options_response>
100
+ <header>
101
+ <name>Access-Control-Allow-Origin</name>
102
+ <value>*</value>
103
+ </header>
104
+ <header>
105
+ <name>Access-Control-Allow-Headers</name>
106
+ <value>accept, origin, x-requested-with, content-type, authorization</value>
107
+ </header>
108
+ <header>
109
+ <name>Access-Control-Allow-Methods</name>
110
+ <value>POST, GET, OPTIONS</value>
111
+ </header>
112
+ <header>
113
+ <name>Access-Control-Max-Age</name>
114
+ <value>86400</value>
115
+ </header>
116
+ </http_options_response>
117
+ </clickhouse>
@@ -0,0 +1,54 @@
1
+ <?xml version="1.0"?>
2
+ <clickhouse>
3
+
4
+ <http_port>8123</http_port>
5
+ <tcp_port>9000</tcp_port>
6
+
7
+ <users_config>users.xml</users_config>
8
+ <default_profile>default</default_profile>
9
+ <default_database>default</default_database>
10
+
11
+ <mark_cache_size>5368709120</mark_cache_size>
12
+
13
+ <path>/var/lib/clickhouse/</path>
14
+ <tmp_path>/var/lib/clickhouse/tmp/</tmp_path>
15
+ <user_files_path>/var/lib/clickhouse/user_files/</user_files_path>
16
+ <access_control_path>/var/lib/clickhouse/access/</access_control_path>
17
+ <keep_alive_timeout>3</keep_alive_timeout>
18
+
19
+ <logger>
20
+ <level>debug</level>
21
+ <log>/var/log/clickhouse-server/clickhouse-server.log</log>
22
+ <errorlog>/var/log/clickhouse-server/clickhouse-server.err.log</errorlog>
23
+ <size>1000M</size>
24
+ <count>10</count>
25
+ <console>1</console>
26
+ </logger>
27
+
28
+ <query_log>
29
+ <database>system</database>
30
+ <table>query_log</table>
31
+ <partition_by>toYYYYMM(event_date)</partition_by>
32
+ <flush_interval_milliseconds>1000</flush_interval_milliseconds>
33
+ </query_log>
34
+
35
+ <http_options_response>
36
+ <header>
37
+ <name>Access-Control-Allow-Origin</name>
38
+ <value>*</value>
39
+ </header>
40
+ <header>
41
+ <name>Access-Control-Allow-Headers</name>
42
+ <value>accept, origin, x-requested-with, content-type, authorization</value>
43
+ </header>
44
+ <header>
45
+ <name>Access-Control-Allow-Methods</name>
46
+ <value>POST, GET, OPTIONS</value>
47
+ </header>
48
+ <header>
49
+ <name>Access-Control-Max-Age</name>
50
+ <value>86400</value>
51
+ </header>
52
+ </http_options_response>
53
+
54
+ </clickhouse>
@@ -0,0 +1,34 @@
1
+ <?xml version="1.0"?>
2
+ <clickhouse>
3
+
4
+ <profiles>
5
+ <default>
6
+ <load_balancing>random</load_balancing>
7
+ </default>
8
+ </profiles>
9
+
10
+ <users>
11
+ <default>
12
+ <password></password>
13
+ <networks>
14
+ <ip>::/0</ip>
15
+ </networks>
16
+ <profile>default</profile>
17
+ <quota>default</quota>
18
+ <access_management>1</access_management>
19
+ </default>
20
+ </users>
21
+
22
+ <quotas>
23
+ <default>
24
+ <interval>
25
+ <duration>3600</duration>
26
+ <queries>0</queries>
27
+ <errors>0</errors>
28
+ <result_rows>0</result_rows>
29
+ <read_rows>0</read_rows>
30
+ <execution_time>0</execution_time>
31
+ </interval>
32
+ </default>
33
+ </quotas>
34
+ </clickhouse>
@@ -0,0 +1,52 @@
1
+ version: '3.5'
2
+
3
+ services:
4
+ clickhouse1:
5
+ image: 'clickhouse/clickhouse-server:${CLICKHOUSE_VERSION-23.11-alpine}'
6
+ ulimits:
7
+ nofile:
8
+ soft: 262144
9
+ hard: 262144
10
+ hostname: clickhouse1
11
+ container_name: clickhouse-activerecord-clickhouse-server-1
12
+ ports:
13
+ - '8124:8123'
14
+ - '9001:9000'
15
+ volumes:
16
+ - './clickhouse/cluster/server1_config.xml:/etc/clickhouse-server/config.xml'
17
+ - './clickhouse/users.xml:/etc/clickhouse-server/users.xml'
18
+ healthcheck:
19
+ test: bash -c "exec 6<> /dev/tcp/localhost/8123"
20
+ interval: 5s
21
+
22
+ clickhouse2:
23
+ image: 'clickhouse/clickhouse-server:${CLICKHOUSE_VERSION-23.11-alpine}'
24
+ ulimits:
25
+ nofile:
26
+ soft: 262144
27
+ hard: 262144
28
+ hostname: clickhouse2
29
+ container_name: clickhouse-activerecord-clickhouse-server-2
30
+ ports:
31
+ - '8125:8123'
32
+ volumes:
33
+ - './clickhouse/cluster/server2_config.xml:/etc/clickhouse-server/config.xml'
34
+ - './clickhouse/users.xml:/etc/clickhouse-server/users.xml'
35
+ healthcheck:
36
+ test: bash -c "exec 6<> /dev/tcp/localhost/8123"
37
+ interval: 5s
38
+
39
+ # Using Nginx as a cluster entrypoint and a round-robin load balancer for HTTP requests
40
+ nginx:
41
+ image: 'nginx:1.23.1-alpine'
42
+ hostname: nginx
43
+ ports:
44
+ - '28123:8123'
45
+ volumes:
46
+ - './nginx/local.conf:/etc/nginx/conf.d/local.conf'
47
+ container_name: clickhouse-activerecord-nginx
48
+ depends_on:
49
+ clickhouse1:
50
+ condition: service_healthy
51
+ clickhouse2:
52
+ condition: service_healthy
@@ -0,0 +1,17 @@
1
+ version: '3.8'
2
+ services:
3
+ clickhouse:
4
+ image: 'clickhouse/clickhouse-server:${CLICKHOUSE_VERSION-23.11-alpine}'
5
+ container_name: 'clickhouse-activerecord-clickhouse-server'
6
+ ports:
7
+ - '18123:8123'
8
+ ulimits:
9
+ nofile:
10
+ soft: 262144
11
+ hard: 262144
12
+ volumes:
13
+ - './clickhouse/single/config.xml:/etc/clickhouse-server/config.xml'
14
+ - './clickhouse/users.xml:/etc/clickhouse-server/users.xml'
15
+ healthcheck:
16
+ test: bash -c "exec 6<> /dev/tcp/localhost/8123"
17
+ interval: 5s
@@ -0,0 +1,12 @@
1
+ upstream clickhouse_cluster {
2
+ server clickhouse1:8123;
3
+ server clickhouse2:8123;
4
+ }
5
+
6
+ server {
7
+ listen 8123;
8
+ client_max_body_size 100M;
9
+ location / {
10
+ proxy_pass http://clickhouse_cluster;
11
+ }
12
+ }
@@ -0,0 +1,77 @@
1
+ name: Testing
2
+
3
+ on:
4
+ push:
5
+ branches: [ "master" ]
6
+ pull_request:
7
+ branches: [ "master" ]
8
+
9
+ jobs:
10
+ tests_single:
11
+ name: Testing single server
12
+ runs-on: ubuntu-latest
13
+
14
+ env:
15
+ CLICKHOUSE_PORT: 18123
16
+ CLICKHOUSE_DATABASE: default
17
+
18
+ strategy:
19
+ fail-fast: true
20
+ max-parallel: 1
21
+ matrix:
22
+ ruby-version: [ '2.7', '3.0', '3.2' ]
23
+ clickhouse: [ '22.1' ]
24
+
25
+ steps:
26
+ - uses: actions/checkout@v4
27
+
28
+ - name: Start ClickHouse ${{ matrix.clickhouse }}
29
+ uses: isbang/compose-action@v1.5.1
30
+ env:
31
+ CLICKHOUSE_VERSION: ${{ matrix.clickhouse }}
32
+ with:
33
+ compose-file: '.docker/docker-compose.yml'
34
+ down-flags: '--volumes'
35
+
36
+ - name: Set up Ruby ${{ matrix.ruby-version }}
37
+ uses: ruby/setup-ruby@v1
38
+ with:
39
+ ruby-version: ${{ matrix.ruby-version }}
40
+ bundler-cache: true
41
+
42
+ - run: bundle exec rspec spec/single
43
+
44
+ tests_cluster:
45
+ name: Testing cluster server
46
+ runs-on: ubuntu-latest
47
+
48
+ env:
49
+ CLICKHOUSE_PORT: 28123
50
+ CLICKHOUSE_DATABASE: default
51
+ CLICKHOUSE_CLUSTER: test_cluster
52
+
53
+ strategy:
54
+ fail-fast: true
55
+ max-parallel: 1
56
+ matrix:
57
+ ruby-version: [ '2.7', '3.0', '3.2' ]
58
+ clickhouse: [ '22.1' ]
59
+
60
+ steps:
61
+ - uses: actions/checkout@v4
62
+
63
+ - name: Start ClickHouse Cluster ${{ matrix.clickhouse }}
64
+ uses: isbang/compose-action@v1.5.1
65
+ env:
66
+ CLICKHOUSE_VERSION: ${{ matrix.clickhouse }}
67
+ with:
68
+ compose-file: '.docker/docker-compose.cluster.yml'
69
+ down-flags: '--volumes'
70
+
71
+ - name: Set up Ruby ${{ matrix.ruby-version }}
72
+ uses: ruby/setup-ruby@v1
73
+ with:
74
+ ruby-version: ${{ matrix.ruby-version }}
75
+ bundler-cache: true
76
+
77
+ - run: bundle exec rspec spec/cluster
data/CHANGELOG.md CHANGED
@@ -1,3 +1,31 @@
1
+ ### Version 1.0.5 (Mar 14, 2024)
2
+
3
+ * GitHub workflows
4
+ * Fix injection internal and schema classes for rails 7
5
+ * Add support for binary string by [@PauloMiranda98](https://github.com/PauloMiranda98) in (#116)
6
+
7
+ ### Version 1.0.4 (Feb 2, 2024)
8
+
9
+ * Use ILIKE for `model.arel_table[:column]#matches` by [@stympy](https://github.com/stympy) in (#115)
10
+ * Fixed `insert_all` for array column (#71)
11
+ * Register Bool and UUID in type map by [@lukinski](https://github.com/lukinski) in (#110)
12
+ * Refactoring `final` method
13
+ * Support update & delete for clickhouse from version 23.3 and newer (#93)
14
+
15
+ ### Version 1.0.0 (Nov 29, 2023)
16
+
17
+ * Full support Rails 7.1+
18
+ * Full support primary or multiple databases
19
+
20
+ ### Version 0.6.0 (Oct 19, 2023)
21
+
22
+ * Added `Bool` column type instead `Uint8` (#78). Supports ClickHouse 22+ database only
23
+ * Added `final` method (#81) (The `ar_internal_metadata` table needs to be deleted after a gem update)
24
+ * Added `settings` method (#82)
25
+ * Fixed convert aggregation type (#92)
26
+ * Fixed raise error not database exist (#91)
27
+ * Fixed internal metadata update (#84)
28
+
1
29
  ### Version 0.5.10 (Jun 22, 2022)
2
30
 
3
31
  * Fixes to create_table method (#70)
data/README.md CHANGED
@@ -203,7 +203,7 @@ false`. The default integer is `UInt32`
203
203
  Example:
204
204
 
205
205
  ``` ruby
206
- class CreateDataItems < ActiveRecord::Migration
206
+ class CreateDataItems < ActiveRecord::Migration[7.1]
207
207
  def change
208
208
  create_table "data_items", id: false, options: "VersionedCollapsingMergeTree(sign, version) PARTITION BY toYYYYMM(day) ORDER BY category", force: :cascade do |t|
209
209
  t.date "day", null: false
@@ -212,9 +212,32 @@ class CreateDataItems < ActiveRecord::Migration
212
212
  t.integer "sign", limit: 1, unsigned: false, default: -> { "CAST(1, 'Int8')" }, null: false
213
213
  t.integer "version", limit: 8, default: -> { "CAST(toUnixTimestamp(now()), 'UInt64')" }, null: false
214
214
  end
215
+
216
+ create_table "with_index", id: false, options: 'MergeTree PARTITION BY toYYYYMM(date) ORDER BY (date)' do |t|
217
+ t.integer :int1, null: false
218
+ t.integer :int2, null: false
219
+ t.date :date, null: false
220
+
221
+ t.index '(int1 * int2, date)', name: 'idx', type: 'minmax', granularity: 3
222
+ end
223
+
224
+ remove_index :some, 'idx'
225
+
226
+ add_index :some, 'int1 * int2', name: 'idx2', type: 'set(10)', granularity: 4
227
+ end
228
+ end
229
+ ```
230
+
231
+ Create table with custom column structure:
232
+
233
+ ``` ruby
234
+ class CreateDataItems < ActiveRecord::Migration
235
+ def change
236
+ create_table "data_items", id: false, options: "MergeTree PARTITION BY toYYYYMM(timestamp) ORDER BY timestamp", force: :cascade do |t|
237
+ t.column "timestamp", "DateTime('UTC') CODEC(DoubleDelta, LZ4)"
238
+ end
215
239
  end
216
240
  end
217
-
218
241
  ```
219
242
 
220
243
 
@@ -246,6 +269,12 @@ After checking out the repo, run `bin/setup` to install dependencies. You can al
246
269
 
247
270
  To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
248
271
 
272
+ Testing github actions:
273
+
274
+ ```bash
275
+ act
276
+ ```
277
+
249
278
  ## Contributing
250
279
 
251
280
  Bug reports and pull requests are welcome on GitHub at [https://github.com/pnixx/clickhouse-activerecord](https://github.com/pnixx/clickhouse-activerecord). This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
@@ -6,6 +6,7 @@ module ActiveRecord
6
6
  module OID # :nodoc:
7
7
  class Uuid < Type::Value # :nodoc:
8
8
  ACCEPTABLE_UUID = %r{\A(\{)?([a-fA-F0-9]{4}-?){8}(?(1)\}|)\z}
9
+ CANONICAL_UUID = %r{\A[0-9a-f]{8}-(?:[0-9a-f]{4}-){3}[0-9a-f]{12}\z}
9
10
 
10
11
  alias :serialize :deserialize
11
12
 
@@ -13,23 +14,32 @@ module ActiveRecord
13
14
  :uuid
14
15
  end
15
16
 
16
- def changed?(old_value, new_value, _)
17
+ def changed?(old_value, new_value, _new_value_before_type_cast)
17
18
  old_value.class != new_value.class ||
18
- new_value && old_value.casecmp(new_value) != 0
19
+ new_value != old_value
19
20
  end
20
21
 
21
22
  def changed_in_place?(raw_old_value, new_value)
22
23
  raw_old_value.class != new_value.class ||
23
- new_value && raw_old_value.casecmp(new_value) != 0
24
+ new_value != raw_old_value
24
25
  end
25
26
 
26
27
  private
27
28
 
28
29
  def cast_value(value)
29
- casted = value.to_s
30
- casted if casted.match?(ACCEPTABLE_UUID)
30
+ value = value.to_s
31
+ format_uuid(value) if value.match?(ACCEPTABLE_UUID)
31
32
  end
32
- end
33
+
34
+ def format_uuid(uuid)
35
+ if uuid.match?(CANONICAL_UUID)
36
+ uuid
37
+ else
38
+ uuid = uuid.delete("{}-").downcase
39
+ "#{uuid[..7]}-#{uuid[8..11]}-#{uuid[12..15]}-#{uuid[16..19]}-#{uuid[20..]}"
40
+ end
41
+ end
42
+ end
33
43
  end
34
44
  end
35
45
  end
@@ -1,4 +1,3 @@
1
- # frozen_string_literal: true
2
1
  begin
3
2
  require "active_record/connection_adapters/deduplicable"
4
3
  rescue LoadError => e
@@ -93,6 +92,14 @@ module ActiveRecord
93
92
 
94
93
  statements = o.columns.map { |c| accept c }
95
94
  statements << accept(o.primary_keys) if o.primary_keys
95
+
96
+ if supports_indexes_in_create?
97
+ indexes = o.indexes.map do |expression, options|
98
+ accept(@conn.add_index_options(o.name, expression, **options))
99
+ end
100
+ statements.concat(indexes)
101
+ end
102
+
96
103
  create_sql << "(#{statements.join(', ')})" if statements.present?
97
104
  # Attach options for only table or materialized view without TO section
98
105
  add_table_options!(create_sql, o) if !o.view || o.view && o.materialized && !o.to
@@ -108,7 +115,7 @@ module ActiveRecord
108
115
 
109
116
  def visit_ChangeColumnDefinition(o)
110
117
  column = o.column
111
- column.sql_type = type_to_sql(column.type, column.options)
118
+ column.sql_type = type_to_sql(column.type, **column.options)
112
119
  options = column_options(column)
113
120
 
114
121
  quoted_column_name = quote_column_name(o.name)
@@ -124,6 +131,23 @@ module ActiveRecord
124
131
  change_column_sql
125
132
  end
126
133
 
134
+ def visit_IndexDefinition(o, create = false)
135
+ sql = create ? ["ALTER TABLE #{quote_table_name(o.table)} ADD"] : []
136
+ sql << "INDEX"
137
+ sql << "IF NOT EXISTS" if o.if_not_exists
138
+ sql << "IF EXISTS" if o.if_exists
139
+ sql << "#{quote_column_name(o.name)} (#{o.expression}) TYPE #{o.type}"
140
+ sql << "GRANULARITY #{o.granularity}" if o.granularity
141
+ sql << "FIRST #{quote_column_name(o.first)}" if o.first
142
+ sql << "AFTER #{quote_column_name(o.after)}" if o.after
143
+
144
+ sql.join(' ')
145
+ end
146
+
147
+ def visit_CreateIndexDefinition(o)
148
+ visit_IndexDefinition(o.index, true)
149
+ end
150
+
127
151
  def current_database
128
152
  ActiveRecord::Base.connection_db_config.database
129
153
  end