activerecord-cockroachdb-adapter 7.0.3 → 7.1.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 594ac59a7a678d5619ea771e3130a481481560adcc88032d7c17d61b6dabc279
4
- data.tar.gz: 0cd6ea6bd6a1fe808142a91e35a24d4e15a59b48f56e4dba37d8a25584dd7a8a
3
+ metadata.gz: 672289521537934d4b9ed2d707c3faf55b4761c8d2b4e9e12cd8622166963ae7
4
+ data.tar.gz: 345a84d7c5bca0d574aa65eb0fb0e30986a23fcc2830f422e5b1d80ffa971076
5
5
  SHA512:
6
- metadata.gz: 56205a247976012b6a25691045a773ca9fefecc1b98bb47ee83fb85dffede72a8aed5bc605a332d00b31fb57f67ee1018b850d14638581454980a6b96d2e8865
7
- data.tar.gz: 92515e498cc8cedfe284cfe4cf9b3cb87eae72630aa5828e5983dfabe488ad214386561a0fb8072963b0796559209ee033cb010495d263d44eb1abf048afaa37
6
+ metadata.gz: 4ce6d2119bfc27192630c32ec488b3e7f533cc64963fc04035609122e5bdbc33e75b83766ca68e3eb73e2592b2fe0a1bae53a74389527762f790b16bda687da9
7
+ data.tar.gz: 42e10ab1106e4ffc4df89bbbf98f8ddbd05b6bccf97b062a9445ebf874a8bfef9e628dce8b39c3287424a7094f70790457293a2766a849bd39ac0e20c7a684fe
data/.editorconfig ADDED
@@ -0,0 +1,7 @@
1
+ root = true
2
+
3
+ [*.rb]
4
+ indent_style = space
5
+ indent_size = 2
6
+ trim_trailing_whitespace = true
7
+ insert_final_newline = true
@@ -4,12 +4,9 @@
4
4
  name: Test
5
5
 
6
6
  on:
7
- # Triggers the workflow on push or pull request events.
8
7
  push:
9
- # This should disable running the workflow on tags, according to the
10
- # on.<push|pull_request>.<branches|tags> GitHub Actions docs.
11
- branches:
12
- - "*"
8
+ branches: [master]
9
+ # Triggers the workflow on pull request events.
13
10
  pull_request:
14
11
  types: [opened, reopened, synchronize]
15
12
 
@@ -18,40 +15,69 @@ on:
18
15
 
19
16
  # This allows a subsequently queued workflow run to interrupt previous runs.
20
17
  concurrency:
21
- group: '${{ github.workflow }} @ ${{ github.event.pull_request.head.label || github.head_ref || github.ref }}'
18
+ group: "${{ github.workflow }} @ ${{ github.ref }}"
22
19
  cancel-in-progress: true
23
20
 
24
21
  jobs:
22
+ # Since the name of the matrix job depends on the version, we define another job with a more stable name.
23
+ test_results:
24
+ if: ${{ always() }}
25
+ runs-on: ubuntu-latest
26
+ name: Test Results
27
+ needs: [test]
28
+ steps:
29
+ - run: |
30
+ result="${{ needs.test.result }}"
31
+ if [[ $result == "success" || $result == "skipped" ]]; then
32
+ exit 0
33
+ else
34
+ exit 1
35
+ fi
36
+
25
37
  test:
26
38
  runs-on: ubuntu-latest
27
39
  strategy:
40
+ fail-fast: false
28
41
  matrix:
29
- crdb: [v23.1.5]
30
- ruby: [ruby-head]
42
+ # https://www.cockroachlabs.com/docs/releases/release-support-policy
43
+ crdb: [v22.2, v23.1, v23.2]
44
+ ruby: [head]
31
45
  name: Test (crdb=${{ matrix.crdb }} ruby=${{ matrix.ruby }})
32
46
  steps:
33
47
  - name: Set Up Actions
34
- uses: actions/checkout@v3
48
+ uses: actions/checkout@v4
35
49
  - name: Install GEOS
36
- run: sudo apt-get install libgeos-dev
50
+ run: sudo apt-get install -yqq libgeos-dev
37
51
  - name: Set Up Ruby
38
52
  uses: ruby/setup-ruby@v1
39
53
  with:
40
- ruby-version: ${{ matrix.ruby }}
41
- bundler-cache: true
54
+ ruby-version: ${{ matrix.ruby }}
55
+ bundler-cache: true
42
56
  - name: Install and Start Cockroachdb
43
57
  run: |
44
58
  # Download CockroachDB
45
- wget -qO- https://binaries.cockroachdb.com/cockroach-${{ matrix.crdb }}.linux-amd64.tgz | tar xvz
59
+ readonly full_version=$(ruby -rnet/http -ruri -ryaml -e '
60
+ link = "https://raw.githubusercontent.com/cockroachdb/docs/main/src/current/_data/releases.yml"
61
+ puts YAML.safe_load(Net::HTTP.get(URI(link))).reverse.find {
62
+ _1["major_version"] == "${{ matrix.crdb }}" &&
63
+ _1["release_type"] == "Production" &&
64
+ !_1["cloud_only"] &&
65
+ !_1["withdrawn"] &&
66
+ !_1["release_name"].include?("-") # Pre-release
67
+ }["release_name"]
68
+ ')
69
+
70
+ echo "Downloading $full_version..."
71
+ wget -qO- "https://binaries.cockroachdb.com/cockroach-$full_version.linux-amd64.tgz" | tar xvz
46
72
 
47
- export PATH=./cockroach-${{ matrix.crdb }}.linux-amd64/:$PATH
73
+ export PATH=./cockroach-$full_version.linux-amd64/:$PATH
48
74
  readonly urlfile=cockroach-url
49
75
 
50
76
  # Start a CockroachDB server and wait for it to become ready.
51
77
  rm -f "$urlfile"
52
78
  rm -rf cockroach-data
53
79
  # Start CockroachDB.
54
- cockroach start-single-node --max-sql-memory=25% --cache=25% --insecure --host=localhost --spatial-libs=./cockroach-${{ matrix.crdb }}.linux-amd64/lib --listening-url-file="$urlfile" >/dev/null 2>&1 &
80
+ cockroach start-single-node --max-sql-memory=25% --cache=25% --insecure --host=localhost --spatial-libs=./cockroach-$full_version.linux-amd64/lib --listening-url-file="$urlfile" >/dev/null 2>&1 &
55
81
  # Ensure CockroachDB is stopped on script exit.
56
82
  # Wait until CockroachDB has started.
57
83
  for i in {0..3}; do
@@ -60,27 +86,6 @@ jobs:
60
86
  echo "server not yet available; sleeping for $backoff seconds"
61
87
  sleep $backoff
62
88
  done
63
- cockroach sql --insecure -e "
64
- CREATE DATABASE activerecord_unittest;
65
- CREATE DATABASE activerecord_unittest2;
66
- SET CLUSTER SETTING sql.stats.automatic_collection.enabled = false;
67
- SET CLUSTER SETTING sql.stats.histogram_collection.enabled = false;
68
- SET CLUSTER SETTING jobs.retention_time = '180s';
69
- SET CLUSTER SETTING sql.defaults.experimental_alter_column_type.enabled = 'true';
70
-
71
- ALTER RANGE default CONFIGURE ZONE USING num_replicas = 1, gc.ttlseconds = 30;
72
- ALTER TABLE system.public.jobs CONFIGURE ZONE USING num_replicas = 1, gc.ttlseconds = 30;
73
- ALTER RANGE meta CONFIGURE ZONE USING num_replicas = 1, gc.ttlseconds = 30;
74
- ALTER RANGE system CONFIGURE ZONE USING num_replicas = 1, gc.ttlseconds = 30;
75
- ALTER RANGE liveness CONFIGURE ZONE USING num_replicas = 1, gc.ttlseconds = 30;
76
-
77
- SET CLUSTER SETTING kv.range_merge.queue_interval = '50ms';
78
- SET CLUSTER SETTING kv.raft_log.disable_synchronization_unsafe = 'true';
79
- SET CLUSTER SETTING jobs.registry.interval.cancel = '180s';
80
- SET CLUSTER SETTING jobs.registry.interval.gc = '30s';
81
- SET CLUSTER SETTING kv.range_split.by_load_merge_delay = '5s';
82
-
83
- SET CLUSTER SETTING sql.defaults.experimental_temporary_tables.enabled = 'true';
84
- "
89
+ cat ${{ github.workspace }}/setup.sql | cockroach sql --insecure
85
90
  - name: Test
86
- run: bundle exec rake test
91
+ run: bundle exec rake test TESTOPTS='--profile=3'
data/.ruby-version CHANGED
@@ -1 +1 @@
1
- 3.2.1
1
+ 3.2.3
data/CHANGELOG.md CHANGED
@@ -2,6 +2,18 @@
2
2
 
3
3
  ## Ongoing
4
4
 
5
+ ## 7.1.1 - 2024-05-01
6
+
7
+ - Enable precision support ([#318](https://github.com/cockroachdb/activerecord-cockroachdb-adapter/pull/318))
8
+ - Support arbitrary max identifier length ([#317](https://github.com/cockroachdb/activerecord-cockroachdb-adapter/pull/317)).
9
+ - Fix `#schema_names` not to return `crdb_internal` ([#316](https://github.com/cockroachdb/activerecord-cockroachdb-adapter/pull/316))
10
+
11
+ ## 7.1.0 - 2024-01-30
12
+
13
+ - Add support for Rails 7.1 ([#300](https://github.com/cockroachdb/activerecord-cockroachdb-adapter/pull/300)).
14
+ - Add support for [AOST](cockroachlabs.com/docs/stable/as-of-system-time) queries ([#284](https://github.com/cockroachdb/activerecord-cockroachdb-adapter/pull/284))
15
+ - Dump schema name in foreign keys ([#289](https://github.com/cockroachdb/activerecord-cockroachdb-adapter/pull/289))
16
+
5
17
  ## 7.0.3 - 2023-08-23
6
18
 
7
19
  - Fix Multiple Database connections ([#283](https://github.com/cockroachdb/activerecord-cockroachdb-adapter/pull/)).
data/Gemfile CHANGED
@@ -10,6 +10,11 @@ module RailsTag
10
10
  def call
11
11
  req = gemspec_requirement
12
12
  "v" + all_activerecord_versions.find { req.satisfied_by?(_1) }.version
13
+ rescue => e
14
+ warn "Unable to determine Rails version. Using last used. Error: #{e.message}"
15
+ lockfile = File.expand_path("Gemfile.lock", __dir__)
16
+ File.foreach(lockfile, chomp: true).find { _1[/tag: (.*)$/] }
17
+ Regexp.last_match(1)
13
18
  end
14
19
 
15
20
  def gemspec_requirement
@@ -43,9 +48,17 @@ group :development, :test do
43
48
  # a specific rails codebase.
44
49
  gem "rails", github: "rails/rails", tag: RailsTag.call
45
50
 
51
+ # Needed for the test suite
52
+ gem "msgpack", ">= 1.7.0"
53
+
46
54
  gem "rake"
47
- gem "byebug"
55
+ gem "debug"
48
56
  gem "minitest-excludes", "~> 2.0.1"
57
+ gem "minitest-github_action_reporter", github: "BuonOmo/minitest-github_action_reporter", require: "minitest/github_action_reporter_plugin"
58
+ gem "ostruct", "~> 0.6"
59
+
60
+ # Gems used for tests meta-programming.
61
+ gem "parser"
49
62
 
50
63
  # Gems used by the ActiveRecord test suite
51
64
  gem "bcrypt", "~> 3.1.18"
@@ -14,7 +14,7 @@ Gem::Specification.new do |spec|
14
14
  spec.description = "Allows the use of CockroachDB as a backend for ActiveRecord and Rails apps."
15
15
  spec.homepage = "https://github.com/cockroachdb/activerecord-cockroachdb-adapter"
16
16
 
17
- spec.add_dependency "activerecord", "~> 7.0.3"
17
+ spec.add_dependency "activerecord", "~> 7.1.0"
18
18
  spec.add_dependency "pg", "~> 1.2"
19
19
  spec.add_dependency "rgeo-activerecord", "~> 7.0.0"
20
20
 
data/bin/console CHANGED
@@ -12,39 +12,23 @@ require "active_record"
12
12
  # structure_load(Post.connection_db_config, "awesome-file.sql")
13
13
  require "active_record/connection_adapters/cockroachdb/database_tasks"
14
14
 
15
- begin
16
- retried = false
17
- ActiveRecord::Base.establish_connection(
18
- #Alternative version: "cockroachdb://root@localhost:26257/ar_crdb_console"
19
- adapter: "cockroachdb",
20
- host: "localhost",
21
- port: 26257,
22
- user: "root",
23
- database: "ar_crdb_console"
24
- )
25
- ActiveRecord::Base.connection
26
- rescue ActiveRecord::NoDatabaseError
27
- raise if retried
28
- system("cockroach sql --insecure --host=localhost:26257 --execute='create database ar_crdb_console'",
29
- exception: true)
30
- retried = true
31
- retry
32
- end
33
-
34
- class Post < ActiveRecord::Base
35
- end
36
-
37
- unless Post.table_exists?
38
- migration = Class.new(ActiveRecord::Migration::Current) do
39
- def up
40
- create_table("posts") do |t|
41
- t.string :title
42
- t.text :body
43
- end
44
- end
45
- end
46
- migration.migrate(:up)
47
- end
15
+ schema_kind = ENV.fetch("SCHEMA_KIND", ENV.fetch("SCHEMA", "default"))
16
+
17
+ system("cockroach sql --insecure --host=localhost:26257 --execute='drop database if exists ar_crdb_console'",
18
+ exception: true)
19
+ system("cockroach sql --insecure --host=localhost:26257 --execute='create database ar_crdb_console'",
20
+ exception: true)
21
+
22
+ ActiveRecord::Base.establish_connection(
23
+ #Alternative version: "cockroachdb://root@localhost:26257/ar_crdb_console"
24
+ adapter: "cockroachdb",
25
+ host: "localhost",
26
+ port: 26257,
27
+ user: "root",
28
+ database: "ar_crdb_console"
29
+ )
30
+
31
+ load "#{__dir__}/console_schemas/#{schema_kind}.rb"
48
32
 
49
33
  require "irb"
50
34
  IRB.start(__FILE__)
@@ -0,0 +1,9 @@
1
+ class Post < ActiveRecord::Base
2
+ end
3
+
4
+ ActiveRecord::Schema.define do
5
+ create_table("posts") do |t|
6
+ t.string :title
7
+ t.text :body
8
+ end
9
+ end
@@ -0,0 +1,23 @@
1
+ class Post < ActiveRecord::Base
2
+ self.table_name = "bar.posts"
3
+ end
4
+
5
+ class Comment < ActiveRecord::Base
6
+ self.table_name = "foo.comments"
7
+ end
8
+
9
+ ActiveRecord::Schema.define do
10
+ create_schema("foo")
11
+ create_schema("bar")
12
+ create_table("bar.posts") do |t|
13
+ t.string :title
14
+ t.text :body
15
+ end
16
+
17
+ create_table("foo.comments") do |t|
18
+ t.integer :post_id
19
+ t.text :body
20
+ end
21
+
22
+ add_foreign_key "foo.comments", "bar.posts", column: "post_id"
23
+ end
@@ -9,6 +9,7 @@ pid_file="$root_dir/tmp/cockroach.pid"
9
9
  log_file="$root_dir/tmp/cockroachdb.log"
10
10
 
11
11
  mkdir -p "$root_dir/tmp"
12
+ [[ -f "$pid_file" ]] && kill -9 $(cat "$pid_file") || true
12
13
  rm -f "$pid_file"
13
14
 
14
15
  if ! (( ${+commands[cockroach]} )); then
@@ -17,32 +18,16 @@ See https://www.cockroachlabs.com/docs/stable/install-cockroachdb.html'
17
18
  fi
18
19
 
19
20
  cockroach start-single-node \
20
- --insecure --store=type=mem,size=0.25 --advertise-addr=localhost --pid-file "$pid_file" \
21
+ --insecure --store=type=mem,size=0.25 --advertise-addr=localhost \
22
+ --spatial-libs="$(geos-config --includes)" \
23
+ --pid-file "$pid_file" \
21
24
  &> "$log_file" &
22
25
 
23
- cockroach_pid=$!
24
-
25
26
  until [[ -f "$pid_file" ]]; do
26
27
  sleep 1
27
28
  done
28
29
 
29
30
 
30
- cat <<-SQL | cockroach sql --insecure --host=localhost:26257 > /dev/null
31
- -- https://www.cockroachlabs.com/docs/stable/local-testing.html
32
- SET CLUSTER SETTING kv.raft_log.disable_synchronization_unsafe = true;
33
- SET CLUSTER SETTING kv.range_merge.queue_interval = '50ms';
34
- SET CLUSTER SETTING jobs.registry.interval.gc = '30s';
35
- SET CLUSTER SETTING jobs.registry.interval.cancel = '180s';
36
- SET CLUSTER SETTING jobs.retention_time = '15s';
37
- SET CLUSTER SETTING sql.stats.automatic_collection.enabled = false;
38
- SET CLUSTER SETTING kv.range_split.by_load_merge_delay = '5s';
39
- ALTER RANGE default CONFIGURE ZONE USING "gc.ttlseconds" = 600;
40
- ALTER DATABASE system CONFIGURE ZONE USING "gc.ttlseconds" = 600;
41
-
42
- CREATE DATABASE activerecord_unittest;
43
- CREATE DATABASE activerecord_unittest2;
44
- SQL
45
-
46
- tail -f "$log_file"
31
+ cat "$root_dir/setup.sql" | cockroach sql --insecure --host=localhost:26257 > /dev/null
47
32
 
48
- trap "kill $cockroach_pid" EXIT
33
+ echo "CockroachDB started. PID: $(cat "$pid_file"). log: $log_file"
data/build/Dockerfile CHANGED
@@ -1,7 +1,7 @@
1
1
  # This Dockerfile extends the Examples-ORM testing image in order to
2
2
  # install specific dependencies required for ActiveRecord tests.
3
3
 
4
- FROM cockroachdb/example-orms-builder:20200413-1918
4
+ FROM us-east1-docker.pkg.dev/crl-ci-images/cockroach/example-orms-builder:20200413-1918
5
5
 
6
6
  # Native dependencies for libxml-ruby and sqlite3.
7
7
  RUN apt-get --allow-releaseinfo-change update -y && apt-get install -y \
@@ -22,6 +22,14 @@ module Arel # :nodoc:
22
22
  module Visitors # :nodoc:
23
23
  class CockroachDB < PostgreSQL # :nodoc:
24
24
  include RGeo::ActiveRecord::SpatialToSql
25
+
26
+ def visit_Arel_Nodes_JoinSource(o, collector)
27
+ super
28
+ if o.aost
29
+ collector << " AS OF SYSTEM TIME '#{o.aost.iso8601}'"
30
+ end
31
+ collector
32
+ end
25
33
  end
26
34
  end
27
35
  end
@@ -1,11 +1,11 @@
1
1
  module ActiveRecord
2
2
  module ConnectionAdapters
3
3
  module CockroachDB
4
- class Column < PostgreSQLColumn
4
+ class Column < PostgreSQL::Column
5
5
  # most functions taken from activerecord-postgis-adapter spatial_column
6
6
  # https://github.com/rgeo/activerecord-postgis-adapter/blob/master/lib/active_record/connection_adapters/postgis/spatial_column.rb
7
7
  def initialize(name, default, sql_type_metadata = nil, null = true,
8
- default_function = nil, collation: nil, comment: nil,
8
+ default_function = nil, collation: nil, comment: nil, identity: nil,
9
9
  serial: nil, spatial: nil, generated: nil, hidden: nil)
10
10
  @sql_type_metadata = sql_type_metadata
11
11
  @geographic = !!(sql_type_metadata.sql_type =~ /geography\(/i)
@@ -30,7 +30,7 @@ module ActiveRecord
30
30
  build_from_sql_type(sql_type_metadata.sql_type)
31
31
  end
32
32
  super(name, default, sql_type_metadata, null, default_function,
33
- collation: collation, comment: comment, serial: serial, generated: generated)
33
+ collation: collation, comment: comment, serial: serial, generated: generated, identity: identity)
34
34
  if spatial? && @srid
35
35
  @limit = { srid: @srid, type: to_type_name(geometric_type) }
36
36
  @limit[:has_z] = true if @has_z
@@ -53,10 +53,6 @@ module ActiveRecord
53
53
  spatial? ? @limit : super
54
54
  end
55
55
 
56
- def virtual?
57
- @generated.present?
58
- end
59
-
60
56
  def hidden?
61
57
  @hidden
62
58
  end
@@ -45,6 +45,14 @@ module ActiveRecord
45
45
  def st_polygon(name, options = {})
46
46
  column(name, :st_polygon, **options)
47
47
  end
48
+
49
+ private
50
+
51
+ def valid_column_definition_options
52
+ spatial = [:srid, :has_z, :has_m, :geographic, :spatial_type]
53
+ crdb = [:hidden]
54
+ super + spatial + crdb
55
+ end
48
56
  end
49
57
  end
50
58
 
@@ -2,21 +2,6 @@ module ActiveRecord
2
2
  module ConnectionAdapters
3
3
  module CockroachDB
4
4
  module DatabaseStatements
5
- # Since CockroachDB will run all transactions with serializable isolation,
6
- # READ UNCOMMITTED, READ COMMITTED, and REPEATABLE READ are all aliases
7
- # for SERIALIZABLE. This lets the adapter support all isolation levels,
8
- # but READ UNCOMMITTED has been removed from this list because the
9
- # ActiveRecord transaction isolation test fails for READ UNCOMMITTED.
10
- # See https://www.cockroachlabs.com/docs/v19.2/transactions.html#isolation-levels
11
- def transaction_isolation_levels
12
- {
13
- read_committed: "READ COMMITTED",
14
- repeatable_read: "REPEATABLE READ",
15
- serializable: "SERIALIZABLE",
16
- read_uncommitted: "READ UNCOMMITTED"
17
- }
18
- end
19
-
20
5
  # Overridden to avoid using transactions for schema creation.
21
6
  def insert_fixtures_set(fixture_set, tables_to_delete = [])
22
7
  fixture_inserts = build_fixture_statements(fixture_set)
@@ -29,74 +14,6 @@ module ActiveRecord
29
14
  end
30
15
  end
31
16
  end
32
-
33
- private
34
- def execute_batch(statements, name = nil)
35
- statements.each do |statement|
36
- execute(statement, name)
37
- end
38
- end
39
-
40
- DEFAULT_INSERT_VALUE = Arel.sql("DEFAULT").freeze
41
- private_constant :DEFAULT_INSERT_VALUE
42
-
43
- def default_insert_value(column)
44
- DEFAULT_INSERT_VALUE
45
- end
46
-
47
- def build_fixture_sql(fixtures, table_name)
48
- columns = schema_cache.columns_hash(table_name)
49
-
50
- values_list = fixtures.map do |fixture|
51
- fixture = fixture.stringify_keys
52
-
53
- unknown_columns = fixture.keys - columns.keys
54
- if unknown_columns.any?
55
- raise Fixture::FixtureError, %(table "#{table_name}" has no columns named #{unknown_columns.map(&:inspect).join(', ')}.)
56
- end
57
-
58
- columns.map do |name, column|
59
- if fixture.key?(name)
60
- type = lookup_cast_type_from_column(column)
61
- with_yaml_fallback(type.serialize(fixture[name]))
62
- else
63
- default_insert_value(column)
64
- end
65
- end
66
- end
67
-
68
- table = Arel::Table.new(table_name)
69
- manager = Arel::InsertManager.new
70
- manager.into(table)
71
-
72
- if values_list.size == 1
73
- values = values_list.shift
74
- new_values = []
75
- columns.each_key.with_index { |column, i|
76
- unless values[i].equal?(DEFAULT_INSERT_VALUE)
77
- new_values << values[i]
78
- manager.columns << table[column]
79
- end
80
- }
81
- values_list << new_values
82
- else
83
- columns.each_key { |column| manager.columns << table[column] }
84
- end
85
-
86
- manager.values = manager.create_values_list(values_list)
87
- manager.to_sql
88
- end
89
-
90
- def build_fixture_statements(fixture_set)
91
- fixture_set.map do |table_name, fixtures|
92
- next if fixtures.empty?
93
- build_fixture_sql(fixtures, table_name)
94
- end.compact
95
- end
96
-
97
- def with_multi_statements
98
- yield
99
- end
100
17
  end
101
18
  end
102
19
  end
@@ -10,37 +10,45 @@ module ActiveRecord
10
10
  "https://github.com/cockroachdb/activerecord-cockroachdb-adapter/issues/new"
11
11
  end
12
12
 
13
- case ActiveRecord.dump_schemas
14
- when :all, String
15
- raise "Custom schemas are not supported in CockroachDB. " \
16
- "See https://github.com/cockroachdb/cockroach/issues/26443."
17
- when :schema_search_path
18
- if configuration_hash[:schema_search_path]
19
- raise "Custom schemas are not supported in CockroachDB. " \
20
- "See https://github.com/cockroachdb/cockroach/issues/26443."
13
+ # "See https://github.com/cockroachdb/cockroach/issues/26443."
14
+ search_path =
15
+ case ActiveRecord.dump_schemas
16
+ when :schema_search_path
17
+ configuration_hash[:schema_search_path]
18
+ when :all
19
+ nil
20
+ when String
21
+ ActiveRecord.dump_schemas
21
22
  end
22
- end
23
23
 
24
24
  conn = ActiveRecord::Base.connection
25
- File.open(filename, "w") do |file|
26
- %w(SCHEMAS TYPES).each do |object_kind|
27
- ActiveRecord::Base.connection.execute("SHOW CREATE ALL #{object_kind}").each_row { file.puts _1 }
28
- end
25
+ begin
26
+ old_search_path = conn.schema_search_path
27
+ conn.schema_search_path = search_path
28
+ File.open(filename, "w") do |file|
29
+ # NOTE: There is no issue with the crdb_internal schema, it is ignored by SHOW CREATE.
30
+ %w(SCHEMAS TYPES).each do |object_kind|
31
+ ActiveRecord::Base.connection.execute("SHOW CREATE ALL #{object_kind}").each_row { file.puts _1 }
32
+ end
29
33
 
30
- ignore_tables = ActiveRecord::SchemaDumper.ignore_tables.to_set
34
+ ignore_tables = ActiveRecord::SchemaDumper.ignore_tables.to_set
31
35
 
32
- conn.execute("SHOW CREATE ALL TABLES").each_row do |(sql)|
33
- if sql.start_with?("CREATE")
34
- table_name = sql[/CREATE TABLE (?:.*?\.)?\"?(.*?)[\" ]/, 1]
35
- next if ignore_tables.member?(table_name)
36
- elsif sql.start_with?("ALTER")
37
- table_name = sql[/ALTER TABLE (?:.*?\.)?\"?(.*?)[\" ]/, 1]
38
- ref_table_name = sql[/REFERENCES (?:.*?\.)?\"?(.*?)[\" ]/, 1]
39
- next if ignore_tables.member?(table_name) || ignore_tables.member?(ref_table_name)
40
- end
36
+ conn.execute("SHOW CREATE ALL TABLES").each_row do |(sql)|
37
+ if sql.start_with?("CREATE")
38
+ table_name = sql[/CREATE TABLE (?:.*?\.)?\"?(.*?)[\" ]/, 1]
39
+ next if ignore_tables.member?(table_name)
40
+ elsif sql.start_with?("ALTER")
41
+ table_name = sql[/ALTER TABLE (?:.*?\.)?\"?(.*?)[\" ]/, 1]
42
+ ref_table_name = sql[/REFERENCES (?:.*?\.)?\"?(.*?)[\" ]/, 1]
43
+ next if ignore_tables.member?(table_name) || ignore_tables.member?(ref_table_name)
44
+ end
41
45
 
42
- file.puts sql
46
+ file.puts sql
47
+ end
48
+ file.puts "SET search_path TO #{conn.schema_search_path};\n\n"
43
49
  end
50
+ ensure
51
+ conn.schema_search_path = old_search_path
44
52
  end
45
53
  end
46
54
 
@@ -11,6 +11,14 @@ module ActiveRecord
11
11
  module ConnectionAdapters
12
12
  module CockroachDB
13
13
  module ReferentialIntegrity
14
+ # CockroachDB will raise a `PG::ForeignKeyViolation` when re-enabling
15
+ # referential integrity (e.g: adding a foreign key with invalid data
16
+ # raises).
17
+ # So foreign keys should always be valid for that matter.
18
+ def check_all_foreign_keys_valid!
19
+ true
20
+ end
21
+
14
22
  def disable_referential_integrity
15
23
  foreign_keys = tables.map { |table| foreign_keys(table) }.flatten
16
24
 
@@ -31,16 +39,12 @@ module ActiveRecord
31
39
 
32
40
  begin
33
41
  foreign_keys.each do |foreign_key|
34
- begin
35
- add_foreign_key(foreign_key.from_table, foreign_key.to_table, **foreign_key.options)
36
- rescue ActiveRecord::StatementInvalid => error
37
- if error.cause.class == PG::DuplicateObject
38
- # This error is safe to ignore because the yielded caller
39
- # already re-added the foreign key constraint.
40
- else
41
- raise error
42
- end
43
- end
42
+ # Avoid having PG:DuplicateObject error if a test is ran in transaction.
43
+ # TODO: verify that there is no cache issue related to running this (e.g: fk
44
+ # still in cache but not in db)
45
+ next if foreign_key_exists?(foreign_key.from_table, name: foreign_key.options[:name])
46
+
47
+ add_foreign_key(foreign_key.from_table, foreign_key.to_table, **foreign_key.options)
44
48
  end
45
49
  ensure
46
50
  ActiveRecord::Base.table_name_prefix = old_prefix