activerecord-cockroachdb-adapter 0.2.3 → 0.3.0.beta1
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 +5 -5
- data/.gitmodules +0 -3
- data/CONTRIBUTING.md +18 -58
- data/Gemfile +58 -6
- data/README.md +2 -2
- data/Rakefile +17 -5
- data/activerecord-cockroachdb-adapter.gemspec +2 -6
- data/build/Dockerfile +1 -1
- data/build/teamcity-test.sh +12 -35
- data/lib/active_record/connection_adapters/cockroachdb/attribute_methods.rb +28 -0
- data/lib/active_record/connection_adapters/cockroachdb/column.rb +15 -0
- data/lib/active_record/connection_adapters/cockroachdb/database_statements.rb +21 -0
- data/lib/active_record/connection_adapters/cockroachdb/quoting.rb +28 -0
- data/lib/active_record/connection_adapters/cockroachdb/referential_integrity.rb +23 -38
- data/lib/active_record/connection_adapters/cockroachdb/schema_statements.rb +29 -43
- data/lib/active_record/connection_adapters/cockroachdb/transaction_manager.rb +14 -16
- data/lib/active_record/connection_adapters/cockroachdb/type.rb +14 -0
- data/lib/active_record/connection_adapters/cockroachdb_adapter.rb +65 -120
- metadata +10 -54
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
|
-
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: 48ca5207eae1d4bf1c26da960ad80e78f54099b1eb62466e89ff5186c9d41632
|
|
4
|
+
data.tar.gz: d3d8a5c38a3adda552b283663d4aaf88e05587b3ac9e0da28418fa05d72cfcdd
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 955dca7f67f68b93fd2ebd19cd6027de446598c823abbc108ce5630fbf6d566c14c09e283f37e3d04fb306ff72a68e55f6856daea91a61f9488636f9da957920
|
|
7
|
+
data.tar.gz: 9cb056da8d37cd199427f2ae25d354bcb3fb606fde92e1c01fb2cef7eedd2122a9eccbf0b3693d7d0c7197f8ff8d7d4b1321d16d9212db4331673ddf5669b934
|
data/.gitmodules
CHANGED
data/CONTRIBUTING.md
CHANGED
|
@@ -11,15 +11,19 @@ CockroachDBAdapter to initialize ActiveRecord for their projects.
|
|
|
11
11
|
This adapter extends the PostgreSQL ActiveRecord adapter in order to
|
|
12
12
|
override and monkey-patch functionality.
|
|
13
13
|
|
|
14
|
-
The other repository is a fork of [Rails]. The tests have been modified
|
|
15
|
-
for the purposes of testing our CockroachDB adapter.
|
|
16
|
-
|
|
17
14
|
[activerecord-cockroachdb-adapter]: https://github.com/cockroachdb/activerecord-cockroachdb-adapter/
|
|
18
|
-
[Rails]: https://github.com/lego/ruby-on-rails
|
|
19
|
-
|
|
20
15
|
|
|
21
16
|
## Setup and running tests
|
|
22
17
|
|
|
18
|
+
In CockroachDB, create two databases to be used by the ActiveRecord test suite:
|
|
19
|
+
activerecord_unittest and activerecord_unittest2.
|
|
20
|
+
|
|
21
|
+
```sql
|
|
22
|
+
CREATE DATABASE activerecord_unittest;
|
|
23
|
+
|
|
24
|
+
CREATE DATABASE activerecord_unittest2;
|
|
25
|
+
```
|
|
26
|
+
|
|
23
27
|
It is best to have a Ruby environment manager installed, such as
|
|
24
28
|
[rvm](https://rvm.io/), as Rails has varying Ruby version requirements.
|
|
25
29
|
If you are using rvm, you then install and use the required Ruby
|
|
@@ -37,65 +41,30 @@ rvm use 2.2.5
|
|
|
37
41
|
```
|
|
38
42
|
|
|
39
43
|
Using [bundler](http://bundler.io/), install the dependancies of Rails.
|
|
40
|
-
Additionally, make sure the Rails git submodule is loaded.
|
|
41
44
|
|
|
42
45
|
```bash
|
|
43
|
-
|
|
44
|
-
git submodule update
|
|
45
|
-
# Install rails dependancies.
|
|
46
|
-
(cd rails && bundle install)
|
|
46
|
+
bundle install
|
|
47
47
|
```
|
|
48
48
|
|
|
49
|
-
Then, to run the test with an active CockroachDB instance:
|
|
49
|
+
Then, to run the full ActiveRecord test suite with an active CockroachDB instance:
|
|
50
50
|
|
|
51
51
|
```bash
|
|
52
|
-
|
|
53
|
-
(cd rails/activerecord && BUNDLE_GEMFILE=../Gemfile bundle exec rake db:cockroachdb:rebuild)
|
|
54
|
-
(cd rails/activerecord && BUNDLE_GEMFILE=../Gemfile bundle exec rake test:cockroachdb)
|
|
52
|
+
bundle exec rake test
|
|
55
53
|
```
|
|
56
54
|
|
|
57
|
-
|
|
55
|
+
To run specific tests, set environemnt variable `TEST_FILES_AR`. For example, to run ActiveRecord tests `test/cases/associations_test.rb` and `test/cases/ar_schema_test.rb.rb`
|
|
58
56
|
|
|
59
57
|
```bash
|
|
60
|
-
|
|
58
|
+
TEST_FILES_AR="test/cases/associations_test.rb,test/cases/ar_schema_test.rb" bundle exec rake test
|
|
61
59
|
```
|
|
62
60
|
|
|
63
|
-
|
|
64
|
-
This configuration specifies:
|
|
65
|
-
|
|
66
|
-
- CockroachDB port and host the test suite uses.
|
|
67
|
-
- Database names used for the different test connections. (ActiveRecord
|
|
68
|
-
uses two separate connections for some tests.)
|
|
69
|
-
|
|
70
|
-
```
|
|
71
|
-
(cd rails/activerecord && BUNDLE_GEMFILE=../Gemfile bundle exec rake db:cockroachdb:rebuild)
|
|
72
|
-
```
|
|
61
|
+
By default, tests will be run from the bundled version of Rails. To run against a local copy, set environemnt variable `RAILS_SOURCE`.
|
|
73
62
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
- This command needs to be run from activerecord folder in order to use
|
|
78
|
-
the ActiveRecord `Rakefile`. The `Rakefile` defines scripts (called
|
|
79
|
-
tasks) such as executing tests.
|
|
80
|
-
- `BUNDLE_GEMFILE=../Gemfile` tells `bundle` to use the dependancies for
|
|
81
|
-
Rails that were previously installed.
|
|
82
|
-
- `bundle exec rake` uses `bundle` to execute the Ruby package `rake`.
|
|
83
|
-
- `rake db:cockroachdb:rebuild` runs the specified Rake task. All tasks
|
|
84
|
-
can be found in `rails/activerecord/Rakefile`.
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
```
|
|
88
|
-
(cd rails/activerecord && BUNDLE_GEMFILE=../Gemfile bundle exec rake test:cockroachdb)
|
|
63
|
+
```bash
|
|
64
|
+
RAILS_SOURCE="path/to/local_copy" bundle exec rake test
|
|
89
65
|
```
|
|
90
66
|
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
- Like the previous command, this one uses the Activerecord Rakefile and
|
|
94
|
-
the Rails Gemfile. The task code can be found in the Rakefile.
|
|
95
|
-
- Running specific test files can be done by appending
|
|
96
|
-
`TESTFILES=test/cases/attribute_methods.rb` to the command. Globs are
|
|
97
|
-
used. Multiple individual files cannot be specified.
|
|
98
|
-
|
|
67
|
+
`test/config.yml` assumes CockroachDB will be running at localhost:26257 with a root user. Make changes to `test/config.yml` as needed.
|
|
99
68
|
|
|
100
69
|
# Improvements
|
|
101
70
|
|
|
@@ -143,15 +112,6 @@ A possible way to approach this would be to add a shim to cause any
|
|
|
143
112
|
tests that use it to fail, and grep the tests that pass and then skip
|
|
144
113
|
them.
|
|
145
114
|
|
|
146
|
-
# Cleanup
|
|
147
|
-
|
|
148
|
-
One of the earlier commits to the Rails repo did a big grep of
|
|
149
|
-
`PostgreSQLAdapter` -> `CockroachDBAdapter`. In order to better support
|
|
150
|
-
changes upstream, this modification should be changed to instead only
|
|
151
|
-
add `CockroachDBAdapter` alongside any `PostgreSQLAdapter`. The later
|
|
152
|
-
test cleanup commit will conflict on any further changes (like adding
|
|
153
|
-
back PostgreSQL, or removing CockroachDB for PostgreSQL).
|
|
154
|
-
|
|
155
115
|
## Publishing to Rubygems
|
|
156
116
|
|
|
157
117
|
TODO: Expand on this. Jordan is likely the only person with publishing
|
data/Gemfile
CHANGED
|
@@ -1,11 +1,63 @@
|
|
|
1
|
+
require 'openssl'
|
|
1
2
|
source 'https://rubygems.org'
|
|
3
|
+
gemspec
|
|
2
4
|
|
|
3
|
-
|
|
5
|
+
if ENV['RAILS_SOURCE']
|
|
6
|
+
gemspec path: ENV['RAILS_SOURCE']
|
|
7
|
+
else
|
|
8
|
+
def get_version_from_gemspec
|
|
9
|
+
gemspec = eval(File.read('activerecord-cockroachdb-adapter.gemspec'))
|
|
4
10
|
|
|
5
|
-
|
|
11
|
+
gem_version = gemspec.dependencies.
|
|
12
|
+
find { |dep| dep.name == 'activerecord' }.
|
|
13
|
+
requirement.
|
|
14
|
+
requirements.
|
|
15
|
+
first.
|
|
16
|
+
last
|
|
6
17
|
|
|
7
|
-
|
|
8
|
-
|
|
18
|
+
major, minor, tiny, pre = gem_version.segments
|
|
19
|
+
|
|
20
|
+
if pre
|
|
21
|
+
gem_version.to_s
|
|
22
|
+
else
|
|
23
|
+
find_latest_matching_version(major, minor)
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def find_latest_matching_version(gemspec_major, gemspec_minor)
|
|
28
|
+
all_activerecord_versions.
|
|
29
|
+
reject { |version| version["prerelease"] }.
|
|
30
|
+
map { |version| version["number"].split(".").map(&:to_i) }.
|
|
31
|
+
find { |major, minor|
|
|
32
|
+
major == gemspec_major && (minor == gemspec_minor || gemspec_minor.nil?)
|
|
33
|
+
}.join(".")
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def all_activerecord_versions
|
|
37
|
+
require 'net/http'
|
|
38
|
+
require 'yaml'
|
|
39
|
+
|
|
40
|
+
uri = URI.parse "https://rubygems.org/api/v1/versions/activerecord.yaml"
|
|
41
|
+
http = Net::HTTP.new(uri.host, uri.port)
|
|
42
|
+
http.use_ssl = true
|
|
43
|
+
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
|
44
|
+
|
|
45
|
+
YAML.load(
|
|
46
|
+
http.request(Net::HTTP::Get.new(uri.request_uri)).body
|
|
47
|
+
)
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
# Get Rails from source beacause 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
|
+
end
|
|
54
|
+
|
|
55
|
+
group :development do
|
|
56
|
+
gem "byebug"
|
|
57
|
+
gem "minitest-excludes"
|
|
9
58
|
|
|
10
|
-
#
|
|
11
|
-
gem "
|
|
59
|
+
# Gems used by the ActiveRecord test suite
|
|
60
|
+
gem "bcrypt"
|
|
61
|
+
gem "mocha"
|
|
62
|
+
gem "sqlite3"
|
|
63
|
+
end
|
data/README.md
CHANGED
|
@@ -7,7 +7,7 @@ CockroachDB adapter for ActiveRecord 4 and 5. This is a lightweight extension of
|
|
|
7
7
|
Add this line to your project's Gemfile:
|
|
8
8
|
|
|
9
9
|
```ruby
|
|
10
|
-
gem 'activerecord-cockroachdb-adapter', '~> 0.2
|
|
10
|
+
gem 'activerecord-cockroachdb-adapter', '~> 0.2'
|
|
11
11
|
```
|
|
12
12
|
|
|
13
13
|
If you're using Rails 4.x, use the `0.1.x` versions of this gem.
|
|
@@ -26,4 +26,4 @@ development:
|
|
|
26
26
|
## Modifying the adapter?
|
|
27
27
|
|
|
28
28
|
See [CONTRIBUTING.md](/CONTRIBUTING.md) for more details on setting up
|
|
29
|
-
the environment and making modifications.
|
|
29
|
+
the environment and making modifications.
|
data/Rakefile
CHANGED
|
@@ -1,10 +1,22 @@
|
|
|
1
1
|
require "bundler/gem_tasks"
|
|
2
2
|
require "rake/testtask"
|
|
3
|
+
require_relative 'test/support/paths_cockroachdb'
|
|
4
|
+
require_relative 'test/support/rake_helpers'
|
|
3
5
|
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
6
|
+
task test: ["test:cockroachdb"]
|
|
7
|
+
task default: [:test]
|
|
8
|
+
|
|
9
|
+
namespace :test do
|
|
10
|
+
Rake::TestTask.new("cockroachdb") do |t|
|
|
11
|
+
t.libs = ARTest::CockroachDB.test_load_paths
|
|
12
|
+
t.test_files = test_files
|
|
13
|
+
t.warning = !!ENV["WARNING"]
|
|
14
|
+
t.verbose = false
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
task "cockroachdb:env" do
|
|
18
|
+
ENV["ARCONN"] = "cockroachdb"
|
|
19
|
+
end
|
|
8
20
|
end
|
|
9
21
|
|
|
10
|
-
task :
|
|
22
|
+
task 'test:cockroachdb' => 'test:cockroachdb:env'
|
|
@@ -4,7 +4,7 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
|
4
4
|
|
|
5
5
|
Gem::Specification.new do |spec|
|
|
6
6
|
spec.name = "activerecord-cockroachdb-adapter"
|
|
7
|
-
spec.version = "0.
|
|
7
|
+
spec.version = "0.3.0.beta1"
|
|
8
8
|
spec.licenses = ["Apache-2.0"]
|
|
9
9
|
spec.authors = ["Cockroach Labs"]
|
|
10
10
|
spec.email = ["cockroach-db@googlegroups.com"]
|
|
@@ -14,7 +14,7 @@ Gem::Specification.new do |spec|
|
|
|
14
14
|
spec.homepage = "https://github.com/cockroachdb/activerecord-cockroachdb-adapter"
|
|
15
15
|
|
|
16
16
|
spec.add_dependency "activerecord", "~> 5.2"
|
|
17
|
-
spec.add_dependency "pg", ">= 0.20"
|
|
17
|
+
spec.add_dependency "pg", ">= 0.20"
|
|
18
18
|
|
|
19
19
|
# Prevent pushing this gem to RubyGems.org. To allow pushes either set the 'allowed_push_host'
|
|
20
20
|
# to allow pushing to a single host or delete this section to allow pushing to any host.
|
|
@@ -31,8 +31,4 @@ Gem::Specification.new do |spec|
|
|
|
31
31
|
spec.bindir = "exe"
|
|
32
32
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
|
33
33
|
spec.require_paths = ["lib"]
|
|
34
|
-
|
|
35
|
-
spec.add_development_dependency "bundler", "~> 1.14"
|
|
36
|
-
spec.add_development_dependency "rake", "~> 10.0"
|
|
37
|
-
spec.add_development_dependency "minitest", "~> 5.0"
|
|
38
34
|
end
|
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/
|
|
4
|
+
FROM cockroachdb/example-orms-builder:20200413-1918
|
|
5
5
|
|
|
6
6
|
# Native dependencies for libxml-ruby and sqlite3.
|
|
7
7
|
RUN apt-get update -y && apt-get install -y \
|
data/build/teamcity-test.sh
CHANGED
|
@@ -2,15 +2,14 @@
|
|
|
2
2
|
|
|
3
3
|
set -euo pipefail
|
|
4
4
|
|
|
5
|
-
# Download CockroachDB
|
|
6
|
-
|
|
7
|
-
VERSION=v2.0-alpha.20171218
|
|
5
|
+
# Download CockroachDB
|
|
6
|
+
VERSION=v20.1.0-rc.1
|
|
8
7
|
wget -qO- https://binaries.cockroachdb.com/cockroach-$VERSION.linux-amd64.tgz | tar xvz
|
|
9
8
|
readonly COCKROACH=./cockroach-$VERSION.linux-amd64/cockroach
|
|
10
9
|
|
|
11
10
|
# Make sure cockroach can be found on the path. This is required for the
|
|
12
11
|
# ActiveRecord Rakefile that rebuilds the test database.
|
|
13
|
-
export PATH
|
|
12
|
+
export PATH=./cockroach-$VERSION.linux-amd64/:$PATH
|
|
14
13
|
readonly urlfile=cockroach-url
|
|
15
14
|
|
|
16
15
|
run_cockroach() {
|
|
@@ -32,45 +31,23 @@ run_cockroach() {
|
|
|
32
31
|
echo "server not yet available; sleeping for $backoff seconds"
|
|
33
32
|
sleep $backoff
|
|
34
33
|
done
|
|
34
|
+
cockroach sql --insecure -e 'CREATE DATABASE activerecord_unittest;'
|
|
35
|
+
cockroach sql --insecure -e 'CREATE DATABASE activerecord_unittest2;'
|
|
35
36
|
}
|
|
36
37
|
|
|
37
|
-
# Target the Rails dependency file.
|
|
38
|
-
export BUNDLE_GEMFILE=$(pwd)/rails/Gemfile
|
|
39
|
-
|
|
40
38
|
# Install ruby dependencies.
|
|
39
|
+
gem install bundler:2.1.4
|
|
41
40
|
bundle install
|
|
42
41
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
# 'Install' our adapter. This involves symlinking it inside of
|
|
46
|
-
# ActiveRecord. Normally the adapter will transitively install
|
|
47
|
-
# ActiveRecord, but we need to execute tests from inside the Rails
|
|
48
|
-
# context so we cannot rely on that. We also need previous links to make
|
|
49
|
-
# tests idempotent.
|
|
50
|
-
rm -f rails/activerecord/lib/active_record/connection_adapters/cockroachdb_adapter.rb
|
|
51
|
-
ln -s $(pwd)/lib/active_record/connection_adapters/cockroachdb_adapter.rb rails/activerecord/lib/active_record/connection_adapters/cockroachdb_adapter.rb
|
|
52
|
-
rm -rf rails/activerecord/lib/active_record/connection_adapters/cockroachdb
|
|
53
|
-
ln -s $(pwd)/lib/active_record/connection_adapters/cockroachdb rails/activerecord/lib/active_record/connection_adapters/cockroachdb
|
|
42
|
+
run_cockroach
|
|
54
43
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
for TESTFILE in ${TESTS}; do
|
|
59
|
-
# Start CockroachDB
|
|
60
|
-
run_cockroach
|
|
61
|
-
# Run the tests.
|
|
62
|
-
echo "Rebuilding database"
|
|
63
|
-
(cd rails/activerecord && bundle exec rake db:cockroachdb:rebuild)
|
|
64
|
-
echo "Running test: $TESTFILE"
|
|
65
|
-
# Run the test. Continue testing even if this file fails.
|
|
66
|
-
if ! (cd rails/activerecord && bundle exec rake test:cockroachdb TESTFILES=$TESTFILE); then
|
|
67
|
-
echo "Test FAILED: $TESTFILE"
|
|
44
|
+
if ! (bundle exec rake test); then
|
|
45
|
+
echo "Tests failed"
|
|
68
46
|
HAS_FAILED=1
|
|
69
|
-
|
|
70
|
-
echo "
|
|
47
|
+
else
|
|
48
|
+
echo "Tests passed"
|
|
71
49
|
HAS_FAILED=0
|
|
72
|
-
|
|
73
|
-
done
|
|
50
|
+
fi
|
|
74
51
|
|
|
75
52
|
# Attempt a clean shutdown for good measure. We'll force-kill in the
|
|
76
53
|
# exit trap if this script fails.
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
module ActiveRecord
|
|
2
|
+
module CockroachDB
|
|
3
|
+
module AttributeMethodsMonkeyPatch
|
|
4
|
+
|
|
5
|
+
private
|
|
6
|
+
|
|
7
|
+
# Filter out rowid so it doesn't get inserted by ActiveRecord. rowid is a
|
|
8
|
+
# column added by CockroachDB for tables that don't define primary keys.
|
|
9
|
+
# CockroachDB will automatically insert rowid values. See
|
|
10
|
+
# https://www.cockroachlabs.com/docs/v19.2/create-table.html#create-a-table.
|
|
11
|
+
def attributes_for_create(attribute_names)
|
|
12
|
+
super.reject { |name| name == ConnectionAdapters::CockroachDBAdapter::DEFAULT_PRIMARY_KEY }
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
# Filter out rowid so it doesn't get updated by ActiveRecord. rowid is a
|
|
16
|
+
# column added by CockroachDB for tables that don't define primary keys.
|
|
17
|
+
# CockroachDB will automatically insert rowid values. See
|
|
18
|
+
# https://www.cockroachlabs.com/docs/v19.2/create-table.html#create-a-table.
|
|
19
|
+
def attributes_for_update(attribute_names)
|
|
20
|
+
super.reject { |name| name == ConnectionAdapters::CockroachDBAdapter::DEFAULT_PRIMARY_KEY }
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
class Base
|
|
26
|
+
prepend CockroachDB::AttributeMethodsMonkeyPatch
|
|
27
|
+
end
|
|
28
|
+
end
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
module ActiveRecord
|
|
2
|
+
module ConnectionAdapters
|
|
3
|
+
module CockroachDB
|
|
4
|
+
module PostgreSQLColumnMonkeyPatch
|
|
5
|
+
def serial?
|
|
6
|
+
default_function == "unique_rowid()"
|
|
7
|
+
end
|
|
8
|
+
end
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
class PostgreSQLColumn
|
|
12
|
+
prepend CockroachDB::PostgreSQLColumnMonkeyPatch
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
module ActiveRecord
|
|
2
|
+
module ConnectionAdapters
|
|
3
|
+
module CockroachDB
|
|
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
|
+
}
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
module ActiveRecord
|
|
2
|
+
module ConnectionAdapters
|
|
3
|
+
module CockroachDB
|
|
4
|
+
module Quoting
|
|
5
|
+
private
|
|
6
|
+
|
|
7
|
+
# CockroachDB does not allow inserting integer values into string
|
|
8
|
+
# columns, but ActiveRecord expects this to work. CockroachDB will
|
|
9
|
+
# however allow inserting string values into integer columns. It will
|
|
10
|
+
# try to parse string values and convert them to integers so they can be
|
|
11
|
+
# inserted in integer columns.
|
|
12
|
+
#
|
|
13
|
+
# We take advantage of this behavior here by forcing numeric values to
|
|
14
|
+
# always be strings. Then, we won't have to make any additional changes
|
|
15
|
+
# to ActiveRecord to support inserting integer values into string
|
|
16
|
+
# columns.
|
|
17
|
+
def _quote(value)
|
|
18
|
+
case value
|
|
19
|
+
when Numeric
|
|
20
|
+
"'#{quote_string(value.to_s)}'"
|
|
21
|
+
else
|
|
22
|
+
super
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
@@ -1,51 +1,36 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
#
|
|
2
|
+
|
|
3
|
+
# The PostgresSQL Adapter's ReferentialIntegrity module can disable and
|
|
4
|
+
# re-enable foreign key constraints by disabling all table triggers. Since
|
|
5
|
+
# triggers are not available in CockroachDB, we have to remove foreign keys and
|
|
6
|
+
# re-add them via the ActiveRecord API.
|
|
7
|
+
#
|
|
8
|
+
# This module is commonly used to load test fixture data without having to worry
|
|
9
|
+
# about the order in which that data is loaded.
|
|
4
10
|
module ActiveRecord
|
|
5
11
|
module ConnectionAdapters
|
|
6
12
|
module CockroachDB
|
|
7
|
-
module ReferentialIntegrity
|
|
8
|
-
def disable_referential_integrity
|
|
9
|
-
|
|
10
|
-
fkeys = nil
|
|
13
|
+
module ReferentialIntegrity
|
|
14
|
+
def disable_referential_integrity
|
|
15
|
+
foreign_keys = tables.map { |table| foreign_keys(table) }.flatten
|
|
11
16
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
tables.each do |table_name|
|
|
15
|
-
fkeys = foreign_keys(table_name)
|
|
16
|
-
fkeys.each do |fkey|
|
|
17
|
-
remove_foreign_key table_name, name: fkey.options[:name]
|
|
18
|
-
end
|
|
19
|
-
end
|
|
20
|
-
end
|
|
21
|
-
rescue ActiveRecord::ActiveRecordError => e
|
|
22
|
-
original_exception = e
|
|
17
|
+
foreign_keys.each do |foreign_key|
|
|
18
|
+
remove_foreign_key(foreign_key.from_table, name: foreign_key.options[:name])
|
|
23
19
|
end
|
|
24
20
|
|
|
25
|
-
|
|
26
|
-
yield
|
|
27
|
-
rescue ActiveRecord::InvalidForeignKey => e
|
|
28
|
-
warn <<-WARNING
|
|
29
|
-
WARNING: Rails was not able to disable referential integrity.
|
|
30
|
-
|
|
31
|
-
Please go to https://github.com/cockroachdb/activerecord-cockroachdb-adapter
|
|
32
|
-
and report this issue.
|
|
33
|
-
|
|
34
|
-
cause: #{original_exception.try(:message)}
|
|
35
|
-
|
|
36
|
-
WARNING
|
|
37
|
-
raise e
|
|
38
|
-
end
|
|
21
|
+
yield
|
|
39
22
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
23
|
+
foreign_keys.each do |foreign_key|
|
|
24
|
+
begin
|
|
25
|
+
add_foreign_key(foreign_key.from_table, foreign_key.to_table, foreign_key.options)
|
|
26
|
+
rescue ActiveRecord::StatementInvalid => error
|
|
27
|
+
if error.cause.class == PG::DuplicateObject
|
|
28
|
+
# This error is safe to ignore because the yielded caller
|
|
29
|
+
# already re-added the foreign key constraint.
|
|
30
|
+
else
|
|
31
|
+
raise error
|
|
46
32
|
end
|
|
47
33
|
end
|
|
48
|
-
rescue ActiveRecord::ActiveRecordError
|
|
49
34
|
end
|
|
50
35
|
end
|
|
51
36
|
end
|
|
@@ -1,57 +1,43 @@
|
|
|
1
|
-
require 'active_record/connection_adapters/postgresql/schema_statements'
|
|
2
|
-
|
|
3
1
|
module ActiveRecord
|
|
4
2
|
module ConnectionAdapters
|
|
5
3
|
module CockroachDB
|
|
6
4
|
module SchemaStatements
|
|
7
5
|
include ActiveRecord::ConnectionAdapters::PostgreSQL::SchemaStatements
|
|
8
|
-
# NOTE(joey): This was ripped from PostgresSQL::SchemaStatements, with a
|
|
9
|
-
# slight modification to change setval(string, int, bool) to just
|
|
10
|
-
# setval(string, int) for CockroachDB compatbility.
|
|
11
|
-
# See https://github.com/cockroachdb/cockroach/issues/19723
|
|
12
|
-
#
|
|
13
|
-
# Resets the sequence of a table's primary key to the maximum value.
|
|
14
|
-
def reset_pk_sequence!(table, pk = nil, sequence = nil) #:nodoc:
|
|
15
|
-
unless pk && sequence
|
|
16
|
-
default_pk, default_sequence = pk_and_sequence_for(table)
|
|
17
6
|
|
|
18
|
-
|
|
19
|
-
|
|
7
|
+
def add_index(table_name, column_name, options = {})
|
|
8
|
+
super
|
|
9
|
+
rescue ActiveRecord::StatementInvalid => error
|
|
10
|
+
if debugging? && error.cause.class == PG::FeatureNotSupported
|
|
11
|
+
warn "#{error}\n\nThis error will be ignored and the index will not be created.\n\n"
|
|
12
|
+
else
|
|
13
|
+
raise error
|
|
20
14
|
end
|
|
15
|
+
end
|
|
21
16
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
17
|
+
# ActiveRecord allows for tables to exist without primary keys.
|
|
18
|
+
# Databases like PostgreSQL support this behavior, but CockroachDB does
|
|
19
|
+
# not. If a table is created without a primary key, CockroachDB will add
|
|
20
|
+
# a rowid column to serve as its primary key. This breaks a lot of
|
|
21
|
+
# ActiveRecord's assumptions so we'll treat tables with rowid primary
|
|
22
|
+
# keys as if they didn't have primary keys at all.
|
|
23
|
+
# https://www.cockroachlabs.com/docs/v19.2/create-table.html#create-a-table
|
|
24
|
+
# https://api.rubyonrails.org/v5.2.4/classes/ActiveRecord/ConnectionAdapters/SchemaStatements.html#method-i-create_table
|
|
25
|
+
def primary_key(table_name)
|
|
26
|
+
pk = super
|
|
25
27
|
|
|
26
|
-
if pk
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
if postgresql_version >= 100000
|
|
31
|
-
minvalue = query_value("SELECT seqmin FROM pg_sequence WHERE seqrelid = #{quote(quoted_sequence)}::regclass", "SCHEMA")
|
|
32
|
-
else
|
|
33
|
-
minvalue = query_value("SELECT min_value FROM #{quoted_sequence}", "SCHEMA")
|
|
34
|
-
end
|
|
35
|
-
end
|
|
36
|
-
if max_pk
|
|
37
|
-
# NOTE(joey): This is done to replace the call:
|
|
38
|
-
#
|
|
39
|
-
# SELECT setval(..., max_pk, false)
|
|
40
|
-
#
|
|
41
|
-
# with
|
|
42
|
-
#
|
|
43
|
-
# SELECT setval(..., max_pk-1)
|
|
44
|
-
#
|
|
45
|
-
# These two statements are semantically equivilant, but
|
|
46
|
-
# setval(string, int, bool) is not supported by CockroachDB.
|
|
47
|
-
#
|
|
48
|
-
# FIXME(joey): This is incorrect if the sequence is not 1
|
|
49
|
-
# incremented. We would need to pull out the custom increment value.
|
|
50
|
-
max_pk - 1
|
|
51
|
-
end
|
|
52
|
-
query_value("SELECT setval(#{quote(quoted_sequence)}, #{max_pk ? max_pk : minvalue})", "SCHEMA")
|
|
28
|
+
if pk == CockroachDBAdapter::DEFAULT_PRIMARY_KEY
|
|
29
|
+
nil
|
|
30
|
+
else
|
|
31
|
+
pk
|
|
53
32
|
end
|
|
54
33
|
end
|
|
34
|
+
|
|
35
|
+
# CockroachDB uses unique_rowid() for primary keys, not sequences. It's
|
|
36
|
+
# possible to force a table to use sequences, but since it's not the
|
|
37
|
+
# default behavior we'll always return nil for default_sequence_name.
|
|
38
|
+
def default_sequence_name(table_name, pk = "id")
|
|
39
|
+
nil
|
|
40
|
+
end
|
|
55
41
|
end
|
|
56
42
|
end
|
|
57
43
|
end
|
|
@@ -1,25 +1,23 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require 'active_record/connection_adapters/abstract/transaction'
|
|
4
|
-
|
|
5
3
|
module ActiveRecord
|
|
6
4
|
module ConnectionAdapters
|
|
7
|
-
|
|
8
|
-
# NOTE(joey): This is a very sad monkey patch. Unfortunately, it is
|
|
9
|
-
# required in order to prevent doing more than 2 nested transactions
|
|
10
|
-
# while still allowing a single nested transaction. This is because
|
|
11
|
-
# CockroachDB only supports a single savepoint at the beginning of a
|
|
12
|
-
# transaction. Allowing this works for the common case of testing.
|
|
13
5
|
module CockroachDB
|
|
14
6
|
module TransactionManagerMonkeyPatch
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
7
|
+
# Capture ActiveRecord::SerializationFailure errors caused by
|
|
8
|
+
# transactions that fail due to serialization errors. Failed
|
|
9
|
+
# transactions will be retried until they pass or the max retry limit is
|
|
10
|
+
# exceeded.
|
|
11
|
+
def within_new_transaction(options = {})
|
|
12
|
+
attempts = options.fetch(:attempts, 0)
|
|
13
|
+
super
|
|
14
|
+
rescue ActiveRecord::SerializationFailure => error
|
|
15
|
+
raise if attempts >= @connection.max_transaction_retries
|
|
16
|
+
|
|
17
|
+
attempts += 1
|
|
18
|
+
sleep_seconds = (2 ** attempts + rand) / 10
|
|
19
|
+
sleep(sleep_seconds)
|
|
20
|
+
within_new_transaction(options.merge(attempts: attempts)) { yield }
|
|
23
21
|
end
|
|
24
22
|
end
|
|
25
23
|
end
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
module ActiveRecord
|
|
2
|
+
module Type
|
|
3
|
+
class << self
|
|
4
|
+
private
|
|
5
|
+
|
|
6
|
+
# Return :postgresql instead of :cockroachdb for current_adapter_name so
|
|
7
|
+
# we can continue using the ActiveRecord::Types defined in
|
|
8
|
+
# PostgreSQLAdapter.
|
|
9
|
+
def current_adapter_name
|
|
10
|
+
:postgresql
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
@@ -1,8 +1,12 @@
|
|
|
1
1
|
require 'active_record/connection_adapters/postgresql_adapter'
|
|
2
|
-
require "active_record/connection_adapters/postgresql/schema_statements"
|
|
3
2
|
require "active_record/connection_adapters/cockroachdb/schema_statements"
|
|
4
3
|
require "active_record/connection_adapters/cockroachdb/referential_integrity"
|
|
5
4
|
require "active_record/connection_adapters/cockroachdb/transaction_manager"
|
|
5
|
+
require "active_record/connection_adapters/cockroachdb/column"
|
|
6
|
+
require "active_record/connection_adapters/cockroachdb/database_statements"
|
|
7
|
+
require "active_record/connection_adapters/cockroachdb/quoting"
|
|
8
|
+
require "active_record/connection_adapters/cockroachdb/type"
|
|
9
|
+
require "active_record/connection_adapters/cockroachdb/attribute_methods"
|
|
6
10
|
|
|
7
11
|
module ActiveRecord
|
|
8
12
|
module ConnectionHandling
|
|
@@ -32,16 +36,25 @@ module ActiveRecord
|
|
|
32
36
|
module ConnectionAdapters
|
|
33
37
|
class CockroachDBAdapter < PostgreSQLAdapter
|
|
34
38
|
ADAPTER_NAME = "CockroachDB".freeze
|
|
39
|
+
DEFAULT_PRIMARY_KEY = "rowid"
|
|
35
40
|
|
|
36
41
|
include CockroachDB::SchemaStatements
|
|
37
42
|
include CockroachDB::ReferentialIntegrity
|
|
43
|
+
include CockroachDB::DatabaseStatements
|
|
44
|
+
include CockroachDB::Quoting
|
|
38
45
|
|
|
46
|
+
def debugging?
|
|
47
|
+
!!ENV["DEBUG_COCKROACHDB_ADAPTER"]
|
|
48
|
+
end
|
|
39
49
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
50
|
+
def max_transaction_retries
|
|
51
|
+
@max_transaction_retries ||= @config.fetch(:max_transaction_retries, 3)
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
# CockroachDB 20.1 can run queries that work against PostgreSQL 10+.
|
|
55
|
+
def postgresql_version
|
|
56
|
+
100000
|
|
57
|
+
end
|
|
45
58
|
|
|
46
59
|
def supports_json?
|
|
47
60
|
# FIXME(joey): Add a version check.
|
|
@@ -65,10 +78,6 @@ module ActiveRecord
|
|
|
65
78
|
false
|
|
66
79
|
end
|
|
67
80
|
|
|
68
|
-
def supports_pg_crypto_uuid?
|
|
69
|
-
false
|
|
70
|
-
end
|
|
71
|
-
|
|
72
81
|
def supports_partial_index?
|
|
73
82
|
# See cockroachdb/cockroach#9683
|
|
74
83
|
false
|
|
@@ -103,116 +112,6 @@ module ActiveRecord
|
|
|
103
112
|
false
|
|
104
113
|
end
|
|
105
114
|
|
|
106
|
-
def supports_savepoints?
|
|
107
|
-
# See cockroachdb/cockroach#10735.
|
|
108
|
-
false
|
|
109
|
-
end
|
|
110
|
-
|
|
111
|
-
def transaction_isolation_levels
|
|
112
|
-
{
|
|
113
|
-
# Explicitly prevent READ UNCOMMITTED from being used. This
|
|
114
|
-
# was due to the READ UNCOMMITTED test failing.
|
|
115
|
-
# read_uncommitted: "READ UNCOMMITTED",
|
|
116
|
-
read_committed: "READ COMMITTED",
|
|
117
|
-
repeatable_read: "REPEATABLE READ",
|
|
118
|
-
serializable: "SERIALIZABLE"
|
|
119
|
-
}
|
|
120
|
-
end
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
# Sadly, we can only do savepoints at the beginning of
|
|
124
|
-
# transactions. This means that we cannot use them for most cases
|
|
125
|
-
# of transaction, so we just pretend they're usable.
|
|
126
|
-
def create_savepoint(name = "COCKROACH_RESTART"); end
|
|
127
|
-
|
|
128
|
-
def exec_rollback_to_savepoint(name = "COCKROACH_RESTART"); end
|
|
129
|
-
|
|
130
|
-
def release_savepoint(name = "COCKROACH_RESTART"); end
|
|
131
|
-
|
|
132
|
-
def indexes(table_name, name = nil) # :nodoc:
|
|
133
|
-
# The PostgreSQL adapter uses a correlated subquery in the following query,
|
|
134
|
-
# which CockroachDB does not yet support. That portion of the query fetches
|
|
135
|
-
# any non-standard opclasses that each index uses. CockroachDB also doesn't
|
|
136
|
-
# support opclasses at this time, so the query is modified to just remove
|
|
137
|
-
# the section about opclasses entirely.
|
|
138
|
-
if name
|
|
139
|
-
ActiveSupport::Deprecation.warn(<<-MSG.squish)
|
|
140
|
-
Passing name to #indexes is deprecated without replacement.
|
|
141
|
-
MSG
|
|
142
|
-
end
|
|
143
|
-
|
|
144
|
-
table = Utils.extract_schema_qualified_name(table_name.to_s)
|
|
145
|
-
|
|
146
|
-
result = query(<<-SQL, "SCHEMA")
|
|
147
|
-
SELECT distinct i.relname, d.indisunique, d.indkey, pg_get_indexdef(d.indexrelid), t.oid,
|
|
148
|
-
pg_catalog.obj_description(i.oid, 'pg_class') AS comment
|
|
149
|
-
FROM pg_class t
|
|
150
|
-
INNER JOIN pg_index d ON t.oid = d.indrelid
|
|
151
|
-
INNER JOIN pg_class i ON d.indexrelid = i.oid
|
|
152
|
-
LEFT JOIN pg_namespace n ON n.oid = i.relnamespace
|
|
153
|
-
WHERE i.relkind = 'i'
|
|
154
|
-
AND d.indisprimary = 'f'
|
|
155
|
-
AND t.relname = '#{table.identifier}'
|
|
156
|
-
AND n.nspname = #{table.schema ? "'#{table.schema}'" : 'ANY (current_schemas(false))'}
|
|
157
|
-
ORDER BY i.relname
|
|
158
|
-
SQL
|
|
159
|
-
|
|
160
|
-
result.map do |row|
|
|
161
|
-
index_name = row[0]
|
|
162
|
-
unique = row[1]
|
|
163
|
-
indkey = row[2].split(" ").map(&:to_i)
|
|
164
|
-
inddef = row[3]
|
|
165
|
-
oid = row[4]
|
|
166
|
-
comment = row[5]
|
|
167
|
-
|
|
168
|
-
expressions, where = inddef.scan(/\((.+?)\)(?: WHERE (.+))?\z/).flatten
|
|
169
|
-
|
|
170
|
-
if indkey.include?(0)
|
|
171
|
-
columns = expressions
|
|
172
|
-
else
|
|
173
|
-
columns = Hash[query(<<-SQL.strip_heredoc, "SCHEMA")].values_at(*indkey).compact
|
|
174
|
-
SELECT a.attnum, a.attname
|
|
175
|
-
FROM pg_attribute a
|
|
176
|
-
WHERE a.attrelid = #{oid}
|
|
177
|
-
AND a.attnum IN (#{indkey.join(",")})
|
|
178
|
-
SQL
|
|
179
|
-
|
|
180
|
-
# add info on sort order for columns (only desc order is explicitly specified, asc is the default)
|
|
181
|
-
orders = Hash[
|
|
182
|
-
expressions.scan(/(\w+) DESC/).flatten.map { |order_column| [order_column, :desc] }
|
|
183
|
-
]
|
|
184
|
-
end
|
|
185
|
-
|
|
186
|
-
# FIXME(joey): This may be specific to ActiveRecord 5.2.
|
|
187
|
-
IndexDefinition.new(
|
|
188
|
-
table_name,
|
|
189
|
-
index_name,
|
|
190
|
-
unique,
|
|
191
|
-
columns,
|
|
192
|
-
orders: orders,
|
|
193
|
-
where: where,
|
|
194
|
-
comment: comment.presence
|
|
195
|
-
)
|
|
196
|
-
end.compact
|
|
197
|
-
end
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
def primary_keys(table_name)
|
|
201
|
-
name = Utils.extract_schema_qualified_name(table_name.to_s)
|
|
202
|
-
select_values(<<-SQL.strip_heredoc, "SCHEMA")
|
|
203
|
-
SELECT column_name
|
|
204
|
-
FROM information_schema.key_column_usage kcu
|
|
205
|
-
JOIN information_schema.table_constraints tc
|
|
206
|
-
ON kcu.table_name = tc.table_name
|
|
207
|
-
AND kcu.table_schema = tc.table_schema
|
|
208
|
-
AND kcu.constraint_name = tc.constraint_name
|
|
209
|
-
WHERE constraint_type = 'PRIMARY KEY'
|
|
210
|
-
AND kcu.table_name = #{quote(name.identifier)}
|
|
211
|
-
AND kcu.table_schema = #{name.schema ? quote(name.schema) : "ANY (current_schemas(false))"}
|
|
212
|
-
ORDER BY kcu.ordinal_position
|
|
213
|
-
SQL
|
|
214
|
-
end
|
|
215
|
-
|
|
216
115
|
# This is hardcoded to 63 (as previously was in ActiveRecord 5.0) to aid in
|
|
217
116
|
# migration from PostgreSQL to CockroachDB. In practice, this limitation
|
|
218
117
|
# is arbitrary since CockroachDB supports index name lengths and table alias
|
|
@@ -295,6 +194,52 @@ module ActiveRecord
|
|
|
295
194
|
end
|
|
296
195
|
end
|
|
297
196
|
|
|
197
|
+
# Override extract_value_from_default because the upstream definition
|
|
198
|
+
# doesn't handle the variations in CockroachDB's behavior.
|
|
199
|
+
def extract_value_from_default(default)
|
|
200
|
+
super ||
|
|
201
|
+
extract_escaped_string_from_default(default) ||
|
|
202
|
+
extract_time_from_default(default)
|
|
203
|
+
end
|
|
204
|
+
|
|
205
|
+
# Both PostgreSQL and CockroachDB use C-style string escapes under the
|
|
206
|
+
# covers. PostgreSQL obscures this for us and unescapes the strings, but
|
|
207
|
+
# CockroachDB does not. Here we'll use Ruby to unescape the string.
|
|
208
|
+
# See https://github.com/cockroachdb/cockroach/issues/47497 and
|
|
209
|
+
# https://www.postgresql.org/docs/9.2/sql-syntax-lexical.html#SQL-SYNTAX-STRINGS-ESCAPE.
|
|
210
|
+
def extract_escaped_string_from_default(default)
|
|
211
|
+
# Escaped strings start with an e followed by the string in quotes (e'…')
|
|
212
|
+
return unless default =~ /\A[\(B]?e'(.*)'.*::"?([\w. ]+)"?(?:\[\])?\z/m
|
|
213
|
+
|
|
214
|
+
# String#undump doesn't account for escaped single quote characters
|
|
215
|
+
"\"#{$1}\"".undump.gsub("\\'".freeze, "'".freeze)
|
|
216
|
+
end
|
|
217
|
+
|
|
218
|
+
# This method exists to extract the correct time and date defaults for a
|
|
219
|
+
# couple of reasons.
|
|
220
|
+
# 1) There's a bug in CockroachDB where the date type is missing from
|
|
221
|
+
# the column info query.
|
|
222
|
+
# https://github.com/cockroachdb/cockroach/issues/47285
|
|
223
|
+
# 2) PostgreSQL's timestamp without time zone type maps to CockroachDB's
|
|
224
|
+
# TIMESTAMP type. TIMESTAMP includes a UTC time zone while timestamp
|
|
225
|
+
# without time zone doesn't.
|
|
226
|
+
# https://www.cockroachlabs.com/docs/v19.2/timestamp.html#variants
|
|
227
|
+
def extract_time_from_default(default)
|
|
228
|
+
return unless default =~ /\A'(.*)'\z/
|
|
229
|
+
|
|
230
|
+
# If default has a UTC time zone, we'll drop the time zone information
|
|
231
|
+
# so it acts like PostgreSQL's timestamp without time zone. Then, try
|
|
232
|
+
# to parse the resulting string to verify if it's a time.
|
|
233
|
+
time = if default =~ /\A'(.*)(\+00:00)'\z/
|
|
234
|
+
$1
|
|
235
|
+
else
|
|
236
|
+
default
|
|
237
|
+
end
|
|
238
|
+
|
|
239
|
+
Time.parse(time).to_s
|
|
240
|
+
rescue
|
|
241
|
+
nil
|
|
242
|
+
end
|
|
298
243
|
|
|
299
244
|
# end private
|
|
300
245
|
end
|
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: 0.
|
|
4
|
+
version: 0.3.0.beta1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Cockroach Labs
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date:
|
|
11
|
+
date: 2020-04-17 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: activerecord
|
|
@@ -31,9 +31,6 @@ dependencies:
|
|
|
31
31
|
- - ">="
|
|
32
32
|
- !ruby/object:Gem::Version
|
|
33
33
|
version: '0.20'
|
|
34
|
-
- - "<"
|
|
35
|
-
- !ruby/object:Gem::Version
|
|
36
|
-
version: '0.22'
|
|
37
34
|
type: :runtime
|
|
38
35
|
prerelease: false
|
|
39
36
|
version_requirements: !ruby/object:Gem::Requirement
|
|
@@ -41,51 +38,6 @@ dependencies:
|
|
|
41
38
|
- - ">="
|
|
42
39
|
- !ruby/object:Gem::Version
|
|
43
40
|
version: '0.20'
|
|
44
|
-
- - "<"
|
|
45
|
-
- !ruby/object:Gem::Version
|
|
46
|
-
version: '0.22'
|
|
47
|
-
- !ruby/object:Gem::Dependency
|
|
48
|
-
name: bundler
|
|
49
|
-
requirement: !ruby/object:Gem::Requirement
|
|
50
|
-
requirements:
|
|
51
|
-
- - "~>"
|
|
52
|
-
- !ruby/object:Gem::Version
|
|
53
|
-
version: '1.14'
|
|
54
|
-
type: :development
|
|
55
|
-
prerelease: false
|
|
56
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
57
|
-
requirements:
|
|
58
|
-
- - "~>"
|
|
59
|
-
- !ruby/object:Gem::Version
|
|
60
|
-
version: '1.14'
|
|
61
|
-
- !ruby/object:Gem::Dependency
|
|
62
|
-
name: rake
|
|
63
|
-
requirement: !ruby/object:Gem::Requirement
|
|
64
|
-
requirements:
|
|
65
|
-
- - "~>"
|
|
66
|
-
- !ruby/object:Gem::Version
|
|
67
|
-
version: '10.0'
|
|
68
|
-
type: :development
|
|
69
|
-
prerelease: false
|
|
70
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
71
|
-
requirements:
|
|
72
|
-
- - "~>"
|
|
73
|
-
- !ruby/object:Gem::Version
|
|
74
|
-
version: '10.0'
|
|
75
|
-
- !ruby/object:Gem::Dependency
|
|
76
|
-
name: minitest
|
|
77
|
-
requirement: !ruby/object:Gem::Requirement
|
|
78
|
-
requirements:
|
|
79
|
-
- - "~>"
|
|
80
|
-
- !ruby/object:Gem::Version
|
|
81
|
-
version: '5.0'
|
|
82
|
-
type: :development
|
|
83
|
-
prerelease: false
|
|
84
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
85
|
-
requirements:
|
|
86
|
-
- - "~>"
|
|
87
|
-
- !ruby/object:Gem::Version
|
|
88
|
-
version: '5.0'
|
|
89
41
|
description: Allows the use of CockroachDB as a backend for ActiveRecord and Rails
|
|
90
42
|
apps.
|
|
91
43
|
email:
|
|
@@ -109,10 +61,15 @@ files:
|
|
|
109
61
|
- build/local-test.sh
|
|
110
62
|
- build/teamcity-test.sh
|
|
111
63
|
- docker.sh
|
|
64
|
+
- lib/active_record/connection_adapters/cockroachdb/attribute_methods.rb
|
|
65
|
+
- lib/active_record/connection_adapters/cockroachdb/column.rb
|
|
66
|
+
- lib/active_record/connection_adapters/cockroachdb/database_statements.rb
|
|
112
67
|
- lib/active_record/connection_adapters/cockroachdb/database_tasks.rb
|
|
68
|
+
- lib/active_record/connection_adapters/cockroachdb/quoting.rb
|
|
113
69
|
- lib/active_record/connection_adapters/cockroachdb/referential_integrity.rb
|
|
114
70
|
- lib/active_record/connection_adapters/cockroachdb/schema_statements.rb
|
|
115
71
|
- lib/active_record/connection_adapters/cockroachdb/transaction_manager.rb
|
|
72
|
+
- lib/active_record/connection_adapters/cockroachdb/type.rb
|
|
116
73
|
- lib/active_record/connection_adapters/cockroachdb_adapter.rb
|
|
117
74
|
- lib/activerecord-cockroachdb-adapter.rb
|
|
118
75
|
homepage: https://github.com/cockroachdb/activerecord-cockroachdb-adapter
|
|
@@ -131,12 +88,11 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
131
88
|
version: '0'
|
|
132
89
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
133
90
|
requirements:
|
|
134
|
-
- - "
|
|
91
|
+
- - ">"
|
|
135
92
|
- !ruby/object:Gem::Version
|
|
136
|
-
version:
|
|
93
|
+
version: 1.3.1
|
|
137
94
|
requirements: []
|
|
138
|
-
|
|
139
|
-
rubygems_version: 2.5.2
|
|
95
|
+
rubygems_version: 3.1.2
|
|
140
96
|
signing_key:
|
|
141
97
|
specification_version: 4
|
|
142
98
|
summary: CockroachDB adapter for ActiveRecord.
|