|
1 // Copyright (c) 1998-2009 Nokia Corporation and/or its subsidiary(-ies). |
|
2 // All rights reserved. |
|
3 // This component and the accompanying materials are made available |
|
4 // under the terms of "Eclipse Public License v1.0" |
|
5 // which accompanies this distribution, and is available |
|
6 // at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
7 // |
|
8 // Initial Contributors: |
|
9 // Nokia Corporation - initial contribution. |
|
10 // |
|
11 // Contributors: |
|
12 // |
|
13 // Description: |
|
14 // |
|
15 |
|
16 #include <jni.h> |
|
17 #include "DbmsConnection.h" |
|
18 #include "Utils.h" |
|
19 #include "dbmsjni/com_symbian_dbms_jdbc_DbmsConnection.h" |
|
20 #include <stdlib.h> |
|
21 #include <stdio.h> |
|
22 |
|
23 CTrapCleanup* gCleanup = NULL; // get clean-up stack |
|
24 TInt gConnectionCount = 0; |
|
25 jclass gExcCls = NULL; |
|
26 TUint32 gThirdUid = 0; |
|
27 |
|
28 extern TPanicHandler gPanicHandler; |
|
29 extern TInt gBlockSize; |
|
30 extern TInt gClusterSize; |
|
31 extern TExtendedLocale gLocale; |
|
32 |
|
33 // // |
|
34 // DbmsConnection peer |
|
35 // // |
|
36 |
|
37 DbmsConnection::DbmsConnection(){ |
|
38 iOpen = EFalse; |
|
39 } |
|
40 |
|
41 DbmsConnection::~DbmsConnection(){ |
|
42 } |
|
43 |
|
44 TInt DbmsConnection::Open(const TDesC& aFileName){ |
|
45 RFs fs; |
|
46 TInt res = iDatabase.Open(fs, aFileName); |
|
47 if ( res == KErrNotFound ) { |
|
48 if ( gThirdUid != 0 ) { |
|
49 TBuf<64> buf; |
|
50 buf.Append(_L("SECURE[")); |
|
51 buf.AppendNum(gThirdUid, EHex); |
|
52 buf.Append(_L("]")); |
|
53 res = iDatabase.Create(fs, aFileName, buf); |
|
54 } else { |
|
55 res = iDatabase.Create(fs, aFileName); |
|
56 } |
|
57 } |
|
58 if ( res == KErrNone ) { |
|
59 iOpen = ETrue; |
|
60 } |
|
61 return res; |
|
62 } |
|
63 |
|
64 void DbmsConnection::Close(){ |
|
65 if ( iOpen ) |
|
66 { |
|
67 iDatabase.Compact(); |
|
68 } |
|
69 iDatabase.Close(); |
|
70 iOpen = EFalse; |
|
71 } |
|
72 |
|
73 // // |
|
74 // JNI |
|
75 // // |
|
76 |
|
77 /* |
|
78 * Class: com_symbian_dbms_jdbc_DbmsConnection |
|
79 * Method: _globalInit |
|
80 * Signature: ()V |
|
81 */ |
|
82 JNIEXPORT void JNICALL Java_com_symbian_dbms_jdbc_DbmsConnection__1globalInit |
|
83 (JNIEnv *aEnv, jobject) { |
|
84 if ( gCleanup == NULL ) { |
|
85 // init globals |
|
86 gCleanup=CTrapCleanup::New(); // get clean-up stack |
|
87 gPanicHandler = &SosPanicHandler; |
|
88 jclass excCls = aEnv->FindClass("java/lang/RuntimeException"); |
|
89 if ( excCls == NULL ) |
|
90 { |
|
91 printf("Could not create exception class java/lang/RuntimeException in DbmsConnection::init ...\n"); |
|
92 } |
|
93 else |
|
94 { |
|
95 gExcCls = (jclass)(aEnv->NewGlobalRef(excCls)); |
|
96 if ( gExcCls == NULL ) |
|
97 { |
|
98 printf("Could not create glref to exception class java/lang/RuntimeException in DbmsConnection::init ...\n"); |
|
99 } |
|
100 } |
|
101 } |
|
102 } |
|
103 |
|
104 |
|
105 JNIEXPORT jint JNICALL Java_com_symbian_dbms_jdbc_DbmsConnection__1init |
|
106 (JNIEnv *aEnv, jobject aObject, jstring aString) { |
|
107 gConnectionCount++; |
|
108 DbmsConnection* connection = new DbmsConnection(); |
|
109 RJString file(*aEnv, aString); |
|
110 TInt res = connection->Open(file); |
|
111 if ( res != KErrNone ){ |
|
112 connection->Close(); |
|
113 delete connection; |
|
114 return (jint) res; |
|
115 } else { |
|
116 return (jint) connection; |
|
117 } |
|
118 } |
|
119 |
|
120 /* |
|
121 * Class: com_symbian_dbms_jdbc_DbmsConnection |
|
122 * Method: _setSecureId |
|
123 * Signature: (I)V |
|
124 */ |
|
125 JNIEXPORT void JNICALL Java_com_symbian_dbms_jdbc_DbmsConnection__1setSecureId |
|
126 (JNIEnv *, jobject, jint aSecureId) { |
|
127 gThirdUid = aSecureId; |
|
128 } |
|
129 |
|
130 /* |
|
131 * Class: com_symbian_dbms_jdbc_DbmsConnection |
|
132 * Method: _close |
|
133 * Signature: (I)V |
|
134 */ |
|
135 JNIEXPORT void JNICALL Java_com_symbian_dbms_jdbc_DbmsConnection__1close |
|
136 (JNIEnv * aEnv, jobject aJavaObj, jint aPeer) { |
|
137 DbmsConnection* connection = (DbmsConnection*) aPeer; |
|
138 connection->Close(); |
|
139 delete connection; |
|
140 gConnectionCount--; |
|
141 if ( gConnectionCount == 0 && gCleanup != NULL ) { |
|
142 delete gCleanup; |
|
143 gCleanup = NULL; |
|
144 } |
|
145 } |
|
146 |
|
147 /* |
|
148 * Class: com_symbian_dbms_jdbc_DbmsConnection |
|
149 * Method: _setLocaleDll |
|
150 * Signature: (Ljava/lang/String;)I |
|
151 */ |
|
152 JNIEXPORT jint JNICALL Java_com_symbian_dbms_jdbc_DbmsConnection__1setLocaleDll |
|
153 (JNIEnv *aEnv, jobject, jstring aDllFile){ |
|
154 RJString rj(*aEnv, aDllFile); |
|
155 return gLocale.LoadLocale(rj); |
|
156 } |
|
157 |
|
158 /* |
|
159 * Class: com_symbian_dbms_jdbc_DbmsConnection |
|
160 * Method: _setBlockSize |
|
161 * Signature: (I)V |
|
162 */ |
|
163 JNIEXPORT void JNICALL Java_com_symbian_dbms_jdbc_DbmsConnection__1setBlockSize |
|
164 (JNIEnv *, jobject, jint aBlockSize){ |
|
165 gBlockSize = aBlockSize; |
|
166 } |
|
167 |
|
168 /* |
|
169 * Class: com_symbian_dbms_jdbc_DbmsConnection |
|
170 * Method: _setClusterSize |
|
171 * Signature: (I)V |
|
172 */ |
|
173 JNIEXPORT void JNICALL Java_com_symbian_dbms_jdbc_DbmsConnection__1setClusterSize |
|
174 (JNIEnv *, jobject, jint aClusterSize){ |
|
175 gClusterSize = aClusterSize; |
|
176 } |
|
177 |
|
178 |
|
179 void PrintColTypeName(TDes8& aDes, TDbCol& col) |
|
180 { |
|
181 _LIT8(KNotNull, "not-null "); |
|
182 _LIT8(KAutoIncrement, "auto-increment"); |
|
183 _LIT8(KColNameInt8, "EDbColInt8"); |
|
184 _LIT8(KColNameInt16, "EDbColInt16"); |
|
185 _LIT8(KColNameInt32, "EDbColInt32"); |
|
186 _LIT8(KColNameInt64, "EDbColInt64"); |
|
187 _LIT8(KColNameUInt8, "EDbColUint8"); |
|
188 _LIT8(KColNameUInt16, "EDbColUint16"); |
|
189 _LIT8(KColNameUInt32, "EDbColUint32"); |
|
190 _LIT8(KColNameBit, "EDbColBit"); |
|
191 _LIT8(KColNameReal32,"EDbColReal32"); |
|
192 _LIT8(KColNameReal64,"EDbColReal64"); |
|
193 _LIT8(KColNameDateTime,"EDbColDateTime"); |
|
194 _LIT8(KColNameBinary,"EDbColBinary"); |
|
195 _LIT8(KColNameText8,"EDbColText8"); |
|
196 _LIT8(KColNameText16,"EDbColText16"); |
|
197 _LIT8(KColNameLongBinary,"EDbColLongBinary"); |
|
198 _LIT8(KColNameLongText8,"EDbColLongText8"); |
|
199 _LIT8(KColNameLongText16,"EDbColLongText16"); |
|
200 _LIT8(KFormattingPrefix, "| "); |
|
201 aDes.Append(KFormattingPrefix); |
|
202 switch ( col.iType ) |
|
203 { |
|
204 case EDbColInt8: |
|
205 { |
|
206 aDes.Append(KColNameInt8); |
|
207 break; |
|
208 } |
|
209 case EDbColInt16: |
|
210 { |
|
211 aDes.Append(KColNameInt16); |
|
212 break; |
|
213 } |
|
214 case EDbColInt32: |
|
215 { |
|
216 aDes.Append(KColNameInt32); |
|
217 break; |
|
218 } |
|
219 case EDbColInt64: |
|
220 { |
|
221 aDes.Append(KColNameInt64); |
|
222 break; |
|
223 } |
|
224 case EDbColUint8: |
|
225 { |
|
226 aDes.Append(KColNameUInt8); |
|
227 break; |
|
228 } |
|
229 case EDbColUint16: |
|
230 { |
|
231 aDes.Append(KColNameUInt16); |
|
232 break; |
|
233 } |
|
234 case EDbColUint32: |
|
235 { |
|
236 aDes.Append(KColNameUInt32); |
|
237 break; |
|
238 } |
|
239 case EDbColBit: |
|
240 { |
|
241 aDes.Append(KColNameBit); |
|
242 break; |
|
243 } |
|
244 case EDbColReal32: |
|
245 { |
|
246 aDes.Append(KColNameReal32); |
|
247 break; |
|
248 } |
|
249 case EDbColReal64: |
|
250 { |
|
251 aDes.Append(KColNameReal64); |
|
252 break; |
|
253 } |
|
254 case EDbColDateTime: |
|
255 { |
|
256 aDes.Append(KColNameDateTime); |
|
257 break; |
|
258 } |
|
259 case EDbColBinary: |
|
260 { |
|
261 aDes.Append(KColNameBinary); |
|
262 break; |
|
263 } |
|
264 case EDbColText8: |
|
265 { |
|
266 aDes.Append(KColNameText8); |
|
267 aDes.Append('['); |
|
268 aDes.AppendNum(col.iMaxLength); |
|
269 aDes.Append(']'); |
|
270 break; |
|
271 } |
|
272 case EDbColText16: |
|
273 { |
|
274 aDes.Append(KColNameText16); |
|
275 aDes.Append('['); |
|
276 aDes.AppendNum(col.iMaxLength); |
|
277 aDes.Append(']'); |
|
278 break; |
|
279 } |
|
280 case EDbColLongBinary: |
|
281 { |
|
282 aDes.Append(KColNameLongBinary); |
|
283 break; |
|
284 } |
|
285 case EDbColLongText8: |
|
286 { |
|
287 aDes.Append(KColNameLongText8); |
|
288 break; |
|
289 } |
|
290 case EDbColLongText16: |
|
291 { |
|
292 aDes.Append(KColNameLongText16); |
|
293 break; |
|
294 } |
|
295 } // end switch |
|
296 TInt len = aDes.Length(); |
|
297 for (TInt i = len; i < 46 ; i++ ) |
|
298 aDes.Append(' '); |
|
299 |
|
300 aDes.Append(KFormattingPrefix); |
|
301 if ( col.iAttributes & TDbCol::ENotNull ) |
|
302 { |
|
303 aDes.Append(KNotNull); |
|
304 } |
|
305 if ( col.iAttributes & TDbCol::EAutoIncrement ) |
|
306 { |
|
307 aDes.Append(KAutoIncrement); |
|
308 } |
|
309 } |
|
310 |
|
311 |
|
312 jstring DumpSchemaL(JNIEnv *aEnv, jobject, jint aPeer){ |
|
313 _LIT8(KSchemaTableLabel, "Table: "); |
|
314 _LIT8(KSchemaIndexLabel, "| INDEX: "); |
|
315 _LIT8(KLine, "----------------------------------------------------------------------------\n"); |
|
316 DbmsConnection* connection = (DbmsConnection*) aPeer; |
|
317 RDbNamedDatabase& db = connection->iDatabase; |
|
318 TInt KMaxSchemaSize = 1024*1024; // 1Mb |
|
319 |
|
320 CDbTableNames* tableNames = db.TableNamesL(); |
|
321 RBuf8 resultBuf; |
|
322 RBuf retBuf; |
|
323 TBuf8<512> printBuf; |
|
324 TInt err = resultBuf.Create(KMaxSchemaSize); |
|
325 if ( err != KErrNone ) { |
|
326 ThrowExc(aEnv, err ); |
|
327 return NULL; |
|
328 } |
|
329 err = retBuf.Create(KMaxSchemaSize); |
|
330 if ( err != KErrNone ) { |
|
331 resultBuf.Close(); |
|
332 ThrowExc(aEnv, err ); |
|
333 return NULL; |
|
334 } |
|
335 for (int i = 0; i < tableNames->Count(); i++ ) |
|
336 { |
|
337 TBuf<64> tableName; |
|
338 tableName.Copy((*tableNames)[i]); |
|
339 printBuf.Copy(KSchemaTableLabel); |
|
340 printBuf.Append(tableName); |
|
341 resultBuf.Append( KLine); |
|
342 resultBuf.Append(_L8("| ")); |
|
343 resultBuf.Append(printBuf); |
|
344 for( TInt j = printBuf.Length() ; j < 74; j++) |
|
345 resultBuf.Append(_L8(" ")); |
|
346 resultBuf.Append(_L8("|\n")); |
|
347 resultBuf.Append(KLine); |
|
348 |
|
349 CDbColSet* colSet = db.ColSetL(tableName); |
|
350 CleanupStack::PushL(colSet); |
|
351 printBuf.Zero(); |
|
352 |
|
353 resultBuf.Append(_L8("| Column name ")); |
|
354 resultBuf.Append(_L8("| Type ")); |
|
355 resultBuf.Append(_L8("| Flags |\n")); |
|
356 resultBuf.Append(KLine); |
|
357 for ( TInt ii = 0 ; ii < colSet->Count() ; ii++ ) |
|
358 { |
|
359 TDbCol col = (*colSet)[ii+1]; |
|
360 TBuf8<128> cn; |
|
361 cn.Copy(col.iName); |
|
362 printBuf.Copy(cn); |
|
363 printBuf.Append(' '); |
|
364 for(TInt j = cn.Length() ; j < 25; j++ ) |
|
365 printBuf.Append(' '); |
|
366 PrintColTypeName(printBuf, col); |
|
367 printBuf.Append(' '); |
|
368 resultBuf.Append(_L8("| ")); |
|
369 resultBuf.Append(printBuf); |
|
370 for( TInt j = printBuf.Length() ; j < 74; j++) |
|
371 resultBuf.Append(_L8(" ")); |
|
372 resultBuf.Append(_L8("|\n")); |
|
373 } |
|
374 |
|
375 CleanupStack::PopAndDestroy(); |
|
376 |
|
377 // indices |
|
378 _LIT8(KPrimary, " PRIMARY KEY "); |
|
379 _LIT8(KUnique, " UNIQUE "); |
|
380 _LIT8(KFolded, " Comparison: FOLDED "); |
|
381 _LIT8(KCollated, " Comparison: COLLATED "); |
|
382 _LIT8(KNormal, " Comparison: NORMAL "); |
|
383 |
|
384 CDbIndexNames* indexNames = db.IndexNamesL(tableName); |
|
385 |
|
386 if ( indexNames->Count() > 0 ) |
|
387 resultBuf.Append(KLine); |
|
388 |
|
389 for (int j = 0; j < indexNames->Count(); j++ ) |
|
390 { |
|
391 TBuf<64> indexName; |
|
392 indexName.Copy((*indexNames)[j]); |
|
393 printBuf.Copy(KSchemaIndexLabel); |
|
394 printBuf.Append(indexName); |
|
395 printBuf.Append(' '); |
|
396 printBuf.Append('('); |
|
397 printBuf.Append(' '); |
|
398 CDbKey* key = db.KeyL(indexName, tableName); |
|
399 CleanupStack::PushL(key); |
|
400 // indexed columns |
|
401 for ( int k = 0 ; k < key->Count(); k ++ ) |
|
402 { |
|
403 if ( k != 0 ) |
|
404 { |
|
405 printBuf.Append(','); |
|
406 printBuf.Append(' '); |
|
407 } |
|
408 TDbKeyCol col = (*key)[k]; |
|
409 printBuf.Append(col.iName); |
|
410 } |
|
411 printBuf.Append(' '); |
|
412 printBuf.Append(')'); |
|
413 printBuf.Append(' '); |
|
414 if ( key->IsPrimary() ) |
|
415 { |
|
416 printBuf.Append(KPrimary); |
|
417 } |
|
418 if ( key->IsUnique() ) |
|
419 { |
|
420 printBuf.Append(KUnique); |
|
421 } |
|
422 switch ( key->Comparison() ) |
|
423 { |
|
424 case EDbCompareNormal: |
|
425 { |
|
426 printBuf.Append(KNormal); |
|
427 break; |
|
428 } |
|
429 case EDbCompareFolded: |
|
430 { |
|
431 printBuf.Append(KFolded); |
|
432 break; |
|
433 } |
|
434 case EDbCompareCollated: |
|
435 { |
|
436 printBuf.Append(KCollated); |
|
437 break; |
|
438 } |
|
439 } |
|
440 CleanupStack::PopAndDestroy(); |
|
441 |
|
442 resultBuf.Append(printBuf); |
|
443 for( TInt j = printBuf.Length() ; j < 76; j++) |
|
444 resultBuf.Append(_L8(" ")); |
|
445 resultBuf.Append(_L8("|\n")); |
|
446 } |
|
447 |
|
448 resultBuf.Append(KLine); |
|
449 resultBuf.Append(_L8("\n")); |
|
450 } |
|
451 delete tableNames; |
|
452 // create java string - must copy into 16 bit desc |
|
453 retBuf.Copy(resultBuf); |
|
454 resultBuf.Close(); |
|
455 jstring jret = CreateJavaString( aEnv, retBuf ); |
|
456 retBuf.Close(); |
|
457 return jret; |
|
458 } |
|
459 |
|
460 /* |
|
461 * Class: com_symbian_dbms_jdbc_DbmsConnection |
|
462 * Method: _schema |
|
463 * Signature: (I)Ljava/lang/String; |
|
464 */ |
|
465 JNIEXPORT jstring JNICALL Java_com_symbian_dbms_jdbc_DbmsConnection__1schema |
|
466 (JNIEnv *aEnv, jobject aObj, jint aPeer) { |
|
467 jstring ret = NULL; |
|
468 TRAPD(err, ret = DumpSchemaL(aEnv, aObj, aPeer)); |
|
469 if ( err != KErrNone ) { |
|
470 ThrowExc(aEnv, err ); |
|
471 return NULL; |
|
472 } |
|
473 return ret; |
|
474 } |