quick-etl 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
+
|