activerecord-cockroachdb-adapter 7.0.3 → 7.1.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 +4 -4
- data/.editorconfig +7 -0
- data/.github/workflows/ci.yml +43 -38
- data/.ruby-version +1 -1
- data/CHANGELOG.md +12 -0
- data/Gemfile +14 -1
- data/activerecord-cockroachdb-adapter.gemspec +1 -1
- data/bin/console +17 -33
- data/bin/console_schemas/default.rb +9 -0
- data/bin/console_schemas/schemas.rb +23 -0
- data/bin/start-cockroachdb +6 -21
- data/build/Dockerfile +1 -1
- data/lib/active_record/connection_adapters/cockroachdb/arel_tosql.rb +8 -0
- data/lib/active_record/connection_adapters/cockroachdb/column.rb +3 -7
- data/lib/active_record/connection_adapters/cockroachdb/column_methods.rb +8 -0
- data/lib/active_record/connection_adapters/cockroachdb/database_statements.rb +0 -83
- data/lib/active_record/connection_adapters/cockroachdb/database_tasks.rb +32 -24
- data/lib/active_record/connection_adapters/cockroachdb/referential_integrity.rb +14 -10
- data/lib/active_record/connection_adapters/cockroachdb/schema_statements.rb +49 -14
- data/lib/active_record/connection_adapters/cockroachdb/type.rb +3 -2
- data/lib/active_record/connection_adapters/cockroachdb_adapter.rb +116 -233
- data/lib/active_record/relation/query_methods_ext.rb +29 -1
- data/lib/arel/nodes/join_source_ext.rb +28 -0
- data/lib/version.rb +1 -1
- data/setup.sql +18 -0
- metadata +9 -5
- data/lib/active_record/connection_adapters/cockroachdb/oid/type_map_initializer.rb +0 -26
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 672289521537934d4b9ed2d707c3faf55b4761c8d2b4e9e12cd8622166963ae7
|
4
|
+
data.tar.gz: 345a84d7c5bca0d574aa65eb0fb0e30986a23fcc2830f422e5b1d80ffa971076
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4ce6d2119bfc27192630c32ec488b3e7f533cc64963fc04035609122e5bdbc33e75b83766ca68e3eb73e2592b2fe0a1bae53a74389527762f790b16bda687da9
|
7
|
+
data.tar.gz: 42e10ab1106e4ffc4df89bbbf98f8ddbd05b6bccf97b062a9445ebf874a8bfef9e628dce8b39c3287424a7094f70790457293a2766a849bd39ac0e20c7a684fe
|
data/.editorconfig
ADDED
data/.github/workflows/ci.yml
CHANGED
@@ -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
|
-
|
10
|
-
|
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:
|
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
|
-
|
30
|
-
|
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@
|
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
|
-
|
41
|
-
|
54
|
+
ruby-version: ${{ matrix.ruby }}
|
55
|
+
bundler-cache: true
|
42
56
|
- name: Install and Start Cockroachdb
|
43
57
|
run: |
|
44
58
|
# Download CockroachDB
|
45
|
-
|
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-$
|
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-$
|
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
|
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
|
+
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 "
|
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
|
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
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
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,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
|
data/bin/start-cockroachdb
CHANGED
@@ -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
|
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
|
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
|
-
|
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
|
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 <
|
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
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
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
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
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
|
-
|
34
|
+
ignore_tables = ActiveRecord::SchemaDumper.ignore_tables.to_set
|
31
35
|
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
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
|
-
|
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
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
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
|