extract 0.1.1 → 0.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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