LoginSignup
1
1

More than 5 years have passed since last update.

ridgepoleの仕組み

Posted at

※2016-10-20時点の情報です(ridgepole/master 021728f9ff31d35eb5b7f3ee113a7938f429e864

ridgepoleは内部でActiveRecordを使っている。
現状のスキーマとSchemafileの差分を取る部分のコード(delta.rb 464行、diff.rb 405行)がやや長いが、それ以外はけっこうシンプルなようだ。

現状のスキーマの取得方法

ActiveRecord::SchemaDumper.dumpを使っている。このメソッドによりRailsのdb/schema.rbの内容と同じ文字列が得られる。

lib/ridgepole/dumper.rb
class Ridgepole::Dumper
  def initialize(options = {})
    @options = options
  end

  def dump
    stream = StringIO.new
    conn = ActiveRecord::Base.connection

    (中略)

    ActiveRecord::SchemaDumper.dump(conn, stream) 

DSL(Schemafile)で使えるキーワード

lib/ridgepole/dsl_parser.rbに書いてある。

lib/ridgepole/dsl_parser.rb
      TYPES = [
        # https://github.com/rails/rails/blob/v4.2.1/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb#L274        :string,
        :text,
        :integer,
        :bigint,
        :float,
        :decimal,
        :datetime,
        :timestamp,
        :time,
        :date,
        :binary,
        :boolean,
(略)

DSLのパースにはinstance_evalしている。
create_tableadd_indexなどのメソッドは独自に定義している。

dsl_parser.rb
    def self.eval(dsl, opts = {}) 
      ctx = self.new(opts)

      if opts[:path]
        ctx.instance_eval(dsl, opts[:path])
      else
        ctx.instance_eval(dsl)
      end 

      [ctx.__definition, ctx.__execute]
    end 

    def create_table(table_name, options = {}) 
      table_name = table_name.to_s
      table_definition = TableDefinition.new(table_name, self)

      [:primary_key].each do |key|
        options[key] = options[key].to_s if options[key]
      end 

      yield(table_definition)
      @__definition[table_name] ||= {}

      if @__definition[table_name][:definition]
        raise "Table `#{table_name}` already defined"
      end 

      @__definition[table_name][:definition] = table_definition.__definition
      options.delete(:force)
      @__definition[table_name][:options] = options
    end
1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1