[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-commits
Subject:    koffice/kexi/migration/xbase
From:       Sharan Rao <sharanrao () gmail ! com>
Date:       2008-05-15 20:07:14
Message-ID: 1210882034.670216.32071.nullmailer () svn ! kde ! org
[Download RAW message or body]

SVN commit 808154 by sharan:

Support for index files and blobs in xBase migration plugin.
TODO: A better way of selecting index files ( we're going by \
<tablename>_<fieldName>.ndx or .ntx convention now )

Also, need to find some real database to do better testing.



 M  +137 -8    xbasemigrate.cpp  
 M  +6 -0      xbasemigrate.h  


--- trunk/koffice/kexi/migration/xbase/xbasemigrate.cpp #808153:808154
@@ -81,7 +81,7 @@
 		// to the dbfList of xbXBase class ( if there is no error )
 		QString absoluteFileName = xBaseDirectory.filePath( fileName );
 		fileName.chop( 4 ); // remove the letters .dbf
-		tableNamePathMap[fileName] = absoluteFileName;
+		tableNamePathMap[fileName.toLower()] = absoluteFileName;
 
 		if (  ( returnCode = table->OpenDatabase( absoluteFileName.toUtf8().constData() ) \
) != XB_NO_ERROR ) {  switch( returnCode ) {
@@ -102,8 +102,6 @@
 	}
 
 	kDebug()<<"Successfully processed all the dbf files in the directory";
-	//! TODO Open .NDX,.NTX, .DBT files too
-
 	return true;
 }
 
@@ -155,13 +153,12 @@
 
 	for( xbShort i = 0; i < numFlds; i = i + 1 ) {
 		QString fldName = QString::fromLatin1( tableDbf->GetFieldName( i ) );
-		QString fldID( KexiUtils::string2Identifier( fldName ) );
+		QString fldID( KexiUtils::string2Identifier( fldName.toLower() ) );
 
 		KexiDB::Field *fld =
 		    new KexiDB::Field( fldID, type( tableDbf->GetFieldType( i ) ) );
 
-		//! TODO Open Index files and fill in these constraints
-		// getConstraints()
+		getConstraints(originalName, fld);
 
 		tableSchema.addField(fld);
 	}
@@ -210,7 +207,14 @@
 		// fields are indexed from 0
 		for( xbShort j = 0; j < numFlds; j = j + 1 ) {
 			const char* data = tableDbf->GetField(j);
-                        QVariant val;
+			QVariant val;
+
+			#ifdef XB_MEMO_FIELDS
+				int blobFieldLength;
+				char* memoBuffer = 0;
+				int rc;
+			#endif
+	
 			switch ( type( tableDbf->GetFieldType( j ) ) ) {
 				case KexiDB::Field::Date:
 					val = QDate::fromString( data, "yyyyMMdd" );
@@ -228,13 +232,36 @@
 							break;
 					}
 					break;
+				case KexiDB::Field::BLOB:
+				#ifdef XB_MEMO_FIELDS
+					blobFieldLength = tableDbf->GetMemoFieldLen(j);
+					memoBuffer = new char[blobFieldLength];
+
+					#ifdef XB_LOCKING_ON
+						tableDbf->LockMemoFile( F_SETLK, F_RDLCK );
+					#endif
+
+					if ( ( rc = tableDbf->GetMemoField( j , blobFieldLength, memoBuffer, F_SETLKW ) \
) != XB_NO_ERROR ) { +						kDebug()<<"Error reading blob field. Error code: "<<rc; \
// make error message more verbose +					} else {
+						val = KexiDB::cstringToVariant( memoBuffer, fieldsExpanded.at(j)->field, \
blobFieldLength ); +					}
+					#ifdef XB_LOCKING_ON
+						tableDbf->LockMemoFile( F_SETLK, F_UNLCK );
+					#endif
+
+					delete[] memoBuffer;
+					break;
+				#else
+					kDebug()<<"XB_MEMO_FIELDS support disabled during compilation of XBase \
libraries"; +				#endif
+
 				default:
 					val = KexiDB::cstringToVariant(data, fieldsExpanded.at(j)->field, strlen( data \
) ) ;  break;
 			}
 			vals.append( val );
 		}
-		kDebug()<<vals;
 		if (!destConn->insertRecord(*dstTable, vals)) {
 			return false;
 		}
@@ -274,4 +301,106 @@
 	return kexiType;
 }
 
+void KexiMigration::xBaseMigrate::getConstraints(const QString& tableName, \
KexiDB::Field* fld) +{
+	// 1. Get the names of the index files
+	// 2. Create appropriate xbIndex type object ( xbNdx or xbNtx ) depending on \
extension +	// 3. Open the index file
+	// 4. Check the expression of the index to crosscheck whether this is indeed the \
index file on the required field. +	// 5. Determine the index type ( unique or not )
+	// 6. Set appropriate properties to the field
+	
+	// Create a base class pointer to an xbIndex
+	xbIndex* index = 0;
+	
+	QStringList indexFileNames = getIndexFileNames(tableName, fld->name());
+	
+	if ( indexFileNames.isEmpty() ) {
+		// no index files exist for this field
+		return;
+	}
+	
+	foreach( QString indexFileName, indexFileNames ) {
+	
+		// get dbf pointer for table
+		QString tablePath = tableNamePathMap[tableName];
+		xbDbf* tableDbf = GetDbfPtr( tablePath.toLatin1().constData() );
+
+		// determine type of indexFile
+		// currently done by checking extension.
+		//! @TODO Check mimetype instead
+		QString fileExtension = indexFileName.right( 3 );
+	
+		if ( fileExtension.toLower() == "ndx" ) {
+			index = new xbNdx( tableDbf );
+		} else if ( fileExtension.toLower() == "ntx" ) {
+			index = new xbNtx( tableDbf );
+		} else {
+			// couldn't recognize extension
+			kDebug()<<"Couldn't recognize extension";
+			return;
+		}
+	
+		if ( index->OpenIndex( indexFileName.toLatin1().constData() ) != XB_NO_ERROR ) {
+			kDebug()<<"Couldn't open index file"<<indexFileName;
+			return;
+		}
+	
+		// verfiy if this index is on the required field
+		char buf[256];
+		index->GetExpression( buf, 256 );
+		QString expressionName = QString::fromLatin1( buf );
+	
+		if ( expressionName.toLower() != fld->name() ) {
+			kDebug()<<"Expression mismatch in "<<indexFileName;
+			continue;
+		}
+	
+		// all is well, set the index
+		if ( index->UniqueIndex() == XB_UNIQUE ) {
+			fld->setUniqueKey( true );
+			kDebug()<<"Unique Index on "<<fld->name();
+		} else {  // index->UniqueIndex() == XB_NOT_UNIQUE
+			fld->setIndexed( true );
+			kDebug()<<"Normal Index on "<<fld->name();
+		}
+		
+		delete xbIndex;
+		xbIndex = 0;
+		// ok, moving through the loop is fairly useless as we can only set a single index \
on a field anyway +		// does any one use multiple indexes on the same field ?
+		// well anyway, when Kexi supports it, we'll use IndexSchemas till then ...
+	}
+}
+
+QStringList KexiMigration::xBaseMigrate::getIndexFileNames(const QString& tableName, \
const QString& fieldName) +{
+	// this function needs to return a lits of index files corresponding to the given \
tablename and field. +	// The current policy uses the xbsql ( \
http://www.quaking.demon.co.uk/xbsql/ ) semantics for determining +	// the filenames \
of the index files +	// index files are assumed to be of the type \
<tablename>_<fieldname>.ndx or .ntx +	
+	// Though the current semantics allows only one index on a field ( actually two, \
considering we can +	// have both .ndx and .ntx index, there can be multiple indices, \
hence a list of filenames is returned +	// (Note: Kexi fields support only a single \
index. But we have a separate IndexSchema class ...) +	
+	QString dbPath = data()->source->dbPath();
+	QDir xBaseDirectory( dbPath );
+	
+	QString fileName = tableName + '_' + fieldName;
+	
+	QStringList indexFilters;
+	indexFilters<<fileName+'*'; // filter all files of the form <tableName>_<fieldName>
+	
+	xBaseDirectory.setNameFilters( indexFilters );
+	QStringList fileNameList = xBaseDirectory.entryList();
+	
+	QStringList absolutePathNames;
+	foreach( QString fileName, fileNameList ) {
+		absolutePathNames<<xBaseDirectory.filePath( fileName );
+	}
+	
+	return absolutePathNames;
+}
+
 #include "xbasemigrate.moc"
--- trunk/koffice/kexi/migration/xbase/xbasemigrate.h #808153:808154
@@ -62,6 +62,12 @@
 	private:
 		KexiDB::Field::Type type(char xBaseColumnType);
 
+		//! Sets and existing constraints on the field
+		void getConstraints(const QString& tableName, KexiDB::Field* fld);
+
+		//! Returns a list of index files corresponding to the specific fieldName
+		QStringList getIndexFileNames(const QString& tableName, const QString& fieldName);
+
 		//! Mapping tableNames to actual absoolute file name paths
 		//  XBase only deals with absolute names ( with the .dbf extension ) which is \
pretty cumbersome  QMap<QString,QString> tableNamePathMap;


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic