activerecord-cockroachdb-adapter 0.2.2 → 0.2.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitmodules +3 -0
- data/CONTRIBUTING.md +248 -0
- data/Gemfile +7 -0
- data/README.md +11 -1
- data/activerecord-cockroachdb-adapter.gemspec +2 -2
- data/build/Dockerfile +17 -0
- data/build/config.teamcity.yml +28 -0
- data/build/local-test.sh +38 -0
- data/build/teamcity-test.sh +82 -0
- data/docker.sh +38 -0
- data/lib/active_record/connection_adapters/cockroachdb/referential_integrity.rb +54 -0
- data/lib/active_record/connection_adapters/cockroachdb/schema_statements.rb +58 -0
- data/lib/active_record/connection_adapters/cockroachdb/transaction_manager.rb +31 -0
- data/lib/active_record/connection_adapters/cockroachdb_adapter.rb +259 -105
- metadata +15 -12
- data/.travis.yml +0 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 96a284c08e5798cc8b45332be543b14f60bdb8c0
|
4
|
+
data.tar.gz: ffa757e8b581788ba8d1880842d37eca7058695e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 456d42bc6a8a973488a6c66a9631d8e78f7e4a35abb379b3958239b6fb474bce9a3503678be6a098d788bb09425c02d30732fb1ee546b3d4c2b8cb21b3a7fe57
|
7
|
+
data.tar.gz: 40ada5999c613d6d2f953ce7fc99b9fbb3793685d258fe9cef790e2421df96d218ee3684081a499571ed38cc129be6e65de6a87328d57297fdd62323430c61c6
|
data/.gitmodules
ADDED
data/CONTRIBUTING.md
ADDED
@@ -0,0 +1,248 @@
|
|
1
|
+
# Getting started
|
2
|
+
|
3
|
+
|
4
|
+
## ActiveRecord adapters and you
|
5
|
+
|
6
|
+
There are two repositories for the ActiveRecord adapter. The one you're in
|
7
|
+
currently, [activerecord-cockroachdb-adapter], is the CockroachDB specific
|
8
|
+
ActiveRecord code. Users install this alongside ActiveRecord then use
|
9
|
+
CockroachDBAdapter to initialize ActiveRecord for their projects.
|
10
|
+
|
11
|
+
This adapter extends the PostgreSQL ActiveRecord adapter in order to
|
12
|
+
override and monkey-patch functionality.
|
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
|
+
[activerecord-cockroachdb-adapter]: https://github.com/cockroachdb/activerecord-cockroachdb-adapter/
|
18
|
+
[Rails]: https://github.com/lego/ruby-on-rails
|
19
|
+
|
20
|
+
|
21
|
+
## Setup and running tests
|
22
|
+
|
23
|
+
It is best to have a Ruby environment manager installed, such as
|
24
|
+
[rvm](https://rvm.io/), as Rails has varying Ruby version requirements.
|
25
|
+
If you are using rvm, you then install and use the required Ruby
|
26
|
+
version. The current tests use Rails 5.2.0 beta and Ruby >= 2.2.2.
|
27
|
+
|
28
|
+
(Alternatively, one can use `./docker.sh build/teamcity-test.sh` to run
|
29
|
+
tests similarily to TeamCity. The database is destroyed between each
|
30
|
+
test file.)
|
31
|
+
|
32
|
+
|
33
|
+
```bash
|
34
|
+
rvm install 2.2.5
|
35
|
+
# This only makes Ruby 2.2.5 active for the length of the terminal session.
|
36
|
+
rvm use 2.2.5
|
37
|
+
```
|
38
|
+
|
39
|
+
Using [bundler](http://bundler.io/), install the dependancies of Rails.
|
40
|
+
Additionally, make sure the Rails git submodule is loaded.
|
41
|
+
|
42
|
+
```bash
|
43
|
+
# Ensure the rails fork is fetched.
|
44
|
+
git submodule update
|
45
|
+
# Install rails dependancies.
|
46
|
+
(cd rails && bundle install)
|
47
|
+
```
|
48
|
+
|
49
|
+
Then, to run the test with an active CockroachDB instance:
|
50
|
+
|
51
|
+
```bash
|
52
|
+
cp build/config.teamcity.yml rails/activerecord/test/config.yml
|
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)
|
55
|
+
```
|
56
|
+
|
57
|
+
### Test commands in detail
|
58
|
+
|
59
|
+
```bash
|
60
|
+
cp build/config.teamcity.yml rails/activerecord/test/config.yml
|
61
|
+
```
|
62
|
+
|
63
|
+
This copies the TeamCity ActiveRecord configuration for the application.
|
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
|
+
```
|
73
|
+
|
74
|
+
This prepares CockroachDB for running tests. It only drops and
|
75
|
+
re-creates all of the databases needed.
|
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)
|
89
|
+
```
|
90
|
+
|
91
|
+
This executes the CockroachDB tests.
|
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
|
+
|
99
|
+
|
100
|
+
# Improvements
|
101
|
+
|
102
|
+
|
103
|
+
## Support past Rails versions
|
104
|
+
|
105
|
+
Currently, only a beta version of Rails is tested. This means that the
|
106
|
+
adapter has been modified in to accomodate unreleased changes. In order
|
107
|
+
to run the tests for Rails 5.1 or 4.2, the test changes will need to be
|
108
|
+
cherry-picked back. Conflicts are mostly only expected for tests that
|
109
|
+
have not yet been added.
|
110
|
+
|
111
|
+
Sadly, this does mean that we will have to have multiple versions of the
|
112
|
+
driver for the multiple versions of Rails.
|
113
|
+
|
114
|
+
A proposal for the CockroachDB adapter versioning would be to follow
|
115
|
+
ActiveRecord minor versions. For example, if you use Rails 4.2.5, you
|
116
|
+
would specify the CockroachDB version `~> 4.2.0`.
|
117
|
+
|
118
|
+
|
119
|
+
## Running CI automatically
|
120
|
+
|
121
|
+
Currently the fork is set up to run using TeamCity only on the current
|
122
|
+
master branch, with an alpha build of CockroachDB. it would be even
|
123
|
+
better to be able to test multiple versions of the adapter, and do so
|
124
|
+
against different versions of CockroachDB.
|
125
|
+
|
126
|
+
|
127
|
+
## Adding feature support
|
128
|
+
|
129
|
+
As CockroachDB improves, so do the features that can be supported in
|
130
|
+
ActiveRecord. Many of them are gated by conditions the
|
131
|
+
CockroachDBAdapter has overrided. As these features are completed, these
|
132
|
+
gates should be toggled. Something that would help this process would be
|
133
|
+
linking those issues back to this adapter so that part of the feature
|
134
|
+
completing includes updating the adapter.
|
135
|
+
|
136
|
+
|
137
|
+
## Execute only tests that run with a connection
|
138
|
+
|
139
|
+
I have not investigated if this is already possible, but I would assume
|
140
|
+
no.
|
141
|
+
|
142
|
+
A possible way to approach this would be to add a shim to cause any
|
143
|
+
tests that use it to fail, and grep the tests that pass and then skip
|
144
|
+
them.
|
145
|
+
|
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
|
+
## Publishing to Rubygems
|
156
|
+
|
157
|
+
TODO: Expand on this. Jordan is likely the only person with publishing
|
158
|
+
credentials. I'm not sure if there is anything else other than:
|
159
|
+
|
160
|
+
```
|
161
|
+
gem build ...
|
162
|
+
gem publish <output file>
|
163
|
+
```
|
164
|
+
|
165
|
+
|
166
|
+
# Notes
|
167
|
+
|
168
|
+
When executing the test suite, each test file will reload fixtures. This
|
169
|
+
drops and creates about 200 tables (2 databases, 100 tables each).
|
170
|
+
Currently there are performance problems that rise from having lots of
|
171
|
+
table descriptors around, [cockroachdb/cockroach#20753]. At best, we can
|
172
|
+
run test files individually, clear out the CockroachDB data, and restart
|
173
|
+
the node to alleviate this.
|
174
|
+
|
175
|
+
Currently, annotations have been added to test files to indicate if it
|
176
|
+
is failing, and some brief details on why. Any annotated failures have
|
177
|
+
been skipped right now for further investigation. The pattern is the
|
178
|
+
following:
|
179
|
+
|
180
|
+
`# FILE(OK)` indicates that the file is currently passing, with no skips
|
181
|
+
required.
|
182
|
+
|
183
|
+
`# FILE(BAD)` indicates that there are failures that have been skipped.
|
184
|
+
These skips will look like `skip(reason) if current_adapter?(:CockroachDBAdapter)`.
|
185
|
+
|
186
|
+
`# FILE(BROKEN)` indicates that there are failures that have not been
|
187
|
+
skipped. This is often done if the entirety of a test file is
|
188
|
+
unsupported.
|
189
|
+
|
190
|
+
`# FILE(NOT DONE)` indicates files that have not yet been executed,
|
191
|
+
cleaned up, or skipped until passing.
|
192
|
+
|
193
|
+
The purpose of these was to make the tests grep-able while going through
|
194
|
+
all the failures.
|
195
|
+
|
196
|
+
|
197
|
+
[cockroachdb/cockroach#20753]: https://github.com/cockroachdb/cockroach/issues/20753#issuecomment-352810425
|
198
|
+
|
199
|
+
|
200
|
+
## Tracked test failures
|
201
|
+
|
202
|
+
Some of the skipped failures are:
|
203
|
+
|
204
|
+
- `default:` key is not working for columns in table schema
|
205
|
+
definitions. This causes tests to fail due to unexpected data.
|
206
|
+
|
207
|
+
- `array:` key is not working for columns in table schema definitions.
|
208
|
+
|
209
|
+
- `"Salary is not appearing in list"` is being raised in a number of
|
210
|
+
places. Likely during fixture setup.
|
211
|
+
|
212
|
+
- `sum` function seems to result in a different type in ActiveRecord.
|
213
|
+
Instead of returning a Ruby `int`, it returns a Ruby `string`. It
|
214
|
+
appears that MySQL2 also does this. A suspected cause might be how
|
215
|
+
`Decimal` is handled if `sum` consumes integers and return a
|
216
|
+
decimal.
|
217
|
+
|
218
|
+
- Potentially fork the PostgreSQL::SchemaDumper to handle anything
|
219
|
+
specific to CockroachDB, like primary keys or bigints.
|
220
|
+
|
221
|
+
- You can call `@connection.create_table(..., id: :bigint)`, but this
|
222
|
+
will not changes things for CockroachDB (I think...), so it would be
|
223
|
+
not allowed. Even better, our adapter could interpret this and
|
224
|
+
generate the appropriate explicit pkey column. Not sure what string
|
225
|
+
pkeys look like...
|
226
|
+
|
227
|
+
- `string` types are introspected to `text` types.
|
228
|
+
|
229
|
+
- A user can do an update, delete, and insert on views.
|
230
|
+
|
231
|
+
- Postgres specific bit strings are not properly supported.
|
232
|
+
|
233
|
+
Grepping for `FIXME(joey)`, `TODO(joey)`, and `NOTE(joey)` will yeild
|
234
|
+
most of the touchpoints including test failures and temporary monkey
|
235
|
+
patches. Some monkey patches were made directly to Rails, which will
|
236
|
+
need to be cleaned up.
|
237
|
+
|
238
|
+
|
239
|
+
# Notes for the non-Rubyer
|
240
|
+
|
241
|
+
rvm is an environment manager that lets you manage and swap between
|
242
|
+
multiple verisons of Ruby and their dependancies.
|
243
|
+
|
244
|
+
bundle is dependancy manager that uses a projects `Gemfile` (and often
|
245
|
+
`<project>.gemspec`) to manage and load dependancies and their required
|
246
|
+
versions. When using projects commands are prefixed with
|
247
|
+
`bundle exec ...`. Bundle will ensure that all depenedncies are fetched
|
248
|
+
and used.
|
data/Gemfile
CHANGED
@@ -1,4 +1,11 @@
|
|
1
1
|
source 'https://rubygems.org'
|
2
2
|
|
3
|
+
# gem 'activerecord', git: 'https://github.com/lego/ruby-on-rails.git'
|
4
|
+
|
5
|
+
git_source(:github) { |repo| "https://github.com/#{repo}.git" }
|
6
|
+
|
3
7
|
# Specify your gem's dependencies in activerecord-cockroachdb-adapter.gemspec
|
4
8
|
gemspec
|
9
|
+
|
10
|
+
# We need a newish Rake since Active Job sets its test tasks' descriptions.
|
11
|
+
gem "rake", ">= 11.1"
|
data/README.md
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# ActiveRecord CockroachDB Adapter
|
2
2
|
|
3
|
-
CockroachDB adapter for ActiveRecord 5. This is a lightweight extension of the PostgreSQL adapter that establishes compatibility with [CockroachDB](https://github.com/cockroachdb/cockroach).
|
3
|
+
CockroachDB adapter for ActiveRecord 4 and 5. This is a lightweight extension of the PostgreSQL adapter that establishes compatibility with [CockroachDB](https://github.com/cockroachdb/cockroach).
|
4
4
|
|
5
5
|
## Installation
|
6
6
|
|
@@ -10,10 +10,20 @@ Add this line to your project's Gemfile:
|
|
10
10
|
gem 'activerecord-cockroachdb-adapter', '~> 0.2.2'
|
11
11
|
```
|
12
12
|
|
13
|
+
If you're using Rails 4.x, use the `0.1.x` versions of this gem.
|
14
|
+
|
13
15
|
In `database.yml`, use the following adapter setting:
|
14
16
|
|
15
17
|
```
|
16
18
|
development:
|
17
19
|
adapter: cockroachdb
|
18
20
|
port: 26257
|
21
|
+
host: <hostname>
|
22
|
+
user: <username>
|
19
23
|
```
|
24
|
+
|
25
|
+
|
26
|
+
## Modifying the adapter?
|
27
|
+
|
28
|
+
See [CONTRIBUTING.md](/CONTRIBUTING.md) for more details on setting up
|
29
|
+
the environment and making modifications.
|
@@ -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.2.
|
7
|
+
spec.version = "0.2.3"
|
8
8
|
spec.licenses = ["Apache-2.0"]
|
9
9
|
spec.authors = ["Cockroach Labs"]
|
10
10
|
spec.email = ["cockroach-db@googlegroups.com"]
|
@@ -13,7 +13,7 @@ Gem::Specification.new do |spec|
|
|
13
13
|
spec.description = "Allows the use of CockroachDB as a backend for ActiveRecord and Rails apps."
|
14
14
|
spec.homepage = "https://github.com/cockroachdb/activerecord-cockroachdb-adapter"
|
15
15
|
|
16
|
-
spec.add_dependency "activerecord", "~> 5.
|
16
|
+
spec.add_dependency "activerecord", "~> 5.2"
|
17
17
|
spec.add_dependency "pg", ">= 0.20", "< 0.22"
|
18
18
|
|
19
19
|
# Prevent pushing this gem to RubyGems.org. To allow pushes either set the 'allowed_push_host'
|
data/build/Dockerfile
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
# This Dockerfile extends the Examples-ORM testing image in order to
|
2
|
+
# install specific dependencies required for ActiveRecord tests.
|
3
|
+
|
4
|
+
FROM cockroachdb/postgres-test:20170308-1644
|
5
|
+
|
6
|
+
# Native dependencies for libxml-ruby and sqlite3.
|
7
|
+
RUN apt-get update -y && apt-get install -y \
|
8
|
+
libxslt-dev \
|
9
|
+
libxml2-dev \
|
10
|
+
libsqlite3-dev \
|
11
|
+
&& rm -rf /var/lib/apt/lists/*
|
12
|
+
|
13
|
+
# Ruby testing dependencies.
|
14
|
+
RUN gem install bundle rake
|
15
|
+
|
16
|
+
# Add global Gem binaries to the path.
|
17
|
+
ENV PATH /usr/local/lib/ruby/gems/2.4.0::$PATH
|
@@ -0,0 +1,28 @@
|
|
1
|
+
default_connection: cockroachdb
|
2
|
+
|
3
|
+
with_manual_interventions: false
|
4
|
+
|
5
|
+
connections:
|
6
|
+
cockroachdb:
|
7
|
+
arunit:
|
8
|
+
database: activerecord_unittest
|
9
|
+
host: localhost
|
10
|
+
port: 26257
|
11
|
+
user: root
|
12
|
+
requiressl: disable
|
13
|
+
min_messages: warning
|
14
|
+
arunit_without_prepared_statements:
|
15
|
+
database: activerecord_unittest
|
16
|
+
host: localhost
|
17
|
+
port: 26257
|
18
|
+
user: root
|
19
|
+
requiressl: disable
|
20
|
+
min_messages: warning
|
21
|
+
prepared_statements: false
|
22
|
+
arunit2:
|
23
|
+
database: activerecord_unittest2
|
24
|
+
host: localhost
|
25
|
+
port: 26257
|
26
|
+
user: root
|
27
|
+
requiressl: disable
|
28
|
+
min_messages: warning
|
data/build/local-test.sh
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
#!/usr/bin/env bash
|
2
|
+
|
3
|
+
set -euo pipefail
|
4
|
+
|
5
|
+
readonly urlfile=cockroach-url
|
6
|
+
|
7
|
+
# Start a CockroachDB server, wait for it to become ready, and arrange for it to
|
8
|
+
# be force-killed when the script exits.
|
9
|
+
rm -f "$urlfile"
|
10
|
+
# Clean out a past CockroachDB instance. This happens if a build was
|
11
|
+
# canceled on an agent.
|
12
|
+
rm -rf $HOME/tmp/rails &
|
13
|
+
# Start CockroachDB.
|
14
|
+
cockroach quit --insecure || true
|
15
|
+
cockroach start --insecure --host=localhost --listening-url-file="$urlfile" --store=path=$HOME/tmp/rails &
|
16
|
+
trap "echo 'Exit routine: Killing CockroachDB.' && kill -9 $! &> /dev/null" EXIT
|
17
|
+
for i in {0..3}
|
18
|
+
do
|
19
|
+
[[ -f "$urlfile" ]] && break
|
20
|
+
backoff=$((2 ** i))
|
21
|
+
echo "server not yet available; sleeping for $backoff seconds"
|
22
|
+
sleep $backoff
|
23
|
+
done
|
24
|
+
|
25
|
+
# Target the Rails dependency file.
|
26
|
+
export BUNDLE_GEMFILE=$(pwd)/rails/Gemfile
|
27
|
+
|
28
|
+
# Run the tests.
|
29
|
+
cp build/config.teamcity.yml rails/activerecord/test/config.yml
|
30
|
+
echo "Rebuilding database"
|
31
|
+
(cd rails/activerecord && bundle exec rake db:cockroachdb:rebuild)
|
32
|
+
echo "Starting tests"
|
33
|
+
(cd rails/activerecord && bundle exec rake test:cockroachdb TESTFILES=$1)
|
34
|
+
|
35
|
+
# Attempt a clean shutdown for good measure. We'll force-kill in the atexit
|
36
|
+
# handler if this fails.
|
37
|
+
cockroach quit --insecure
|
38
|
+
trap - EXIT
|
@@ -0,0 +1,82 @@
|
|
1
|
+
#!/usr/bin/env bash
|
2
|
+
|
3
|
+
set -euo pipefail
|
4
|
+
|
5
|
+
# Download CockroachDB. NB: currently this uses an alpha, due to feature
|
6
|
+
# requirements.
|
7
|
+
VERSION=v2.0-alpha.20171218
|
8
|
+
wget -qO- https://binaries.cockroachdb.com/cockroach-$VERSION.linux-amd64.tgz | tar xvz
|
9
|
+
readonly COCKROACH=./cockroach-$VERSION.linux-amd64/cockroach
|
10
|
+
|
11
|
+
# Make sure cockroach can be found on the path. This is required for the
|
12
|
+
# ActiveRecord Rakefile that rebuilds the test database.
|
13
|
+
export PATH=$(pwd)/cockroach-$VERSION.linux-amd64/:$PATH
|
14
|
+
readonly urlfile=cockroach-url
|
15
|
+
|
16
|
+
run_cockroach() {
|
17
|
+
# Start a CockroachDB server, wait for it to become ready, and arrange
|
18
|
+
# for it to be force-killed when the script exits.
|
19
|
+
rm -f "$urlfile"
|
20
|
+
# Clean out a past CockroachDB instance. This will clean out leftovers
|
21
|
+
# from the build agent, and also between CockroachDB runs.
|
22
|
+
cockroach quit --insecure || true
|
23
|
+
rm -rf cockroach-data
|
24
|
+
# Start CockroachDB.
|
25
|
+
cockroach start --insecure --host=localhost --listening-url-file="$urlfile" >/dev/null 2>&1 &
|
26
|
+
# Ensure CockroachDB is stopped on script exit.
|
27
|
+
trap "echo 'Exit routine: Killing CockroachDB.' && kill -9 $! &> /dev/null" EXIT
|
28
|
+
# Wait until CockroachDB has started.
|
29
|
+
for i in {0..3}; do
|
30
|
+
[[ -f "$urlfile" ]] && break
|
31
|
+
backoff=$((2 ** i))
|
32
|
+
echo "server not yet available; sleeping for $backoff seconds"
|
33
|
+
sleep $backoff
|
34
|
+
done
|
35
|
+
}
|
36
|
+
|
37
|
+
# Target the Rails dependency file.
|
38
|
+
export BUNDLE_GEMFILE=$(pwd)/rails/Gemfile
|
39
|
+
|
40
|
+
# Install ruby dependencies.
|
41
|
+
bundle install
|
42
|
+
|
43
|
+
cp build/config.teamcity.yml rails/activerecord/test/config.yml
|
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
|
54
|
+
|
55
|
+
# Get the test files with "# FILE(OK)". These should pass.
|
56
|
+
TESTS=$(cd rails/activerecord && find test/cases -type f \( -name "*_test.rb" \) -exec grep -l "# FILE(OK)" {} +)
|
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"
|
68
|
+
HAS_FAILED=1
|
69
|
+
else
|
70
|
+
echo "Test PASSED: $TESTFILE"
|
71
|
+
HAS_FAILED=0
|
72
|
+
fi
|
73
|
+
done
|
74
|
+
|
75
|
+
# Attempt a clean shutdown for good measure. We'll force-kill in the
|
76
|
+
# exit trap if this script fails.
|
77
|
+
cockroach quit --insecure
|
78
|
+
trap - EXIT
|
79
|
+
|
80
|
+
if [ $HAS_FAILED -eq 1 ]; then
|
81
|
+
exit 1
|
82
|
+
fi
|
data/docker.sh
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
#!/bin/bash
|
2
|
+
#
|
3
|
+
# This file is largely cargo-culted from cockroachdb/cockroach/build/builder.sh.
|
4
|
+
|
5
|
+
set -euo pipefail
|
6
|
+
|
7
|
+
DOCKER_IMAGE_TAG=activerecord_test_container
|
8
|
+
|
9
|
+
# Build the docker image to use.
|
10
|
+
docker build -t ${DOCKER_IMAGE_TAG} build/
|
11
|
+
|
12
|
+
# Absolute path to this repository.
|
13
|
+
repo_root=$(cd "$(dirname "${0}")" && pwd)
|
14
|
+
|
15
|
+
# Make a fake passwd file for the invoking user.
|
16
|
+
#
|
17
|
+
# This setup is so that files created from inside the container in a mounted
|
18
|
+
# volume end up being owned by the invoking user and not by root.
|
19
|
+
# We'll mount a fresh directory owned by the invoking user as /root inside the
|
20
|
+
# container because the container needs a $HOME (without one the default is /)
|
21
|
+
# and because various utilities (e.g. bash writing to .bash_history) need to be
|
22
|
+
# able to write to there.
|
23
|
+
username=$(id -un)
|
24
|
+
uid_gid=$(id -u):$(id -g)
|
25
|
+
container_root=${repo_root}/docker_root
|
26
|
+
mkdir -p "${container_root}"/{etc,home,home/"${username}"/activerecord-cockroachdb-adapter,home/.gems}
|
27
|
+
echo "${username}:x:${uid_gid}::/home/${username}:/bin/bash" > "${container_root}/etc/passwd"
|
28
|
+
|
29
|
+
docker run \
|
30
|
+
--volume="${container_root}/etc/passwd:/etc/passwd" \
|
31
|
+
--volume="${container_root}/home/${username}:/home/${username}" \
|
32
|
+
--volume="${repo_root}:/home/${username}/activerecord-cockroachdb-adapter" \
|
33
|
+
--workdir="/home/${username}/activerecord-cockroachdb-adapter" \
|
34
|
+
--env=PIP_USER=1 \
|
35
|
+
--env=GEM_HOME="/home/${username}/.gems" \
|
36
|
+
--user="${uid_gid}" \
|
37
|
+
"${DOCKER_IMAGE_TAG}" \
|
38
|
+
"$@"
|
@@ -0,0 +1,54 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
# NOTE(joey): This is cradled from connection_adapters/postgresql/referential_integrity.rb
|
3
|
+
# It is commonly used for setting up fixtures during tests.
|
4
|
+
module ActiveRecord
|
5
|
+
module ConnectionAdapters
|
6
|
+
module CockroachDB
|
7
|
+
module ReferentialIntegrity # :nodoc:
|
8
|
+
def disable_referential_integrity # :nodoc:
|
9
|
+
original_exception = nil
|
10
|
+
fkeys = nil
|
11
|
+
|
12
|
+
begin
|
13
|
+
transaction do
|
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
|
23
|
+
end
|
24
|
+
|
25
|
+
begin
|
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
|
39
|
+
|
40
|
+
begin
|
41
|
+
transaction do
|
42
|
+
if !fkeys.nil?
|
43
|
+
fkeys.each do |fkey|
|
44
|
+
add_foreign_key fkey.from_table, fkey.to_table, fkey.options
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
rescue ActiveRecord::ActiveRecordError
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
require 'active_record/connection_adapters/postgresql/schema_statements'
|
2
|
+
|
3
|
+
module ActiveRecord
|
4
|
+
module ConnectionAdapters
|
5
|
+
module CockroachDB
|
6
|
+
module SchemaStatements
|
7
|
+
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
|
+
|
18
|
+
pk ||= default_pk
|
19
|
+
sequence ||= default_sequence
|
20
|
+
end
|
21
|
+
|
22
|
+
if @logger && pk && !sequence
|
23
|
+
@logger.warn "#{table} has primary key #{pk} with no default sequence."
|
24
|
+
end
|
25
|
+
|
26
|
+
if pk && sequence
|
27
|
+
quoted_sequence = quote_table_name(sequence)
|
28
|
+
max_pk = query_value("SELECT MAX(#{quote_column_name pk}) FROM #{quote_table_name(table)}", "SCHEMA")
|
29
|
+
if max_pk.nil?
|
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")
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'active_record/connection_adapters/abstract/transaction'
|
4
|
+
|
5
|
+
module ActiveRecord
|
6
|
+
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
|
+
module CockroachDB
|
14
|
+
module TransactionManagerMonkeyPatch
|
15
|
+
def begin_transaction(options={})
|
16
|
+
@connection.lock.synchronize do
|
17
|
+
# If the transaction nesting is already 2 deep, raise an error.
|
18
|
+
if @connection.adapter_name == "CockroachDB" && @stack.is_a?(ActiveRecord::ConnectionAdapters::SavepointTransaction)
|
19
|
+
raise(ArgumentError, "cannot nest more than 1 transaction at a time. this is a CockroachDB limitation")
|
20
|
+
end
|
21
|
+
end
|
22
|
+
super(options)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
class TransactionManager
|
28
|
+
prepend CockroachDB::TransactionManagerMonkeyPatch
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -1,4 +1,8 @@
|
|
1
1
|
require 'active_record/connection_adapters/postgresql_adapter'
|
2
|
+
require "active_record/connection_adapters/postgresql/schema_statements"
|
3
|
+
require "active_record/connection_adapters/cockroachdb/schema_statements"
|
4
|
+
require "active_record/connection_adapters/cockroachdb/referential_integrity"
|
5
|
+
require "active_record/connection_adapters/cockroachdb/transaction_manager"
|
2
6
|
|
3
7
|
module ActiveRecord
|
4
8
|
module ConnectionHandling
|
@@ -13,7 +17,7 @@ module ActiveRecord
|
|
13
17
|
conn_params[:dbname] = conn_params.delete(:database) if conn_params[:database]
|
14
18
|
|
15
19
|
# Forward only valid config params to PG::Connection.connect.
|
16
|
-
valid_conn_param_keys = PG::Connection.conndefaults_hash.keys + [:
|
20
|
+
valid_conn_param_keys = PG::Connection.conndefaults_hash.keys + [:sslmode, :application_name]
|
17
21
|
conn_params.slice!(*valid_conn_param_keys)
|
18
22
|
|
19
23
|
# The postgres drivers don't allow the creation of an unconnected
|
@@ -24,125 +28,275 @@ module ActiveRecord
|
|
24
28
|
end
|
25
29
|
end
|
26
30
|
|
27
|
-
|
28
|
-
|
31
|
+
module ActiveRecord
|
32
|
+
module ConnectionAdapters
|
33
|
+
class CockroachDBAdapter < PostgreSQLAdapter
|
34
|
+
ADAPTER_NAME = "CockroachDB".freeze
|
29
35
|
|
30
|
-
|
31
|
-
|
32
|
-
# To ensure backward compatibility with both <5.1 and 5.1, we rename it here
|
33
|
-
# to use the same original `Utils` module.
|
34
|
-
Utils = ActiveRecord::ConnectionAdapters::PostgreSQL::Utils
|
36
|
+
include CockroachDB::SchemaStatements
|
37
|
+
include CockroachDB::ReferentialIntegrity
|
35
38
|
|
36
|
-
def supports_json?
|
37
|
-
false
|
38
|
-
end
|
39
39
|
|
40
|
-
|
41
|
-
|
42
|
-
|
40
|
+
# Note that in the migration from ActiveRecord 5.0 to 5.1, the
|
41
|
+
# `extract_schema_qualified_name` method was aliased in the PostgreSQLAdapter.
|
42
|
+
# To ensure backward compatibility with both <5.1 and 5.1, we rename it here
|
43
|
+
# to use the same original `Utils` module.
|
44
|
+
Utils = PostgreSQL::Utils
|
43
45
|
|
44
|
-
|
45
|
-
|
46
|
-
|
46
|
+
def supports_json?
|
47
|
+
# FIXME(joey): Add a version check.
|
48
|
+
true
|
49
|
+
end
|
47
50
|
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
+
def supports_ddl_transactions?
|
52
|
+
false
|
53
|
+
end
|
51
54
|
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
+
def supports_extensions?
|
56
|
+
false
|
57
|
+
end
|
55
58
|
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
+
def supports_ranges?
|
60
|
+
# See cockroachdb/cockroach#17022
|
61
|
+
false
|
62
|
+
end
|
59
63
|
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
64
|
+
def supports_materialized_views?
|
65
|
+
false
|
66
|
+
end
|
67
|
+
|
68
|
+
def supports_pg_crypto_uuid?
|
69
|
+
false
|
70
|
+
end
|
71
|
+
|
72
|
+
def supports_partial_index?
|
73
|
+
# See cockroachdb/cockroach#9683
|
74
|
+
false
|
75
|
+
end
|
76
|
+
|
77
|
+
def supports_expression_index?
|
78
|
+
# See cockroachdb/cockroach#9682
|
79
|
+
false
|
80
|
+
end
|
81
|
+
|
82
|
+
def supports_datetime_with_precision?
|
83
|
+
false
|
84
|
+
end
|
85
|
+
|
86
|
+
def supports_comments?
|
87
|
+
# See cockroachdb/cockroach#19472.
|
88
|
+
false
|
89
|
+
end
|
90
|
+
|
91
|
+
def supports_comments_in_create?
|
92
|
+
# See cockroachdb/cockroach#19472.
|
93
|
+
false
|
94
|
+
end
|
95
|
+
|
96
|
+
def supports_advisory_locks?
|
97
|
+
# FIXME(joey): We may want to make this false.
|
98
|
+
true
|
99
|
+
end
|
100
|
+
|
101
|
+
def supports_virtual_columns?
|
102
|
+
# See cockroachdb/cockroach#20882.
|
103
|
+
false
|
104
|
+
end
|
71
105
|
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
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
|
106
158
|
SQL
|
107
159
|
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
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
|
112
197
|
end
|
113
198
|
|
114
|
-
ActiveRecord::ConnectionAdapters::IndexDefinition.new(table_name, index_name, unique, columns, [], orders, where, nil, nil, comment.presence)
|
115
|
-
end.compact
|
116
|
-
end
|
117
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
|
118
215
|
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
216
|
+
# This is hardcoded to 63 (as previously was in ActiveRecord 5.0) to aid in
|
217
|
+
# migration from PostgreSQL to CockroachDB. In practice, this limitation
|
218
|
+
# is arbitrary since CockroachDB supports index name lengths and table alias
|
219
|
+
# lengths far greater than this value. For the time being though, we match
|
220
|
+
# the original behavior for PostgreSQL to simplify migrations.
|
221
|
+
#
|
222
|
+
# Note that in the migration to ActiveRecord 5.1, this was changed in
|
223
|
+
# PostgreSQLAdapter to use `SHOW max_identifier_length` (which does not
|
224
|
+
# exist in CockroachDB). Therefore, we have to redefine this here.
|
225
|
+
def max_identifier_length
|
226
|
+
63
|
227
|
+
end
|
228
|
+
alias index_name_length max_identifier_length
|
229
|
+
alias table_alias_length max_identifier_length
|
230
|
+
|
231
|
+
private
|
232
|
+
|
233
|
+
def initialize_type_map(m = type_map)
|
234
|
+
super(m)
|
235
|
+
# NOTE(joey): PostgreSQL intervals have a precision.
|
236
|
+
# CockroachDB intervals do not, so overide the type
|
237
|
+
# definition. Returning a ArgumentError may not be correct.
|
238
|
+
# This needs to be tested.
|
239
|
+
m.register_type "interval" do |_, _, sql_type|
|
240
|
+
precision = extract_precision(sql_type)
|
241
|
+
if precision
|
242
|
+
raise(ArgumentError, "CockroachDB does not support precision on intervals, but got precision: #{precision}")
|
243
|
+
end
|
244
|
+
OID::SpecializedString.new(:interval, precision: precision)
|
245
|
+
end
|
246
|
+
end
|
247
|
+
|
248
|
+
# Configures the encoding, verbosity, schema search path, and time zone of the connection.
|
249
|
+
# This is called by #connect and should not be called manually.
|
250
|
+
#
|
251
|
+
# NOTE(joey): This was cradled from postgresql_adapter.rb. This
|
252
|
+
# was due to needing to override configuration statements.
|
253
|
+
def configure_connection
|
254
|
+
if @config[:encoding]
|
255
|
+
@connection.set_client_encoding(@config[:encoding])
|
256
|
+
end
|
257
|
+
self.client_min_messages = @config[:min_messages] || "warning"
|
258
|
+
self.schema_search_path = @config[:schema_search_path] || @config[:schema_order]
|
259
|
+
|
260
|
+
# Use standard-conforming strings so we don't have to do the E'...' dance.
|
261
|
+
set_standard_conforming_strings
|
134
262
|
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
263
|
+
variables = @config.fetch(:variables, {}).stringify_keys
|
264
|
+
|
265
|
+
# If using Active Record's time zone support configure the connection to return
|
266
|
+
# TIMESTAMP WITH ZONE types in UTC.
|
267
|
+
unless variables["timezone"]
|
268
|
+
if ActiveRecord::Base.default_timezone == :utc
|
269
|
+
variables["timezone"] = "UTC"
|
270
|
+
elsif @local_tz
|
271
|
+
variables["timezone"] = @local_tz
|
272
|
+
end
|
273
|
+
end
|
274
|
+
|
275
|
+
# NOTE(joey): This is a workaround as CockroachDB 1.1.x
|
276
|
+
# supports SET TIME ZONE <...> and SET "time zone" = <...> but
|
277
|
+
# not SET timezone = <...>.
|
278
|
+
if variables.key?("timezone")
|
279
|
+
tz = variables.delete("timezone")
|
280
|
+
execute("SET TIME ZONE #{quote(tz)}", "SCHEMA")
|
281
|
+
end
|
282
|
+
|
283
|
+
# SET statements from :variables config hash
|
284
|
+
# https://www.postgresql.org/docs/current/static/sql-set.html
|
285
|
+
variables.map do |k, v|
|
286
|
+
if v == ":default" || v == :default
|
287
|
+
# Sets the value to the global or compile default
|
288
|
+
|
289
|
+
# NOTE(joey): I am not sure if simply commenting this out
|
290
|
+
# is technically correct.
|
291
|
+
# execute("SET #{k} = DEFAULT", "SCHEMA")
|
292
|
+
elsif !v.nil?
|
293
|
+
execute("SET SESSION #{k} = #{quote(v)}", "SCHEMA")
|
294
|
+
end
|
295
|
+
end
|
296
|
+
end
|
297
|
+
|
298
|
+
|
299
|
+
# end private
|
300
|
+
end
|
146
301
|
end
|
147
|
-
alias index_name_length table_alias_length
|
148
302
|
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.2.
|
4
|
+
version: 0.2.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:
|
11
|
+
date: 2018-04-19 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|
@@ -16,20 +16,14 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '5.
|
20
|
-
- - ">="
|
21
|
-
- !ruby/object:Gem::Version
|
22
|
-
version: 5.1.1
|
19
|
+
version: '5.2'
|
23
20
|
type: :runtime
|
24
21
|
prerelease: false
|
25
22
|
version_requirements: !ruby/object:Gem::Requirement
|
26
23
|
requirements:
|
27
24
|
- - "~>"
|
28
25
|
- !ruby/object:Gem::Version
|
29
|
-
version: '5.
|
30
|
-
- - ">="
|
31
|
-
- !ruby/object:Gem::Version
|
32
|
-
version: 5.1.1
|
26
|
+
version: '5.2'
|
33
27
|
- !ruby/object:Gem::Dependency
|
34
28
|
name: pg
|
35
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -101,7 +95,8 @@ extensions: []
|
|
101
95
|
extra_rdoc_files: []
|
102
96
|
files:
|
103
97
|
- ".gitignore"
|
104
|
-
- ".
|
98
|
+
- ".gitmodules"
|
99
|
+
- CONTRIBUTING.md
|
105
100
|
- Gemfile
|
106
101
|
- LICENSE
|
107
102
|
- README.md
|
@@ -109,7 +104,15 @@ files:
|
|
109
104
|
- activerecord-cockroachdb-adapter.gemspec
|
110
105
|
- bin/console
|
111
106
|
- bin/setup
|
107
|
+
- build/Dockerfile
|
108
|
+
- build/config.teamcity.yml
|
109
|
+
- build/local-test.sh
|
110
|
+
- build/teamcity-test.sh
|
111
|
+
- docker.sh
|
112
112
|
- lib/active_record/connection_adapters/cockroachdb/database_tasks.rb
|
113
|
+
- lib/active_record/connection_adapters/cockroachdb/referential_integrity.rb
|
114
|
+
- lib/active_record/connection_adapters/cockroachdb/schema_statements.rb
|
115
|
+
- lib/active_record/connection_adapters/cockroachdb/transaction_manager.rb
|
113
116
|
- lib/active_record/connection_adapters/cockroachdb_adapter.rb
|
114
117
|
- lib/activerecord-cockroachdb-adapter.rb
|
115
118
|
homepage: https://github.com/cockroachdb/activerecord-cockroachdb-adapter
|
@@ -133,7 +136,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
133
136
|
version: '0'
|
134
137
|
requirements: []
|
135
138
|
rubyforge_project:
|
136
|
-
rubygems_version: 2.
|
139
|
+
rubygems_version: 2.5.2
|
137
140
|
signing_key:
|
138
141
|
specification_version: 4
|
139
142
|
summary: CockroachDB adapter for ActiveRecord.
|