quick-etl 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/README ADDED
@@ -0,0 +1,126 @@
1
+ = QuickETL = Quicken Extract Transform and Load
2
+
3
+ Version: 0.1.0
4
+ Date: 2008-02-10
5
+
6
+ ---
7
+
8
+ QuickETL = Quicken Extract Transform and Load
9
+ QuickETL - Copyright 2008 by Chris Joakim.
10
+ QuickETL is available under GNU General Public License (GPL) license.
11
+
12
+ QuickETL is used to parse your Quicken *.qif files into csv format, then
13
+ load this csv data into a sqlite database, where it can be subsequently
14
+ queried and used for reporting.
15
+
16
+ QuickETL functionality is invoked from a command line with the Ruby Rake program.
17
+ File 'rakefile.rb' is included in the gem file.
18
+
19
+ Future versions of QuickETL will add a User Interface for running queries
20
+ and generating reports.
21
+
22
+
23
+ = General
24
+
25
+ Author:: Chris Joakim <chris@joakim-systems.com>
26
+ Requires:: Ruby 1.8.4 or later
27
+ License:: Copyright 2008 by Chris Joakim.
28
+ GNU General Public License (GPL) license.
29
+ See http://www.gnu.org/copyleft/gpl.html
30
+
31
+
32
+ = License
33
+
34
+ QuickETL is available under GNU General Public License (GPL) license.
35
+
36
+
37
+ = Download
38
+
39
+ The latest version of QuickETL can be found at http://rubyforge.org/projects/quick-etl/
40
+
41
+
42
+ = Installation
43
+
44
+ Please perform the following steps to install QuickETL.
45
+
46
+ 1. Create a directory on your computer which will be considered the "home" directory
47
+ for QuickETL. This directory will contain your Quicken *.qif files, as well as
48
+ the following files:
49
+ - QuickenData.qif (YOUR qif file, created by using the Quicken File -> Export... function)
50
+ - rakefile.rb (The Ruby Rake "rakefile"; your interface to QuickETL functionality)
51
+ - quick-etl.properties (required but unused in this release)
52
+ - quick-etl.csv (csv file created by parsing your *.qif file).
53
+ - quick-etl.db (sqlite database file).
54
+ - quick-etl.load (generated file used to load the csv file)
55
+
56
+ 2. Create the environment variable QUICK_ETL_HOME, and set its value to the directory name
57
+ you chose in step 1. This environment variable MUST be set for QuickETL to function properly.
58
+
59
+ Restart your shell program after setting this environment variable.
60
+
61
+ 3. Verify that you have the sqlite3 program installed on your computer.
62
+ See http://www.sqlite.org/ for sqlite3 installation and usage instructions.
63
+
64
+ For Max OS/X 10.4+ users, the sqlite3 is already installed with the OS.
65
+
66
+ 4. QuickETL is packaged and installed as a ruby 'gem'. Download the latest gem to
67
+ your computer, then run the following command from your download directory.
68
+
69
+ gem install quick-etl-1.0.0.gem
70
+
71
+ 5. Unpack the 'quick-etl-0.1.0.gem' file in your download directory with the following command:
72
+
73
+ gem unpack quick-etl-0.1.0.gem
74
+
75
+ Then copy the 'rakefile.rb' and 'quick-etl.properties' files, that were unpacked from the gem,
76
+ to your QUICK_ETL_HOME directory.
77
+
78
+
79
+ = Usage
80
+
81
+ 1. Use your Quicken program to export its data to the QUICK_ETL_HOME directory.
82
+ Specify output file 'QuickenData.qif'.
83
+
84
+ 2. Open a shell window in your QUICK_ETL_HOME directory.
85
+
86
+ Execute command 'rake -T' to see the list of functions available.
87
+
88
+ Execute command 'rake parse' to parse the qif file into csv format.
89
+
90
+ Execute command 'rake load' to load the csv file data into sqlite3 database 'quick-etl.db'.
91
+
92
+ Execute command 'rake parse_and_load' to run both the parsing and loading function.
93
+
94
+ Execute command 'rake show_ddl' to see the structure of the database table and its column names.
95
+
96
+ 3. Use the sqlite3 CLP (Command Line Program) to query the database.
97
+ From the QUICK_ETL_HOME directory, execute command 'sqlite3 quick-etl.db'.
98
+
99
+ You can then enter and execute queries like the following:
100
+
101
+ sqlite> select * from transactions;
102
+ sqlite> select * from transactions where tran_date == '2008-02-05';
103
+
104
+ Note: A User Interface will be created for QuickETL its next release.
105
+
106
+
107
+ = Road Map / TODO List
108
+
109
+ 1. Develop a UI for the quick-etl.db sqlite database.
110
+
111
+ 2. Develop reporting functionality.
112
+
113
+ 3. Support the "merging" of multiple *qif files into one database.
114
+
115
+
116
+ = Support
117
+
118
+ Please see http://rubyforge.org/projects/quick-etl/ to submit a request or report
119
+ a bug, on the Tracker page.
120
+
121
+
122
+ = Warranty
123
+
124
+ This software is provided "as is" and without any express or implied warranties,
125
+ including, without limitation, the implied warranties of merchantibility and
126
+ fitness for a particular purpose.
@@ -0,0 +1,231 @@
1
+
2
+ http://www.intuit.com/quicken/technical-support/quicken/old-faqs/dosfaqs/60006.html
3
+
4
+ Q: What is the Quicken interchange format (QIF)?
5
+
6
+ A: The Quicken interchange format (QIF) is a specially formatted text (ASCII)
7
+ file that lets you to move Quicken transactions:
8
+
9
+ From one Quicken account register into another Quicken account register, or
10
+ To/From another application that supports the QIF format.
11
+ Note: For Quicken to translate data from a text file into the Quicken register
12
+ as transactions, the text file must be in the QIF format.
13
+
14
+
15
+ Required File Formatting:
16
+
17
+
18
+ Each transaction must end with a symbol, indicating the end of entry.
19
+ Each item in the transaction must display on a separate line.
20
+ When Quicken exports an account register or list, it adds a line to the top
21
+ of the file that identifies the type of account or list. Listed below are
22
+ the header lines Quicken adds to the exported files:
23
+
24
+ Header Type of data
25
+ !Type:Bank Bank account transactions
26
+ !Type:Cash Cash account transactions
27
+ !Type:CCard Credit card account transactions
28
+ !Type:Invst Investment account transactions
29
+ !Type:Oth A Asset account transactions
30
+ !Type:Oth L Liability account transactions
31
+ !Account Account list or which account follows
32
+ !Type:Cat Category list
33
+ !Type:Class Class list
34
+ !Type:Memorized Memorized transaction list
35
+
36
+
37
+ You can force Quicken to import all transfers, regardless of whether
38
+ Ignore Transfers is selected when the file is imported. You must add a
39
+ line to the file being imported into a Quicken account. Use a text editor
40
+ or word processor to put the following line right after the header line
41
+ at the top of the file:
42
+
43
+ !Option:AllXfr
44
+
45
+ Items for Non-Investment Accounts
46
+
47
+ Each item in a bank, cash, credit card, other liability, or other asset
48
+ account must begin with a letter that indicates the field in the Quicken
49
+ register. The non-split items can be in any sequence:
50
+
51
+ Field Indicator Explanation
52
+ D Date
53
+ T Amount
54
+ C Cleared status
55
+ N Num (check or reference number)
56
+ P Payee
57
+ M Memo
58
+ A Address (up to five lines; the sixth line is an optional message)
59
+ L Category (Category/Subcategory/Transfer/Class)
60
+ S Category in split (Category/Transfer/Class)
61
+ E Memo in split
62
+ $ Dollar amount of split
63
+ ^ End of the entry
64
+
65
+ Note: Repeat the S, E, and $ lines as many times as needed for additional
66
+ items in a split. If an item is omitted from the transaction in the QIF
67
+ file, Quicken treats it as a blank item.
68
+
69
+ Items for Investment Accounts
70
+
71
+ Field Indicator Explanation
72
+ D Date
73
+ N Action
74
+ Y Security
75
+ I Price
76
+ Q Quantity (number of shares or split ratio)
77
+ T Transaction amount
78
+ C Cleared status
79
+ P Text in the first line for transfers and reminders
80
+ M Memo
81
+ O Commission
82
+ L Account for the transfer
83
+ $ Amount transferred
84
+ ^ End of the entry
85
+
86
+ Items for Account Information
87
+
88
+ The account header !Account is used in two places-at the start of an account
89
+ list and the start of a list of transactions to specify to which account they
90
+ belong.
91
+
92
+ Field Indicator Explanation
93
+ N Name
94
+ T Type of account
95
+ D Description
96
+ L Credit limit (only for credit card accounts)
97
+ / Statement balance date
98
+ $ Statement balance amount
99
+ ^ End of entry
100
+
101
+ Items for a Category List
102
+
103
+ Field Indicator Explanation
104
+ N Category name:subcategory name
105
+ D Description
106
+ T Tax related if included, not tax related if omitted
107
+ I Income category
108
+ E Expense category
109
+ (if category type is unspecified, quicken assumes expense type)
110
+ B Budget amount (only in a Budget Amounts QIF file)
111
+ R Tax schedule information
112
+ ^ End of entry
113
+
114
+ Items for a Class List
115
+
116
+ Field Indicator Explanation
117
+ N Class name
118
+ D Description
119
+ ^ End of entry
120
+
121
+ Items for a Memorized Transaction List
122
+
123
+ Immediately preceding the ^ character, each entry must end with one of the
124
+ following file indicators to specify the transaction type.
125
+
126
+ KC
127
+ KD
128
+ KP
129
+ KI
130
+ KE
131
+ With that exception, memorized transaction entries have the same format as
132
+ regular transaction entries (non-investment accounts). However, the Date
133
+ or Num field is included. All items are optional, but if an amortization
134
+ record is included, all seven amortization lines must also be included.
135
+
136
+ Field Indicator Explanation
137
+ KC Check transaction
138
+ KD Deposit transaction
139
+ KP Payment transaction
140
+ KI Investment transaction
141
+ KE Electronic payee transaction
142
+ T Amount
143
+ C Cleared status
144
+ P Payee
145
+ M Memo
146
+ A Address
147
+ L Category or Transfer/Class
148
+ S Category/class in split
149
+ E Memo in split
150
+ $ Dollar amount of split
151
+ 1 Amortization: First payment date
152
+ 2 Amortization: Total years for loan
153
+ 3 Amortization: Number of payments already made
154
+ 4 Amortization: Number of periods per year
155
+ 5 Amortization: Interest rate
156
+ 6 Amortization: Current loan balance
157
+ 7 Amortization: Original loan amount
158
+ ^ End of entry
159
+
160
+ Examples of QIF files
161
+
162
+ Normal Transactions Example
163
+
164
+ Transaction Item Comment (not in file)
165
+ !Type:Bank Header
166
+ D6/ 1/94 Date
167
+ T-1,000.00 Amount
168
+ N1005 Check number
169
+ PBank Of Mortgage Payee
170
+ L[linda] Category
171
+ S[linda] First category in split
172
+ $-253.64 First amount in split
173
+ SMort Int Second category in split
174
+ $-746.36 Second amount in split
175
+ ^ End of the transaction
176
+ D6/ 2/94 Date
177
+ T75.00 Amount
178
+ PDeposit Payee
179
+ ^ End of the transaction
180
+ D6/ 3/94 Date
181
+ T-10.00 Amount
182
+ PJoBob Biggs Payee
183
+ MJ.B. gets bucks Memo
184
+ LEntertain Category
185
+ A1010 Rodeo Dr. Address (line 1)
186
+ AWaco, Tx Address (line 2)
187
+ A80505 Address (line 3)
188
+ A Address (line 4)
189
+ A Address (line 5)
190
+ A Address (line 6)
191
+ ^ End of the transaction
192
+
193
+ Investment Example
194
+
195
+ Transaction Item Comment (not in file)
196
+ !Type:Invst Header line
197
+ D8/25/93 Date
198
+ NShrsIn Action (optional)
199
+ Yibm4 Security
200
+ I11.260 Price
201
+ Q88.81 Quantity
202
+ CX Cleared Status
203
+ T1,000.00 Amount
204
+ MOpening Balance Memo
205
+ ^ End of the transaction
206
+ D8/25/93 Date
207
+ NBuyX Action
208
+ Yibm4 Security
209
+ I11.030 Price
210
+ Q9.066 Quantity
211
+ T100.00 Amount
212
+ MEst. price as of 8/25/93 Memo
213
+ L[CHECKING] Account for transfer
214
+ $100.00 Amount transferred
215
+ ^ End of the transaction
216
+
217
+ Memorized List Example
218
+
219
+ Transaction Item Comment (not in file)
220
+ !Type:Memorized Header line
221
+ T-50.00 Amount
222
+ PJoe Hayes Payee
223
+ MRent Memo
224
+ KC Check transaction
225
+ ^ End of the transaction
226
+ T-25.00 Amount
227
+ T-25.00 Company Payee
228
+ LTelephone Category
229
+ KP Payment transaction
230
+ ^ End of the transaction
231
+
@@ -0,0 +1,28 @@
1
+ =begin rdoc
2
+
3
+ QuickETL = Quicken Extract Transform and Load
4
+ QuickETL - Copyright 2008 by Chris Joakim.
5
+ QuickETL is available under GNU General Public License (GPL) license.
6
+
7
+ -
8
+
9
+ This is the main ruby file for this project. It contains require statements
10
+ for all of the necessary ruby standard libraries, and quick_etl custom files.
11
+
12
+ =end
13
+
14
+ # System libraries and gems:
15
+ require 'rubygems'
16
+ require 'rbconfig'
17
+ require 'date'
18
+ require 'time'
19
+ require 'sqlite3'
20
+
21
+ # Custom libraries:
22
+ require 'quick_etl_kernel'
23
+ require 'quick_etl_object'
24
+ require 'quick_etl_dbo'
25
+ require 'quick_etl_money'
26
+ require 'quick_etl_qif_date'
27
+ require 'quick_etl_qif_file_reader'
28
+ require 'quick_etl_qif_transaction'
@@ -0,0 +1,88 @@
1
+ =begin rdoc
2
+
3
+ QuickETL = Quicken Extract Transform and Load
4
+ QuickETL - Copyright 2008 by Chris Joakim.
5
+ QuickETL is available under GNU General Public License (GPL) license.
6
+
7
+ -
8
+
9
+ This class is used to interface with the sqlite3 database.
10
+
11
+ =end
12
+
13
+ module QuickETL
14
+
15
+ class DBO < QuickETLObject
16
+
17
+ attr_accessor :db , :db_filename
18
+
19
+ def initialize()
20
+ @db_filename = "#{home_dir}/#{QuickETL::DATABASE_FILE}"
21
+ end
22
+
23
+ def open_database
24
+ @db = SQLite3::Database.new(@db_filename)
25
+ end
26
+
27
+ def show_ddl
28
+ puts "\nThe following DDL (SQL) is used to create database #{@db_filename}"
29
+ puts ""
30
+ puts drop_transactions_ddl
31
+ puts create_transactions_ddl
32
+ puts ""
33
+ end
34
+
35
+ def drop_and_create_database
36
+ open_database
37
+ puts @db.execute(drop_transactions_ddl);
38
+ puts @db.execute(create_transactions_ddl);
39
+ puts "\nDatabase has been created - #{@db_filename}"
40
+ puts "Database schema is shown below:"
41
+ puts ""
42
+ puts `sqlite3 #{@db_filename} VACUUM`
43
+ puts `sqlite3 #{@db_filename} .schema`
44
+ puts ""
45
+ end
46
+
47
+ def drop_transactions_ddl
48
+ "drop table if exists transactions;"
49
+ end
50
+
51
+ def create_transactions_ddl
52
+ s = "create table transactions ( \n"
53
+ s << " id INTEGER PRIMARY KEY, \n"
54
+ s << " account_owner TEXT, \n"
55
+ s << " account_name TEXT, \n"
56
+ s << " account_type TEXT, \n"
57
+ s << " tran_date TEXT, \n"
58
+ s << " cleared_status TEXT, \n"
59
+ s << " item_number INTEGER, \n"
60
+ s << " amount REAL, \n"
61
+ s << " payee TEXT, \n"
62
+ s << " category TEXT, \n"
63
+ s << " memo TEXT, \n"
64
+ s << " line_number INTEGER \n"
65
+ s << ");"
66
+ s
67
+ end
68
+
69
+ def load_database
70
+ command_file = "#{home_dir}/#{LOAD_COMMAND_FILE}"
71
+ lines = Array.new
72
+ lines << ".import #{home_dir}/quick-etl.csv transactions"
73
+ write_lines(command_file, lines)
74
+ puts `sqlite3 #{@db_filename} < #{command_file}`
75
+ end
76
+
77
+ def query_all_transactions
78
+ command_file = "#{home_dir}/#{QUERY_ALL_FILE}"
79
+ results_file = "#{home_dir}/output.txt"
80
+ lines = Array.new
81
+ lines << "select * from transactions;"
82
+ write_lines(command_file, lines)
83
+ puts `sqlite3 #{@db_filename} < #{command_file} > #{results_file}`
84
+ end
85
+
86
+ end
87
+
88
+ end
@@ -0,0 +1,295 @@
1
+ =begin rdoc
2
+
3
+ QuickETL = Quicken Extract Transform and Load
4
+ QuickETL - Copyright 2008 by Chris Joakim.
5
+ QuickETL is available under GNU General Public License (GPL) license.
6
+
7
+ -
8
+
9
+ This is the core module for this project, and is included in base class
10
+ QuickETLObject.
11
+
12
+ =end
13
+
14
+ module QuickETL
15
+
16
+ DATABASE_FILE = 'quick-etl.db'
17
+ PROPERTIES_FILE = 'quick-etl.properties'
18
+ LOAD_COMMAND_FILE = 'quick-etl.load'
19
+ QUERY_ALL_FILE = 'query_all.sql'
20
+ DEFAULT_QIF_FILE = 'QuickenData.qif'
21
+ DAY_NAMES = %w(Sun Mon Tue Wed Thu Fri Sat)
22
+ QUICK_ETL_HOME = 'QUICK_ETL_HOME'
23
+ QUICK_ETL_DEV_HOME = 'QUICK_ETL_DEV_HOME'
24
+
25
+ @@properties = Hash.new
26
+ @@debug = false
27
+
28
+ module QuickETLKernel
29
+
30
+ def project_name
31
+ 'QuickETL'
32
+ end
33
+
34
+ def project_version_number
35
+ '0.1.0'
36
+ end
37
+
38
+ def project_date
39
+ '2008/02/10'
40
+ end
41
+
42
+ def project_author
43
+ 'Chris Joakim'
44
+ end
45
+
46
+ def project_year
47
+ project_date[0...4] # start, length
48
+ end
49
+
50
+ def project_copyright
51
+ "Copyright (C) #{project_year} #{project_author}"
52
+ end
53
+
54
+ def project_embedded_comment
55
+ "#{project_name} #{project_version_number}"
56
+ end
57
+
58
+ def project_license
59
+ 'GNU General Public License (GPL). See http://www.gnu.org/copyleft/gpl.html'
60
+ end
61
+
62
+ def display_general_info
63
+ puts ""
64
+ puts "This is '#{project_name}'. "
65
+ puts "#{project_copyright} "
66
+ puts "#{project_license} "
67
+ puts ""
68
+ puts "QuickETL home pages: "
69
+ puts " -- http://rubyforge.org/projects/quick-etl/ "
70
+ puts " -- http://www.joakim-systems.com/ "
71
+ puts ""
72
+ puts "QuickETL uses the SQLite3 database; see the following URLs: "
73
+ puts " -- http://www.sqlite.org/"
74
+ puts " -- http://sqlite-ruby.rubyforge.org/ "
75
+ puts " -- http://sqlite-ruby.rubyforge.org/sqlite3/faq.html "
76
+ puts ""
77
+ puts "Enter 'rake help' for QuickETL usage instructions. "
78
+ puts "Enter 'rake -T' for the list of available QuickETL rake commands. "
79
+ puts ""
80
+
81
+ home = home_dir
82
+ if (home_dir)
83
+ puts "Your QuickETL home directory is currently set to: #{home_dir}"
84
+ else
85
+ puts "Warning: You have not yet set your 'QUICK_ETL_HOME' environment variable."
86
+ end
87
+ puts ""
88
+ end
89
+
90
+ def display_usage_instructions
91
+ puts "usage"
92
+ puts ""
93
+ end
94
+
95
+ def home_dir
96
+ is_dev = ENV['dev']
97
+ if ((is_dev) && (is_dev == 'y'))
98
+ ENV[QUICK_ETL_DEV_HOME]
99
+ else
100
+ ENV[QUICK_ETL_HOME]
101
+ end
102
+ end
103
+
104
+ def command_line_arg(name, default)
105
+ value = default
106
+ if name
107
+ value = ENV[name]
108
+ value = default if value == nil
109
+ end
110
+ value
111
+ end
112
+
113
+ def command_line_boolean_arg(name, default)
114
+ v = command_line_arg(name, "#{default}")
115
+ return true if ((v.downcase == 'true') || (v.downcase == 't'))
116
+ return true if ((v.downcase == 'yes') || (v.downcase == 'y'))
117
+ false
118
+ end
119
+
120
+ def command_line_array_arg(name, default)
121
+ s = command_line_arg(name, nil)
122
+ return default if s == nil
123
+ return s.split(',')
124
+ end
125
+
126
+ def get_property(name, default='')
127
+ if @@properties.has_key? "#{name}"
128
+ return @@properties["#{name}"]
129
+ end
130
+ default
131
+ end
132
+
133
+ def get_array_property(name, default=Array.new)
134
+ s = get_property(name)
135
+ if s
136
+ return s.split(',')
137
+ end
138
+ default
139
+ end
140
+
141
+ def startup
142
+ load_properties("#{home_dir}/#{QuickETL::PROPERTIES_FILE}")
143
+ end
144
+
145
+ def load_properties(properties_filename)
146
+ props = Hash.new
147
+ if File.exist? properties_filename
148
+ File.open(properties_filename, 'r') do | properties_file |
149
+ properties_file.read.each_line do |line|
150
+ line.strip!
151
+ if (line[0] != ?# and line[0] != ?=)
152
+ i = line.index('=')
153
+ if (i)
154
+ props[line[0..i - 1].strip] = line[i + 1..-1].strip
155
+ else
156
+ props[line] = ''
157
+ end
158
+ end
159
+ end
160
+ puts "properties file read - #{properties_filename} , entry count=#{props.size}" if true
161
+ end
162
+ else
163
+ puts "properties file does not exist - #{properties_filename}" if false
164
+ end
165
+ @@properties = props
166
+ end
167
+
168
+ def parse_qif_files
169
+ qif_file = command_line_arg('qif', QuickETL::DEFAULT_QIF_FILE)
170
+ qif_dir = get_property('qif_dir', home_dir)
171
+ qif_path = "#{qif_dir}/#{qif_file}"
172
+ owner = command_line_arg('owner', 'owner')
173
+ reader = QuickETL::QifFileReader.new(owner, qif_path)
174
+ array = Array.new
175
+ reader.transactions.each_with_index { | tran, idx|
176
+ array << "#{idx+1}#{tran.to_s}"
177
+ }
178
+ write_lines("#{home_dir}/quick-etl.csv", array)
179
+ end
180
+
181
+ def read_lines(filename, strip=false)
182
+ array = IO.readlines(filename)
183
+ array = strip_lines(array) if strip
184
+ array
185
+ end
186
+
187
+ def write_file(out_name, content)
188
+ out = File.new out_name, "w+"
189
+ out.write content
190
+ out.flush
191
+ out.close
192
+ puts "file written: #{out_name}"
193
+ end
194
+
195
+ def write_lines(out_name, lines)
196
+ s = ''
197
+ lines.each { | line | s << "#{line}\n" }
198
+ write_file(out_name, s)
199
+ end
200
+
201
+ def read_as_ascii_lines(filename, delim=10, strip=false)
202
+ array = Array.new
203
+ file = File.new(filename)
204
+ currLine = ''
205
+ bytesRead = 0
206
+ linesRead = 0
207
+
208
+ file.each_byte { |b|
209
+ bytesRead = bytesRead + 1
210
+ if (b == delim) # delim is 13 for quicken, 10 for address book xml
211
+ array << currLine
212
+ currLine = ''
213
+ linesRead = linesRead + 1
214
+ else
215
+ if (b < 127)
216
+ currLine << "#{b.chr}"
217
+ end
218
+ end
219
+ }
220
+ if currLine.size > 0
221
+ array << currLine
222
+ end
223
+ if strip
224
+ array = strip_lines(array)
225
+ end
226
+ array
227
+ end
228
+
229
+ def strip_lines(array)
230
+ newArray = Array.new
231
+ if (array != nil)
232
+ array.each { |line| line.strip! ; newArray << line }
233
+ end
234
+ newArray
235
+ end
236
+
237
+ def line_value(s)
238
+ if ((s == nil) || (s.size < 1))
239
+ s
240
+ else
241
+ s[1, s.size]
242
+ end
243
+ end
244
+
245
+ def tokenize(string, delim=nil, strip=false)
246
+ if string
247
+ tokens = string.split(delim)
248
+ if strip
249
+ tokens.each { |tok| tok.strip! }
250
+ end
251
+ tokens
252
+ else
253
+ Array.new
254
+ end
255
+ end
256
+
257
+ def default_delimiter
258
+ '|'
259
+ end
260
+
261
+ def usage_instructions
262
+ s = <<HERE
263
+
264
+ 1. Use your Quicken program to export its data to the QUICK_ETL_HOME directory.
265
+ Specify output file 'QuickenData.qif'.
266
+
267
+ 2. Open a shell window in your QUICK_ETL_HOME directory.
268
+
269
+ Execute command 'rake -T' to see the list of functions available.
270
+
271
+ Execute command 'rake parse' to parse the qif file into csv format.
272
+
273
+ Execute command 'rake load' to load the csv file data into sqlite3 database 'quick-etl.db'.
274
+
275
+ Execute command 'rake parse_and_load' to run both the parsing and loading function.
276
+
277
+ Execute command 'rake show_ddl' to see the structure of the database table and its column names.
278
+
279
+ 3. Use the sqlite3 CLP (Command Line Program) to query the database.
280
+ From the QUICK_ETL_HOME directory, execute command 'sqlite3 quick-etl.db'.
281
+
282
+ You can then enter and execute queries like the following:
283
+
284
+ sqlite> select * from transactions;
285
+ sqlite> select * from transactions where tran_date == '2008-02-05';
286
+
287
+ Note: A User Interface will be created for QuickETL its next release.
288
+
289
+ HERE
290
+ s
291
+ end
292
+
293
+ end
294
+
295
+ end
@@ -0,0 +1,48 @@
1
+ =begin rdoc
2
+
3
+ QuickETL = Quicken Extract Transform and Load
4
+ QuickETL - Copyright 2008 by Chris Joakim.
5
+ QuickETL is available under GNU General Public License (GPL) license.
6
+
7
+ -
8
+
9
+ Instances of this class represent a monetary amount from within a Quicken qif file,
10
+ such as 'T-38.09' (i.e. - $38.09 US Dollars).
11
+
12
+ =end
13
+
14
+ module QuickETL
15
+
16
+ class Money < QuickETLObject
17
+
18
+ attr_accessor :string_value, :numeric_value
19
+
20
+ def initialize(s='0.00')
21
+ s ? @string_value = s : @string_value = '0.00'
22
+ @string_value.strip!
23
+ @numeric_value = numeric(@string_value).to_f
24
+ end
25
+
26
+ def to_s
27
+ "#{@numeric_value}"
28
+ end
29
+
30
+ private
31
+
32
+ def numeric(s)
33
+ n = ''
34
+ if s
35
+ s.each_byte { | b |
36
+ if ((b == 44) || (b == 32))
37
+ # bypass commas (44) and spaces (32)
38
+ else
39
+ n << "#{b.chr}"
40
+ end
41
+ }
42
+ end
43
+ n
44
+ end
45
+
46
+ end
47
+
48
+ end
@@ -0,0 +1,20 @@
1
+ =begin rdoc
2
+
3
+ QuickETL = Quicken Extract Transform and Load
4
+ QuickETL - Copyright 2008 by Chris Joakim.
5
+ QuickETL is available under GNU General Public License (GPL) license.
6
+
7
+ -
8
+
9
+ This is the abstract superclass of several QuickETL classes.
10
+ It includes module QuickETLKernel.
11
+
12
+ =end
13
+
14
+ module QuickETL
15
+
16
+ class QuickETLObject
17
+ include QuickETL::QuickETLKernel
18
+ end
19
+
20
+ end
@@ -0,0 +1,44 @@
1
+ =begin rdoc
2
+
3
+ QuickETL = Quicken Extract Transform and Load
4
+ QuickETL - Copyright 2008 by Chris Joakim.
5
+ QuickETL is available under GNU General Public License (GPL) license.
6
+
7
+ -
8
+
9
+ Instances of this class represent a date from within a Quicken qif file,
10
+ such as 'D5/24/94'.
11
+
12
+ =end
13
+
14
+ module QuickETL
15
+
16
+ class QifDate < QuickETLObject
17
+
18
+ attr_accessor :raw_line, :ccyymmdd, :year, :year_mm, :yy, :mm, :dd
19
+
20
+ def initialize(raw_line)
21
+ @raw_line = raw_line
22
+ @y, @m, @d = 0, 0, 0
23
+ @cc, @yy, @mm, @dd = '00', '00', '00', '00'
24
+
25
+ if @raw_line
26
+ tokens = @raw_line.split('/')
27
+ if (tokens && tokens.size > 2)
28
+ m = tokens[0].to_i
29
+ d = tokens[1].to_i
30
+ y = tokens[2].to_i
31
+ @yy = tokens[2]
32
+ y < 50 ? @cc = "20" : @cc = "19"
33
+ m < 10 ? @mm = "0#{m}" : @mm = "#{m}"
34
+ d < 10 ? @dd = "0#{d}" : @dd = "#{d}"
35
+ end
36
+ end
37
+ @ccyymmdd = "#{@cc}#{@yy}-#{@mm}-#{@dd}"
38
+ @year = "#{@cc}#{@yy}"
39
+ @year_mm = "#{@cc}#{@yy}-#{@mm}"
40
+ end
41
+
42
+ end
43
+
44
+ end
@@ -0,0 +1,90 @@
1
+ =begin rdoc
2
+
3
+ QuickETL = Quicken Extract Transform and Load
4
+ QuickETL - Copyright 2008 by Chris Joakim.
5
+ QuickETL is available under GNU General Public License (GPL) license.
6
+
7
+ -
8
+
9
+ Instances of this class are used to read and parse a Quicken qif file.
10
+
11
+ =end
12
+
13
+ module QuickETL
14
+
15
+ class QifFileReader < QuickETLObject
16
+
17
+ attr_accessor :filename, :transactions, :debug
18
+
19
+ def initialize(owner, filename, debug=false)
20
+ @owner = owner
21
+ @filename = filename
22
+ @debug = debug
23
+ @transactions = Array.new
24
+ read
25
+ end
26
+
27
+ def read
28
+ @lines = read_as_ascii_lines(@filename, 13, false)
29
+ in_tran_zone = false
30
+ in_acct_header = false
31
+ @acct_name = ''
32
+ @acct_type = ''
33
+ line_num = 0
34
+ tran = QifTran.new(@owner, @acct_name, @acct_type, 0)
35
+ start_token = '!Type:Class'
36
+
37
+ @lines.each { | line |
38
+ line_num = line_num + 1
39
+
40
+ if (line == start_token)
41
+ in_tran_zone = true
42
+ next
43
+ end
44
+
45
+ if (line.match(/^!Account/))
46
+ in_acct_header = true
47
+ next
48
+ end
49
+
50
+ if in_acct_header
51
+ if (line.match(/^N/))
52
+ @acct_name = (line_value(line))
53
+ tran.acct_name = @acct_name
54
+ elsif (line.match(/^T/))
55
+ @acct_type = (line_value(line))
56
+ tran.acct_type = @acct_type
57
+ elsif (line == '^')
58
+ in_acct_header = false
59
+ end
60
+ next
61
+ end
62
+
63
+ if in_tran_zone
64
+ if (line == '^')
65
+ add_transaction(tran)
66
+ tran = QifTran.new(@owner, @acct_name, @acct_type, line_num)
67
+ else
68
+ tran.add_line(line)
69
+ end
70
+ end
71
+ }
72
+ end
73
+
74
+ def add_transaction(t)
75
+ t.parse
76
+ if t.valid
77
+ @transactions.push(t)
78
+ else
79
+ puts "invalid trans"
80
+ end
81
+ end
82
+
83
+ public
84
+
85
+ def to_s
86
+ "QifFileReader #{@filename} #{@lines.size} #{@transactions.size}"
87
+ end
88
+ end
89
+
90
+ end
@@ -0,0 +1,91 @@
1
+ =begin rdoc
2
+
3
+ QuickETL = Quicken Extract Transform and Load
4
+ QuickETL - Copyright 2008 by Chris Joakim.
5
+ QuickETL is available under GNU General Public License (GPL) license.
6
+
7
+ -
8
+
9
+ Instances of this class represent one transaction within a Quicken qif file.
10
+
11
+ =end
12
+
13
+ module QuickETL
14
+
15
+ class QifTran < QuickETLObject
16
+
17
+ attr_accessor :raw_lines, :acct_owner, :acct_name, :acct_type, :date, :amount
18
+ attr_accessor :valid, :balance, :cleared, :category, :number, :payee, :memo
19
+
20
+ def initialize(anOwner, aName, aType, line_num, delim='|')
21
+ @acct_owner = "#{anOwner}"
22
+ @acct_name = "#{aName}"
23
+ @acct_type = "#{aType}"
24
+ @line_num = line_num
25
+ @delim = delim
26
+ @valid = false
27
+ @cleared = ' '
28
+ @number = ' '
29
+ @memo = ' '
30
+ @raw_lines = Array.new
31
+ @splits = Array.new
32
+ end
33
+
34
+ public
35
+
36
+ def add_line(line)
37
+ @raw_lines.push(line)
38
+ end
39
+
40
+ =begin
41
+ Field Indicator Explanations:
42
+ D Date
43
+ T Amount
44
+ C Cleared status
45
+ N Num (check or reference number)
46
+ P Payee
47
+ M Memo
48
+ A Address (up to five lines; the sixth line is an optional message) NOT IMPLEMENTED IN QUICK-ETL
49
+ L Category (Category/Subcategory/Transfer/Class)
50
+ S Category in split (Category/Transfer/Class)
51
+ E Memo in split
52
+ $ Dollar amount of split
53
+ ^ End of the entry
54
+ =end
55
+
56
+ def parse
57
+ @raw_lines.each { | line |
58
+ if (line.match(/^D/))
59
+ @date = QifDate.new(line_value(line))
60
+ elsif (line.match(/^T/))
61
+ s = line_value(line)
62
+ @amount = Money.new(s)
63
+ elsif (line.match(/^P/))
64
+ @payee = line_value(line)
65
+ elsif (line.match(/^C/))
66
+ @cleared = line_value(line)
67
+ elsif (line.match(/^N/))
68
+ @number = line_value(line)
69
+ elsif (line.match(/^M/))
70
+ @memo = line_value(line)
71
+ elsif (line.match(/^L/))
72
+ @category = line_value(line)
73
+ elsif (line.match(/^S/))
74
+ @split_category = line_value(line)
75
+ elsif (line.match(/^E/))
76
+ @split_memo = line_value(line)
77
+ elsif (line.match(/^$/))
78
+ @split_amount = Money.new(line_value(line))
79
+ end
80
+ }
81
+ if (@date && @amount && @payee)
82
+ @valid = true
83
+ end
84
+ end
85
+
86
+ def to_s
87
+ "#{@delim}#{@acct_owner}#{@delim}#{@acct_name}#{@delim}#{@acct_type}#{@delim}#{@date.ccyymmdd}#{@delim}#{@cleared}#{@delim}#{@number}#{@delim}#{@amount.to_s}#{@delim}#{@payee}#{@delim}#{@category}#{@delim}#{@memo}#{@delim}#{@line_num}"
88
+ end
89
+ end
90
+
91
+ end
@@ -0,0 +1,3 @@
1
+ qif_files=c
2
+ qif_file_c=QuickenData.qif
3
+ qif_file_t=TQuickenData.qif
@@ -0,0 +1,79 @@
1
+ =begin
2
+
3
+ Ruby Rakefile for Quick-ETL.
4
+
5
+ Quick-ETL - Copyright 2008 by Chris Joakim.
6
+ Quick-ETL is available under GNU General Public License (GPL) license.
7
+
8
+ http://sqlite-ruby.rubyforge.org/
9
+ http://sqlite-ruby.rubyforge.org/sqlite3/faq.html
10
+ =end
11
+
12
+ require 'rubygems'
13
+ require 'rake'
14
+ require 'rbconfig'
15
+ require 'date'
16
+ require 'time'
17
+ require 'sqlite3'
18
+
19
+ # The following prefixes /lib to the active ruby load path
20
+ #$:.unshift File.join(File.dirname(__FILE__), "", "lib")
21
+ require 'quick_etl.rb'
22
+
23
+ desc "Display information about this open-source project."
24
+ task :default do
25
+ obj = QuickETL::QuickETLObject.new
26
+ obj.display_general_info
27
+ end
28
+
29
+ desc "Display QuickETL usage instructions."
30
+ task :help do
31
+ obj = QuickETL::QuickETLObject.new
32
+ puts obj.usage_instructions
33
+ end
34
+
35
+ desc "Show the DDL (SQL) used to create the sqlite3 'quick-etl.db' database."
36
+ task :show_ddl do
37
+ dbo = QuickETL::DBO.new
38
+ dbo.show_ddl
39
+ end
40
+
41
+ desc "Drop and (re)create the sqlite3 'quick-etl.db' database."
42
+ task :drop_create_db do
43
+ startup
44
+ dbo = QuickETL::DBO.new
45
+ dbo.drop_and_create_database
46
+ end
47
+
48
+ desc "Parse *qif files into csv per properties file."
49
+ task :parse do
50
+ startup
51
+ obj = QuickETL::QuickETLObject.new
52
+ obj.parse_qif_files
53
+ end
54
+
55
+ desc "Parse *qif files into csv per properties file."
56
+ task :load do
57
+ startup
58
+ dbo = QuickETL::DBO.new
59
+ dbo.drop_and_create_database
60
+ dbo.load_database
61
+ end
62
+
63
+ desc "Parse *qif files into csv per properties file."
64
+ task :parse_and_load do
65
+ startup
66
+
67
+ obj = QuickETL::QuickETLObject.new
68
+ obj.parse_qif_files
69
+
70
+ dbo = QuickETL::DBO.new
71
+ dbo.drop_and_create_database
72
+ dbo.load_database
73
+ end
74
+
75
+ # -----------------------------------------------------------------------------
76
+
77
+ def startup
78
+ QuickETL::QuickETLObject.new.startup
79
+ end
metadata ADDED
@@ -0,0 +1,59 @@
1
+ --- !ruby/object:Gem::Specification
2
+ rubygems_version: 0.9.4
3
+ specification_version: 1
4
+ name: quick-etl
5
+ version: !ruby/object:Gem::Version
6
+ version: 0.1.0
7
+ date: 2008-02-10 00:00:00 -05:00
8
+ summary: Quicken Extract Transform and Load
9
+ require_paths:
10
+ - lib
11
+ email: chris@joakim-systems.com
12
+ homepage: http://rubyforge.org/projects/quick-etl/
13
+ rubyforge_project: quick-etl
14
+ description:
15
+ autorequire:
16
+ default_executable:
17
+ bindir: bin
18
+ has_rdoc: false
19
+ required_ruby_version: !ruby/object:Gem::Version::Requirement
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: 1.8.4
24
+ version:
25
+ platform: ruby
26
+ signing_key:
27
+ cert_chain:
28
+ post_install_message:
29
+ authors:
30
+ - Chris Joakim
31
+ files:
32
+ - doc/qifFormatDoc.txt
33
+ - lib/quick_etl.rb
34
+ - lib/quick_etl_dbo.rb
35
+ - lib/quick_etl_kernel.rb
36
+ - lib/quick_etl_money.rb
37
+ - lib/quick_etl_object.rb
38
+ - lib/quick_etl_qif_date.rb
39
+ - lib/quick_etl_qif_file_reader.rb
40
+ - lib/quick_etl_qif_transaction.rb
41
+ - README
42
+ - rakefile.rb
43
+ - quick-etl.properties
44
+ test_files: []
45
+
46
+ rdoc_options: []
47
+
48
+ extra_rdoc_files:
49
+ - README
50
+ - rakefile.rb
51
+ - quick-etl.properties
52
+ executables: []
53
+
54
+ extensions: []
55
+
56
+ requirements: []
57
+
58
+ dependencies: []
59
+