discourse/lib/export/json_encoder.rb

74 lines
1.8 KiB
Ruby

module Export
class SchemaArgumentsError < RuntimeError; end
class JsonEncoder
def initialize
@table_data = {}
end
def tmp_directory
@tmp_directory ||= begin
f = File.join( Rails.root, 'tmp', Time.now.strftime('export%Y%m%d%H%M%S') )
Dir.mkdir(f) unless Dir[f].present?
f
end
end
def json_output_stream
@json_output_stream ||= File.new( File.join( tmp_directory, 'tables.json' ), 'w+b' )
end
def write_schema_info(args)
raise SchemaArgumentsError unless args[:source].present? && args[:version].present?
@schema_data = {
schema: {
source: args[:source],
version: args[:version]
}
}
end
def write_table(table_name, columns)
@table_data[table_name] ||= {}
@table_data[table_name][:fields] = columns.map(&:name)
@table_data[table_name][:rows] ||= []
row_count = 0
begin
rows = yield(row_count)
if rows
row_count += rows.size
@table_data[table_name][:rows] << rows
end
# TODO: write to multiple files as needed.
# one file per table? multiple files per table?
end while rows && rows.size > 0
@table_data[table_name][:rows].flatten!(1)
@table_data[table_name][:row_count] = @table_data[table_name][:rows].size
end
def finish
@schema_data[:schema][:table_count] = @table_data.keys.count
json_output_stream.write( Oj.dump(@schema_data.merge(@table_data),
:mode => :compat) )
json_output_stream.close
@filenames = [File.join( tmp_directory, 'tables.json' )]
end
def filenames
@filenames ||= []
end
def cleanup_temp
FileUtils.rm_rf(tmp_directory) if Dir[tmp_directory].present?
end
end
end