-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdbci.rb
executable file
·159 lines (129 loc) · 4.35 KB
/
dbci.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
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
57
58
59
60
61
62
63
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
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
#!/usr/bin/ruby
txt_usage = "Usage: dbci.rb <full_path_of_sqlite_db> -table:{<table_name_in_db>=<full_path_of_textfile>,*args} [-int:{<column_name>,*args} [-append:<boolean>]]"
txt_info = <<TEXT
#*******************************************************************************
# NAME
# dbci.rb - creates sqlite database, and inserts record from text files
#
# SYNOPSIS
# #{txt_usage}
#
#
# DESCRIPTION
# There are times calculating deep logical data with awk(sed, joins) is
# much time consuming or later some aspects of them gradually
# becomes maintainence nightmare. What if we could write custom SQL
# commands, and execute them over those plain text files?
#
# In some case, writing SQL is much more easier and quicker. This little
# tool helps CGI programmers to import plain text file into sqlite database
# as a structured table. Means, it enables a programmer to concentrate on the
# the program logic rather than typing & asserting various IO operations.
#
# First row of the text file will be considered as column names.
# Every column in each row must have some data(not space).
# Plain file example below:
#
# Line.No | employee file data
# -----------------------------
# 001. | id name sex age
# 002. | AA Battur male 26
# 003. | BB George male 45
# 004. | CC Sarah female 30
#
#
# -table:{<table_name_in_db>=<full_path_of_textfile>,*args}
# Provide table names and the full path of your text files.
#
# -int:{<column_name>,*args}
# Name numeric columns here. Later it's easier to sort & filter.
# This parameter is optional.
#
# -append:<boolean>
# Supply 'true' or 'false' here. If you put 'true' records will
# be appended into existing table.
# This parameter is optional.
#
#
# Note: This tool is intended for CGI programmers doing lot of text
# based operation. Therefore may not fit for every case on earth ;)
#
#
# EXAMPLE
# dbci.rb company.db -table:{positions=/abc_company/position,employees=/abc_company/employees/} -int:{age,salary} -append:true
# Note: Do not put space between sub options!
#
#
# AUTHOR
# Battur Sanchin
#
# {
# :homepage => 'http://battur.blogspot.com',
# :email => '[email protected]',
# :flickr => 'http://flickr.com/photos/battur'
# }
#
# COPYRIGHT
# Copyright © 2009 Battur Sanchin. Licence: MIT License
#
# SEE ALSO
# SQLite homepage: http://www.sqlite.org
#
#
TEXT
tmp = "/tmp/tmp#{$$}"
def err
puts "Non applicable arguments. Type 'dbci.rb -help' for usage tips."
exit 1
end
db = ARGV[0]
err unless ARGV.shift
if db.eql? '-help' then
puts txt_info.gsub(/^\# ?(\*+)?/,'')
exit 0
end
Table = Struct.new(:name, :txtfile)
tables, integers, append = [], [], false
# load supplied options here
ARGV.each do |a|
key, val = a.split(':')[0], a.split(':')[1].gsub(/\{|\}/,'')
if key.eql? '-table'
params = val.split('=')
err if params.size < 2
tables << Table.new(params[0], params[1])
elsif key.eql? '-int'
integers << val
elsif key.eql? '-append'
append = (val.eql? 'true') ? true : false
elsif key.match(/^[^-]+/)
puts "Option '#{key}' should start with '-' sign."
puts txt_usage
err
end
end
# iterate over tables
tables.each do |table|
# fetch column names
header = `head -1 #{table.txtfile}`
col_defs, columns = [], header.split
# create SQL statement, define data type
columns.each do |col|
col_defs << "#{col} #{integers.include? col ? 'INTEGER' : 'TEXT'}"
end
create_stmt = "CREATE TABLE #{table.name} (" << col_defs.join(', ') << ");"
# we need data without header to import into db
datafile = "#{tmp}-data"
`sed '1d' #{table.txtfile} > #{datafile}`
File.open("#{tmp}-insert_stmt", "w") do |file|
file.puts '.separator " "'
file.puts ".import #{datafile} #{table.name}"
end
# execute SQL statements
`sqlite3 #{db} "DROP TABLE IF EXISTS #{table.name};"` unless append == true
`sqlite3 #{db} "#{create_stmt}"` unless append == true
`sqlite3 #{db} < "#{tmp}-insert_stmt"`
# remove temporary files
`rm #{tmp}-*`
end
# that's the end ;)
exit 0