extract 0.1.1 → 0.1.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -14,7 +14,7 @@ module Extract
14
14
  def max(*args)
15
15
  args.flatten.select { |x| x }.sort.reverse.first
16
16
  end
17
- def vlookup(lookup_val,range,col_num)
17
+ def vlookup(lookup_val,range,col_num,*junk)
18
18
  range.each do |row|
19
19
  if row[0] == lookup_val
20
20
  return row[col_num-1]
@@ -0,0 +1,8 @@
1
+ module Extract
2
+ module Export
3
+ class Ddl
4
+ include FromHash
5
+ attr_accessor :tables
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,48 @@
1
+ module Extract
2
+ module Export
3
+ class Table
4
+ include FromHash
5
+ attr_accessor :name
6
+ fattr(:rows) { [] }
7
+
8
+ def cols
9
+ rows.map { |x| x.keys }.flatten.uniq
10
+ end
11
+
12
+ def quoted_col(col)
13
+ return col
14
+ if col.to_s[0..0] =~ /\d/
15
+ "\"#{col}\""
16
+ else
17
+ col
18
+ end
19
+ end
20
+
21
+ def create_table_sql
22
+ col_str = cols.map { |x| " #{quoted_col(x)} varchar(255)" }.join(",\n")
23
+ "CREATE TABLE #{name} (
24
+ #{col_str}
25
+ );"
26
+ end
27
+
28
+ def inserts
29
+ res = []
30
+ rows.each do |row|
31
+ col_str = row.keys.map { |x| quoted_col(x) }.join(",")
32
+ val_str = row.values.map { |x| "'#{x}'" }.join(',')
33
+ str = "INSERT INTO #{name} (#{col_str}) VALUES (#{val_str});"
34
+ res << str
35
+ end
36
+ res
37
+ end
38
+
39
+ def sql_statements
40
+ [create_table_sql,inserts].flatten
41
+ end
42
+
43
+ def sql
44
+ sql_statements.join("\n")
45
+ end
46
+ end
47
+ end
48
+ end
@@ -57,6 +57,9 @@ grammar Formula
57
57
  def excel_value
58
58
  (text_value == "TRUE") ? true : false
59
59
  end
60
+ def deps
61
+ []
62
+ end
60
63
  }
61
64
  end
62
65
 
@@ -0,0 +1,38 @@
1
+ module Extract
2
+ class InlineDef
3
+ include FromHash
4
+ attr_accessor :raw
5
+ def parse_raw_cell(cell)
6
+ if cell == '_'
7
+ nil
8
+ elsif cell =~ /^=/
9
+ cell
10
+ elsif cell =~ /[a-z]/i
11
+ cell
12
+ elsif cell =~ /[0-9]/i
13
+ cell.to_f
14
+ else
15
+ raise "dunno"
16
+ end
17
+ end
18
+ fattr(:rows) do
19
+ raw.strip.split("\n").map do |str|
20
+ str.strip.split(" ").map do |cell|
21
+ parse_raw_cell(cell)
22
+ end
23
+ end
24
+ end
25
+
26
+ fattr(:sheet) do
27
+ res = Sheet.new
28
+ letters = ("A".."Z").to_a
29
+ rows.each_with_index do |row,row_i|
30
+ row.each_with_index do |val,col_i|
31
+ cell = letters[col_i] + (row_i+1).to_s
32
+ res[cell] = val if val
33
+ end
34
+ end
35
+ res
36
+ end
37
+ end
38
+ end
@@ -17,6 +17,9 @@ module Extract
17
17
  res
18
18
  end
19
19
  end
20
+ def raw_value(c)
21
+ cells[c]
22
+ end
20
23
 
21
24
  def clear_cache!
22
25
  self.cache = {}
@@ -58,18 +61,19 @@ module Extract
58
61
 
59
62
 
60
63
  class << self
61
- def load(file)
64
+ def load(file,sheet_name=nil)
62
65
  w = Roo::Excelx.new(file)
63
- w.default_sheet = w.sheets.first
66
+ w.default_sheet = sheet_name || w.sheets.first
64
67
 
65
68
  sheet = Extract::Sheet.new
66
69
 
67
70
  ("A".."Z").each do |col|
68
71
  (1..100).each do |row|
69
- val = if w.formula?(row,col)
72
+ cell_text = w.cell(row,col)
73
+ val = if cell_text.present? && w.formula?(row,col)
70
74
  "=" + w.formula(row,col).gsub(" ","")
71
75
  else
72
- w.cell(row,col)
76
+ cell_text
73
77
  end
74
78
  loaded = w.cell(row,col)
75
79
  sheet["#{col}#{row}"] = val if val.present?
@@ -79,6 +83,10 @@ module Extract
79
83
 
80
84
  sheet
81
85
  end
86
+
87
+ def inline(str)
88
+ InlineDef.new(:raw => str).sheet
89
+ end
82
90
  end
83
91
 
84
92
  end
@@ -3,6 +3,8 @@ module Extract
3
3
  include FromHash
4
4
  attr_accessor :sheet
5
5
 
6
+ fattr(:tables) { Tables.new(:sheet_def => self) }
7
+
6
8
  def prev_letter(letter)
7
9
  r = ("A".."Z").to_a
8
10
  raise "bad letter #{letter}" unless r.index(letter)
@@ -19,19 +21,19 @@ module Extract
19
21
  res = {}
20
22
  (input_cells + output_cells).each do |c|
21
23
  n = left(c)
22
- res[c] = sheet[n]
24
+ res[c] = sheet[n] if !sheet[n].kind_of?(Numeric) && sheet[n].to_s.strip != '' && sheet[n].to_s.strip != 'N/A'
25
+ end
26
+
27
+ each_other_basic do |c|
28
+ n = left(c)
29
+ res[c] = sheet[n] if !sheet[n].kind_of?(Numeric) && sheet[n].to_s.strip != '' && sheet[n].to_s.strip != 'N/A'
23
30
  end
31
+
24
32
  res
25
33
  end
26
34
  fattr(:output_cells) { [] }
27
35
  def output_cells=(arr)
28
- @output_cells = arr.map do |c|
29
- if c =~ /:/
30
- Extract::Tree::Range.cells_in_range(c)
31
- else
32
- c
33
- end
34
- end.flatten
36
+ @output_cells = Extract.expand_cells(arr).uniq
35
37
  end
36
38
 
37
39
  fattr(:dep_map) do
@@ -48,6 +50,20 @@ module Extract
48
50
  res
49
51
  end
50
52
 
53
+ def deps(cell,ops={})
54
+ raw = sheet.deps(cell)
55
+ if ops[:table]
56
+ res = []
57
+ raw.each do |c|
58
+ t = tables.for_cell(c)
59
+ res << (t || c)
60
+ end
61
+ res.uniq.sort
62
+ else
63
+ raw
64
+ end
65
+ end
66
+
51
67
  fattr(:input_cells) do
52
68
  output_cells.map do |c|
53
69
  a = dep_map[c] || []
@@ -86,6 +102,9 @@ module Extract
86
102
  def [](c)
87
103
  sheet[c]
88
104
  end
105
+ def raw_value(c)
106
+ sheet.cells[c]
107
+ end
89
108
 
90
109
  def each_input
91
110
  input_cells.each do |cell|
@@ -99,7 +118,7 @@ module Extract
99
118
  end
100
119
  end
101
120
 
102
- def each_other
121
+ def each_other_basic
103
122
  res = []
104
123
  bad = input_cells + output_cells
105
124
  sheet.cells.each do |k,v|
@@ -110,15 +129,21 @@ module Extract
110
129
 
111
130
  res.each do |c|
112
131
  d = sheet.deps(c)
113
- yield c,sheet.cells[c],d if sheet.cells[c].present? && d.size > 0
132
+ yield c if sheet.cells[c].present? && d.size > 0
114
133
  end
134
+ end
115
135
 
136
+ def each_other
137
+ each_other_basic do |c|
138
+ d = sheet.deps(c)
139
+ yield c,cell_names[c],sheet[c],sheet.cells[c],d
140
+ end
116
141
  end
117
142
 
118
143
  class << self
119
- def load(file,output)
144
+ def load(file,output,sheet_name=nil)
120
145
  res = new
121
- res.sheet = Sheet.load(file)
146
+ res.sheet = Sheet.load(file,sheet_name)
122
147
  res.output_cells = output
123
148
  res
124
149
  end
@@ -0,0 +1,67 @@
1
+ module Extract
2
+ class Row
3
+ include FromHash
4
+ include Enumerable
5
+ attr_accessor :table, :cells
6
+
7
+ fattr(:value_hash) do
8
+ res = {}
9
+ raise "bad match" unless table.field_names.size == cells.size
10
+ table.field_names.each_with_index do |name,i|
11
+ cell = cells[i]
12
+ res[name] = cell.value
13
+ end
14
+ res
15
+ end
16
+
17
+ def [](k)
18
+ value_hash[k]
19
+ end
20
+
21
+ def each(&b)
22
+ value_hash.each(&b)
23
+ end
24
+
25
+ def present?
26
+ value_hash.values.any? { |x| x.present? }
27
+ end
28
+ end
29
+ class Table
30
+ include FromHash
31
+ attr_accessor :cell_range, :name, :sheet_def
32
+
33
+ def cells
34
+ Extract.expand_cells(cell_range)
35
+ end
36
+
37
+ def cell_objs
38
+ cells.map { |c| Cell.new(:sheet_def => sheet_def, :cell => c) }
39
+ end
40
+ def cell_row_hash
41
+ res = Hash.new { |h,k| h[k] = [] }
42
+ cell_objs.each do |c|
43
+ res[c.row] << c
44
+ end
45
+ res
46
+ end
47
+
48
+ def field_names
49
+ k = cell_row_hash.keys.min
50
+ cell_row_hash[k].map { |x| x.value }
51
+ end
52
+
53
+ def rows
54
+ cell_row_hash.values[1..-1].map { |a| Row.new(:table => self, :cells => a) }.select { |x| x.present? }
55
+ end
56
+
57
+ def sql_statements
58
+ res = Extract::Export::Table.new(:name => name)
59
+ rows.each do |row|
60
+ res.rows << row.value_hash
61
+ end
62
+ res.sql_statements
63
+ end
64
+
65
+
66
+ end
67
+ end
@@ -0,0 +1,39 @@
1
+ module Extract
2
+ class Tables
3
+ include FromHash
4
+ attr_accessor :sheet_def
5
+ fattr(:tables) { {} }
6
+
7
+ def add(name,range)
8
+ self.tables[name] = Table.new(:cell_range => range, :name => name, :sheet_def => sheet_def)
9
+ end
10
+
11
+ fattr(:cell_map) do
12
+ res = {}
13
+ tables.each do |name,table|
14
+ table.cells.each do |c|
15
+ res[c] = name
16
+ end
17
+ end
18
+ res
19
+ end
20
+
21
+ def for_cell(c)
22
+ cell_map[c]
23
+ end
24
+
25
+ def [](c)
26
+ if c.to_s == 'all'
27
+ Table.new(:cell_range => "A1:D100", :name => "all", :sheet_def => sheet_def)
28
+ else
29
+ tables[c]
30
+ end
31
+ end
32
+ def each(&b)
33
+ tables.each(&b)
34
+ end
35
+ def values
36
+ tables.values
37
+ end
38
+ end
39
+ end
Binary file
@@ -0,0 +1,31 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+ describe 'Cell' do
4
+ let(:sheet) do
5
+ res = Extract::Sheet.new
6
+ {"A1" => 1, "A2" => 2, "A3" => 3, "B1" => 4, "B2" => 5, "B3" => 6}.each do |k,v|
7
+ res[k] = v
8
+ end
9
+ res["C1"] = "=A1"
10
+ res['D1'] = "=C1"
11
+ res['E1'] = "=D1"
12
+
13
+ res['F1'] = "=A1+A2"
14
+ res
15
+ end
16
+
17
+ let(:cell) do
18
+ Extract::Cell.new(:sheet_def => sheet, :cell => "C1")
19
+ end
20
+
21
+ it 'value' do
22
+ cell.value.should == 1
23
+ end
24
+
25
+ it 'row' do
26
+ cell.row.should == 1
27
+ end
28
+ it 'col' do
29
+ cell.col.should == "C"
30
+ end
31
+ end
@@ -3,4 +3,11 @@ development:
3
3
  default:
4
4
  database: mongoid_dev
5
5
  hosts:
6
- - localhost:27017
6
+ - localhost:27017
7
+ test:
8
+ sessions:
9
+ default:
10
+ uri: mongodb://extract_test:extract_test@linus.mongohq.com:10038/extract_test
11
+ options:
12
+ skip_version_check: true
13
+ safe: true
@@ -0,0 +1,45 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+
3
+ class String
4
+ def ssf
5
+ gsub("\n"," ").gsub(/[ ]{2,99}/," ")
6
+ end
7
+ end
8
+
9
+ describe 'Export Table' do
10
+ describe "basic" do
11
+ let(:table) do
12
+ res = Extract::Export::Table.new(:name => "widgets")
13
+ res.rows << {:color => "Green", :price => 20}
14
+ res
15
+ end
16
+
17
+ it 'create table sql' do
18
+ exp = "CREATE TABLE widgets (
19
+ color varchar(255),
20
+ price varchar(255)
21
+ );"
22
+ table.create_table_sql.ssf.should == exp.ssf
23
+ end
24
+
25
+ it 'inserts' do
26
+ table.inserts.size.should == 1
27
+ table.inserts[0].ssf.should == "INSERT INTO widgets (color,price) VALUES ('Green','20');"
28
+ end
29
+ end
30
+
31
+ describe "needs quotes" do
32
+ let(:table) do
33
+ res = Extract::Export::Table.new(:name => "widgets")
34
+ res.rows << {"2B" => 14}
35
+ res
36
+ end
37
+
38
+ it 'create table' do
39
+ exp = 'CREATE TABLE widgets (
40
+ "2B" varchar(255)
41
+ );'
42
+ table.create_table_sql.ssf.should == exp.ssf
43
+ end
44
+ end
45
+ end