Class: Arison::Core

Inherits:
Object
  • Object
show all
Defined in:
lib/arison/core.rb

Instance Method Summary collapse

Constructor Details

#initialize(profile) ⇒ Core

Returns a new instance of Core.



8
9
10
11
12
13
# File 'lib/arison/core.rb', line 8

def initialize(profile)
  @profile = profile
  ActiveRecord::Base.establish_connection(@profile)
  ActiveRecord::Base.default_timezone = :local
  @connection = ActiveRecord::Base.connection
end

Instance Method Details

#add_column_live(table_name, data) ⇒ Object



162
163
164
165
166
167
168
169
170
171
172
173
# File 'lib/arison/core.rb', line 162

def add_column_live(table_name, data)
  data.each do |record|
    limits = get_limit_hash(get_class(table_name))
    diff_keys = (record.keys - limits.keys)

    diff_keys.each do |column|
      add_column_dsl = get_add_column_dsl(table_name, column, record)
      Arison::Migration.run_dsl(add_column_dsl)
    end
    ActiveRecord::Base.establish_connection(@profile)
  end
end

#columns(klass) ⇒ Object



23
24
25
26
27
# File 'lib/arison/core.rb', line 23

def columns(klass)
  klass.columns.map do |column|
    JSON.parse(column.to_json)
  end
end

#columns_with_table_name(table_name) ⇒ Object



19
20
21
# File 'lib/arison/core.rb', line 19

def columns_with_table_name(table_name)
  columns(get_class(table_name))
end

#create_table(table_name, data) ⇒ Object



80
81
82
83
84
85
86
87
88
89
# File 'lib/arison/core.rb', line 80

def create_table(table_name, data)
  first = data.class == Array ? data.first : data
  if @connection.data_source_exists?(table_name)
    add_column_live(table_name, data)
    return 
  end
  create_table_dsl = get_create_table_dsl(table_name, first)
  Arison::Migration.run_dsl(create_table_dsl)
  add_column_live(table_name, data)
end

#define_class(table_name) ⇒ Object



108
109
110
111
112
113
114
115
116
# File 'lib/arison/core.rb', line 108

def define_class(table_name)
  klass_sym = table_name.camelcase.to_sym
  if Object.constants.include?(klass_sym)
    Object.send(:remove_const, klass_sym)
  end
  Object.const_set(table_name.camelcase, Class.new(ActiveRecord::Base) do
    self.table_name = table_name
  end)
end

#get_add_column_dsl(table_name, column_name, record) ⇒ Object



74
75
76
77
78
# File 'lib/arison/core.rb', line 74

def get_add_column_dsl(table_name, column_name, record)
  dsl = %Q{
  add_column "#{table_name}", "#{column_name}", :#{get_type(column_name, record['column_name'])}
  }
end

#get_add_index_dsl(table_name, uniq_columns) ⇒ Object



68
69
70
71
72
# File 'lib/arison/core.rb', line 68

def get_add_index_dsl(table_name, uniq_columns)
  dsl = %Q{
  add_index(:#{table_name}, #{uniq_columns.map(&:to_sym)}, unique: true)
  }
end

#get_class(table_name) ⇒ Object



103
104
105
106
# File 'lib/arison/core.rb', line 103

def get_class(table_name)
  define_class(table_name)
  table_name.camelcase.constantize
end

#get_column_schema(hash) ⇒ Object



118
119
120
121
122
123
# File 'lib/arison/core.rb', line 118

def get_column_schema(hash)
  hash.map do |k, v|
    type = get_type(k, v)
    %Q{t.#{type} "#{k}"} unless type.nil?
  end
end

#get_create_table_dsl(table_name, hash) ⇒ Object



58
59
60
61
62
63
64
65
66
# File 'lib/arison/core.rb', line 58

def get_create_table_dsl(table_name, hash)
  dsl = %Q{
  create_table "#{table_name}" do |t|
    #{get_column_schema(hash).join("\n")}
    t.datetime "created_at"
    t.datetime "updated_at"
  end
  }
end

#get_limit_hash(klass) ⇒ Object



155
156
157
158
159
160
# File 'lib/arison/core.rb', line 155

def get_limit_hash(klass)
  columns(klass).inject({}){ |result, column| 
    result[column['name']] = column['limit']
    result
  }
end

#get_type(k, v) ⇒ Object



125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
# File 'lib/arison/core.rb', line 125

def get_type(k, v)
  if v.nil?
    %Q{string}
  elsif k =~ /^id$/i
    nil
  elsif v.class == String
    to_time_or_nil(v).nil? ? %Q{string} : %Q{datetime}
  elsif v.class == TrueClass || v.class == FalseClass
    %Q{boolean}
  elsif v.class == Fixnum
    %Q{integer}
  elsif v.class == Float
    %Q{float}
  elsif v.class == Array || v.class == Hash
    %Q{text}
  elsif v.respond_to?(:strftime)
    %Q{datetime}
  end
end

#import(table_name, data) ⇒ Object



33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
# File 'lib/arison/core.rb', line 33

def import(table_name, data)
  klass = get_class(table_name)
  limits = get_limit_hash(klass)
  instances = []
  data.each do |record|
    instance = klass.new
    begin
      record = record.inject({}){ |result, (k, v)|
        length = limits[k]
        result[k] = (length.nil? || v.nil? || v.class != String) ? v : v.slice(0, length)
        result
      }
      instance.attributes = record
    rescue ActiveRecord::UnknownAttributeError => e
    rescue => e
      puts "\n#{e.message}\n#{e.backtrace.join("\n")}"
    ensure
      instances << instance
    end
  end
  instances.in_groups_of(10000, false) do |block|
    klass.import(block)
  end
end

#parse_json(buffer) ⇒ Object



91
92
93
94
95
96
97
98
99
100
101
# File 'lib/arison/core.rb', line 91

def parse_json(buffer)
  begin
    data = JSON.parse(buffer)
  rescue => e
    data = []
    buffer.lines.each do |line|
      data << JSON.parse(line)
    end
  end
  data
end

#query(sql) ⇒ Object



15
16
17
# File 'lib/arison/core.rb', line 15

def query(sql)
  @connection.exec_query(sql).to_a
end

#tablesObject



29
30
31
# File 'lib/arison/core.rb', line 29

def tables
  @connection.tables
end

#to_time_or_nil(value) ⇒ Object



145
146
147
148
149
150
151
152
153
# File 'lib/arison/core.rb', line 145

def to_time_or_nil(value)
  return nil if value.slice(0, 4) !~ /^[0-9][0-9][0-9][0-9]/
  begin
    time = value.to_time
    time.to_i >= 0 ? time : nil
  rescue => e
    nil
  end
end