lib/ridgepole/dsl_parser.rb in ridgepole-0.6.6.beta vs lib/ridgepole/dsl_parser.rb in ridgepole-0.6.6.beta2

- old
+ new

@@ -1,256 +1,5 @@ class Ridgepole::DSLParser - class Context - class TableDefinition - attr_reader :__definition - - def initialize(table_name, base) - @__definition = {} - @table_name = table_name - @base = base - end - - def column(name, type, options = {}) - name = name.to_s - - @__definition[name] = { - :type => type, - :options => options, - } - end - - 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, - - # https://github.com/rails/rails/blob/v4.2.1/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb#L79 - :daterange, - :numrange, - :tsrange, - :tstzrange, - :int4range, - :int8range, - :binary, - :boolean, - :bigint, - :xml, - :tsvector, - :hstore, - :inet, - :cidr, - :macaddr, - :uuid, - :json, - :jsonb, - :ltree, - :citext, - :point, - :bit, - :bit_varying, - :money, - ].uniq - - TYPES.each do |column_type| - define_method column_type do |*args| - options = args.extract_options! - column_names = args - column_names.each {|name| column(name, column_type, options) } - end - end - - ALIAS_TYPES = { - # https://github.com/rails/rails/blob/v5.0.0.rc1/activerecord/lib/active_record/connection_adapters/mysql/schema_definitions.rb - tinyblob: [:blob, {limit: 255}], - mediumblob: [:binary, {limit: 16777215}], - longblob: [:binary, {limit: 4294967295}], - tinytext: [:text, {limit: 255}], - mediumtext: [:text, {limit: 16777215}], - longtext: [:text, {limit: 4294967295}], - unsigned_integer: [:integer, {unsigned: true}], - unsigned_bigint: [:bigint, {unsigned: true}], - unsigned_float: [:float, {limit: 24, unsigned: true}], - unsigned_decimal: [:decimal, {precision: 10, unsigned: true}], - } - - # XXX: - def blob(*args) - options = args.extract_options! - options = {limit: 65535}.merge(options) - column_names = args - - column_names.each do |name| - column_type = (0..0xff).include?(options[:limit]) ? :blob : :binary - column(name, column_type, options) - end - end - - ALIAS_TYPES.each do |alias_type, (column_type, default_options)| - define_method alias_type do |*args| - options = args.extract_options! - options = default_options.merge(options) - column_names = args - column_names.each {|name| column(name, column_type, options) } - end - end - - def index(name, options = {}) - @base.add_index(@table_name, name, options) - end - - def timestamps(*args) - options = {:null => false}.merge(args.extract_options!) - column(:created_at, :datetime, options) - column(:updated_at, :datetime, options) - end - - def references(*args) - options = args.extract_options! - polymorphic = options.delete(:polymorphic) - index_options = options.delete(:index) - type = options.delete(:type) || :integer - - args.each do |col| - column("#{col}_id", type, options) - column("#{col}_type", :string, polymorphic.is_a?(Hash) ? polymorphic : options) if polymorphic - if index_options - index("#{col}_id", index_options.is_a?(Hash) ? index_options : {}) - index("#{col}_type", index_options.is_a?(Hash) ? index_options : {}) if polymorphic - end - end - end - alias :belongs_to :references - end - - attr_reader :__definition - attr_reader :__execute - - def initialize(opts = {}) - @__working_dir = File.expand_path(opts[:path] ? File.dirname(opts[:path]) : Dir.pwd) - @__definition = {} - @__execute = [] - end - - 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) - - if options[:primary_key] and options[:primary_key].is_a?(Symbol) - options[:primary_key] = options[:primary_key].to_s - 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 - - def add_index(table_name, column_name, options = {}) - table_name = table_name.to_s - # Keep column_name for expression index support - # https://github.com/rails/rails/pull/23393 - unless column_name.is_a?(String) && /\W/ === column_name - column_name = [column_name].flatten.map {|i| i.to_s } - end - options[:name] = options[:name].to_s if options[:name] - @__definition[table_name] ||= {} - @__definition[table_name][:indices] ||= {} - idx = options[:name] || column_name - - if @__definition[table_name][:indices][idx] - raise "Index `#{table_name}(#{idx})` already defined" - end - - if options[:length].is_a?(Numeric) - index_length = options[:length] - options[:length] = {} - - column_name.each do |col| - options[:length][col] = index_length - end - - # XXX: fix for https://github.com/rails/rails/commit/5025fd3a99c68f95bdd6fd43f382c62e9653236b - if ActiveRecord::VERSION::MAJOR >= 6 or (ActiveRecord::VERSION::MAJOR == 5 and (ActiveRecord::VERSION::MINOR >= 1 or ActiveRecord::VERSION::TINY >= 1)) - options[:length] = options[:length].symbolize_keys - end - end - - @__definition[table_name][:indices][idx] = { - :column_name => column_name, - :options => options, - } - end - - def add_foreign_key(from_table, to_table, options = {}) - unless options[:name] - raise "Foreign key name in `#{from_table}` is undefined" - end - - from_table = from_table.to_s - to_table = to_table.to_s - options[:name] = options[:name].to_s - @__definition[from_table] ||= {} - @__definition[from_table][:foreign_keys] ||= {} - idx = options[:name] - - if @__definition[from_table][:foreign_keys][idx] - raise "Foreign Key `#{from_table}(#{idx})` already defined" - end - - @__definition[from_table][:foreign_keys][idx] = { - :to_table => to_table, - :options => options, - } - end - - def require(file) - schemafile = (file =~ %r|\A/|) ? file : File.join(@__working_dir, file) - - if File.exist?(schemafile) - instance_eval(File.read(schemafile), schemafile) - elsif File.exist?(schemafile + '.rb') - instance_eval(File.read(schemafile + '.rb'), schemafile + '.rb') - else - Kernel.require(file) - end - end - - def execute(sql, name = nil, &cond) - @__execute << { - :sql => sql, - :condition => cond, - } - end - end - def initialize(options = {}) @options = options end def parse(dsl, opts = {})