class Parse::Db::Import

Constants

DATE_CONVENTIONS
VERSION

Public Instance Methods

create_missing_columns(klass, missing_columns) click to toggle source
# File lib/parse/db/import/activerecord_helpers.rb, line 66
def create_missing_columns(klass, missing_columns)
  return if missing_columns.length == 0

  #Create any columns that are missing.
  dbconnection = klass.connection
  dbconnection.change_table(klass.table_name) do |t|
    missing_columns.each do |k,v|
      if v.is_a? Fixnum
        t.column k, :string, { limit: v }
      else
        t.column k, v
      end
    end
  end
  klass.reset_column_information
  klass.inheritance_column = "ar_type"
end
create_schema(options) click to toggle source
# File lib/parse/db/import/create_schema.rb, line 7
def create_schema(options)
  Dir["#{options.path}/#{options.entity}/data.json"].each do |file|
    missing_columns = {}
    klass = klass_from_file(file)
    puts "Scanning....#{klass.name}"
    process_parse_file(file) do |record|
      columns = get_missing_columns(klass, record.keys)
      unless columns.empty?
        columns.each do |k|
          missing_columns[k] = get_column_type(record[k], k)
        end
      end
      missing_columns.each do |k, v|
        next unless v.is_a? Fixnum
        len = record[k].to_s.length 
        missing_columns[k] = len if v < len
      end
    end
    if (missing_columns.length)
      puts "Creating....#{klass.name} columns #{missing_columns.map{|k,v| "#{k} varchar(#{v})"}.join(", ")}"
      create_missing_columns(klass, missing_columns)
    end
  end
end
create_table_if_missing(klass) click to toggle source
# File lib/parse/db/import/activerecord_helpers.rb, line 25
def create_table_if_missing klass
  dbconnection = klass.connection
  dbconnection = klass.connection
  dbconnection.create_table(klass.table_name) unless dbconnection.table_exists? klass.table_name
end
get_class(class_name) click to toggle source
# File lib/parse/db/import/activerecord_helpers.rb, line 16
def get_class(class_name)
  return self.class.const_get(class_name, false) if self.class.const_defined?(class_name, false)
  klass = self.class.const_set(class_name, Class.new(ActiveRecord::Base) do
    @inheritance_column = "ar_type"
  end)
  create_table_if_missing(klass)
  klass
end
get_column_type(val, column) click to toggle source
# File lib/parse/db/import/activerecord_helpers.rb, line 52
def get_column_type(val, column)
  return :timestamp if is_date_by_naming_convention(column)
  case val
    when String
      val.length
    when TrueClass, FalseClass
      :boolean
    when Float
      :float
    when Fixnum
      :integer
  end
end
get_missing_columns(klass, columns) click to toggle source
# File lib/parse/db/import/activerecord_helpers.rb, line 30
def get_missing_columns(klass, columns)
  @seen_columns ||= {}
  missing_columns = []
  # Get the list of columns that we've already checked.
  seen_columns = @seen_columns[klass.table_name] || []

  # We don't need to check columns that we've already checked.
  columns -= seen_columns
  return columns if columns.empty?


  dbconnection = klass.connection

  #Get a listing of all the columns that don't exist in the entity
  columns.each { |k| missing_columns.push(k) unless dbconnection.column_exists?(klass.table_name, k) }


  #Mark that we've seen all these columns so we don't need to search the database again.
  @seen_columns[klass.table_name] = seen_columns | columns
  missing_columns
end
import_data(options) click to toggle source
# File lib/parse/db/import/import_data.rb, line 6
def import_data(options)
  Dir["#{options.path}/#{options.entity}/data.json"].each do |file|
    klass = klass_from_file(file)
    puts "Importing....#{klass.name}"
    process_parse_file(file) do |record|
      begin
        klass.new(record).save!()
      rescue Exception
        puts record
        raise
      end
    end
  end
end
init_active_record(options) click to toggle source
# File lib/parse/db/import/activerecord_helpers.rb, line 7
def init_active_record(options)
  ActiveRecord::Base.establish_connection({
    adapter: options.adapter,
    host: options.host,
    username: options.dbuser,
    password: options.dbpassword,
    database: options.dbname
  })
end
is_date_by_naming_convention(column_name) click to toggle source
# File lib/parse/db/import/utils.rb, line 16
def is_date_by_naming_convention column_name
  DATE_CONVENTIONS.any? { |regx| column_name =~ regx }
end
klass_from_file(file) click to toggle source
# File lib/parse/db/import/utils.rb, line 20
def klass_from_file(file)
  class_name = File.basename(File.dirname(file))
  get_class(class_name)
end
map_data_types(record) click to toggle source
# File lib/parse/db/import/utils.rb, line 9
def map_data_types(record)
  #Convert arrays to strings, since we're not supporting them yet.
  record.each { |k, v| record[k] = v.join(', ') if v.is_a? Array }
  #Convert epoch to datetime
  record.each { |k, v| record[k] =  DateTime.strptime(v.to_s, "%Q") if is_date_by_naming_convention(k) }
end
process_parse_file(file) { |record| ... } click to toggle source
# File lib/parse/db/import/utils.rb, line 25
def process_parse_file(file, &block)
  IO.foreach(file) do |record|
    record = JSON.parse(record)
    record = map_data_types(record)
    next if record["delete"]
    yield(record)
  end
end
run(options) click to toggle source
# File lib/parse/db/import.rb, line 9
def run(options)
  options.default({ host: "localhost", adapter: "postgresql", entity: "**" })
  init_active_record options
  create_schema options
  import_data options
end