configlib/dbmsjdbc/src/native/DbmsConnection.cpp
author m2lahtel
Tue, 10 Aug 2010 14:29:28 +0300
changeset 3 e7e0ae78773e
parent 1 b538b70cbe51
permissions -rw-r--r--
ConE 1.2.11 release

// Copyright (c) 1998-2009 Nokia Corporation and/or its subsidiary(-ies).
// All rights reserved.
// This component and the accompanying materials are made available
// under the terms of "Eclipse Public License v1.0"
// which accompanies this distribution, and is available
// at the URL "http://www.eclipse.org/legal/epl-v10.html".
//
// Initial Contributors:
// Nokia Corporation - initial contribution.
//
// Contributors:
//
// Description:
//

#include <jni.h>
#include "DbmsConnection.h"
#include "Utils.h"
#include "dbmsjni/com_symbian_dbms_jdbc_DbmsConnection.h"
#include <stdlib.h>
#include <stdio.h>

CTrapCleanup* gCleanup = NULL; // get clean-up stack
TInt gConnectionCount = 0;
jclass gExcCls = NULL;
TUint32 gThirdUid = 0;

extern TPanicHandler gPanicHandler;
extern TInt gBlockSize;
extern TInt gClusterSize;
extern TExtendedLocale gLocale;

// //
// DbmsConnection peer
// //

DbmsConnection::DbmsConnection(){
	iOpen = EFalse;
}

DbmsConnection::~DbmsConnection(){
}

TInt DbmsConnection::Open(const TDesC& aFileName){
	RFs fs;
	TInt res = iDatabase.Open(fs, aFileName);
	if ( res == KErrNotFound ) {
		if ( gThirdUid != 0 ) {
			TBuf<64> buf;
			buf.Append(_L("SECURE["));
			buf.AppendNum(gThirdUid, EHex);
			buf.Append(_L("]"));
			res = iDatabase.Create(fs, aFileName, buf);
		} else {
			res = iDatabase.Create(fs, aFileName);
		}
	}
	if ( res == KErrNone ) {
		iOpen = ETrue;
	}
	return res;
}

void DbmsConnection::Close(){
	if ( iOpen )
		{
		iDatabase.Compact();
		}
	iDatabase.Close();
	iOpen = EFalse;
}

// //
// JNI
// //

/*
 * Class:     com_symbian_dbms_jdbc_DbmsConnection
 * Method:    _globalInit
 * Signature: ()V
 */
JNIEXPORT void JNICALL Java_com_symbian_dbms_jdbc_DbmsConnection__1globalInit
  (JNIEnv *aEnv, jobject) {
	if ( gCleanup == NULL ) {
		// init globals
		gCleanup=CTrapCleanup::New(); // get clean-up stack
		gPanicHandler = &SosPanicHandler;
		jclass excCls = aEnv->FindClass("java/lang/RuntimeException");
		if ( excCls == NULL )
			{
			printf("Could not create exception class java/lang/RuntimeException in DbmsConnection::init ...\n");
			}
		else
			{
			gExcCls = (jclass)(aEnv->NewGlobalRef(excCls));
			if ( gExcCls == NULL )
				{
				printf("Could not create glref to exception class java/lang/RuntimeException in DbmsConnection::init ...\n");
				}
			}
	}
}


JNIEXPORT jint JNICALL Java_com_symbian_dbms_jdbc_DbmsConnection__1init
  (JNIEnv *aEnv, jobject aObject, jstring aString) {
	gConnectionCount++;
	DbmsConnection* connection = new DbmsConnection();
	RJString file(*aEnv, aString);
	TInt res = connection->Open(file);
	if ( res != KErrNone ){
		connection->Close();
		delete connection;
		return (jint) res;
	} else {
		return (jint) connection;
	}
}

/*
 * Class:     com_symbian_dbms_jdbc_DbmsConnection
 * Method:    _setSecureId
 * Signature: (I)V
 */
JNIEXPORT void JNICALL Java_com_symbian_dbms_jdbc_DbmsConnection__1setSecureId
  (JNIEnv *, jobject, jint aSecureId) {
	gThirdUid = aSecureId;
}

/*
 * Class:     com_symbian_dbms_jdbc_DbmsConnection
 * Method:    _close
 * Signature: (I)V
 */
JNIEXPORT void JNICALL Java_com_symbian_dbms_jdbc_DbmsConnection__1close
  (JNIEnv * aEnv, jobject aJavaObj, jint aPeer) {
	DbmsConnection* connection = (DbmsConnection*) aPeer;
	connection->Close();
	delete connection;
	gConnectionCount--;
	if ( gConnectionCount == 0 && gCleanup != NULL ) {
		delete gCleanup;
		gCleanup = NULL;
	}
}

/*
 * Class:     com_symbian_dbms_jdbc_DbmsConnection
 * Method:    _setLocaleDll
 * Signature: (Ljava/lang/String;)I
 */
JNIEXPORT jint JNICALL Java_com_symbian_dbms_jdbc_DbmsConnection__1setLocaleDll
  (JNIEnv *aEnv, jobject, jstring aDllFile){
	RJString rj(*aEnv, aDllFile);
	return gLocale.LoadLocale(rj);
}

/*
 * Class:     com_symbian_dbms_jdbc_DbmsConnection
 * Method:    _setBlockSize
 * Signature: (I)V
 */
JNIEXPORT void JNICALL Java_com_symbian_dbms_jdbc_DbmsConnection__1setBlockSize
  (JNIEnv *, jobject, jint aBlockSize){
	gBlockSize = aBlockSize;
}

/*
 * Class:     com_symbian_dbms_jdbc_DbmsConnection
 * Method:    _setClusterSize
 * Signature: (I)V
 */
JNIEXPORT void JNICALL Java_com_symbian_dbms_jdbc_DbmsConnection__1setClusterSize
  (JNIEnv *, jobject, jint aClusterSize){
	gClusterSize = aClusterSize;
}


void PrintColTypeName(TDes8& aDes, TDbCol& col)
	{
	_LIT8(KNotNull, "not-null ");
	_LIT8(KAutoIncrement, "auto-increment");
	_LIT8(KColNameInt8, "EDbColInt8");
	_LIT8(KColNameInt16, "EDbColInt16");
	_LIT8(KColNameInt32, "EDbColInt32");
	_LIT8(KColNameInt64, "EDbColInt64");
	_LIT8(KColNameUInt8, "EDbColUint8");
	_LIT8(KColNameUInt16, "EDbColUint16");
	_LIT8(KColNameUInt32, "EDbColUint32");
	_LIT8(KColNameBit, "EDbColBit");
	_LIT8(KColNameReal32,"EDbColReal32");
	_LIT8(KColNameReal64,"EDbColReal64");
	_LIT8(KColNameDateTime,"EDbColDateTime");
	_LIT8(KColNameBinary,"EDbColBinary");
	_LIT8(KColNameText8,"EDbColText8");
	_LIT8(KColNameText16,"EDbColText16");
	_LIT8(KColNameLongBinary,"EDbColLongBinary");
	_LIT8(KColNameLongText8,"EDbColLongText8");
	_LIT8(KColNameLongText16,"EDbColLongText16");
	_LIT8(KFormattingPrefix, "| ");
	aDes.Append(KFormattingPrefix);
	switch ( col.iType )
		{
		case EDbColInt8:
			{
			aDes.Append(KColNameInt8);
			break;
			}
		case EDbColInt16:
			{
			aDes.Append(KColNameInt16);
			break;
			}
		case EDbColInt32:
			{
			aDes.Append(KColNameInt32);
			break;
			}
		case EDbColInt64:
			{
			aDes.Append(KColNameInt64);
			break;
			}
		case EDbColUint8:
			{
			aDes.Append(KColNameUInt8);
			break;
			}
		case EDbColUint16:
			{
			aDes.Append(KColNameUInt16);
			break;
			}
		case EDbColUint32:
			{
			aDes.Append(KColNameUInt32);
			break;
			}
		case EDbColBit:
			{
			aDes.Append(KColNameBit);
			break;
			}
		case EDbColReal32:
			{
			aDes.Append(KColNameReal32);
			break;
			}
		case EDbColReal64:
			{
			aDes.Append(KColNameReal64);
			break;
			}
		case EDbColDateTime:
			{
			aDes.Append(KColNameDateTime);
			break;
			}
		case EDbColBinary:
			{
			aDes.Append(KColNameBinary);
			break;
			}
		case EDbColText8:
			{
			aDes.Append(KColNameText8);
			aDes.Append('[');
			aDes.AppendNum(col.iMaxLength);
			aDes.Append(']');
			break;
			}
		case EDbColText16:
			{
			aDes.Append(KColNameText16);
			aDes.Append('[');
			aDes.AppendNum(col.iMaxLength);
			aDes.Append(']');
			break;
			}
		case EDbColLongBinary:
			{
			aDes.Append(KColNameLongBinary);
			break;
			}
		case EDbColLongText8:
			{
			aDes.Append(KColNameLongText8);
			break;
			}
		case EDbColLongText16:
			{
			aDes.Append(KColNameLongText16);
			break;
			}
		} // end switch
		TInt len = aDes.Length();
		for (TInt i = len; i < 46 ; i++ )
			aDes.Append(' ');

		aDes.Append(KFormattingPrefix);
		if ( col.iAttributes & TDbCol::ENotNull )
			{
			aDes.Append(KNotNull);
			}
		if ( col.iAttributes & TDbCol::EAutoIncrement )
			{
			aDes.Append(KAutoIncrement);
			}
	}


jstring DumpSchemaL(JNIEnv *aEnv, jobject, jint aPeer){
	_LIT8(KSchemaTableLabel, "Table: ");
	_LIT8(KSchemaIndexLabel, "| INDEX: ");
	_LIT8(KLine, "----------------------------------------------------------------------------\n");
	DbmsConnection* connection = (DbmsConnection*) aPeer;
	RDbNamedDatabase& db = connection->iDatabase;
	TInt KMaxSchemaSize = 1024*1024; // 1Mb

	CDbTableNames* tableNames = db.TableNamesL();
	RBuf8 resultBuf;
	RBuf retBuf;
	TBuf8<512> printBuf;
	TInt err = resultBuf.Create(KMaxSchemaSize);
	if ( err != KErrNone ) {
		ThrowExc(aEnv, err );
		return NULL;
	}
	err = retBuf.Create(KMaxSchemaSize);
	if ( err != KErrNone ) {
		resultBuf.Close();
		ThrowExc(aEnv, err );
		return NULL;
	}
	for (int i = 0; i < tableNames->Count(); i++ )
		{
		TBuf<64> tableName;
		tableName.Copy((*tableNames)[i]);
		printBuf.Copy(KSchemaTableLabel);
		printBuf.Append(tableName);
		resultBuf.Append(	KLine);
		resultBuf.Append(_L8("| "));
		resultBuf.Append(printBuf);
		for( TInt j = printBuf.Length() ; j < 74; j++)
			resultBuf.Append(_L8(" "));
		resultBuf.Append(_L8("|\n"));
		resultBuf.Append(KLine);

		CDbColSet* colSet = db.ColSetL(tableName);
		CleanupStack::PushL(colSet);
		printBuf.Zero();

		resultBuf.Append(_L8("| Column name               "));
		resultBuf.Append(_L8("| Type              "));
		resultBuf.Append(_L8("| Flags                    |\n"));
		resultBuf.Append(KLine);
		for ( TInt ii = 0 ; ii < colSet->Count() ; ii++ )
			{
			TDbCol col = (*colSet)[ii+1];
			TBuf8<128> cn;
			cn.Copy(col.iName);
			printBuf.Copy(cn);
			printBuf.Append(' ');
			for(TInt j = cn.Length() ; j < 25; j++ )
				printBuf.Append(' ');
			PrintColTypeName(printBuf, col);
			printBuf.Append(' ');
			resultBuf.Append(_L8("| "));
			resultBuf.Append(printBuf);
			for( TInt j = printBuf.Length() ; j < 74; j++)
				resultBuf.Append(_L8(" "));
			resultBuf.Append(_L8("|\n"));
			}

		CleanupStack::PopAndDestroy();

		// indices
		_LIT8(KPrimary, " PRIMARY KEY ");
		_LIT8(KUnique, " UNIQUE ");
		_LIT8(KFolded, " Comparison: FOLDED ");
		_LIT8(KCollated, " Comparison: COLLATED ");
		_LIT8(KNormal, " Comparison: NORMAL ");

		CDbIndexNames* indexNames = db.IndexNamesL(tableName);

		if ( indexNames->Count() > 0 )
			resultBuf.Append(KLine);

		for (int j = 0; j < indexNames->Count(); j++ )
			{
			TBuf<64> indexName;
			indexName.Copy((*indexNames)[j]);
			printBuf.Copy(KSchemaIndexLabel);
			printBuf.Append(indexName);
			printBuf.Append(' ');
			printBuf.Append('(');
			printBuf.Append(' ');
			CDbKey* key = db.KeyL(indexName, tableName);
			CleanupStack::PushL(key);
			// indexed columns
			for ( int k = 0 ; k < key->Count(); k ++ )
				{
				if ( k != 0 )
					{
					printBuf.Append(',');
					printBuf.Append(' ');
					}
				TDbKeyCol col = (*key)[k];
				printBuf.Append(col.iName);
				}
			printBuf.Append(' ');
			printBuf.Append(')');
			printBuf.Append(' ');
			if ( key->IsPrimary() )
				{
				printBuf.Append(KPrimary);
				}
			if ( key->IsUnique() )
				{
				printBuf.Append(KUnique);
				}
			switch ( key->Comparison() )
				{
				case EDbCompareNormal:
					{
					printBuf.Append(KNormal);
					break;
					}
				case EDbCompareFolded:
					{
					printBuf.Append(KFolded);
					break;
					}
				case EDbCompareCollated:
					{
					printBuf.Append(KCollated);
					break;
					}
				}
			CleanupStack::PopAndDestroy();

			resultBuf.Append(printBuf);
			for( TInt j = printBuf.Length() ; j < 76; j++)
				resultBuf.Append(_L8(" "));
			resultBuf.Append(_L8("|\n"));
			}

		resultBuf.Append(KLine);
		resultBuf.Append(_L8("\n"));
		}
	delete tableNames;
	// create java string - must copy into 16 bit desc
	retBuf.Copy(resultBuf);
	resultBuf.Close();
	jstring jret = CreateJavaString( aEnv, retBuf );
	retBuf.Close();
	return jret;
}

/*
 * Class:     com_symbian_dbms_jdbc_DbmsConnection
 * Method:    _schema
 * Signature: (I)Ljava/lang/String;
 */
JNIEXPORT jstring JNICALL Java_com_symbian_dbms_jdbc_DbmsConnection__1schema
  (JNIEnv *aEnv, jobject aObj, jint aPeer) {
	jstring ret = NULL;
	TRAPD(err, ret = DumpSchemaL(aEnv, aObj, aPeer));
	if ( err != KErrNone ) {
		ThrowExc(aEnv, err );
		return NULL;
	}
	return ret;
}