Class: Knj::Db::Dump

Inherits:
Object show all
Defined in:
lib/knj/knjdb/dump.rb

Overview

This class can be used to make SQL-dumps of databases, tables or however you want it.

Instance Method Summary collapse

Constructor Details

#initialize(args) ⇒ Dump

Constructor.

Examples

dump = Knj::Db::Dump.new(:db => db)



6
7
8
9
# File 'lib/knj/knjdb/dump.rb', line 6

def initialize(args)
  @args = args
  @debug = @args[:debug]
end

Instance Method Details

#dump(io) ⇒ Object

Dumps all tables into the given IO.



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
# File 'lib/knj/knjdb/dump.rb', line 22

def dump(io)
  print "Going through tables.\n" if @debug
  @rows_count = 0
  
  if @args[:tables]
    tables = @args[:tables]
  else
    tables = @args[:db].tables.list.values
  end
  
  if @on_status
    @on_status.call(:text => "Preparing.")
    
    @rows_count_total = 0
    tables.each do |table_obj|
      @rows_count_total += table_obj.rows_count
    end
  end
  
  tables.each do |table_obj|
    table_obj = @args[:db].tables[table_obj] if table_obj.is_a?(String) or table_obj.is_a?(Symbol)
    next if table_obj.native?
    
    #Figure out keys.
    @keys = []
    table_obj.columns do |col|
      @keys << col.name
    end
    
    @table_obj = table_obj
    self.update_status
    print "Dumping table: '#{table_obj.name}'.\n" if @debug
    self.dump_table(io, table_obj)
  end
end

#dump_insert_multi(io, table_obj, rows) ⇒ Object

Dumps the given rows from the given table into the given IO.



110
111
112
113
114
115
116
117
118
119
120
121
# File 'lib/knj/knjdb/dump.rb', line 110

def dump_insert_multi(io, table_obj, rows)
  print "Inserting #{rows.length} into #{table_obj.name}.\n" if @debug
  sqls = @args[:db].insert_multi(table_obj.name, rows, :return_sql => true, :keys => @keys)
  sqls.each do |sql|
    io.write("#{sql};\n")
  end
  
  rows.clear
  
  #Ensure garbage collection or we might start using A LOT of memory.
  GC.start
end

#dump_table(io, table_obj) ⇒ Object

Dumps the given table into the given IO.



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
# File 'lib/knj/knjdb/dump.rb', line 64

def dump_table(io, table_obj)
  #Get SQL for creating table and add it to IO.
  sqls = @args[:db].tables.create(table_obj.name, table_obj.data, :return_sql => true)
  sqls.each do |sql|
    io.write("#{sql};\n")
  end
  
  
  #Try to find a primary column in the table.
  prim_col = nil
  table_obj.columns do |col|
    if col.primarykey?
      prim_col = col
      break
    end
  end
  
  
  #Set up rows and way to fill rows.
  rows = []
  block_data = proc do |row|
    rows << row
    @rows_count += 1
    
    if rows.length >= 1000
      self.update_status
      self.dump_insert_multi(io, table_obj, rows)
    end
  end
  
  
  #If a primary column is found then use IDQuery. Otherwise use cloned unbuffered query.
  args = {:idquery => prim_col.name.to_sym} if prim_col
  
  
  #Clone the connecting with array-results and execute query.
  @args[:db].clone_conn(:result => "array") do |db|
    db.select(table_obj.name, nil, args, &block_data)
  end
  
  
  #Dump the last rows if any.
  self.dump_insert_multi(io, table_obj, rows) if !rows.empty?
end

#on_status(&block) ⇒ Object

A block can be executed when a new status occurs.



59
60
61
# File 'lib/knj/knjdb/dump.rb', line 59

def on_status(&block)
  @on_status = block
end

#update_statusObject

Method used to update the status.



12
13
14
15
16
17
18
19
# File 'lib/knj/knjdb/dump.rb', line 12

def update_status
  return nil if !@on_status
  rows_count = Knj::Locales.number_out(@rows_count, 0)
  rows_count_total = Knj::Locales.number_out(@rows_count_total, 0)
  percent = (@rows_count.to_f / @rows_count_total.to_f) * 100
  percent_text = Knj::Locales.number_out(percent, 1)
  @on_status.call(:text => "Dumping table: '#{@table_obj.name}' (#{rows_count}/#{rows_count_total} - #{percent_text}%).")
end