activerecord-tidb-adapter 0.3.0 → 5.2.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 442a2dcd175987185739a1fad7a8ef8788d0b13b7263018795ac144a4c10ee03
4
- data.tar.gz: e568154643ebebfc8a9dcfd506b18732d52dea1a19b6500b76e9103965fd2cff
3
+ metadata.gz: 1ec81c5f43cb98b0fe8fb61484ea7b0050a84cb8c7caac6d25e314d58f5f1be0
4
+ data.tar.gz: 4a99eafd9d2f53885e063cc89af6ecf2afce3506e0f9b118a999e52c5fe93e71
5
5
  SHA512:
6
- metadata.gz: d01699afa9a6c147317b8b6fd5763bcbf63852bccaa4fe6dd5bac076405bfc02ff98ae177cd1eef39a8aac95493a4e7eac31896260bceb8b78d2c2b3976605c6
7
- data.tar.gz: 932f70292fde728c25d21bf7180dbad488ca4b5d7630bfe669b70dbf1dee0165f24b311d284ed0ab8edd1b5ab1b688d28d29e7a1748c8a571101950568373a00
6
+ metadata.gz: 66909adaf233af63fb1f7f251cb8f11ba4a484c80e7646c9202c5636a7477575880f85927e01403ce26f8ebaa4a88c5eea6ffa1052a5a34d4e8b12d18f5cbb86
7
+ data.tar.gz: 8ad7289243de4d4f4e1b34d759be041f33c5b02d6b99428e9fc09ad918baa021751d708adc335c126495dce29eae9fca61a63cf7533711c7cd88cb6caf3511a3
@@ -0,0 +1,10 @@
1
+ #!/bin/bash
2
+
3
+ # Place this in /etc/buildkite-agent/hooks/pre-command
4
+ #
5
+ # Needs to be `chown buildkite-agent` and `chmod +x`
6
+
7
+ # RVM uses unbound variables and will fail without this
8
+ set +u
9
+
10
+ source /var/lib/buildkite-agent/.rvm/scripts/rvm
@@ -0,0 +1,7 @@
1
+ env:
2
+ MYSQL_HOST: 127.0.0.1
3
+ MYSQL_USER: root
4
+
5
+ steps:
6
+ - command: "testing.sh"
7
+ label: "Run TiDB ActiveRecord Adapter testing 5-2-stable"
@@ -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,35 @@
1
+ name: activerecord-tidb-adapter ci
2
+
3
+ on:
4
+ push:
5
+ branches:
6
+ - 5-2-stable
7
+ paths-ignore:
8
+ - 'README*.md'
9
+ - 'docs/**'
10
+ pull_request:
11
+ branches:
12
+ - 5-2-stable
13
+ paths-ignore:
14
+ - 'README*.md'
15
+ - 'docs/**'
16
+
17
+ jobs:
18
+ build:
19
+ if: ${{ !contains(github.event.commits[0].message, '[skip ci]') }}
20
+ runs-on: ubuntu-latest
21
+ services:
22
+ tidb:
23
+ image: hawkingrei/tind:v5.1.0
24
+ options: --entrypoint /entrypoint.sh
25
+ env:
26
+ TIDB_VERSION: v5.1.0
27
+ ports: ["4000:4000"]
28
+ steps:
29
+ - uses: actions/checkout@v2
30
+ - uses: ruby/setup-ruby@v1
31
+ with:
32
+ ruby-version: 2.7
33
+ bundler-cache: true
34
+ - 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
35
+ - 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,14 @@ gem 'pry'
14
14
 
15
15
  gem 'rubocop', '~> 1.18'
16
16
 
17
- gem 'rails', git: 'https://github.com/tidb-incubator/rails.git', branch: '6-1-stable'
17
+ gem 'rails', git: 'https://github.com/pingcap/rails.git', branch: '5-2-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 "mocha", "~> 1.13"
26
+
27
+ gem "bcrypt", "~> 3.1"
data/Gemfile.lock CHANGED
@@ -1,100 +1,82 @@
1
1
  GIT
2
- remote: https://github.com/tidb-incubator/rails.git
3
- revision: e377e0dc16e9841a048ec7eab2666c06155b6a0c
4
- branch: 6-1-stable
2
+ remote: https://github.com/pingcap/rails.git
3
+ revision: a1adbde17b229e9131d40787ee4342c1180afb36
4
+ branch: 5-2-stable
5
5
  specs:
6
- actioncable (6.1.4)
7
- actionpack (= 6.1.4)
8
- activesupport (= 6.1.4)
6
+ actioncable (5.2.6)
7
+ actionpack (= 5.2.6)
9
8
  nio4r (~> 2.0)
10
9
  websocket-driver (>= 0.6.1)
11
- actionmailbox (6.1.4)
12
- actionpack (= 6.1.4)
13
- activejob (= 6.1.4)
14
- activerecord (= 6.1.4)
15
- activestorage (= 6.1.4)
16
- activesupport (= 6.1.4)
17
- mail (>= 2.7.1)
18
- actionmailer (6.1.4)
19
- actionpack (= 6.1.4)
20
- actionview (= 6.1.4)
21
- activejob (= 6.1.4)
22
- activesupport (= 6.1.4)
10
+ actionmailer (5.2.6)
11
+ actionpack (= 5.2.6)
12
+ actionview (= 5.2.6)
13
+ activejob (= 5.2.6)
23
14
  mail (~> 2.5, >= 2.5.4)
24
15
  rails-dom-testing (~> 2.0)
25
- actionpack (6.1.4)
26
- actionview (= 6.1.4)
27
- activesupport (= 6.1.4)
28
- rack (~> 2.0, >= 2.0.9)
16
+ actionpack (5.2.6)
17
+ actionview (= 5.2.6)
18
+ activesupport (= 5.2.6)
19
+ rack (~> 2.0, >= 2.0.8)
29
20
  rack-test (>= 0.6.3)
30
21
  rails-dom-testing (~> 2.0)
31
- rails-html-sanitizer (~> 1.0, >= 1.2.0)
32
- actiontext (6.1.4)
33
- actionpack (= 6.1.4)
34
- activerecord (= 6.1.4)
35
- activestorage (= 6.1.4)
36
- activesupport (= 6.1.4)
37
- nokogiri (>= 1.8.5)
38
- actionview (6.1.4)
39
- activesupport (= 6.1.4)
22
+ rails-html-sanitizer (~> 1.0, >= 1.0.2)
23
+ actionview (5.2.6)
24
+ activesupport (= 5.2.6)
40
25
  builder (~> 3.1)
41
26
  erubi (~> 1.4)
42
27
  rails-dom-testing (~> 2.0)
43
- rails-html-sanitizer (~> 1.1, >= 1.2.0)
44
- activejob (6.1.4)
45
- activesupport (= 6.1.4)
28
+ rails-html-sanitizer (~> 1.0, >= 1.0.3)
29
+ activejob (5.2.6)
30
+ activesupport (= 5.2.6)
46
31
  globalid (>= 0.3.6)
47
- activemodel (6.1.4)
48
- activesupport (= 6.1.4)
49
- activerecord (6.1.4)
50
- activemodel (= 6.1.4)
51
- activesupport (= 6.1.4)
52
- activestorage (6.1.4)
53
- actionpack (= 6.1.4)
54
- activejob (= 6.1.4)
55
- activerecord (= 6.1.4)
56
- activesupport (= 6.1.4)
32
+ activemodel (5.2.6)
33
+ activesupport (= 5.2.6)
34
+ activerecord (5.2.6)
35
+ activemodel (= 5.2.6)
36
+ activesupport (= 5.2.6)
37
+ arel (>= 9.0)
38
+ activestorage (5.2.6)
39
+ actionpack (= 5.2.6)
40
+ activerecord (= 5.2.6)
57
41
  marcel (~> 1.0.0)
58
- mini_mime (>= 1.1.0)
59
- activesupport (6.1.4)
42
+ activesupport (5.2.6)
60
43
  concurrent-ruby (~> 1.0, >= 1.0.2)
61
- i18n (>= 1.6, < 2)
62
- minitest (>= 5.1)
63
- tzinfo (~> 2.0)
64
- zeitwerk (~> 2.3)
65
- rails (6.1.4)
66
- actioncable (= 6.1.4)
67
- actionmailbox (= 6.1.4)
68
- actionmailer (= 6.1.4)
69
- actionpack (= 6.1.4)
70
- actiontext (= 6.1.4)
71
- actionview (= 6.1.4)
72
- activejob (= 6.1.4)
73
- activemodel (= 6.1.4)
74
- activerecord (= 6.1.4)
75
- activestorage (= 6.1.4)
76
- activesupport (= 6.1.4)
77
- bundler (>= 1.15.0)
78
- railties (= 6.1.4)
44
+ i18n (>= 0.7, < 2)
45
+ minitest (~> 5.1)
46
+ tzinfo (~> 1.1)
47
+ rails (5.2.6)
48
+ actioncable (= 5.2.6)
49
+ actionmailer (= 5.2.6)
50
+ actionpack (= 5.2.6)
51
+ actionview (= 5.2.6)
52
+ activejob (= 5.2.6)
53
+ activemodel (= 5.2.6)
54
+ activerecord (= 5.2.6)
55
+ activestorage (= 5.2.6)
56
+ activesupport (= 5.2.6)
57
+ bundler (>= 1.3.0)
58
+ railties (= 5.2.6)
79
59
  sprockets-rails (>= 2.0.0)
80
- railties (6.1.4)
81
- actionpack (= 6.1.4)
82
- activesupport (= 6.1.4)
60
+ railties (5.2.6)
61
+ actionpack (= 5.2.6)
62
+ activesupport (= 5.2.6)
83
63
  method_source
84
- rake (>= 0.13)
85
- thor (~> 1.0)
64
+ rake (>= 0.8.7)
65
+ thor (>= 0.19.0, < 2.0)
86
66
 
87
67
  PATH
88
68
  remote: .
89
69
  specs:
90
- activerecord-tidb-adapter (0.3.0)
91
- activerecord (~> 6.1)
70
+ activerecord-tidb-adapter (5.2.2)
71
+ activerecord (~> 5.2)
92
72
  mysql2
93
73
 
94
74
  GEM
95
75
  remote: https://rubygems.org/
96
76
  specs:
77
+ arel (9.0.0)
97
78
  ast (2.4.2)
79
+ bcrypt (3.1.16)
98
80
  builder (3.2.4)
99
81
  byebug (11.1.3)
100
82
  coderay (1.1.3)
@@ -105,7 +87,7 @@ GEM
105
87
  activesupport (>= 5.0)
106
88
  i18n (1.8.10)
107
89
  concurrent-ruby (~> 1.0)
108
- loofah (2.11.0)
90
+ loofah (2.12.0)
109
91
  crass (~> 1.0.2)
110
92
  nokogiri (>= 1.5.9)
111
93
  mail (2.7.1)
@@ -116,8 +98,11 @@ GEM
116
98
  minitest (5.14.4)
117
99
  minitest-excludes (2.0.1)
118
100
  minitest (~> 5.0)
101
+ mocha (1.13.0)
119
102
  mysql2 (0.5.3)
120
103
  nio4r (2.5.8)
104
+ nokogiri (1.12.3-x86_64-darwin)
105
+ racc (~> 1.4)
121
106
  nokogiri (1.12.3-x86_64-linux)
122
107
  racc (~> 1.4)
123
108
  parallel (1.20.1)
@@ -134,22 +119,22 @@ GEM
134
119
  rails-dom-testing (2.0.3)
135
120
  activesupport (>= 4.2.0)
136
121
  nokogiri (>= 1.6)
137
- rails-html-sanitizer (1.3.0)
122
+ rails-html-sanitizer (1.4.1)
138
123
  loofah (~> 2.3)
139
124
  rainbow (3.0.0)
140
125
  rake (13.0.6)
141
126
  regexp_parser (2.1.1)
142
127
  rexml (3.2.5)
143
- rubocop (1.18.4)
128
+ rubocop (1.19.0)
144
129
  parallel (~> 1.10)
145
130
  parser (>= 3.0.0.0)
146
131
  rainbow (>= 2.2.2, < 4.0)
147
132
  regexp_parser (>= 1.8, < 3.0)
148
133
  rexml
149
- rubocop-ast (>= 1.8.0, < 2.0)
134
+ rubocop-ast (>= 1.9.1, < 2.0)
150
135
  ruby-progressbar (~> 1.7)
151
136
  unicode-display_width (>= 1.4.0, < 3.0)
152
- rubocop-ast (1.8.0)
137
+ rubocop-ast (1.10.0)
153
138
  parser (>= 3.0.1.1)
154
139
  ruby-progressbar (1.11.0)
155
140
  sprockets (4.0.2)
@@ -161,13 +146,13 @@ GEM
161
146
  sprockets (>= 3.0.0)
162
147
  sqlite3 (1.4.2)
163
148
  thor (1.1.0)
164
- tzinfo (2.0.4)
165
- concurrent-ruby (~> 1.0)
149
+ thread_safe (0.3.6)
150
+ tzinfo (1.2.9)
151
+ thread_safe (~> 0.1)
166
152
  unicode-display_width (2.0.0)
167
153
  websocket-driver (0.7.5)
168
154
  websocket-extensions (>= 0.1.0)
169
155
  websocket-extensions (0.1.5)
170
- zeitwerk (2.4.2)
171
156
 
172
157
  PLATFORMS
173
158
  x86_64-darwin-18
@@ -175,9 +160,11 @@ PLATFORMS
175
160
 
176
161
  DEPENDENCIES
177
162
  activerecord-tidb-adapter!
163
+ bcrypt (~> 3.1)
178
164
  byebug (~> 11.1)
179
165
  minitest (~> 5.0)
180
166
  minitest-excludes (~> 2.0)
167
+ mocha (~> 1.13)
181
168
  pg (~> 1.2)
182
169
  pry
183
170
  rails!
data/README.md CHANGED
@@ -8,7 +8,7 @@ TiDB adapter for ActiveRecord 5 and 6. This is a lightweight extension of the my
8
8
  Add this line to your application's Gemfile:
9
9
 
10
10
  ```ruby
11
- gem 'activerecord-tidb-adapter'
11
+ gem 'activerecord-tidb-adapter', "~> 5.2.2"
12
12
  ```
13
13
 
14
14
  And then execute:
@@ -44,6 +44,62 @@ development:
44
44
 
45
45
  * demo repo with rails 6.1.4: https://github.com/hooopo/activerecord-tidb-adapter-demo
46
46
 
47
+ ## TiDB features
48
+
49
+ **[Sequence](https://docs.pingcap.com/tidb/stable/sql-statement-create-sequence)**
50
+
51
+ Sequence as primary key
52
+
53
+ ```ruby
54
+ class TestSeq < ActiveRecord::Migration[6.1]
55
+ def up
56
+ # more options: increment, min_value, cycle, cache
57
+ create_sequence :orders_seq, start: 1024
58
+ create_table :orders, id: false do |t|
59
+ t.primary_key :id, default: -> { "nextval(orders_seq)" }
60
+ t.string :name
61
+ end
62
+ end
63
+
64
+ def down
65
+ drop_table :orders
66
+ drop_sequence :orders_seq
67
+ end
68
+ end
69
+ ```
70
+
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
+ This gem also adds a few helpers to interact with `SEQUENCE`
90
+
91
+ ```ruby
92
+ # Advance sequence and return new value
93
+ ActiveRecord::Base.nextval("numbers")
94
+
95
+ # Return value most recently obtained with nextval for specified sequence.
96
+ ActiveRecord::Base.lastval("numbers")
97
+
98
+ # Set sequence's current value
99
+ ActiveRecord::Base.setval("numbers", 1234)
100
+ ```
101
+
102
+
47
103
  ## Setting up local TiDB server
48
104
 
49
105
  Install [tiup](https://github.com/pingcap/tiup)
@@ -84,16 +140,22 @@ MYSQL_USER=root MYSQL_HOST=127.0.0.1 MYSQL_PORT=4000 tidb=1 ARCONN=tidb bundle e
84
140
 
85
141
  ```
86
142
 
87
- run tidb adapter tests
143
+ run tidb adapter tests and activerecord buildin tests
144
+
145
+ ```
146
+ MYSQL_USER=root MYSQL_HOST=127.0.0.1 MYSQL_PORT=4000 tidb=1 ARCONN=tidb bundle exec rake test:tidb
88
147
 
89
148
  ```
90
- MYSQL_USER=root MYSQL_HOST=127.0.0.1 MYSQL_PORT=4000 tidb=1 ARCONN=tidb bundle exec rake test:idb
91
149
 
150
+ run **ONLY** tidb adapter tests using `ONLY_TEST_TIDB` env:
151
+
152
+ ```
153
+ ONLY_TEST_TIDB=1 MYSQL_USER=root MYSQL_HOST=127.0.0.1 MYSQL_PORT=4000 tidb=1 ARCONN=tidb bundle exec rake test:tidb
92
154
  ```
93
155
 
94
156
  ## Contributing
95
157
 
96
- Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/activerecord-tidb-adapter.
158
+ Bug reports and pull requests are welcome on GitHub at https://github.com/pingcap/activerecord-tidb-adapter.
97
159
 
98
160
  ## License
99
161
 
data/Rakefile CHANGED
@@ -15,7 +15,7 @@ namespace :test do
15
15
  Rake::TestTask.new('tidb') do |t|
16
16
  t.libs = ARTest::TiDB.test_load_paths
17
17
  t.test_files = test_files
18
- t.warning = !!ENV['WARNING']
18
+ t.warning = !ENV['WARNING'].nil?
19
19
  t.verbose = false
20
20
  end
21
21
 
@@ -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', '~> 6.1'
32
+ spec.add_dependency 'activerecord', '~> 5.2'
33
33
  spec.add_dependency 'mysql2'
34
34
 
35
35
  # Uncomment to register a new dependency of your gem
@@ -0,0 +1,19 @@
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
+
8
+ return id_value if id_value.present?
9
+ return last_inserted_id(value) if arel.is_a?(String)
10
+ table_name = arel.ast.relation.table_name
11
+ pk_def = schema_cache.columns_hash(table_name)[pk]
12
+ if pk_def&.default_function && pk_def.default_function =~ /nextval/
13
+ query_value("SELECT #{pk_def.default_function.sub('nextval', 'lastval')}")
14
+ else
15
+ last_inserted_id(value)
16
+ end
17
+ end
18
+ alias create insert
19
+ end
@@ -0,0 +1,28 @@
1
+ require 'pry'
2
+ require 'active_record/connection_adapters/mysql/schema_statements'
3
+
4
+
5
+ ActiveRecord::ConnectionAdapters::MySQL::SchemaStatements.class_eval do
6
+ def new_column_from_field(table_name, field)
7
+ type_metadata = fetch_type_metadata(field[:Type], field[:Extra])
8
+ if type_metadata.type == :datetime && /\ACURRENT_TIMESTAMP(?:\([0-6]?\))?\z/i.match?(field[:Default])
9
+ default, default_function = nil, field[:Default]
10
+ elsif field[:Default].to_s =~ /nextval/i
11
+ default_function = field[:Default]
12
+ default = nil
13
+ else
14
+ default, default_function = field[:Default], nil
15
+ end
16
+
17
+ ActiveRecord::ConnectionAdapters::MySQL::Column.new(
18
+ field[:Field],
19
+ default,
20
+ type_metadata,
21
+ field[:Null] == "YES",
22
+ table_name,
23
+ default_function,
24
+ field[:Collation],
25
+ comment: field[:Comment].presence
26
+ )
27
+ end
28
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord
2
4
  module Type
3
5
  class << self
@@ -1,16 +1,18 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'active_record/connection_adapters'
4
3
  require 'active_record/connection_adapters/mysql2_adapter'
5
4
  require 'active_record/connection_adapters/tidb/setup'
6
5
  require_relative '../../version'
6
+ require_relative '../sequence'
7
+ require_relative 'tidb/database_statements'
8
+ require_relative 'tidb/schema_statements'
7
9
 
8
10
  ActiveRecord::ConnectionAdapters::Tidb.initial_setup
9
11
 
10
12
  module ActiveRecord
11
- module ConnectionHandling #:nodoc:
13
+ module ConnectionHandling # :nodoc:
12
14
  # Establishes a connection to the database that's used by all Active Record objects.
13
- def tidb_connection(config) #:nodoc:
15
+ def tidb_connection(config) # :nodoc:
14
16
  config = config.symbolize_keys
15
17
  config[:flags] ||= 0
16
18
 
@@ -29,8 +31,30 @@ module ActiveRecord
29
31
  end
30
32
  end
31
33
 
34
+
35
+
32
36
  module ConnectionAdapters
37
+ class Mysql2Adapter < AbstractMysqlAdapter
38
+ ER_BAD_DB_ERROR = 1049
39
+ ADAPTER_NAME = "Mysql2"
40
+
41
+ include MySQL::DatabaseStatements
42
+
43
+ class << self
44
+ def new_client(config)
45
+ Mysql2::Client.new(config)
46
+ rescue Mysql2::Error => error
47
+ if error.error_number == ConnectionAdapters::Mysql2Adapter::ER_BAD_DB_ERROR
48
+ raise ActiveRecord::NoDatabaseError
49
+ else
50
+ raise ActiveRecord::ConnectionNotEstablished, error.message
51
+ end
52
+ end
53
+ end
54
+ end
55
+
33
56
  class TidbAdapter < Mysql2Adapter
57
+ include ActiveRecord::Sequence::Adapter
34
58
  ADAPTER_NAME = 'Tidb'
35
59
 
36
60
  def supports_savepoints?
@@ -93,7 +117,7 @@ module ActiveRecord
93
117
  end
94
118
 
95
119
  def self.database_exists?(config)
96
- !!ActiveRecord::Base.tidb_connection(config)
120
+ !ActiveRecord::Base.tidb_connection(config).nil?
97
121
  rescue ActiveRecord::NoDatabaseError
98
122
  false
99
123
  end
@@ -0,0 +1,50 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveRecord
4
+ module Sequence
5
+ module Adapter
6
+ def check_sequences
7
+ select_all(
8
+ 'SELECT * FROM information_schema.sequences ORDER BY sequence_name'
9
+ ).to_a
10
+ end
11
+
12
+ def create_sequence(name, options = {})
13
+ increment = options[:increment] || options[:step]
14
+ name = quote_column_name(name)
15
+
16
+ sql = ["CREATE SEQUENCE IF NOT EXISTS #{name}"]
17
+ sql << "INCREMENT BY #{increment}" if increment
18
+ sql << "START WITH #{options[:start]}" if options[:start]
19
+ sql << if options[:cache]
20
+ "CACHE #{options[:cache]}"
21
+ else
22
+ 'NOCACHE'
23
+ end
24
+
25
+ sql << if options[:cycle]
26
+ 'CYCLE'
27
+ else
28
+ 'NOCYCLE'
29
+ end
30
+
31
+ sql << "MIN_VALUE #{options[:min_value]}" if options[:min_value]
32
+
33
+ sql << "COMMENT #{quote(options[:comment].to_s)}" if options[:comment]
34
+
35
+ execute(sql.join("\n"))
36
+ end
37
+
38
+ def drop_sequence(name)
39
+ name = quote_column_name(name)
40
+ sql = "DROP SEQUENCE IF EXISTS #{name}"
41
+ execute(sql)
42
+ end
43
+
44
+ def recreate_sequence(name, options = {})
45
+ drop_sequence(name)
46
+ create_sequence(name, options)
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveRecord
4
+ module Sequence
5
+ module CommandRecorder
6
+ def create_sequence(name, options = {})
7
+ record(__method__, [name, options])
8
+ end
9
+
10
+ def drop_sequence(name)
11
+ record(__method__, [name])
12
+ end
13
+
14
+ def invert_create_sequence(args)
15
+ name, = args
16
+ [:drop_sequence, [name]]
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveRecord
4
+ module Sequence
5
+ module ModelMethods
6
+ def nextval(name)
7
+ name = connection.quote_column_name(name)
8
+ connection.query_value("SELECT nextval(#{name})")
9
+ end
10
+
11
+ def lastval(name)
12
+ name = connection.quote_column_name(name)
13
+ connection.query_value("SELECT lastval(#{name})")
14
+ end
15
+
16
+ def setval(name, value)
17
+ name = connection.quote_column_name(name)
18
+ connection.query_value("SELECT setval(#{name}, #{value})")
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,54 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveRecord
4
+ module Sequence
5
+ module SchemaDumper
6
+ def header(stream)
7
+ super
8
+ sequences(stream)
9
+ end
10
+
11
+ def sequences(stream)
12
+ sequences = @connection.check_sequences
13
+ return if sequences.empty?
14
+
15
+ sequences.each do |seq|
16
+ start_value = seq['START']
17
+ increment = seq['INCREMENT']
18
+ cache = seq['CACHE']
19
+ cache_value = seq['CACHE_VALUE']
20
+ min_value = seq['MIN_VALUE']
21
+ cycle = seq['CYCLE']
22
+ comment = seq['COMMENT']
23
+
24
+ options = []
25
+
26
+ options << "start: #{start_value}" if start_value && Integer(start_value) != 1
27
+
28
+ options << "increment: #{increment}" if increment && Integer(increment) != 1
29
+
30
+ options << "cache: #{cache_value}" if cache_value && Integer(cache_value) != 0
31
+
32
+ options << "min_value: #{min_value}" if min_value
33
+
34
+ options << 'cycle: true' if cycle.to_i != 0
35
+
36
+ options << "comment: #{comment.inspect}" if comment.present?
37
+
38
+ statement = [
39
+ 'create_sequence',
40
+ seq['SEQUENCE_NAME'].inspect
41
+ ].join(' ')
42
+
43
+ if options.any?
44
+ statement << (options.any? ? ", #{options.join(', ')}" : '')
45
+ end
46
+
47
+ stream.puts " #{statement}"
48
+ end
49
+
50
+ stream.puts
51
+ end
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'active_support/all'
4
+ require 'active_record'
5
+ require 'active_record/connection_adapters/mysql/schema_dumper'
6
+ require 'active_record/migration/command_recorder'
7
+ require 'active_record/schema_dumper'
8
+
9
+ module ActiveRecord
10
+ module Sequence
11
+ require 'active_record/sequence/command_recorder'
12
+ require 'active_record/sequence/adapter'
13
+ require 'active_record/sequence/schema_dumper'
14
+ require 'active_record/sequence/model_methods'
15
+ end
16
+ end
17
+
18
+ ActiveRecord::Migration::CommandRecorder.include(ActiveRecord::Sequence::CommandRecorder)
19
+
20
+ ActiveRecord::SchemaDumper.prepend(ActiveRecord::Sequence::SchemaDumper)
21
+ ActiveRecord::Base.extend(ActiveRecord::Sequence::ModelMethods)
data/lib/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ActiveRecord
4
- TIDB_ADAPTER_VERSION = '0.3.0'
4
+ TIDB_ADAPTER_VERSION = '5.2.2'
5
5
  end
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: 0.3.0
4
+ version: 5.2.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Hooopo Wang
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-08-12 00:00:00.000000000 Z
11
+ date: 2021-08-23 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: '6.1'
19
+ version: '5.2'
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: '6.1'
26
+ version: '5.2'
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,12 +59,20 @@ 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
68
+ - lib/active_record/sequence.rb
69
+ - lib/active_record/sequence/adapter.rb
70
+ - lib/active_record/sequence/command_recorder.rb
71
+ - lib/active_record/sequence/model_methods.rb
72
+ - lib/active_record/sequence/schema_dumper.rb
62
73
  - lib/activerecord-tidb-adapter.rb
63
74
  - lib/version.rb
75
+ - testing.sh
64
76
  homepage: https://github.com/pingcap/activerecord-tidb-adapter
65
77
  licenses:
66
78
  - Apache-2.0