activerecord-cockroachdb-adapter 7.0.2 → 7.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/.github/workflows/ci.yml +86 -0
- data/CHANGELOG.md +9 -0
- data/CONTRIBUTING.md +6 -26
- data/Gemfile +34 -43
- data/README.md +1 -1
- data/Rakefile +5 -15
- data/activerecord-cockroachdb-adapter.gemspec +2 -5
- data/bin/console +43 -7
- data/bin/start-cockroachdb +48 -0
- data/build/teamcity-test.sh +2 -7
- data/lib/active_record/connection_adapters/cockroachdb/column.rb +1 -5
- data/lib/active_record/connection_adapters/cockroachdb/database_tasks.rb +79 -2
- data/lib/active_record/connection_adapters/cockroachdb/quoting.rb +6 -0
- data/lib/active_record/connection_adapters/cockroachdb/schema_statements.rb +2 -2
- data/lib/active_record/connection_adapters/cockroachdb/type.rb +5 -2
- data/lib/active_record/connection_adapters/cockroachdb_adapter.rb +2 -0
- data/lib/active_record/relation/query_methods_ext.rb +98 -0
- data/lib/activerecord-cockroachdb-adapter.rb +1 -1
- data/lib/version.rb +1 -1
- metadata +5 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 594ac59a7a678d5619ea771e3130a481481560adcc88032d7c17d61b6dabc279
|
4
|
+
data.tar.gz: 0cd6ea6bd6a1fe808142a91e35a24d4e15a59b48f56e4dba37d8a25584dd7a8a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 56205a247976012b6a25691045a773ca9fefecc1b98bb47ee83fb85dffede72a8aed5bc605a332d00b31fb57f67ee1018b850d14638581454980a6b96d2e8865
|
7
|
+
data.tar.gz: 92515e498cc8cedfe284cfe4cf9b3cb87eae72630aa5828e5983dfabe488ad214386561a0fb8072963b0796559209ee033cb010495d263d44eb1abf048afaa37
|
@@ -0,0 +1,86 @@
|
|
1
|
+
# Inspired from:
|
2
|
+
# - https://github.com/cockroachdb/sqlalchemy-cockroachdb/blob/master/.github/workflows/ci.yml
|
3
|
+
# - https://github.com/rgeo/activerecord-postgis-adapter/blob/master/.github/workflows/tests.yml
|
4
|
+
name: Test
|
5
|
+
|
6
|
+
on:
|
7
|
+
# Triggers the workflow on push or pull request events.
|
8
|
+
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
|
+
- "*"
|
13
|
+
pull_request:
|
14
|
+
types: [opened, reopened, synchronize]
|
15
|
+
|
16
|
+
# Allows you to run this workflow manually from the Actions tab
|
17
|
+
workflow_dispatch:
|
18
|
+
|
19
|
+
# This allows a subsequently queued workflow run to interrupt previous runs.
|
20
|
+
concurrency:
|
21
|
+
group: '${{ github.workflow }} @ ${{ github.event.pull_request.head.label || github.head_ref || github.ref }}'
|
22
|
+
cancel-in-progress: true
|
23
|
+
|
24
|
+
jobs:
|
25
|
+
test:
|
26
|
+
runs-on: ubuntu-latest
|
27
|
+
strategy:
|
28
|
+
matrix:
|
29
|
+
crdb: [v23.1.5]
|
30
|
+
ruby: [ruby-head]
|
31
|
+
name: Test (crdb=${{ matrix.crdb }} ruby=${{ matrix.ruby }})
|
32
|
+
steps:
|
33
|
+
- name: Set Up Actions
|
34
|
+
uses: actions/checkout@v3
|
35
|
+
- name: Install GEOS
|
36
|
+
run: sudo apt-get install libgeos-dev
|
37
|
+
- name: Set Up Ruby
|
38
|
+
uses: ruby/setup-ruby@v1
|
39
|
+
with:
|
40
|
+
ruby-version: ${{ matrix.ruby }}
|
41
|
+
bundler-cache: true
|
42
|
+
- name: Install and Start Cockroachdb
|
43
|
+
run: |
|
44
|
+
# Download CockroachDB
|
45
|
+
wget -qO- https://binaries.cockroachdb.com/cockroach-${{ matrix.crdb }}.linux-amd64.tgz | tar xvz
|
46
|
+
|
47
|
+
export PATH=./cockroach-${{ matrix.crdb }}.linux-amd64/:$PATH
|
48
|
+
readonly urlfile=cockroach-url
|
49
|
+
|
50
|
+
# Start a CockroachDB server and wait for it to become ready.
|
51
|
+
rm -f "$urlfile"
|
52
|
+
rm -rf cockroach-data
|
53
|
+
# 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 &
|
55
|
+
# Ensure CockroachDB is stopped on script exit.
|
56
|
+
# Wait until CockroachDB has started.
|
57
|
+
for i in {0..3}; do
|
58
|
+
[[ -f "$urlfile" ]] && break
|
59
|
+
backoff=$((2 ** i))
|
60
|
+
echo "server not yet available; sleeping for $backoff seconds"
|
61
|
+
sleep $backoff
|
62
|
+
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
|
+
"
|
85
|
+
- name: Test
|
86
|
+
run: bundle exec rake test
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,14 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
+
## Ongoing
|
4
|
+
|
5
|
+
## 7.0.3 - 2023-08-23
|
6
|
+
|
7
|
+
- Fix Multiple Database connections ([#283](https://github.com/cockroachdb/activerecord-cockroachdb-adapter/pull/)).
|
8
|
+
- Add support for sql load in rake tasks ([#275](https://github.com/cockroachdb/activerecord-cockroachdb-adapter/pull/)).
|
9
|
+
- Add support for sql dump in rake tasks ([#273](https://github.com/cockroachdb/activerecord-cockroachdb-adapter/pull/)).
|
10
|
+
- Add support for table optimize hints ([#266](https://github.com/cockroachdb/activerecord-cockroachdb-adapter/pull/)).
|
11
|
+
|
3
12
|
## 7.0.2 - 2023-05-23
|
4
13
|
|
5
14
|
- Fix default numbers test to expect the correct result after
|
data/CONTRIBUTING.md
CHANGED
@@ -15,12 +15,15 @@ override and monkey-patch functionality.
|
|
15
15
|
|
16
16
|
## Setup and running tests
|
17
17
|
|
18
|
-
|
18
|
+
### CockroachDB
|
19
|
+
|
20
|
+
First, You should setup a cockroachdb local instance. You can use the
|
21
|
+
`bin/start-cockroachdb` to help you with that task. Otherwise, once setup,
|
22
|
+
create two databases to be used by the ActiveRecord test suite:
|
19
23
|
activerecord_unittest and activerecord_unittest2.
|
20
24
|
|
21
25
|
```sql
|
22
26
|
CREATE DATABASE activerecord_unittest;
|
23
|
-
|
24
27
|
CREATE DATABASE activerecord_unittest2;
|
25
28
|
```
|
26
29
|
|
@@ -87,12 +90,6 @@ To run a specific test case, use minitest's `-n` option to run tests that match
|
|
87
90
|
TEST_FILES="test/cases/adapter_test.rb" TESTOPTS=`-n=/test_indexes/` bundle exec rake test
|
88
91
|
```
|
89
92
|
|
90
|
-
By default, tests will be run from the bundled version of Rails. To run against a local copy, set environemnt variable `RAILS_SOURCE`. Running against a local copy of Rails can be helpful when try to debug issues.
|
91
|
-
|
92
|
-
```bash
|
93
|
-
RAILS_SOURCE="path/to/local_copy" bundle exec rake test
|
94
|
-
```
|
95
|
-
|
96
93
|
`test/config.yml` assumes CockroachDB will be running at localhost:26257 with a root user. Make changes to `test/config.yml` as needed.
|
97
94
|
|
98
95
|
### Run Tests from a Backup
|
@@ -117,23 +114,6 @@ And the `activerecord_unittest` database will use the `RESTORE` command to load
|
|
117
114
|
|
118
115
|
# Improvements
|
119
116
|
|
120
|
-
|
121
|
-
## Support past Rails versions
|
122
|
-
|
123
|
-
Currently, only a beta version of Rails is tested. This means that the
|
124
|
-
adapter has been modified in to accommodate unreleased changes. In order
|
125
|
-
to run the tests for Rails 5.1 or 4.2, the test changes will need to be
|
126
|
-
cherry-picked back. Conflicts are mostly only expected for tests that
|
127
|
-
have not yet been added.
|
128
|
-
|
129
|
-
Sadly, this does mean that we will have to have multiple versions of the
|
130
|
-
driver for the multiple versions of Rails.
|
131
|
-
|
132
|
-
A proposal for the CockroachDB adapter versioning would be to follow
|
133
|
-
ActiveRecord minor versions. For example, if you use Rails 4.2.5, you
|
134
|
-
would specify the CockroachDB version `~> 4.2.0`.
|
135
|
-
|
136
|
-
|
137
117
|
## Running CI automatically
|
138
118
|
|
139
119
|
Currently the fork is set up to run using TeamCity only on the current
|
@@ -247,7 +227,7 @@ need to be cleaned up.
|
|
247
227
|
|
248
228
|
# Notes for the non-Rubyer
|
249
229
|
|
250
|
-
|
230
|
+
rbenv is an environment manager that lets you manage and swap between
|
251
231
|
multiple versions of Ruby and their dependencies.
|
252
232
|
|
253
233
|
bundle is dependency manager that uses a projects `Gemfile` (and often
|
data/Gemfile
CHANGED
@@ -1,58 +1,49 @@
|
|
1
|
-
|
2
|
-
source 'https://rubygems.org'
|
3
|
-
gemspec
|
1
|
+
# frozen_string_literal: true
|
4
2
|
|
5
|
-
|
6
|
-
gemspec path: ENV['RAILS_SOURCE']
|
7
|
-
else
|
8
|
-
def get_version_from_gemspec
|
9
|
-
gemspec = eval(File.read('activerecord-cockroachdb-adapter.gemspec'))
|
3
|
+
source "https://rubygems.org"
|
10
4
|
|
11
|
-
|
12
|
-
find { |dep| dep.name == 'activerecord' }.
|
13
|
-
requirement.
|
14
|
-
requirements.
|
15
|
-
first.
|
16
|
-
last
|
5
|
+
gemspec
|
17
6
|
|
18
|
-
major, minor, tiny, pre = gem_version.segments
|
19
7
|
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
8
|
+
module RailsTag
|
9
|
+
class << self
|
10
|
+
def call
|
11
|
+
req = gemspec_requirement
|
12
|
+
"v" + all_activerecord_versions.find { req.satisfied_by?(_1) }.version
|
24
13
|
end
|
25
|
-
end
|
26
14
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
end
|
15
|
+
def gemspec_requirement
|
16
|
+
File
|
17
|
+
.foreach(File.expand_path("activerecord-cockroachdb-adapter.gemspec", __dir__), chomp: true)
|
18
|
+
.find { _1[/add_dependency\s.activerecord.,\s.(.*)./] }
|
19
|
+
|
20
|
+
Gem::Requirement.new(Regexp.last_match(1))
|
21
|
+
end
|
35
22
|
|
36
|
-
|
37
|
-
|
38
|
-
|
23
|
+
def all_activerecord_versions
|
24
|
+
require 'net/http'
|
25
|
+
require 'yaml'
|
39
26
|
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
27
|
+
uri = URI.parse "https://rubygems.org/api/v1/versions/activerecord.yaml"
|
28
|
+
http = Net::HTTP.new(uri.host, uri.port)
|
29
|
+
http.use_ssl = true
|
30
|
+
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
44
31
|
|
45
|
-
|
46
|
-
|
47
|
-
|
32
|
+
YAML.load(
|
33
|
+
http.request(Net::HTTP::Get.new(uri.request_uri)).body
|
34
|
+
).map { Gem::Version.new(_1["number"]) }
|
35
|
+
end
|
48
36
|
end
|
49
|
-
|
50
|
-
# Get Rails from source because the gem doesn't include tests
|
51
|
-
version = ENV['RAILS_VERSION'] || get_version_from_gemspec
|
52
|
-
gem 'rails', git: "https://github.com/rails/rails.git", tag: "v#{version}"
|
53
37
|
end
|
54
38
|
|
55
|
-
|
39
|
+
|
40
|
+
group :development, :test do
|
41
|
+
# We need to load the gem from git to have access to activerecord's test files.
|
42
|
+
# You can use `path: "some/local/rails"` if you want to test the gem against
|
43
|
+
# a specific rails codebase.
|
44
|
+
gem "rails", github: "rails/rails", tag: RailsTag.call
|
45
|
+
|
46
|
+
gem "rake"
|
56
47
|
gem "byebug"
|
57
48
|
gem "minitest-excludes", "~> 2.0.1"
|
58
49
|
|
data/README.md
CHANGED
@@ -321,7 +321,7 @@ p modified_fac.parse_wkt(wkt)
|
|
321
321
|
#=> #<RGeo::Geographic::SphericalPolygonImpl>
|
322
322
|
```
|
323
323
|
|
324
|
-
Be careful when performing calculations on potentially invalid geometries, as the results might be nonsensical. For example, the area returned of an hourglass made of 2 equivalent triangles with a self-intersection in the middle is 0.
|
324
|
+
Be careful when performing calculations on potentially invalid geometries, as the results might be nonsensical. For example, the area returned of an hourglass made of 2 equivalent triangles with a self-intersection in the middle is 0.
|
325
325
|
|
326
326
|
Note that when using the `spherical_factory`, there is a chance that valid geometries will be interpreted as invalid due to floating point issues with small geometries.
|
327
327
|
|
data/Rakefile
CHANGED
@@ -4,14 +4,12 @@ require_relative 'test/support/paths_cockroachdb'
|
|
4
4
|
require_relative 'test/support/rake_helpers'
|
5
5
|
require_relative 'test/support/template_creator'
|
6
6
|
|
7
|
-
task test: ["test:cockroachdb"]
|
8
7
|
task default: [:test]
|
9
8
|
|
10
9
|
namespace :db do
|
11
10
|
task "create_test_template" do
|
12
11
|
ENV['DEBUG_COCKROACHDB_ADAPTER'] = "1"
|
13
12
|
ENV['COCKROACH_SKIP_LOAD_SCHEMA'] = "1"
|
14
|
-
ENV["ARCONN"] = "cockroachdb"
|
15
13
|
|
16
14
|
TemplateCreator.connect
|
17
15
|
require_relative 'test/cases/helper'
|
@@ -26,17 +24,9 @@ namespace :db do
|
|
26
24
|
end
|
27
25
|
end
|
28
26
|
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
t.verbose = false
|
35
|
-
end
|
36
|
-
|
37
|
-
task "cockroachdb:env" do
|
38
|
-
ENV["ARCONN"] = "cockroachdb"
|
39
|
-
end
|
27
|
+
Rake::TestTask.new do |t|
|
28
|
+
t.libs = ARTest::CockroachDB.test_load_paths
|
29
|
+
t.test_files = RakeHelpers.test_files
|
30
|
+
t.warning = !!ENV["WARNING"]
|
31
|
+
t.verbose = false
|
40
32
|
end
|
41
|
-
|
42
|
-
task 'test:cockroachdb' => 'test:cockroachdb:env'
|
@@ -1,9 +1,6 @@
|
|
1
|
-
#
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
4
|
-
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
5
|
-
|
6
|
-
require './lib/version.rb'
|
3
|
+
require_relative 'lib/version'
|
7
4
|
version = ActiveRecord::COCKROACH_DB_ADAPTER_VERSION
|
8
5
|
|
9
6
|
Gem::Specification.new do |spec|
|
data/bin/console
CHANGED
@@ -1,14 +1,50 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
|
3
|
-
|
4
|
-
require "activerecord/cockroachdb"
|
3
|
+
$:.unshift(File.expand_path("../lib", __dir__))
|
5
4
|
|
6
|
-
#
|
7
|
-
#
|
5
|
+
# require "bundler/setup"
|
6
|
+
# Bundler.require :development
|
8
7
|
|
9
|
-
|
10
|
-
#
|
11
|
-
#
|
8
|
+
require "active_record"
|
9
|
+
# This allows playing with the rake task as well. Ex:
|
10
|
+
#
|
11
|
+
# ActiveRecord::Tasks::DatabaseTasks.
|
12
|
+
# structure_load(Post.connection_db_config, "awesome-file.sql")
|
13
|
+
require "active_record/connection_adapters/cockroachdb/database_tasks"
|
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
|
12
48
|
|
13
49
|
require "irb"
|
14
50
|
IRB.start(__FILE__)
|
@@ -0,0 +1,48 @@
|
|
1
|
+
#!/usr/bin/env zsh
|
2
|
+
|
3
|
+
set -eu
|
4
|
+
|
5
|
+
die() { echo "$0: $*" 1>&2 ; false; }
|
6
|
+
|
7
|
+
root_dir="$(dirname $(dirname "$0:A"))"
|
8
|
+
pid_file="$root_dir/tmp/cockroach.pid"
|
9
|
+
log_file="$root_dir/tmp/cockroachdb.log"
|
10
|
+
|
11
|
+
mkdir -p "$root_dir/tmp"
|
12
|
+
rm -f "$pid_file"
|
13
|
+
|
14
|
+
if ! (( ${+commands[cockroach]} )); then
|
15
|
+
die 'the `cockroach` toolchain is not installed.
|
16
|
+
See https://www.cockroachlabs.com/docs/stable/install-cockroachdb.html'
|
17
|
+
fi
|
18
|
+
|
19
|
+
cockroach start-single-node \
|
20
|
+
--insecure --store=type=mem,size=0.25 --advertise-addr=localhost --pid-file "$pid_file" \
|
21
|
+
&> "$log_file" &
|
22
|
+
|
23
|
+
cockroach_pid=$!
|
24
|
+
|
25
|
+
until [[ -f "$pid_file" ]]; do
|
26
|
+
sleep 1
|
27
|
+
done
|
28
|
+
|
29
|
+
|
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"
|
47
|
+
|
48
|
+
trap "kill $cockroach_pid" EXIT
|
data/build/teamcity-test.sh
CHANGED
@@ -70,12 +70,7 @@ run_cockroach
|
|
70
70
|
|
71
71
|
if ! (RUBYOPT="-W0" TESTOPTS="-v" bundle exec rake test); then
|
72
72
|
echo "Tests failed"
|
73
|
-
|
74
|
-
else
|
75
|
-
echo "Tests passed"
|
76
|
-
HAS_FAILED=0
|
73
|
+
exit 1
|
77
74
|
fi
|
78
75
|
|
79
|
-
|
80
|
-
exit 1
|
81
|
-
fi
|
76
|
+
echo "Tests passed"
|
@@ -1,7 +1,7 @@
|
|
1
1
|
module ActiveRecord
|
2
2
|
module ConnectionAdapters
|
3
3
|
module CockroachDB
|
4
|
-
|
4
|
+
class Column < PostgreSQLColumn
|
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,
|
@@ -93,9 +93,5 @@ module ActiveRecord
|
|
93
93
|
end
|
94
94
|
end
|
95
95
|
end
|
96
|
-
|
97
|
-
class PostgreSQLColumn
|
98
|
-
prepend CockroachDB::PostgreSQLColumnMonkeyPatch
|
99
|
-
end
|
100
96
|
end
|
101
97
|
end
|
@@ -5,12 +5,89 @@ module ActiveRecord
|
|
5
5
|
module CockroachDB
|
6
6
|
class DatabaseTasks < ActiveRecord::Tasks::PostgreSQLDatabaseTasks
|
7
7
|
def structure_dump(filename, extra_flags=nil)
|
8
|
-
|
8
|
+
if extra_flags
|
9
|
+
raise "No flag supported yet, please raise an issue if needed. " \
|
10
|
+
"https://github.com/cockroachdb/activerecord-cockroachdb-adapter/issues/new"
|
11
|
+
end
|
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."
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
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
|
29
|
+
|
30
|
+
ignore_tables = ActiveRecord::SchemaDumper.ignore_tables.to_set
|
31
|
+
|
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
|
41
|
+
|
42
|
+
file.puts sql
|
43
|
+
end
|
44
|
+
end
|
9
45
|
end
|
10
46
|
|
11
47
|
def structure_load(filename, extra_flags=nil)
|
12
|
-
|
48
|
+
if extra_flags
|
49
|
+
raise "No flag supported yet, please raise an issue if needed. " \
|
50
|
+
"https://github.com/cockroachdb/activerecord-cockroachdb-adapter/issues/new"
|
51
|
+
end
|
52
|
+
|
53
|
+
run_cmd("cockroach", ["sql", "--set", "errexit=false", "--file", filename], "loading")
|
54
|
+
end
|
55
|
+
|
56
|
+
private
|
57
|
+
|
58
|
+
# Adapted from https://github.com/rails/rails/blob/a5fc471b3/activerecord/lib/active_record/tasks/postgresql_database_tasks.rb#L106.
|
59
|
+
# Using https://www.cockroachlabs.com/docs/stable/connection-parameters.html#additional-connection-parameters.
|
60
|
+
def cockroach_env
|
61
|
+
usr_pwd = ""
|
62
|
+
if configuration_hash[:username]
|
63
|
+
usr_pwd += configuration_hash[:username].to_s
|
64
|
+
if configuration_hash[:password]
|
65
|
+
usr_pwd += ":"
|
66
|
+
usr_pwd += configuration_hash[:password].to_s
|
67
|
+
end
|
68
|
+
usr_pwd += "@"
|
69
|
+
end
|
70
|
+
|
71
|
+
port = ""
|
72
|
+
port = ":#{configuration_hash[:port]}" if configuration_hash[:port]
|
73
|
+
|
74
|
+
params = %i(sslmode sslrootcert sslcert sslkey).filter_map do |key|
|
75
|
+
"#{key}=#{configuration_hash[key]}" if configuration_hash[key]
|
76
|
+
end.join("&")
|
77
|
+
params = "?#{params}" unless params.empty?
|
78
|
+
|
79
|
+
url = "postgres://#{usr_pwd}#{db_config.host}#{port}/#{db_config.database}#{params}"
|
80
|
+
|
81
|
+
{
|
82
|
+
# NOTE: sslmode in the url will take precedence over this setting, hence
|
83
|
+
# we don't need to conditionally set it.
|
84
|
+
"COCKROACH_INSECURE" => "true",
|
85
|
+
"COCKROACH_URL" => url
|
86
|
+
}
|
13
87
|
end
|
88
|
+
# The `#run_cmd` method use `psql_env` to set environments variables.
|
89
|
+
# We override it with cockroach env variables.
|
90
|
+
alias_method :psql_env, :cockroach_env
|
14
91
|
end
|
15
92
|
end
|
16
93
|
end
|
@@ -19,6 +19,12 @@ module ActiveRecord
|
|
19
19
|
# converting to WKB, so this does it automatically.
|
20
20
|
def quote(value)
|
21
21
|
if value.is_a?(Numeric)
|
22
|
+
# NOTE: The fact that integers are quoted is important and helps
|
23
|
+
# mitigate a potential vulnerability.
|
24
|
+
#
|
25
|
+
# See
|
26
|
+
# - https://nvd.nist.gov/vuln/detail/CVE-2022-44566
|
27
|
+
# - https://github.com/cockroachdb/activerecord-cockroachdb-adapter/pull/280#discussion_r1288692977
|
22
28
|
"'#{quote_string(value.to_s)}'"
|
23
29
|
elsif RGeo::Feature::Geometry.check_type(value)
|
24
30
|
"'#{RGeo::WKRep::WKBGenerator.new(hex_format: true, type_format: :ewkb, emit_ewkb_srid: true).generate(value)}'"
|
@@ -90,7 +90,7 @@ module ActiveRecord
|
|
90
90
|
# {:dimension=>2, :has_m=>false, :has_z=>false, :name=>"latlon", :srid=>0, :type=>"GEOMETRY"}
|
91
91
|
spatial = spatial_column_info(table_name).get(column_name, type_metadata.sql_type)
|
92
92
|
|
93
|
-
|
93
|
+
CockroachDB::Column.new(
|
94
94
|
column_name,
|
95
95
|
default_value,
|
96
96
|
type_metadata,
|
@@ -112,7 +112,7 @@ module ActiveRecord
|
|
112
112
|
# since type alone is not enough to format the column.
|
113
113
|
# Ex. type_to_sql(:geography, limit: "Point,4326")
|
114
114
|
# => "geography(Point,4326)"
|
115
|
-
#
|
115
|
+
#
|
116
116
|
def type_to_sql(type, limit: nil, precision: nil, scale: nil, array: nil, **) # :nodoc:
|
117
117
|
sql = \
|
118
118
|
case type.to_s
|
@@ -4,8 +4,11 @@ module ActiveRecord
|
|
4
4
|
# Return :postgresql instead of :cockroachdb for current_adapter_name so
|
5
5
|
# we can continue using the ActiveRecord::Types defined in
|
6
6
|
# PostgreSQLAdapter.
|
7
|
-
def adapter_name_from(
|
8
|
-
|
7
|
+
def adapter_name_from(model)
|
8
|
+
name = model.connection_db_config.adapter.to_sym
|
9
|
+
return :postgresql if name == :cockroachdb
|
10
|
+
|
11
|
+
name
|
9
12
|
end
|
10
13
|
end
|
11
14
|
end
|
@@ -23,6 +23,8 @@ require "active_record/connection_adapters/cockroachdb/arel_tosql"
|
|
23
23
|
require_relative "../migration/cockroachdb/compatibility"
|
24
24
|
require_relative "../../version"
|
25
25
|
|
26
|
+
require_relative "../relation/query_methods_ext"
|
27
|
+
|
26
28
|
# Run to ignore spatial tables that will break schemna dumper.
|
27
29
|
# Defined in ./setup.rb
|
28
30
|
ActiveRecord::ConnectionAdapters::CockroachDB.initial_setup
|
@@ -0,0 +1,98 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ActiveRecord
|
4
|
+
class Relation
|
5
|
+
module QueryMethodsExt
|
6
|
+
def from!(...) # :nodoc:
|
7
|
+
@force_index = nil
|
8
|
+
@index_hint = nil
|
9
|
+
super
|
10
|
+
end
|
11
|
+
|
12
|
+
# Set table index hint for the query to the
|
13
|
+
# given `index_name`, and `direction` (either
|
14
|
+
# `ASC` or `DESC`).
|
15
|
+
#
|
16
|
+
# Any call to `ActiveRecord::QueryMethods#from`
|
17
|
+
# will reset the index hint. Index hints are
|
18
|
+
# not set if the `from` clause is not a table
|
19
|
+
# name.
|
20
|
+
#
|
21
|
+
# @see https://www.cockroachlabs.com/docs/v22.2/table-expressions#force-index-selection
|
22
|
+
def force_index(index_name, direction: nil)
|
23
|
+
spawn.force_index!(index_name, direction: direction)
|
24
|
+
end
|
25
|
+
|
26
|
+
def force_index!(index_name, direction: nil)
|
27
|
+
return self unless from_clause_is_a_table_name?
|
28
|
+
|
29
|
+
index_name = sanitize_sql(index_name.to_s)
|
30
|
+
direction = direction.to_s.upcase
|
31
|
+
direction = %w[ASC DESC].include?(direction) ? ",#{direction}" : ""
|
32
|
+
|
33
|
+
@force_index = "FORCE_INDEX=#{index_name}#{direction}"
|
34
|
+
self.from_clause = build_from_clause_with_hints
|
35
|
+
self
|
36
|
+
end
|
37
|
+
|
38
|
+
# Set table index hint for the query with the
|
39
|
+
# given `hint`. This allows more control over
|
40
|
+
# the hint than `ActiveRecord::Relation#force_index`.
|
41
|
+
# For instance, you could set it to `NO_FULL_SCAN`.
|
42
|
+
#
|
43
|
+
# Any call to `ActiveRecord::QueryMethods#from`
|
44
|
+
# will reset the index hint. Index hints are
|
45
|
+
# not set if the `from` clause is not a table
|
46
|
+
# name.
|
47
|
+
#
|
48
|
+
# @see https://www.cockroachlabs.com/docs/v22.2/table-expressions#force-index-selection
|
49
|
+
def index_hint(hint)
|
50
|
+
spawn.index_hint!(hint)
|
51
|
+
end
|
52
|
+
|
53
|
+
def index_hint!(hint)
|
54
|
+
return self unless from_clause_is_a_table_name?
|
55
|
+
|
56
|
+
hint = sanitize_sql(hint.to_s)
|
57
|
+
@index_hint = hint.to_s
|
58
|
+
self.from_clause = build_from_clause_with_hints
|
59
|
+
self
|
60
|
+
end
|
61
|
+
|
62
|
+
private
|
63
|
+
|
64
|
+
def from_clause_is_a_table_name?
|
65
|
+
# if empty, we are just dealing with the current table.
|
66
|
+
return true if from_clause.empty?
|
67
|
+
# `from_clause` can be a subquery.
|
68
|
+
return false unless from_clause.value.is_a?(String)
|
69
|
+
# `from_clause` can be a list of tables or a function.
|
70
|
+
# A simple way to check is to see if the string
|
71
|
+
# contains special characters. But we have to
|
72
|
+
# not check against an existing table hint.
|
73
|
+
return !from_clause.value.gsub(/\@{.*?\}/, "").match?(/[,\(]/)
|
74
|
+
end
|
75
|
+
|
76
|
+
def build_from_clause_with_hints
|
77
|
+
table_hints = [@index_hint, @force_index].compact.join(",")
|
78
|
+
|
79
|
+
table_name =
|
80
|
+
if from_clause.empty?
|
81
|
+
quoted_table_name
|
82
|
+
else
|
83
|
+
# Remove previous table hints if any. And spaces.
|
84
|
+
from_clause.value.partition("@").first.strip
|
85
|
+
end
|
86
|
+
Relation::FromClause.new("#{table_name}@{#{table_hints}}", nil)
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
QueryMethods.prepend(QueryMethodsExt)
|
91
|
+
end
|
92
|
+
# `ActiveRecord::Base` ancestors do not include `QueryMethods`.
|
93
|
+
# But the `#all` method returns a relation, which has `QueryMethods`
|
94
|
+
# as ancestor. That is how active_record is doing is as well.
|
95
|
+
#
|
96
|
+
# @see https://github.com/rails/rails/blob/914130a9f/activerecord/lib/active_record/querying.rb#L23
|
97
|
+
Querying.delegate(:force_index, :index_hint, to: :all)
|
98
|
+
end
|
data/lib/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: activerecord-cockroachdb-adapter
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 7.0.
|
4
|
+
version: 7.0.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Cockroach Labs
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-
|
11
|
+
date: 2023-08-23 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|
@@ -74,6 +74,7 @@ executables: []
|
|
74
74
|
extensions: []
|
75
75
|
extra_rdoc_files: []
|
76
76
|
files:
|
77
|
+
- ".github/workflows/ci.yml"
|
77
78
|
- ".github/workflows/docker.yml"
|
78
79
|
- ".gitignore"
|
79
80
|
- ".gitmodules"
|
@@ -87,6 +88,7 @@ files:
|
|
87
88
|
- activerecord-cockroachdb-adapter.gemspec
|
88
89
|
- bin/console
|
89
90
|
- bin/setup
|
91
|
+
- bin/start-cockroachdb
|
90
92
|
- build/Dockerfile
|
91
93
|
- build/config.teamcity.yml
|
92
94
|
- build/local-test.sh
|
@@ -114,6 +116,7 @@ files:
|
|
114
116
|
- lib/active_record/connection_adapters/cockroachdb/type.rb
|
115
117
|
- lib/active_record/connection_adapters/cockroachdb_adapter.rb
|
116
118
|
- lib/active_record/migration/cockroachdb/compatibility.rb
|
119
|
+
- lib/active_record/relation/query_methods_ext.rb
|
117
120
|
- lib/activerecord-cockroachdb-adapter.rb
|
118
121
|
- lib/version.rb
|
119
122
|
homepage: https://github.com/cockroachdb/activerecord-cockroachdb-adapter
|