activerecord-tidb-adapter 6.1.0 → 7.0.0
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/.buildkite/hooks/pre-command +10 -0
- data/.buildkite/pipeline.yml +7 -0
- data/.github/entrypoint.sh +16 -0
- data/.github/workflows/ci.yml +96 -0
- data/Gemfile +3 -1
- data/Gemfile.lock +104 -82
- data/README.md +49 -20
- data/activerecord-tidb-adapter.gemspec +2 -2
- data/config.toml +1 -0
- data/lib/active_record/connection_adapters/tidb/database_statements.rb +25 -0
- data/lib/active_record/connection_adapters/tidb/schema_statements.rb +71 -0
- data/lib/active_record/connection_adapters/tidb_adapter.rb +15 -27
- data/lib/version.rb +1 -1
- data/testing.sh +14 -0
- metadata +12 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 77b7efd6ea4bc98b6a72a6fb761aaab270881143f79eb362369b38e6cfa8965e
|
4
|
+
data.tar.gz: 878ca587a425ae2dd5fbe5bd2da03518b0dc7501c1b99a8c2f92c03fa39b1e19
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c8a5a80313df31083a7c0d54f8e2145ca148293f1844c644bb7530f77e1e73d736e9c79ae5c1d3b89d3b94fae5024bc565ec80a1cb659508e105a2894734c660
|
7
|
+
data.tar.gz: d6004fba604462b1358166c96ed905161dfb40c38285d9050ee0c42497ec6ad32bc897640b628cdc35a7c977d36688905d78a92d84308f7ce9bb76d8cf9171eb
|
@@ -0,0 +1,16 @@
|
|
1
|
+
#!/bin/bash
|
2
|
+
set -eu
|
3
|
+
service supervisor start
|
4
|
+
|
5
|
+
while sleep 60; do
|
6
|
+
ps aux |grep tidb |grep -q -v grep
|
7
|
+
TIDB_STATUS=$?
|
8
|
+
ps aux |grep tikv |grep -q -v grep
|
9
|
+
TIKV_STATUS=$?
|
10
|
+
# If the greps above find anything, they exit with 0 status
|
11
|
+
# If they are not both 0, then something is wrong
|
12
|
+
if [ $TIDB_STATUS -ne 0 -o $TIKV_STATUS -ne 0 ]; then
|
13
|
+
echo "One of the processes has already exited."
|
14
|
+
exit 1
|
15
|
+
fi
|
16
|
+
done
|
@@ -0,0 +1,96 @@
|
|
1
|
+
name: activerecord-tidb-adapter main
|
2
|
+
|
3
|
+
on:
|
4
|
+
push:
|
5
|
+
branches:
|
6
|
+
- main
|
7
|
+
- 7-0-stable
|
8
|
+
paths-ignore:
|
9
|
+
- 'README*.md'
|
10
|
+
- 'docs/**'
|
11
|
+
pull_request:
|
12
|
+
branches:
|
13
|
+
- main
|
14
|
+
- 7-0-stable
|
15
|
+
paths-ignore:
|
16
|
+
- 'README*.md'
|
17
|
+
- 'docs/**'
|
18
|
+
|
19
|
+
jobs:
|
20
|
+
tidb510:
|
21
|
+
if: ${{ !contains(github.event.commits[0].message, '[skip ci]') }}
|
22
|
+
runs-on: ubuntu-latest
|
23
|
+
services:
|
24
|
+
tidb:
|
25
|
+
image: hooopo/tidb-playground:v5.1.0
|
26
|
+
env:
|
27
|
+
TIDB_VERSION: v5.1.0
|
28
|
+
ports: ["4000:4000"]
|
29
|
+
steps:
|
30
|
+
- uses: actions/checkout@v2
|
31
|
+
- uses: ruby/setup-ruby@v1
|
32
|
+
with:
|
33
|
+
ruby-version: 2.7
|
34
|
+
bundler-cache: false
|
35
|
+
- run: bundle install
|
36
|
+
- run: sleep 30 && MYSQL_USER=root MYSQL_HOST=127.0.0.1 MYSQL_PORT=4000 tidb=1 ARCONN=tidb bundle exec rake db:tidb:build
|
37
|
+
- run: sleep 10 && MYSQL_USER=root MYSQL_HOST=127.0.0.1 MYSQL_PORT=4000 tidb=1 ARCONN=tidb bundle exec rake test:tidb
|
38
|
+
|
39
|
+
tidb503:
|
40
|
+
if: ${{ !contains(github.event.commits[0].message, '[skip ci]') }}
|
41
|
+
runs-on: ubuntu-latest
|
42
|
+
services:
|
43
|
+
tidb:
|
44
|
+
image: hooopo/tidb-playground:v5.0.3
|
45
|
+
env:
|
46
|
+
TIDB_VERSION: v5.0.3
|
47
|
+
ports: ["4000:4000"]
|
48
|
+
steps:
|
49
|
+
- uses: actions/checkout@v2
|
50
|
+
- uses: ruby/setup-ruby@v1
|
51
|
+
with:
|
52
|
+
ruby-version: 2.7
|
53
|
+
bundler-cache: false
|
54
|
+
- run: bundle install
|
55
|
+
- run: sleep 30 && MYSQL_USER=root MYSQL_HOST=127.0.0.1 MYSQL_PORT=4000 tidb=1 ARCONN=tidb bundle exec rake db:tidb:build
|
56
|
+
- run: mysql --host 127.0.0.1 --database activerecord_unittest --port 4000 -u root -e 'set @@global.tidb_enable_change_column_type = 1'
|
57
|
+
- run: mysql --host 127.0.0.1 --database activerecord_unittest2 --port 4000 -u root -e 'set @@global.tidb_enable_change_column_type = 1'
|
58
|
+
- run: sleep 10 && MYSQL_USER=root MYSQL_HOST=127.0.0.1 MYSQL_PORT=4000 tidb=1 ARCONN=tidb bundle exec rake test:tidb
|
59
|
+
|
60
|
+
tidb511:
|
61
|
+
if: ${{ !contains(github.event.commits[0].message, '[skip ci]') }}
|
62
|
+
runs-on: ubuntu-latest
|
63
|
+
services:
|
64
|
+
tidb:
|
65
|
+
image: hooopo/tidb-playground:v5.1.1
|
66
|
+
env:
|
67
|
+
TIDB_VERSION: v5.1.1
|
68
|
+
ports: ["4000:4000"]
|
69
|
+
steps:
|
70
|
+
- uses: actions/checkout@v2
|
71
|
+
- uses: ruby/setup-ruby@v1
|
72
|
+
with:
|
73
|
+
ruby-version: 2.7
|
74
|
+
bundler-cache: false
|
75
|
+
- run: bundle install
|
76
|
+
- run: sleep 30 && MYSQL_USER=root MYSQL_HOST=127.0.0.1 MYSQL_PORT=4000 tidb=1 ARCONN=tidb bundle exec rake db:tidb:build
|
77
|
+
- run: sleep 10 && MYSQL_USER=root MYSQL_HOST=127.0.0.1 MYSQL_PORT=4000 tidb=1 ARCONN=tidb bundle exec rake test:tidb
|
78
|
+
|
79
|
+
tidb520:
|
80
|
+
if: ${{ !contains(github.event.commits[0].message, '[skip ci]') }}
|
81
|
+
runs-on: ubuntu-latest
|
82
|
+
services:
|
83
|
+
tidb:
|
84
|
+
image: hooopo/tidb-playground:v5.2.0
|
85
|
+
env:
|
86
|
+
TIDB_VERSION: v5.2.0
|
87
|
+
ports: ["4000:4000"]
|
88
|
+
steps:
|
89
|
+
- uses: actions/checkout@v2
|
90
|
+
- uses: ruby/setup-ruby@v1
|
91
|
+
with:
|
92
|
+
ruby-version: 2.7
|
93
|
+
bundler-cache: false
|
94
|
+
- run: bundle install
|
95
|
+
- run: sleep 30 && MYSQL_USER=root MYSQL_HOST=127.0.0.1 MYSQL_PORT=4000 tidb=1 ARCONN=tidb bundle exec rake db:tidb:build
|
96
|
+
- run: sleep 10 && MYSQL_USER=root MYSQL_HOST=127.0.0.1 MYSQL_PORT=4000 tidb=1 ARCONN=tidb bundle exec rake test:tidb
|
data/Gemfile
CHANGED
@@ -14,10 +14,12 @@ gem 'pry'
|
|
14
14
|
|
15
15
|
gem 'rubocop', '~> 1.18'
|
16
16
|
|
17
|
-
gem 'rails', git: 'https://github.com/pingcap/rails.git', branch: '
|
17
|
+
gem 'rails', git: 'https://github.com/pingcap/rails.git', branch: '7-0-stable'
|
18
18
|
|
19
19
|
gem 'byebug', '~> 11.1'
|
20
20
|
|
21
21
|
gem 'sqlite3', '~> 1.4'
|
22
22
|
|
23
23
|
gem 'pg', '~> 1.2'
|
24
|
+
|
25
|
+
gem "benchmark-ips", "~> 2.9"
|
data/Gemfile.lock
CHANGED
@@ -1,126 +1,150 @@
|
|
1
1
|
GIT
|
2
2
|
remote: https://github.com/pingcap/rails.git
|
3
|
-
revision:
|
4
|
-
branch:
|
3
|
+
revision: 8e88c0ecd838d642c542e8246a0b7c6e9df9c806
|
4
|
+
branch: 7-0-stable
|
5
5
|
specs:
|
6
|
-
actioncable (
|
7
|
-
actionpack (=
|
8
|
-
activesupport (=
|
6
|
+
actioncable (7.0.2.3)
|
7
|
+
actionpack (= 7.0.2.3)
|
8
|
+
activesupport (= 7.0.2.3)
|
9
9
|
nio4r (~> 2.0)
|
10
10
|
websocket-driver (>= 0.6.1)
|
11
|
-
actionmailbox (
|
12
|
-
actionpack (=
|
13
|
-
activejob (=
|
14
|
-
activerecord (=
|
15
|
-
activestorage (=
|
16
|
-
activesupport (=
|
11
|
+
actionmailbox (7.0.2.3)
|
12
|
+
actionpack (= 7.0.2.3)
|
13
|
+
activejob (= 7.0.2.3)
|
14
|
+
activerecord (= 7.0.2.3)
|
15
|
+
activestorage (= 7.0.2.3)
|
16
|
+
activesupport (= 7.0.2.3)
|
17
17
|
mail (>= 2.7.1)
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
18
|
+
net-imap
|
19
|
+
net-pop
|
20
|
+
net-smtp
|
21
|
+
actionmailer (7.0.2.3)
|
22
|
+
actionpack (= 7.0.2.3)
|
23
|
+
actionview (= 7.0.2.3)
|
24
|
+
activejob (= 7.0.2.3)
|
25
|
+
activesupport (= 7.0.2.3)
|
23
26
|
mail (~> 2.5, >= 2.5.4)
|
27
|
+
net-imap
|
28
|
+
net-pop
|
29
|
+
net-smtp
|
24
30
|
rails-dom-testing (~> 2.0)
|
25
|
-
actionpack (
|
26
|
-
actionview (=
|
27
|
-
activesupport (=
|
28
|
-
rack (~> 2.0, >= 2.0
|
31
|
+
actionpack (7.0.2.3)
|
32
|
+
actionview (= 7.0.2.3)
|
33
|
+
activesupport (= 7.0.2.3)
|
34
|
+
rack (~> 2.0, >= 2.2.0)
|
29
35
|
rack-test (>= 0.6.3)
|
30
36
|
rails-dom-testing (~> 2.0)
|
31
37
|
rails-html-sanitizer (~> 1.0, >= 1.2.0)
|
32
|
-
actiontext (
|
33
|
-
actionpack (=
|
34
|
-
activerecord (=
|
35
|
-
activestorage (=
|
36
|
-
activesupport (=
|
38
|
+
actiontext (7.0.2.3)
|
39
|
+
actionpack (= 7.0.2.3)
|
40
|
+
activerecord (= 7.0.2.3)
|
41
|
+
activestorage (= 7.0.2.3)
|
42
|
+
activesupport (= 7.0.2.3)
|
43
|
+
globalid (>= 0.6.0)
|
37
44
|
nokogiri (>= 1.8.5)
|
38
|
-
actionview (
|
39
|
-
activesupport (=
|
45
|
+
actionview (7.0.2.3)
|
46
|
+
activesupport (= 7.0.2.3)
|
40
47
|
builder (~> 3.1)
|
41
48
|
erubi (~> 1.4)
|
42
49
|
rails-dom-testing (~> 2.0)
|
43
50
|
rails-html-sanitizer (~> 1.1, >= 1.2.0)
|
44
|
-
activejob (
|
45
|
-
activesupport (=
|
51
|
+
activejob (7.0.2.3)
|
52
|
+
activesupport (= 7.0.2.3)
|
46
53
|
globalid (>= 0.3.6)
|
47
|
-
activemodel (
|
48
|
-
activesupport (=
|
49
|
-
activerecord (
|
50
|
-
activemodel (=
|
51
|
-
activesupport (=
|
52
|
-
activestorage (
|
53
|
-
actionpack (=
|
54
|
-
activejob (=
|
55
|
-
activerecord (=
|
56
|
-
activesupport (=
|
57
|
-
marcel (~> 1.0
|
54
|
+
activemodel (7.0.2.3)
|
55
|
+
activesupport (= 7.0.2.3)
|
56
|
+
activerecord (7.0.2.3)
|
57
|
+
activemodel (= 7.0.2.3)
|
58
|
+
activesupport (= 7.0.2.3)
|
59
|
+
activestorage (7.0.2.3)
|
60
|
+
actionpack (= 7.0.2.3)
|
61
|
+
activejob (= 7.0.2.3)
|
62
|
+
activerecord (= 7.0.2.3)
|
63
|
+
activesupport (= 7.0.2.3)
|
64
|
+
marcel (~> 1.0)
|
58
65
|
mini_mime (>= 1.1.0)
|
59
|
-
activesupport (
|
66
|
+
activesupport (7.0.2.3)
|
60
67
|
concurrent-ruby (~> 1.0, >= 1.0.2)
|
61
68
|
i18n (>= 1.6, < 2)
|
62
69
|
minitest (>= 5.1)
|
63
70
|
tzinfo (~> 2.0)
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
activesupport (= 6.1.4)
|
71
|
+
rails (7.0.2.3)
|
72
|
+
actioncable (= 7.0.2.3)
|
73
|
+
actionmailbox (= 7.0.2.3)
|
74
|
+
actionmailer (= 7.0.2.3)
|
75
|
+
actionpack (= 7.0.2.3)
|
76
|
+
actiontext (= 7.0.2.3)
|
77
|
+
actionview (= 7.0.2.3)
|
78
|
+
activejob (= 7.0.2.3)
|
79
|
+
activemodel (= 7.0.2.3)
|
80
|
+
activerecord (= 7.0.2.3)
|
81
|
+
activestorage (= 7.0.2.3)
|
82
|
+
activesupport (= 7.0.2.3)
|
77
83
|
bundler (>= 1.15.0)
|
78
|
-
railties (=
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
activesupport (= 6.1.4)
|
84
|
+
railties (= 7.0.2.3)
|
85
|
+
railties (7.0.2.3)
|
86
|
+
actionpack (= 7.0.2.3)
|
87
|
+
activesupport (= 7.0.2.3)
|
83
88
|
method_source
|
84
|
-
rake (>=
|
89
|
+
rake (>= 12.2)
|
85
90
|
thor (~> 1.0)
|
91
|
+
zeitwerk (~> 2.5)
|
86
92
|
|
87
93
|
PATH
|
88
94
|
remote: .
|
89
95
|
specs:
|
90
|
-
activerecord-tidb-adapter (
|
91
|
-
activerecord (~>
|
96
|
+
activerecord-tidb-adapter (7.0.0)
|
97
|
+
activerecord (~> 7.0.1)
|
92
98
|
mysql2
|
93
99
|
|
94
100
|
GEM
|
95
101
|
remote: https://rubygems.org/
|
96
102
|
specs:
|
97
103
|
ast (2.4.2)
|
104
|
+
benchmark-ips (2.9.1)
|
98
105
|
builder (3.2.4)
|
99
106
|
byebug (11.1.3)
|
100
107
|
coderay (1.1.3)
|
101
|
-
concurrent-ruby (1.1.
|
108
|
+
concurrent-ruby (1.1.10)
|
102
109
|
crass (1.0.6)
|
110
|
+
digest (3.1.0)
|
103
111
|
erubi (1.10.0)
|
104
|
-
globalid (0.
|
112
|
+
globalid (1.0.0)
|
105
113
|
activesupport (>= 5.0)
|
106
|
-
i18n (1.
|
114
|
+
i18n (1.10.0)
|
107
115
|
concurrent-ruby (~> 1.0)
|
108
|
-
|
116
|
+
io-wait (0.2.1)
|
117
|
+
loofah (2.15.0)
|
109
118
|
crass (~> 1.0.2)
|
110
119
|
nokogiri (>= 1.5.9)
|
111
120
|
mail (2.7.1)
|
112
121
|
mini_mime (>= 0.1.1)
|
113
|
-
marcel (1.0.
|
122
|
+
marcel (1.0.2)
|
114
123
|
method_source (1.0.0)
|
115
|
-
mini_mime (1.1.
|
124
|
+
mini_mime (1.1.2)
|
116
125
|
minitest (5.14.4)
|
117
126
|
minitest-excludes (2.0.1)
|
118
127
|
minitest (~> 5.0)
|
119
128
|
mysql2 (0.5.3)
|
129
|
+
net-imap (0.2.3)
|
130
|
+
digest
|
131
|
+
net-protocol
|
132
|
+
strscan
|
133
|
+
net-pop (0.1.1)
|
134
|
+
digest
|
135
|
+
net-protocol
|
136
|
+
timeout
|
137
|
+
net-protocol (0.1.2)
|
138
|
+
io-wait
|
139
|
+
timeout
|
140
|
+
net-smtp (0.3.1)
|
141
|
+
digest
|
142
|
+
net-protocol
|
143
|
+
timeout
|
120
144
|
nio4r (2.5.8)
|
121
|
-
nokogiri (1.
|
145
|
+
nokogiri (1.13.3-x86_64-darwin)
|
122
146
|
racc (~> 1.4)
|
123
|
-
nokogiri (1.
|
147
|
+
nokogiri (1.13.3-x86_64-linux)
|
124
148
|
racc (~> 1.4)
|
125
149
|
parallel (1.20.1)
|
126
150
|
parser (3.0.2.0)
|
@@ -129,14 +153,14 @@ GEM
|
|
129
153
|
pry (0.14.1)
|
130
154
|
coderay (~> 1.1)
|
131
155
|
method_source (~> 1.0)
|
132
|
-
racc (1.
|
156
|
+
racc (1.6.0)
|
133
157
|
rack (2.2.3)
|
134
158
|
rack-test (1.1.0)
|
135
159
|
rack (>= 1.0, < 3)
|
136
160
|
rails-dom-testing (2.0.3)
|
137
161
|
activesupport (>= 4.2.0)
|
138
162
|
nokogiri (>= 1.6)
|
139
|
-
rails-html-sanitizer (1.4.
|
163
|
+
rails-html-sanitizer (1.4.2)
|
140
164
|
loofah (~> 2.3)
|
141
165
|
rainbow (3.0.0)
|
142
166
|
rake (13.0.6)
|
@@ -154,29 +178,27 @@ GEM
|
|
154
178
|
rubocop-ast (1.10.0)
|
155
179
|
parser (>= 3.0.1.1)
|
156
180
|
ruby-progressbar (1.11.0)
|
157
|
-
sprockets (4.0.2)
|
158
|
-
concurrent-ruby (~> 1.0)
|
159
|
-
rack (> 1, < 3)
|
160
|
-
sprockets-rails (3.2.2)
|
161
|
-
actionpack (>= 4.0)
|
162
|
-
activesupport (>= 4.0)
|
163
|
-
sprockets (>= 3.0.0)
|
164
181
|
sqlite3 (1.4.2)
|
165
|
-
|
182
|
+
strscan (3.0.1)
|
183
|
+
thor (1.2.1)
|
184
|
+
timeout (0.2.0)
|
166
185
|
tzinfo (2.0.4)
|
167
186
|
concurrent-ruby (~> 1.0)
|
168
187
|
unicode-display_width (2.0.0)
|
169
188
|
websocket-driver (0.7.5)
|
170
189
|
websocket-extensions (>= 0.1.0)
|
171
190
|
websocket-extensions (0.1.5)
|
172
|
-
zeitwerk (2.4
|
191
|
+
zeitwerk (2.5.4)
|
173
192
|
|
174
193
|
PLATFORMS
|
175
194
|
x86_64-darwin-18
|
195
|
+
x86_64-darwin-20
|
196
|
+
x86_64-darwin-21
|
176
197
|
x86_64-linux
|
177
198
|
|
178
199
|
DEPENDENCIES
|
179
200
|
activerecord-tidb-adapter!
|
201
|
+
benchmark-ips (~> 2.9)
|
180
202
|
byebug (~> 11.1)
|
181
203
|
minitest (~> 5.0)
|
182
204
|
minitest-excludes (~> 2.0)
|
@@ -188,4 +210,4 @@ DEPENDENCIES
|
|
188
210
|
sqlite3 (~> 1.4)
|
189
211
|
|
190
212
|
BUNDLED WITH
|
191
|
-
2.
|
213
|
+
2.3.10
|
data/README.md
CHANGED
@@ -1,6 +1,10 @@
|
|
1
1
|
# ActiveRecord TiDB Adapter
|
2
2
|
|
3
|
-
|
3
|
+
[](https://badge.fury.io/rb/activerecord-tidb-adapter)
|
4
|
+
[](https://github.com/pingcap/activerecord-tidb-adapter/actions/workflows/ci.yml)
|
5
|
+
|
6
|
+
TiDB adapter for ActiveRecord 5.2, 6.1 and 7.0
|
7
|
+
This is a lightweight extension of the mysql2 adapter that establishes compatibility with [TiDB](https://github.com/pingcap/tidb).
|
4
8
|
|
5
9
|
|
6
10
|
## Installation
|
@@ -8,9 +12,13 @@ TiDB adapter for ActiveRecord 5 and 6. This is a lightweight extension of the my
|
|
8
12
|
Add this line to your application's Gemfile:
|
9
13
|
|
10
14
|
```ruby
|
11
|
-
gem 'activerecord-tidb-adapter',
|
15
|
+
gem 'activerecord-tidb-adapter', '~> 6.1.0'
|
12
16
|
```
|
13
17
|
|
18
|
+
If you're using Rails 5.2, use the 5.2.x versions of this gem.
|
19
|
+
|
20
|
+
If you're using Rails 6.1, use the 6.1.x versions of this gem.
|
21
|
+
|
14
22
|
And then execute:
|
15
23
|
|
16
24
|
$ bundle install
|
@@ -68,24 +76,6 @@ class TestSeq < ActiveRecord::Migration[6.1]
|
|
68
76
|
end
|
69
77
|
```
|
70
78
|
|
71
|
-
Generated DDL
|
72
|
-
```sql
|
73
|
-
mysql> show create table orders_seq\G;
|
74
|
-
*************************** 1. row ***************************
|
75
|
-
Sequence: orders_seq
|
76
|
-
Create Sequence: CREATE SEQUENCE `orders_seq` start with 1024 minvalue 1 maxvalue 9223372036854775806 increment by 1 nocache nocycle ENGINE=InnoDB
|
77
|
-
|
78
|
-
mysql> show create table orders\G;
|
79
|
-
*************************** 1. row ***************************
|
80
|
-
Table: orders
|
81
|
-
Create Table: CREATE TABLE `orders` (
|
82
|
-
`id` bigint(20) NOT NULL DEFAULT nextval(`activerecord_tidb_adapter_demo_development`.`orders_seq`),
|
83
|
-
`name` varchar(255) COLLATE utf8mb4_general_ci DEFAULT NULL,
|
84
|
-
PRIMARY KEY (`id`) /*T![clustered_index] CLUSTERED */
|
85
|
-
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci
|
86
|
-
|
87
|
-
```
|
88
|
-
|
89
79
|
This gem also adds a few helpers to interact with `SEQUENCE`
|
90
80
|
|
91
81
|
```ruby
|
@@ -99,6 +89,41 @@ ActiveRecord::Base.lastval("numbers")
|
|
99
89
|
ActiveRecord::Base.setval("numbers", 1234)
|
100
90
|
```
|
101
91
|
|
92
|
+
**[CTE](https://docs.pingcap.com/tidb/dev/sql-statement-with#with)**
|
93
|
+
|
94
|
+
```bash
|
95
|
+
$ bundle add activerecord-cte
|
96
|
+
|
97
|
+
```
|
98
|
+
|
99
|
+
```ruby
|
100
|
+
require 'activerecord/cte'
|
101
|
+
|
102
|
+
Post
|
103
|
+
.with(posts_with_tags: "SELECT * FROM posts WHERE tags_count > 0")
|
104
|
+
.from("posts_with_tags AS posts")
|
105
|
+
# WITH posts_with_tags AS (
|
106
|
+
# SELECT * FROM posts WHERE (tags_count > 0)
|
107
|
+
# )
|
108
|
+
# SELECT * FROM posts_with_tags AS posts
|
109
|
+
|
110
|
+
Post
|
111
|
+
.with(posts_with_tags: "SELECT * FROM posts WHERE tags_count > 0")
|
112
|
+
.from("posts_with_tags AS posts")
|
113
|
+
.count
|
114
|
+
|
115
|
+
# WITH posts_with_tags AS (
|
116
|
+
# SELECT * FROM posts WHERE (tags_count > 0)
|
117
|
+
# )
|
118
|
+
# SELECT COUNT(*) FROM posts_with_tags AS posts
|
119
|
+
|
120
|
+
Post
|
121
|
+
.with(posts_with_tags: Post.where("tags_count > 0"))
|
122
|
+
.from("posts_with_tags AS posts")
|
123
|
+
.count
|
124
|
+
|
125
|
+
```
|
126
|
+
|
102
127
|
|
103
128
|
## Setting up local TiDB server
|
104
129
|
|
@@ -113,6 +138,10 @@ Starting TiDB playground
|
|
113
138
|
$ tiup playground nightly
|
114
139
|
```
|
115
140
|
|
141
|
+
## Tutorials
|
142
|
+
|
143
|
+
* [Build a Rails App with TiDB and the ActiveRecord TiDB Adapter](https://gist.github.com/hooopo/83db933ab07a054f70e23da0ff945747)
|
144
|
+
|
116
145
|
## Development
|
117
146
|
|
118
147
|
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
@@ -12,7 +12,7 @@ Gem::Specification.new do |spec|
|
|
12
12
|
spec.description = 'Allows the use of TiDB as a backend for ActiveRecord and Rails apps.'
|
13
13
|
spec.homepage = 'https://github.com/pingcap/activerecord-tidb-adapter'
|
14
14
|
spec.license = 'Apache-2.0'
|
15
|
-
spec.required_ruby_version = '>= 2.
|
15
|
+
spec.required_ruby_version = '>= 2.7.0'
|
16
16
|
|
17
17
|
# spec.metadata["allowed_push_host"] = "TODO: Set to 'https://mygemserver.com'"
|
18
18
|
|
@@ -29,7 +29,7 @@ Gem::Specification.new do |spec|
|
|
29
29
|
spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
|
30
30
|
spec.require_paths = ['lib']
|
31
31
|
|
32
|
-
spec.add_dependency 'activerecord', '~>
|
32
|
+
spec.add_dependency 'activerecord', '~> 7.0.1'
|
33
33
|
spec.add_dependency 'mysql2'
|
34
34
|
|
35
35
|
# Uncomment to register a new dependency of your gem
|
data/config.toml
CHANGED
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'active_record/connection_adapters/abstract/database_statements'
|
2
|
+
|
3
|
+
ActiveRecord::ConnectionAdapters::DatabaseStatements.class_eval do
|
4
|
+
def insert(arel, name = nil, pk = nil, id_value = nil, sequence_name = nil, binds = [])
|
5
|
+
sql, binds = to_sql_and_binds(arel, binds)
|
6
|
+
value = exec_insert(sql, name, binds, pk, sequence_name)
|
7
|
+
return id_value if id_value.present?
|
8
|
+
return last_inserted_id(value) if arel.is_a?(String)
|
9
|
+
model = arel.ast.relation.instance_variable_get(:@klass)
|
10
|
+
pk_def = schema_cache.columns_hash(model.table_name)[pk]
|
11
|
+
if pk_def&.default_function && pk_def.default_function =~ /nextval/
|
12
|
+
query_value("SELECT #{pk_def.default_function.sub('nextval', 'lastval')}")
|
13
|
+
else
|
14
|
+
last_inserted_id(value)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
alias create insert
|
18
|
+
|
19
|
+
def transaction_isolation_levels
|
20
|
+
{
|
21
|
+
read_committed: 'READ COMMITTED',
|
22
|
+
repeatable_read: 'REPEATABLE READ'
|
23
|
+
}
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
require 'active_record/connection_adapters/mysql/schema_statements'
|
2
|
+
|
3
|
+
ActiveRecord::ConnectionAdapters::MySQL::SchemaStatements.class_eval do
|
4
|
+
def indexes(table_name)
|
5
|
+
indexes = []
|
6
|
+
current_index = nil
|
7
|
+
execute_and_free("SHOW KEYS FROM #{quote_table_name(table_name)}", "SCHEMA") do |result|
|
8
|
+
each_hash(result) do |row|
|
9
|
+
if current_index != row[:Key_name]
|
10
|
+
next if row[:Key_name] == "PRIMARY" # skip the primary key
|
11
|
+
current_index = row[:Key_name]
|
12
|
+
|
13
|
+
mysql_index_type = row[:Index_type].downcase.to_sym
|
14
|
+
case mysql_index_type
|
15
|
+
when :fulltext, :spatial
|
16
|
+
index_type = mysql_index_type
|
17
|
+
when :btree, :hash
|
18
|
+
index_using = mysql_index_type
|
19
|
+
end
|
20
|
+
|
21
|
+
indexes << [
|
22
|
+
row[:Table],
|
23
|
+
row[:Key_name],
|
24
|
+
row[:Non_unique].to_i == 0,
|
25
|
+
[],
|
26
|
+
lengths: {},
|
27
|
+
orders: {},
|
28
|
+
type: index_type,
|
29
|
+
using: index_using,
|
30
|
+
comment: row[:Index_comment].presence
|
31
|
+
]
|
32
|
+
end
|
33
|
+
|
34
|
+
# FIX https://github.com/pingcap/tidb/issues/26110 for older version of TiDB
|
35
|
+
row[:Expression] = nil if row[:Expression] == 'NULL'
|
36
|
+
|
37
|
+
if row[:Expression]
|
38
|
+
expression = row[:Expression]
|
39
|
+
expression = +"(#{expression})" unless expression.start_with?("(")
|
40
|
+
indexes.last[-2] << expression
|
41
|
+
indexes.last[-1][:expressions] ||= {}
|
42
|
+
indexes.last[-1][:expressions][expression] = expression
|
43
|
+
indexes.last[-1][:orders][expression] = :desc if row[:Collation] == "D"
|
44
|
+
else
|
45
|
+
indexes.last[-2] << row[:Column_name]
|
46
|
+
indexes.last[-1][:lengths][row[:Column_name]] = row[:Sub_part].to_i if row[:Sub_part]
|
47
|
+
indexes.last[-1][:orders][row[:Column_name]] = :desc if row[:Collation] == "D"
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
indexes.map do |index|
|
53
|
+
options = index.pop
|
54
|
+
|
55
|
+
if expressions = options.delete(:expressions)
|
56
|
+
orders = options.delete(:orders)
|
57
|
+
lengths = options.delete(:lengths)
|
58
|
+
|
59
|
+
columns = index[-1].map { |name|
|
60
|
+
[ name.to_sym, expressions[name] || +quote_column_name(name) ]
|
61
|
+
}.to_h
|
62
|
+
|
63
|
+
index[-1] = add_options_for_index_columns(
|
64
|
+
columns, order: orders, length: lengths
|
65
|
+
).values.join(", ")
|
66
|
+
end
|
67
|
+
|
68
|
+
ActiveRecord::ConnectionAdapters::IndexDefinition.new(*index, **options)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
@@ -5,6 +5,8 @@ require 'active_record/connection_adapters/mysql2_adapter'
|
|
5
5
|
require 'active_record/connection_adapters/tidb/setup'
|
6
6
|
require_relative '../../version'
|
7
7
|
require_relative '../sequence'
|
8
|
+
require_relative 'tidb/schema_statements'
|
9
|
+
require_relative 'tidb/database_statements'
|
8
10
|
|
9
11
|
ActiveRecord::ConnectionAdapters::Tidb.initial_setup
|
10
12
|
|
@@ -36,18 +38,22 @@ module ActiveRecord
|
|
36
38
|
ADAPTER_NAME = 'Tidb'
|
37
39
|
|
38
40
|
def supports_savepoints?
|
41
|
+
# https://github.com/pingcap/tidb/issues/6840 support is required
|
39
42
|
false
|
40
43
|
end
|
41
44
|
|
42
45
|
def supports_foreign_keys?
|
46
|
+
# https://github.com/pingcap/tidb/issues/18209 support is required
|
43
47
|
false
|
44
48
|
end
|
45
49
|
|
46
50
|
def supports_bulk_alter?
|
51
|
+
# https://github.com/pingcap/tidb/issues/14766 support is required
|
47
52
|
false
|
48
53
|
end
|
49
54
|
|
50
55
|
def supports_advisory_locks?
|
56
|
+
# https://github.com/pingcap/tidb/issues/14994 support is required
|
51
57
|
false
|
52
58
|
end
|
53
59
|
|
@@ -60,25 +66,23 @@ module ActiveRecord
|
|
60
66
|
end
|
61
67
|
|
62
68
|
def supports_index_sort_order?
|
63
|
-
#
|
64
|
-
|
69
|
+
# https://github.com/pingcap/tidb/issues/2519 support is required
|
70
|
+
false
|
65
71
|
end
|
66
72
|
|
67
73
|
def supports_expression_index?
|
68
|
-
|
74
|
+
sql = <<~SQL
|
75
|
+
SELECT VALUE
|
76
|
+
FROM INFORMATION_SCHEMA.CLUSTER_CONFIG
|
77
|
+
WHERE `KEY` = 'experimental.allow-expression-index' AND `TYPE` = 'tidb'
|
78
|
+
SQL
|
79
|
+
query_value(sql) == 'true'
|
69
80
|
end
|
70
81
|
|
71
82
|
def supports_common_table_expressions?
|
72
83
|
tidb_version >= '5.1.0'
|
73
84
|
end
|
74
85
|
|
75
|
-
def transaction_isolation_levels
|
76
|
-
{
|
77
|
-
read_committed: 'READ COMMITTED',
|
78
|
-
repeatable_read: 'REPEATABLE READ'
|
79
|
-
}
|
80
|
-
end
|
81
|
-
|
82
86
|
def initialize(connection, logger, conn_params, config)
|
83
87
|
super(connection, logger, conn_params, config)
|
84
88
|
|
@@ -100,29 +104,13 @@ module ActiveRecord
|
|
100
104
|
false
|
101
105
|
end
|
102
106
|
|
103
|
-
def insert(arel, name = nil, pk = nil, id_value = nil, sequence_name = nil, binds = [])
|
104
|
-
sql, binds = to_sql_and_binds(arel, binds)
|
105
|
-
value = exec_insert(sql, name, binds, pk, sequence_name)
|
106
|
-
return id_value if id_value.present?
|
107
|
-
|
108
|
-
model = arel.ast.relation.instance_variable_get(:@klass)
|
109
|
-
pk_def = schema_cache.columns_hash(model.table_name)[pk]
|
110
|
-
if pk_def&.default_function && pk_def.default_function =~ /nextval/
|
111
|
-
query_value("SELECT #{pk_def.default_function.sub('nextval', 'lastval')}")
|
112
|
-
elsif model.sequence_name
|
113
|
-
ActiveRecord::Base.lastval(model.sequence_name)
|
114
|
-
else
|
115
|
-
last_inserted_id(value)
|
116
|
-
end
|
117
|
-
end
|
118
|
-
alias create insert
|
119
|
-
|
120
107
|
def new_column_from_field(_table_name, field)
|
121
108
|
type_metadata = fetch_type_metadata(field[:Type], field[:Extra])
|
122
109
|
default = field[:Default]
|
123
110
|
default_function = nil
|
124
111
|
|
125
112
|
if type_metadata.type == :datetime && /\ACURRENT_TIMESTAMP(?:\([0-6]?\))?\z/i.match?(default)
|
113
|
+
default = "#{default} ON UPDATE #{default}" if /on update CURRENT_TIMESTAMP/i.match?(field[:Extra])
|
126
114
|
default_function = default
|
127
115
|
default = nil
|
128
116
|
elsif type_metadata.extra == 'DEFAULT_GENERATED'
|
data/lib/version.rb
CHANGED
data/testing.sh
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/bin/bash
|
2
|
+
|
3
|
+
set -eo pipefail
|
4
|
+
|
5
|
+
bundle config set --local path '/tmp/buildkite-cache'
|
6
|
+
|
7
|
+
echo "Setup gem mirror"
|
8
|
+
bundle config mirror.https://rubygems.org https://gems.ruby-china.com
|
9
|
+
|
10
|
+
echo "Bundle install"
|
11
|
+
bundle install
|
12
|
+
|
13
|
+
echo "Setup database for testing"
|
14
|
+
tidb=1 ARCONN=tidb bundle exec rake db:tidb:rebuild && tidb=1 ARCONN=tidb bundle exec rake test:tidb
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: activerecord-tidb-adapter
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 7.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Hooopo Wang
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2022-03-31 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|
@@ -16,14 +16,14 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version:
|
19
|
+
version: 7.0.1
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version:
|
26
|
+
version: 7.0.1
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: mysql2
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -45,6 +45,10 @@ executables: []
|
|
45
45
|
extensions: []
|
46
46
|
extra_rdoc_files: []
|
47
47
|
files:
|
48
|
+
- ".buildkite/hooks/pre-command"
|
49
|
+
- ".buildkite/pipeline.yml"
|
50
|
+
- ".github/entrypoint.sh"
|
51
|
+
- ".github/workflows/ci.yml"
|
48
52
|
- ".gitignore"
|
49
53
|
- Gemfile
|
50
54
|
- Gemfile.lock
|
@@ -55,7 +59,9 @@ files:
|
|
55
59
|
- bin/console
|
56
60
|
- bin/setup
|
57
61
|
- config.toml
|
62
|
+
- lib/active_record/connection_adapters/tidb/database_statements.rb
|
58
63
|
- lib/active_record/connection_adapters/tidb/database_tasks.rb
|
64
|
+
- lib/active_record/connection_adapters/tidb/schema_statements.rb
|
59
65
|
- lib/active_record/connection_adapters/tidb/setup.rb
|
60
66
|
- lib/active_record/connection_adapters/tidb/type.rb
|
61
67
|
- lib/active_record/connection_adapters/tidb_adapter.rb
|
@@ -66,6 +72,7 @@ files:
|
|
66
72
|
- lib/active_record/sequence/schema_dumper.rb
|
67
73
|
- lib/activerecord-tidb-adapter.rb
|
68
74
|
- lib/version.rb
|
75
|
+
- testing.sh
|
69
76
|
homepage: https://github.com/pingcap/activerecord-tidb-adapter
|
70
77
|
licenses:
|
71
78
|
- Apache-2.0
|
@@ -80,7 +87,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
80
87
|
requirements:
|
81
88
|
- - ">="
|
82
89
|
- !ruby/object:Gem::Version
|
83
|
-
version: 2.
|
90
|
+
version: 2.7.0
|
84
91
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
85
92
|
requirements:
|
86
93
|
- - ">="
|