Class: Knjdbrevision

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

Instance Method Summary collapse

Constructor Details

#initialize(args = {}) ⇒ Knjdbrevision

Returns a new instance of Knjdbrevision.



2
3
4
# File 'lib/knjdbrevision.rb', line 2

def initialize(args = {})
  @args = args
end

Instance Method Details

#init_db(schema, db) ⇒ Object



6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
# File 'lib/knjdbrevision.rb', line 6

def init_db(schema, db)
  schema["tables"].each do |table_name, table_data|
    begin
      begin
        table_obj = db.tables[table_name.to_sym]
        
        if table_data["columns"]
          table_data["columns"].each do |col_data|
            begin
              col_obj = table_obj.column(col_data["name"])
              col_str = "#{table_name}.#{col_obj.name}"
              type = col_data["type"].to_s
              
              #BUGFIX: When using SQLite3 the primary-column or a autoincr-column may never change type from int... This will break it!
              if db.opts[:type] == "sqlite3" and col_obj.type.to_s == "int" and (col_data["primarykey"] or col_data["autoincr"]) and db.int_types.index(col_data["type"].to_s)
                type = "int"
              end
              
              dochange = false
              
              if type and col_obj.type.to_s != type
                print "Type mismatch on #{col_str}: #{col_data["type"]}, #{col_obj.type}\n"
                dochange = true
              end
              
              if col_data.has_key?("maxlength") and col_obj.maxlength.to_s != col_data["maxlength"].to_s
                print "Maxlength mismatch on #{col_str}: #{col_data["maxlength"]}, #{col_obj.maxlength}\n"
                dochange = true
              end
              
              if col_data.has_key?("null") and col_obj.null?.to_s != col_data["null"].to_s
                print "Null mismatch on #{col_str}: #{col_data["null"]}, #{col_obj.null?}\n"
                dochange = true
              end
              
              if col_data.has_key?("default") and col_obj.default.to_s != col_data["default"].to_s
                print "Default mismatch on #{col_str}: #{col_data["default"]}, #{col_obj.default}\n"
                dochange = true
              end
              
              if col_data.has_key?("comment") and col_obj.comment.to_s != col_data["comment"].to_s
                print "Comment mismatch on #{col_str}: #{col_data["comment"]}, #{col_obj.comment}\n"
                dochange = true
              end
              
              if col_data.is_a?(Hash) and col_data["on_before_alter"]
                callback_data = col_data["on_before_alter"].call("db" => db, "table" => table_obj, "col" => col_obj, "col_data" => col_data)
                if callback_data and callback_data["action"]
                  if callback_data["action"] == "retry"
                    raise Knj::Errors::Retry
                  end
                end
              end
              
              col_obj.change(col_data) if dochange
            rescue Knj::Errors::NotFound => e
              print "Column not found: #{table_obj.name}.#{col_data["name"]}.\n"
              
              if col_data.has_key?("renames")
                rename_found = false
                col_data["renames"].each do |col_name|
                  begin
                    col_rename = table_obj.column(col_name)
                  rescue Knj::Errors::NotFound => e
                    next
                  end
                  
                  print "Rename #{table_obj.name}.#{col_name} to #{table_obj.name}.#{col_data["name"]}\n"
                  if col_data.is_a?(Hash) and col_data["on_before_rename"]
                    col_data["on_before_rename"].call("db" => db, "table" => table_obj, "col" => col_rename, "col_data" => col_data)
                  end
                  
                  col_rename.change(col_data)
                  
                  if col_data.is_a?(Hash) and col_data["on_after_rename"]
                    col_data["on_after_rename"].call("db" => db, "table" => table_obj, "col" => col_rename, "col_data" => col_data)
                  end
                  
                  rename_found = true
                  break
                end
                
                retry if rename_found
              end
              
              #Try to find out the previous column - if so we can set "after" which makes the column being created in the right order as defined.
              if !col_data.has_key?("after")
                prev_no = table_data["columns"].index(col_data)
                if prev_no != nil and prev_no != 0
                  prev_no = prev_no - 1
                  prev_col_data = table_data["columns"][prev_no]
                  col_data["after"] = prev_col_data["name"]
                end
              end
              
              oncreated = col_data["on_created"]
              col_data.delete("on_created") if col_data["oncreated"]
              col_obj = table_obj.create_columns([col_data])
              oncreated.call("db" => db, "table" => table_obj) if oncreated
            end
          end
        end
        
        if table_data["columns_remove"]
          table_data["columns_remove"].each do |column_name, column_data|
            begin
              col_obj = table_obj.column(column_name)
            rescue Knj::Errors::NotFound => e
              next
            end
            
            column_data["callback"].call if column_data.is_a?(Hash) and column_data["callback"]
            col_obj.drop
          end
        end
        
        if table_data["indexes"]
          table_data["indexes"].each do |index_data|
            begin
              index_obj = table_obj.index(index_data["name"])
            rescue Knj::Errors::NotFound => e
              table_obj.create_indexes([index_data])
            end
          end
        end
        
        if table_data["indexes_remove"]
          table_data["indexes_remove"].each do |index_name, index_data|
            begin
              index_obj = table_obj.index(index_name)
            rescue Knj::Errors::NotFound => e
              next
            end
            
            if index_data.is_a?(Hash) and index_data["callback"]
              index_data["callback"].call if index_data["callback"]
            end
            
            index_obj.drop
          end
        end
        
        if table_data["rows"]
          table_data["rows"].each do |row_data|
            if row_data["find_by"]
              find_by = row_data["find_by"]
            elsif row_data["data"]
              find_by = row_data["data"]
            else
              raise "Could not figure out the find-by."
            end
            
            rows_found = 0
            q_rows = db.select(table_name, find_by)
            while d_rows = q_rows.fetch
              rows_found += 1
              
              if Knj::ArrayExt.hash_diff?(Knj::ArrayExt.hash_sym(row_data["data"]), Knj::ArrayExt.hash_sym(d_rows), {"h2_to_h1" => false})
                print "Data was not right - updating row: #{JSON.generate(row_data["data"])}\n"
                db.update(table_name, row_data["data"], d_rows)
              end
            end
            
            if rows_found == 0
              print "Inserting row: #{JSON.generate(row_data["data"])}\n"
              db.insert(table_name, row_data["data"])
            end
          end
        end
      rescue Knj::Errors::NotFound => e
        if table_data["renames"]
          table_data["renames"].each do |table_name_rename|
            begin
              table_rename = db.tables[table_name_rename]
              table_rename.rename(table_name)
              raise Knj::Errors::Retry
            rescue Knj::Errors::NotFound
              next
            end
          end
        end
        
        if table_data["on_create"]
          table_data["on_create"].call("db" => db, "table_name" => table_name, "table_data" => table_data)
        end
        
        table_obj = db.tables.create(table_name, table_data)
        
        if table_data["on_create_after"]
          table_data["on_create_after"].call("db" => db, "table_name" => table_name, "table_data" => table_data)
        end
      end
    rescue Knj::Errors::Retry
      retry
    end
  end
  
  if schema["tables_remove"]
    schema["tables_remove"].each do |table_name, table_data|
      begin
        table_obj = db.tables[table_name.to_sym]
        table_data["callback"].call if table_data.is_a?(Hash) and table_data["callback"]
        table_obj.drop
      rescue Knj::Errors::NotFound => e
        next
      end
    end
  end
end