Skip to content

Instantly share code, notes, and snippets.

@grncdr
Created November 5, 2021 20:41
Show Gist options
  • Select an option

  • Save grncdr/a34c344ac1c8622dab7278660b80f3b4 to your computer and use it in GitHub Desktop.

Select an option

Save grncdr/a34c344ac1c8622dab7278660b80f3b4 to your computer and use it in GitHub Desktop.

Revisions

  1. grncdr created this gist Nov 5, 2021.
    73 changes: 73 additions & 0 deletions minimal-schema-loader.rb
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,73 @@
    #!/usr/bin/env ruby
    # frozen_string_literal: true

    module Nop
    def nop(*methods)
    methods.each do |method|
    define_method(method) { |*_args| nil }
    end
    end
    end

    # A simple stub that collects the information in a Rails db/schema.rb file
    class FakeSchemaDSL
    extend Nop

    def initialize(info)
    @info = info
    @tables = {}
    end

    def create_table(name, **opts)
    raise 'block is required' unless block_given?

    t = @tables[name] = TableHelper.new(opts)
    yield t
    end

    attr_reader :tables

    nop :enable_extension, :add_foreign_key

    class TableHelper
    extend Nop

    nop :index

    def initialize(opts)
    @table_opts = opts
    @columns = {}
    end

    attr_reader :columns

    def respond_to_missing?(_name, _include_private = true)
    true
    end

    def method_missing(type, column_name, **opts)
    @columns[column_name] = { type: type, opts: opts }
    end
    end
    end

    module ActiveRecord
    class Schema
    def self.define(info, &block)
    raise '#define called twice' if @dsl

    @dsl = FakeSchemaDSL.new(info)
    @dsl.instance_eval(&block)
    end

    def self.tables
    @dsl.tables
    end
    end
    end

    require_relative '../db/schema' or abort 'noooo'

    require 'pp'

    pp ActiveRecord::Schema.tables.transform_values(&:columns)