Rev 16 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
11 | PointedEar | 1 | /** |
2 | * |
||
3 | */ |
||
4 | package de.pointedears.converter.db; |
||
5 | |||
17 | PointedEar | 6 | import java.text.DateFormat; |
7 | import java.text.ParseException; |
||
8 | import java.text.SimpleDateFormat; |
||
9 | import java.util.Date; |
||
11 | PointedEar | 10 | import java.util.HashMap; |
11 | import java.util.Map.Entry; |
||
12 | |||
13 | import android.content.ContentValues; |
||
17 | PointedEar | 14 | import android.content.Context; |
12 | PointedEar | 15 | import android.database.Cursor; |
11 | PointedEar | 16 | import android.database.sqlite.SQLiteDatabase; |
12 | PointedEar | 17 | import android.database.sqlite.SQLiteException; |
11 | PointedEar | 18 | import android.database.sqlite.SQLiteOpenHelper; |
17 | PointedEar | 19 | import android.util.Log; |
11 | PointedEar | 20 | import de.pointedears.converter.app.CurrenciesActivity; |
21 | |||
22 | /** |
||
23 | * @author pelinux |
||
24 | * |
||
25 | */ |
||
26 | public class CurrenciesDatabase extends SQLiteOpenHelper |
||
27 | { |
||
17 | PointedEar | 28 | |
11 | PointedEar | 29 | private static final String DATABASE_NAME = "currency.db"; //$NON-NLS-1$ |
17 | PointedEar | 30 | private static final int DATABASE_VERSION = 8; |
11 | PointedEar | 31 | |
12 | PointedEar | 32 | private static final String TABLE = "currency"; //$NON-NLS-1$ |
16 | PointedEar | 33 | private static final String COLUMN_CURRENCY = "currency1"; //$NON-NLS-1$ |
12 | PointedEar | 34 | private static final String COLUMN_FACTOR = "factor"; //$NON-NLS-1$ |
17 | PointedEar | 35 | private static final String COLUMN_UPDATED = "updated"; //$NON-NLS-1$ |
11 | PointedEar | 36 | |
17 | PointedEar | 37 | private static HashMap<String, ConversionData> conversionRates = |
38 | new HashMap<String, ConversionData>(); |
||
12 | PointedEar | 39 | static |
40 | { |
||
16 | PointedEar | 41 | /* Default conversion rates from Euro (EUR) to other currencies */ |
17 | PointedEar | 42 | Date epoch = new Date(0); |
16 | PointedEar | 43 | CurrenciesDatabase.conversionRates |
17 | PointedEar | 44 | .put(CurrenciesActivity.VALUE_CHF, |
45 | new ConversionData(1.3013, epoch)); |
||
16 | PointedEar | 46 | CurrenciesDatabase.conversionRates |
17 | PointedEar | 47 | .put(CurrenciesActivity.VALUE_USD, |
48 | new ConversionData(1.3521, epoch)); |
||
12 | PointedEar | 49 | } |
11 | PointedEar | 50 | |
17 | PointedEar | 51 | private SQLiteDatabase database; |
52 | private final DateFormat iso8601format = new SimpleDateFormat( |
||
53 | "yyyy-MM-dd HH:mm:ss"); |
||
54 | |||
11 | PointedEar | 55 | /** |
56 | * @param context |
||
57 | * The Activity in which this wrapper is used |
||
58 | */ |
||
17 | PointedEar | 59 | public CurrenciesDatabase(Context context) |
11 | PointedEar | 60 | { |
61 | super(context, CurrenciesDatabase.DATABASE_NAME, null, |
||
62 | CurrenciesDatabase.DATABASE_VERSION); |
||
12 | PointedEar | 63 | this.readConversionsFromDatabase(); |
11 | PointedEar | 64 | } |
65 | |||
66 | /* |
||
67 | * (non-Javadoc) |
||
68 | * |
||
69 | * @see |
||
70 | * android.database.sqlite.SQLiteOpenHelper#onCreate(android.database.sqlite |
||
71 | * .SQLiteDatabase) |
||
72 | */ |
||
73 | @SuppressWarnings("nls") |
||
74 | @Override |
||
75 | public void onCreate(SQLiteDatabase db) |
||
76 | { |
||
77 | db.execSQL("CREATE TABLE IF NOT EXISTS " + CurrenciesDatabase.TABLE |
||
17 | PointedEar | 78 | + " (" + CurrenciesDatabase.COLUMN_CURRENCY + " TEXT" |
79 | + ", " + CurrenciesDatabase.COLUMN_FACTOR + " NUMERIC" |
||
80 | + ", " + CurrenciesDatabase.COLUMN_UPDATED |
||
81 | + " TEXT" |
||
12 | PointedEar | 82 | + ", CONSTRAINT unique_currency_pair UNIQUE (" |
17 | PointedEar | 83 | + CurrenciesDatabase.COLUMN_CURRENCY + ") ON CONFLICT REPLACE)"); |
11 | PointedEar | 84 | |
17 | PointedEar | 85 | this.writeConversionsToDatabase(db); |
86 | } |
||
87 | |||
88 | /** |
||
89 | * @param db |
||
90 | * The database; <code>null</code> uses the default database |
||
91 | */ |
||
92 | public void writeConversionsToDatabase(SQLiteDatabase db) |
||
93 | { |
||
94 | HashMap<String, ConversionData> currencyConversions = |
||
12 | PointedEar | 95 | this.getConversionRates(); |
17 | PointedEar | 96 | |
97 | if (db == null) |
||
11 | PointedEar | 98 | { |
17 | PointedEar | 99 | db = this.database; |
11 | PointedEar | 100 | } |
17 | PointedEar | 101 | |
102 | if (!db.isOpen()) |
||
103 | { |
||
104 | try |
||
105 | { |
||
106 | db = this.getWritableDatabase(); |
||
107 | } |
||
108 | catch (SQLiteException e) |
||
109 | { |
||
110 | Log.e(this.getClass().toString(), "Could not open database", e); |
||
111 | throw e; |
||
112 | } |
||
113 | } |
||
114 | |||
115 | if (db.isOpen()) |
||
116 | { |
||
117 | for (Entry<String, ConversionData> factorEntry : currencyConversions |
||
118 | .entrySet()) |
||
119 | { |
||
120 | ContentValues values = new ContentValues(); |
||
121 | values.put(CurrenciesDatabase.COLUMN_CURRENCY, factorEntry.getKey()); |
||
122 | values.put(CurrenciesDatabase.COLUMN_FACTOR, factorEntry.getValue() |
||
123 | .getRate()); |
||
124 | values.put(CurrenciesDatabase.COLUMN_UPDATED, |
||
125 | this.iso8601format.format(factorEntry.getValue() |
||
126 | .getUpdated())); |
||
127 | |||
128 | /* INSERT suffices here, thanks to ON CONFLICT REPLACE */ |
||
129 | db.insert(CurrenciesDatabase.TABLE, |
||
130 | CurrenciesDatabase.COLUMN_FACTOR, |
||
131 | values); |
||
132 | } |
||
133 | } |
||
11 | PointedEar | 134 | } |
135 | |||
136 | /* |
||
137 | * (non-Javadoc) |
||
138 | * |
||
139 | * @see |
||
140 | * android.database.sqlite.SQLiteOpenHelper#onUpgrade(android.database.sqlite |
||
141 | * .SQLiteDatabase, int, int) |
||
142 | */ |
||
143 | @SuppressWarnings("nls") |
||
144 | @Override |
||
145 | public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) |
||
146 | { |
||
13 | PointedEar | 147 | /* NOTE: We should migrate an existing database instead */ |
11 | PointedEar | 148 | db.execSQL("DROP TABLE IF EXISTS " + CurrenciesDatabase.TABLE); |
149 | this.onCreate(db); |
||
150 | } |
||
12 | PointedEar | 151 | |
152 | /** |
||
153 | * @return |
||
154 | */ |
||
17 | PointedEar | 155 | public HashMap<String, ConversionData> getConversionRates() |
12 | PointedEar | 156 | { |
13 | PointedEar | 157 | return CurrenciesDatabase.conversionRates; |
12 | PointedEar | 158 | } |
159 | |||
160 | /** |
||
161 | * Reads currency conversions and updates the static currencyConversions field |
||
162 | * of this class |
||
163 | */ |
||
164 | public void readConversionsFromDatabase() |
||
165 | { |
||
166 | try |
||
167 | { |
||
168 | /* Get database connection, but upgrade database first if necessary! */ |
||
17 | PointedEar | 169 | this.database = this.getWritableDatabase(); |
12 | PointedEar | 170 | |
171 | Cursor cursor = |
||
17 | PointedEar | 172 | this.database.query(true, CurrenciesDatabase.TABLE, null, null, null, |
173 | null, null, CurrenciesDatabase.COLUMN_CURRENCY, null); |
||
12 | PointedEar | 174 | |
175 | if (cursor != null) |
||
176 | { |
||
177 | try |
||
178 | { |
||
179 | int currency1Id = |
||
180 | cursor |
||
16 | PointedEar | 181 | .getColumnIndexOrThrow(CurrenciesDatabase.COLUMN_CURRENCY); |
12 | PointedEar | 182 | int factorId = |
183 | cursor.getColumnIndexOrThrow(CurrenciesDatabase.COLUMN_FACTOR); |
||
17 | PointedEar | 184 | int updatedId = |
185 | cursor.getColumnIndexOrThrow(CurrenciesDatabase.COLUMN_UPDATED); |
||
12 | PointedEar | 186 | |
187 | /* NOTE: Don't change the default values if the table is empty */ |
||
188 | if (cursor.moveToFirst()) |
||
189 | { |
||
17 | PointedEar | 190 | HashMap<String, ConversionData> newCurrencyConversions = |
191 | new HashMap<String, ConversionData>(); |
||
12 | PointedEar | 192 | |
193 | do |
||
194 | { |
||
16 | PointedEar | 195 | String currencyStr = cursor.getString(currency1Id); |
12 | PointedEar | 196 | Double factor = cursor.getDouble(factorId); |
17 | PointedEar | 197 | String updatedStr = cursor.getString(updatedId); |
198 | |||
199 | Date updated = new Date(0); |
||
200 | try |
||
201 | { |
||
202 | if (updatedStr != null) |
||
203 | { |
||
204 | updated = this.iso8601format.parse(updatedStr); |
||
205 | } |
||
206 | } |
||
207 | catch (ParseException e) |
||
208 | { |
||
209 | Log.e(this.getClass().toString(), |
||
210 | "Parsing ISO8601 datetime failed: '" + updatedStr + "'", e); |
||
211 | } |
||
212 | |||
213 | newCurrencyConversions.put(currencyStr, new ConversionData( |
||
214 | factor, updated)); |
||
12 | PointedEar | 215 | } |
216 | while (cursor.moveToNext()); |
||
217 | |||
13 | PointedEar | 218 | CurrenciesDatabase.conversionRates = newCurrencyConversions; |
12 | PointedEar | 219 | } |
220 | } |
||
221 | catch (IllegalArgumentException e) |
||
222 | { |
||
17 | PointedEar | 223 | Log.e(this.getClass().toString(), "Could not retrieve column index", |
224 | e); |
||
12 | PointedEar | 225 | } |
226 | } |
||
227 | |||
17 | PointedEar | 228 | this.database.close(); |
12 | PointedEar | 229 | } |
230 | catch (SQLiteException e1) |
||
231 | { |
||
17 | PointedEar | 232 | Log.e(this.getClass().toString(), "Could not open database", e1); |
12 | PointedEar | 233 | } |
234 | } |
||
11 | PointedEar | 235 | } |