Class: ActiveTable::Base

Inherits:
ActiveRecord::Base
  • Object
show all
Defined in:
lib/active_table/base.rb

Constant Summary collapse

@@detected_classes =
[]
@@insert_statements =
[]
@@table_list =
[]

Class Method Summary collapse

Class Method Details

.active_table(&block) ⇒ Object



8
9
10
11
12
13
14
15
16
17
18
19
# File 'lib/active_table/base.rb', line 8

def active_table(&block)
  @table = {}
  block.call

  unless model_loaded?
    create_table!
    model_loaded!
  end

  self.reset_column_information
  self.define_attribute_methods
end

.add_detected_class(grep_match) ⇒ Object



46
47
48
49
# File 'lib/active_table/base.rb', line 46

def add_detected_class(grep_match)
  class_name = grep_match[/class\ (.*) < ActiveTable::Base/, 1]
  @@detected_classes << class_name.constantize
end

.create_table(name, options = {}, &block) ⇒ Object



31
32
33
34
35
# File 'lib/active_table/base.rb', line 31

def create_table(name, options = {}, &block)
  class_name = self.name
  self.set_table_name name
  @table = {:name => name, :options => options, :block => block, :rows => []}
end

.create_table!Object



55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
# File 'lib/active_table/base.rb', line 55

def create_table!
  temp_table_name = "#{@table[:name]}__temp"

  unless connection.table_exists?(temp_table_name)
    db_drop_and_create_table(temp_table_name, @table[:options], @table[:block])
    insert_rows!(@table[:name], :temporary => true)

    case [tables_match?(@table[:name], temp_table_name), rows_match?(@table[:name], temp_table_name)]
      when [false, false], [false, true]
        db_drop_table(@table[:name])
        connection.rename_table(temp_table_name, @table[:name])
      when [true, false]
        db_truncate_and_copy_tables(@table[:name], temp_table_name)
        db_drop_table(temp_table_name)
      when [true, true]
        db_drop_table(temp_table_name)
    end
  end
end

.db_drop_and_create_table(name, options, block) ⇒ Object



115
116
117
118
119
120
# File 'lib/active_table/base.rb', line 115

def db_drop_and_create_table(name, options, block)
  db_drop_table(name)
  connection.create_table name, options do |t|
    block.call(t)
  end
end

.db_drop_table(name) ⇒ Object



122
123
124
# File 'lib/active_table/base.rb', line 122

def db_drop_table(name)
  connection.execute "DROP TABLE IF EXISTS #{connection.quote_table_name(name)}"
end

.db_truncate_and_copy_tables(destination, source) ⇒ Object



110
111
112
113
# File 'lib/active_table/base.rb', line 110

def db_truncate_and_copy_tables(destination, source)
  connection.execute("DELETE FROM #{connection.quote_table_name(destination)}")
  connection.execute("INSERT INTO #{connection.quote_table_name(destination)} SELECT * FROM #{connection.quote_table_name(source)}")
end

.detected_classesObject



51
52
53
# File 'lib/active_table/base.rb', line 51

def detected_classes
  @@detected_classes
end

.generate_insert_sql_for_hash(connection, table_name, params) ⇒ Object



135
136
137
138
139
# File 'lib/active_table/base.rb', line 135

def generate_insert_sql_for_hash(connection, table_name, params)
  keys = params.keys.map {|k| connection.quote_column_name(k.to_s)}.join(", ")
  values = params.values.map {|v| connection.quote(v.to_s)}.join(", ")
  "INSERT INTO #{connection.quote_table_name(table_name.to_s)} (#{keys}) VALUES (#{values})"
end

.insert(params) ⇒ Object



37
38
39
40
# File 'lib/active_table/base.rb', line 37

def insert(params)
  class_name = self.name
  @table[:rows] << params
end

.insert_rows!(table_name, options = {}) ⇒ Object



75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
# File 'lib/active_table/base.rb', line 75

def insert_rows!(table_name, options = {})
  @@insert_statements.reject!{|statement| statement[:table_name] == @table[:name]}
  @@table_list << @table[:name] unless @@table_list.include?(@table[:name])

  @table[:rows].each do |row|
    if options[:temporary]
      insert_sql_now = generate_insert_sql_for_hash(connection, "#{table_name}__temp", row)
      insert_sql_later = generate_insert_sql_for_hash(connection, table_name, row)
    else
      insert_sql_now = insert_sql_later = generate_insert_sql_for_hash(connection, table_name_name, row)
    end
    @@insert_statements << {:table_name => @table[:name], :sql => insert_sql_later}
    connection.execute insert_sql_now
  end
end

.model_loaded!Object



21
22
23
24
# File 'lib/active_table/base.rb', line 21

def model_loaded!
  return unless defined?(Rails)
  Rails.active_table_loaded_model_names << self.name
end

.model_loaded?Boolean

Returns:

  • (Boolean)


26
27
28
29
# File 'lib/active_table/base.rb', line 26

def model_loaded?
  return false unless defined?(Rails)
  Rails.active_table_loaded_model_names.include?(self.name)
end

.rows_match?(table_1, table_2) ⇒ Boolean

Returns:

  • (Boolean)


98
99
100
101
102
103
104
105
106
107
108
# File 'lib/active_table/base.rb', line 98

def rows_match?(table_1, table_2)
  return false unless connection.table_exists?(table_1) and connection.table_exists?(table_2)

  query = "SELECT COUNT(*) AS rows FROM (SELECT DISTINCT * FROM ( SELECT * FROM #{connection.quote_table_name(table_1)} UNION ALL SELECT * FROM #{connection.quote_table_name(table_2)} ) t) s"
  distinct_count = connection.execute(query).first["rows"]

  query = "SELECT COUNT(*) AS rows FROM #{connection.quote_table_name(table_1)}"
  current_count = connection.execute(query).first["rows"]

  distinct_count == current_count
end

.seed!Object



126
127
128
129
130
131
132
133
# File 'lib/active_table/base.rb', line 126

def seed!
  @@insert_statements.each do |insert|
    begin
      connection.execute(insert[:sql])
    rescue ActiveRecord::RecordNotUnique
    end
  end
end

.table_listObject



42
43
44
# File 'lib/active_table/base.rb', line 42

def table_list
  @@table_list
end

.tables_match?(table_1, table_2) ⇒ Boolean

Returns:

  • (Boolean)


91
92
93
94
95
96
# File 'lib/active_table/base.rb', line 91

def tables_match?(table_1, table_2)
  return false unless connection.table_exists?(table_1) and connection.table_exists?(table_2)
  columns_1 = connection.columns(table_1)
  columns_2 = connection.columns(table_2)
  columns_1.to_json == columns_2.to_json
end