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.
- data/README +71 -0
- data/lib/csv2sql.rb +171 -0
- 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
|
+
|