ActiveRecord TiDB Adapter

Gem Version activerecord-tidb-adapter 7.0

TiDB adapter for ActiveRecord 5.2, 6.1 and 7.0 This is a lightweight extension of the mysql2 adapter that establishes compatibility with TiDB.

Installation

Add this line to your application's Gemfile:

gem 'activerecord-tidb-adapter', '~> 6.1.0'

If you're using Rails 5.2, use the 5.2.x versions of this gem.

If you're using Rails 6.1, use the 6.1.x versions of this gem.

And then execute:

$ bundle install

Or install it yourself as:

$ gem install activerecord-tidb-adapter

Usage

config/database.yml

default: &default
  adapter: tidb
  encoding: utf8mb4
  collation: utf8mb4_general_ci
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
  host: 127.0.0.1
  port: 4000
  variables:
    tidb_enable_noop_functions: ON
  username: root
  password:

development:
  <<: *default
  database: activerecord_tidb_adapter_demo_development

TiDB features

Sequence

Sequence as primary key

class TestSeq < ActiveRecord::Migration[6.1]
  def up
    # more options: increment, min_value, cycle, cache
    create_sequence :orders_seq, start: 1024
    create_table :orders, id: false do |t|
      t.primary_key :id, default: -> { "nextval(orders_seq)" }
      t.string :name
    end
  end

  def down
    drop_table :orders
    drop_sequence :orders_seq
  end
end

This gem also adds a few helpers to interact with SEQUENCE

# Advance sequence and return new value
ActiveRecord::Base.nextval("numbers")

# Return value most recently obtained with nextval for specified sequence.
ActiveRecord::Base.lastval("numbers")

# Set sequence's current value
ActiveRecord::Base.setval("numbers", 1234)

CTE

$ bundle add activerecord-cte

require 'activerecord/cte'

Post
  .with(posts_with_tags: "SELECT * FROM posts WHERE tags_count > 0")
  .from("posts_with_tags AS posts")
# WITH posts_with_tags AS (
#   SELECT * FROM posts WHERE (tags_count > 0)
# )
# SELECT * FROM posts_with_tags AS posts

Post
  .with(posts_with_tags: "SELECT * FROM posts WHERE tags_count > 0")
  .from("posts_with_tags AS posts")
  .count

# WITH posts_with_tags AS (
#   SELECT * FROM posts WHERE (tags_count > 0)
# )
# SELECT COUNT(*) FROM posts_with_tags AS posts

Post
  .with(posts_with_tags: Post.where("tags_count > 0"))
  .from("posts_with_tags AS posts")
  .count

Setting up local TiDB server

Install tiup

$ curl --proto '=https' --tlsv1.2 -sSf https://tiup-mirrors.pingcap.com/install.sh | sh

Starting TiDB playground

$ tiup playground  nightly

Tutorials

Development

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.

To install this gem onto your local machine, run bundle exec rake install. To release a new version, update the version number in version.rb, and then run bundle exec rake release, which will create a git tag for the version, push git commits and the created tag, and push the .gem file to rubygems.org.

Testing

install gems

bundle install

start tidb server

tiup playground  nightly

create database for testing

MYSQL_USER=root MYSQL_HOST=127.0.0.1 MYSQL_PORT=4000 tidb=1 ARCONN=tidb bundle exec rake db:tidb:rebuild

run tidb adapter tests and activerecord buildin tests

MYSQL_USER=root MYSQL_HOST=127.0.0.1 MYSQL_PORT=4000 tidb=1 ARCONN=tidb bundle exec rake test:tidb

run ONLY tidb adapter tests using ONLY_TEST_TIDB env:

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

Contributing

Bug reports and pull requests are welcome on GitHub at https://github.com/pingcap/activerecord-tidb-adapter.

License

Apache 2.0