csv2sql 0.1.2

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.
Files changed (3) hide show
  1. data/README +71 -0
  2. data/lib/csv2sql.rb +171 -0
  3. metadata +47 -0
data/README ADDED
@@ -0,0 +1,71 @@
1
+ = Csv2sql -- convert comma-separated-values files to sql
2
+
3
+ Csv2sql class goes deeper into conversion process of csv files, ie:
4
+
5
+ puts Csv2sql.new("test.csv").to_inserts(:bulk => true)
6
+
7
+ outputs:
8
+
9
+ start tramsaction;
10
+ insert into test_csv values
11
+ (1, "test 1"),
12
+ (2, "test 2"),
13
+ (3, "test 3"),
14
+ (4, "test 4");
15
+ commit;
16
+
17
+ or:
18
+
19
+ puts Csv2sql.new("account_balances.csv").to_updates([nil, 'balance'], :table => 'accounts')
20
+
21
+ outputs:
22
+
23
+ start transaction;
24
+ update accounts set balance = "0" where id = "0345S";
25
+ update accounts set balance = "3301.37" where id = "0252S";
26
+ update accounts set balance = "11903.33" where id = "0345G";
27
+ update accounts set balance = "47028.32" where id = "0324G";
28
+ ...
29
+ commit;
30
+
31
+ You can use optional arguments, ie:
32
+
33
+ Csv2sql#to_inserts
34
+ :bulk - to get bulk inserts
35
+
36
+ Csv2sql#to_updates:
37
+ :before
38
+ :after
39
+ :row_filter
40
+ ...
41
+
42
+ For more details see api docs.
43
+
44
+ == Download
45
+
46
+ The latest version of Csv2sql can be found at
47
+
48
+ * http://mirekrusin.com/ruby/csv2sql
49
+
50
+ Documentation can be found at
51
+
52
+ * http://mirekrusin.com/ruby/csv2sql
53
+
54
+ == Installation
55
+
56
+ The preferred method of installing Csv2sql is through its GEM file. You'll need to have
57
+ RubyGems[http://rubygems.rubyforge.org/wiki/wiki.pl] installed for that, though. If you have it,
58
+ then use:
59
+
60
+ % [sudo] gem install csv2sql.gem
61
+
62
+ == License
63
+
64
+ Csv2sql is released under the LGPL license.
65
+
66
+ == Support
67
+
68
+ The Csv2sql homepage is http://mirekrusin.com/ruby/csv2sql
69
+
70
+ For other information, feel free to ask on the ruby-talk mailing list
71
+ (which is mirrored to comp.lang.ruby) or contact mailto:ruby@mirekrusin.com
data/lib/csv2sql.rb ADDED
@@ -0,0 +1,171 @@
1
+ # Csv2sql - Comma separated values files to sql conversion
2
+ #
3
+ # Copyright (c) 2007, London
4
+ # Mirek Rusin <ruby@mirekrusin.com>
5
+ #
6
+ # Licenced under GNU LGPL, http://www.gnu.org/licenses/lgpl.html
7
+ #
8
+ # This library is free software; you can redistribute it and/or
9
+ # modify it under the terms of the GNU Lesser General Public
10
+ # License as published by the Free Software Foundation; either
11
+ # version 2.1 of the License, or (at your option) any later version.
12
+ #
13
+ # This library is distributed in the hope that it will be useful,
14
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16
+ # Lesser General Public License for more details.
17
+ #
18
+ # You should have received a copy of the GNU Lesser General Public
19
+ # License along with this library; if not, write to the Free Software
20
+ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21
+
22
+ require 'csv'
23
+ require 'pathname'
24
+
25
+ # Example:
26
+ #
27
+ # puts Csv2sql.new("account_balances.csv").to_updates([nil, 'balance'], :table => 'accounts')
28
+ #
29
+ class Csv2sql
30
+
31
+ def self.default_value_filter(v, i, j, k)
32
+ return 'null' if v.nil? or v.strip! == ''
33
+ v.gsub!(/"/, '\\"')
34
+ "\"#{v}\""
35
+ end
36
+
37
+ def initialize(filename)
38
+ @filename = filename
39
+ end
40
+
41
+ # Sql inserts
42
+ #
43
+ # Optional named args:
44
+ # :bulk - if true, bulk insert (see cluster size in your sql server to make big bulks to avoid server gone away!)
45
+ # :table - default based on filename
46
+ # :before - default to start transaction
47
+ # :after - default to commit transaction
48
+ # ...see Csv2sql#to_any for the rest
49
+ #
50
+ def to_inserts(args={})
51
+ args[:table] ||= Pathname.new(@filename).basename.to_s.downcase.gsub(/\W/, '_')
52
+ if args[:bulk]
53
+ args[:before] ||= "start transaction;\ninsert into #{args[:table]} values"
54
+ args[:values_glue] ||= ", "
55
+ args[:row_format] ||= " (%s)"
56
+ args[:row_glue] ||= ",\n"
57
+ args[:after] ||= ";\ncommit transaction;\n"
58
+ else
59
+ args[:before] ||= "start transaction;\n"
60
+ args[:values_glue] ||= ", "
61
+ args[:row_format] ||= "insert into #{args[:table]} values(%s)"
62
+ args[:row_glue] ||= ";\n"
63
+ args[:after] ||= ";\ncommit transaction;\n"
64
+ end
65
+ to_any args
66
+ end
67
+
68
+ # Sql updates from csv file (useful when one of the columns is a PK)
69
+ #
70
+ # set_columns - ie. [nil, 'first_name', 'last_name'] will ignore first column (PK probably) and set first_name and last_name attributes
71
+ #
72
+ # Optional args:
73
+ # :pk - default to first (index 0) column in csv file with 'id' name, a pair: [0, 'id']
74
+ #
75
+ def to_updates(set_columns, args={})
76
+ args[:pk] ||= [0, 'id']
77
+ args[:table] ||= Pathname.new(@filename).basename.to_s.downcase.gsub(/\W/, '_')
78
+ args[:before] ||= "start transaction;\n"
79
+ args[:values_glue] ||= ", "
80
+ args[:row_format] ||= lambda do |values|
81
+ r = []
82
+ set_columns.each_with_index { |set_column, i| r << "#{set_column} = #{values[i]}" if set_column }
83
+ "update #{args[:table]} set #{r.join(', ')} where #{args[:pk][1]} = #{values[args[:pk][0]]}"
84
+ end
85
+ args[:row_glue] ||= ";\n"
86
+ args[:after] ||= ";\ncommit transaction;\n"
87
+ to_any args
88
+ end
89
+
90
+ # When :row_format is proc, values_glue is ignored
91
+ # :before
92
+ # :values_glue
93
+ # :row_format
94
+ # :row_glue
95
+ # :after
96
+ #
97
+ def to_any(args={})
98
+ args[:values_glue] ||= ", "
99
+ args[:row_format] ||= "%s"
100
+ args[:row_glue] ||= "\n"
101
+ r = []
102
+ case args[:row_format].class.to_s
103
+ when 'String'
104
+ parse(args) do |values|
105
+ r << sprintf(args[:row_format], values.join(args[:values_glue]))
106
+ end
107
+
108
+ when 'Proc'
109
+ parse(args) do |values|
110
+ r << args[:row_format].call(values) # LOOK OUT: args[:values_glue] ignored
111
+ end
112
+ end
113
+ r = r.join args[:row_glue]
114
+ r = args[:before] + r if args[:before]
115
+ r = r + args[:after] if args[:after]
116
+ r
117
+ end
118
+
119
+ # Parse file
120
+ #
121
+ # args[:csv_line_filter] - proc, called with (line, line_number)
122
+ # args[:values_filter] - proc, called with (values, csv_line_number, filtered_line_number)
123
+ #
124
+ def parse(args={})
125
+ args[:value_filter] ||= Csv2sql.method :default_value_filter
126
+
127
+ i = j = 0
128
+ File.open(@filename, 'r').each_line do |line|
129
+ i += 1
130
+ line = args[:csv_line_filter].call(line, i) if args[:csv_line_filter]
131
+ if line
132
+ j += 1
133
+ unless values = CSV.parse_line(line)
134
+ raise "ERROR:#{@filename}:#{i}:#{j} #{line}"
135
+ else
136
+
137
+ values = args[:values_filter].call(values, i, j) if args[:values_filter]
138
+
139
+ if values
140
+
141
+ if args[:value_filter] # LOOK OUT! value_filter for single value
142
+ k = -1
143
+ values = values.map do |value|
144
+ k += 1
145
+ args[:value_filter].call(value, i, j, k)
146
+ end
147
+ end
148
+
149
+ yield values if values
150
+
151
+ end
152
+ end
153
+ end
154
+ end
155
+ end
156
+
157
+ end
158
+
159
+ # Test
160
+ if $0 == __FILE__
161
+
162
+ csv2sql = Csv2sql.new("GMCLIENT.TXT")
163
+ #~ puts csv2sql.to_inserts(:bulk => true)
164
+
165
+ #~ puts csv2sql.to_inserts()
166
+ #~ puts csv2sql.to_updates([nil, 'balance'], :table => 'accounts')
167
+
168
+ PROPERSYS_ROOT = 'c:/Users/Mirek/Ringley/PROPERSYS2'
169
+ puts Csv2sql.new("#{PROPERSYS_ROOT}/GMTENANT.TXT").to_updates([nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, 'balance'], :table => 'accounts')
170
+
171
+ end
metadata ADDED
@@ -0,0 +1,47 @@
1
+ --- !ruby/object:Gem::Specification
2
+ rubygems_version: 0.9.0
3
+ specification_version: 1
4
+ name: csv2sql
5
+ version: !ruby/object:Gem::Version
6
+ version: 0.1.2
7
+ date: 2007-03-03 00:00:00 +00:00
8
+ summary: Csv2sql provides an easy way to convert comma separated files to sql
9
+ require_paths:
10
+ - lib
11
+ email: ruby@mirekrusin.com
12
+ homepage: http://mirekrusin.com/ruby/csv2sql
13
+ rubyforge_project:
14
+ description:
15
+ autorequire: csv2sql
16
+ default_executable:
17
+ bindir: bin
18
+ has_rdoc: true
19
+ required_ruby_version: !ruby/object:Gem::Version::Requirement
20
+ requirements:
21
+ - - ">"
22
+ - !ruby/object:Gem::Version
23
+ version: 0.0.0
24
+ version:
25
+ platform: ruby
26
+ signing_key:
27
+ cert_chain:
28
+ post_install_message:
29
+ authors:
30
+ - Mirek Rusin
31
+ files:
32
+ - lib/csv2sql.rb
33
+ - README
34
+ test_files: []
35
+
36
+ rdoc_options: []
37
+
38
+ extra_rdoc_files:
39
+ - README
40
+ executables: []
41
+
42
+ extensions: []
43
+
44
+ requirements: []
45
+
46
+ dependencies: []
47
+