# File lib/flattendb/types/mysql.rb, line 43 def initialize(options) super @type = options[:type] || :xml @name, @tables = parse end
# File lib/flattendb/types/mysql.rb, line 54 def flatten!(options = {}) flatten_tables!(tables, root, config) self end
# File lib/flattendb/types/mysql.rb, line 50 def parse(tables = {}) [send("parse_#{type}", tables) || 'root', tables] end
# File lib/flattendb/types/mysql.rb, line 59 def to_xml(output = output, builder_options = {}) initialize_builder(:xml, output, builder_options) builder.instruct! if tables.size > 1 builder.tag!(name) { tables.sort.each { |table, rows| table_to_xml(table, rows, builder) } } else table_to_xml(name, tables.values.first, builder) end self end
# File lib/flattendb/types/mysql.rb, line 199 def field_to_xml(field, value, builder) case value when String, Numeric, true, false, nil builder.tag!(column_to_element(field), value) when Array value.each { |item| field_to_xml(field, item, builder) } when Hash row_to_xml(field, value, builder) else raise ArgumentError, "don't know how to handle value of type #{value.class}" end end
# File lib/flattendb/types/mysql.rb, line 122 def flatten_tables!(tables, primary_table, config) config.each { |foreign_table, spec| case spec when String inject_foreign(tables, primary_table, foreign_table, spec) when Array inject_foreign(tables, primary_table, foreign_table, *spec) when Hash unless spec.has_key?(JOIN_KEY) raise ArgumentError, "invalid join table spec, #{JOIN_KEY.inspect} missing" end unless (join_key_spec = spec.delete(JOIN_KEY)).is_a?(Hash) join_key_spec = { foreign_table => join_key_spec } end foreign_tables = Marshal.load(Marshal.dump(tables)) flatten_tables!(foreign_tables, foreign_table, spec) join_key_spec.each { |foreign_table_name, join_key| local_key, foreign_key = join_key inject_foreign( tables, primary_table, foreign_table, local_key, foreign_key || local_key, foreign_tables, foreign_table_name ) } else raise ArgumentError, "don't know how to handle spec of type #{spec.class}" end } if config tables.delete_if { |table, _| table != primary_table } end
# File lib/flattendb/types/mysql.rb, line 160 def inject_foreign( tables, primary_table, foreign_table, local_key, foreign_key = local_key, foreign_tables = tables, foreign_table_name = foreign_table ) unless tables.has_key?(primary_table) raise ArgumentError, "no such primary table: #{primary_table}" end unless foreign_tables.has_key?(foreign_table) raise ArgumentError, "no such foreign table: #{foreign_table}" end foreign_rows = Hash.new { |h, k| h[k] = [] } foreign_tables[foreign_table].each { |foreign_row| foreign_rows[foreign_row[foreign_key]] << foreign_row } tables[primary_table].each { |row| if row.has_key?(local_key) rows = foreign_rows[row[local_key]] row[foreign_table_name] = rows unless rows.empty? end } end
# File lib/flattendb/types/mysql.rb, line 98 def parse_sql(tables) name = nil Nuggets::MySQL::Parser.parse(input) { |event, *args| case event when :use raise 'dump file contains more than one database' if name name = args.first when :insert fields, _, table, columns, values = {}, *args values.each_with_index { |value, index| if column = columns[index] fields[column] = value.to_s end } (tables[table] ||= []) << fields end } name end
# File lib/flattendb/types/mysql.rb, line 77 def parse_xml(tables) document = LibXML::XML::Document.io(input) database = document.root.find_first('database[@name]') database.find('table_data[@name]').each { |table| rows = tables[table[:name]] ||= [] table.find('row').each { |row| fields = {} row.find('field[@name]').each { |field| fields[field[:name]] = field.content } rows << fields } } database[:name] end
# File lib/flattendb/types/mysql.rb, line 193 def row_to_xml(name, row, builder) builder.tag!(name) { row.sort.each { |field, value| field_to_xml(field, value, builder) } } end
# File lib/flattendb/types/mysql.rb, line 187 def table_to_xml(table, rows, builder) builder.tag!(table) { rows.each { |row| row_to_xml('row', row, builder) } if rows } end