quick-etl 0.1.0
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 +126 -0
- data/doc/qifFormatDoc.txt +231 -0
- data/lib/quick_etl.rb +28 -0
- data/lib/quick_etl_dbo.rb +88 -0
- data/lib/quick_etl_kernel.rb +295 -0
- data/lib/quick_etl_money.rb +48 -0
- data/lib/quick_etl_object.rb +20 -0
- data/lib/quick_etl_qif_date.rb +44 -0
- data/lib/quick_etl_qif_file_reader.rb +90 -0
- data/lib/quick_etl_qif_transaction.rb +91 -0
- data/quick-etl.properties +3 -0
- data/rakefile.rb +79 -0
- metadata +59 -0
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
|
+
|
data/lib/quick_etl.rb
ADDED
@@ -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
|
data/rakefile.rb
ADDED
@@ -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
|
+
|