metadataengine/server/src/mdsimportexport.cpp
changeset 0 c53acadfccc6
child 1 acef663c1218
equal deleted inserted replaced
-1:000000000000 0:c53acadfccc6
       
     1 /*
       
     2 * Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies). 
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:  Metadata schema container within server
       
    15 *
       
    16 */
       
    17 
       
    18 #include <e32cmn.h>
       
    19 #include <charconv.h>
       
    20 #include <convgeneratedcpp.h>
       
    21 #include <badesca.h>
       
    22 #include <e32math.h>
       
    23 #include <pathinfo.h>
       
    24 
       
    25 #include <mdeconstants.h>
       
    26 
       
    27 #include "mdsimportexport.h"
       
    28 
       
    29 #include "mdcresult.h"
       
    30 #include "mdcitem.h"
       
    31 #include "mdcdef.h"
       
    32 #include "mdsnamespacedef.h"
       
    33 #include "mdsobjectdef.h"
       
    34 #include "mdccommon.h"
       
    35 #include "mdspropertydef.h"
       
    36 #include "mdsschema.h"
       
    37 #include "mdssqliteconnection.h"
       
    38 #include "mdsdbconnectionpool.h"
       
    39 #include "mdcserializationbuffer.h"
       
    40 #include "mdssqlobjectmanipulate.h"
       
    41 #include "mdsrelationdef.h"
       
    42 #include "mdseventdef.h"
       
    43 #include "mdsfindsqlclausedef.h"
       
    44 #include "mdsclausebuffer.h"
       
    45 #include "mdsmaintenanceengine.h"
       
    46 #include "mdssqldbmaintenance.h"
       
    47 #include "mdspreferences.h"
       
    48 #include "mdscommoninternal.h"
       
    49 
       
    50 const TInt KMdsMaxUriLenght = KMaxFileName;
       
    51 const TChar KMdsLineFeed = '\n';
       
    52 
       
    53 const TInt KMdsMaxLogLineLenght( 2056 );
       
    54 
       
    55 _LIT( KMdsErrorLogDirectory, "Metadata" );
       
    56 _LIT( KMdsErrorLogFilename, "importerror.log" );
       
    57 
       
    58 // keyword definitions in import file
       
    59 _LIT8( KMdsKeywordComment,     "//" );
       
    60 _LIT8( KMdsKeywordNamespace,   "namespace" );
       
    61 _LIT8( KMdsKeywordObjectDef,   "object" );
       
    62 _LIT8( KMdsKeywordPropertyDef, "property" );
       
    63 _LIT8( KMdsKeywordRelationDef, "relationdef" );
       
    64 _LIT8( KMdsKeywordEventDef,    "eventdef" );
       
    65 
       
    66 _LIT8( KMdsKeywordVersion, "version" );
       
    67 
       
    68 _LIT8( KMdsKeywordObject,   "object" );
       
    69 _LIT8( KMdsKeywordProperty, "property" );
       
    70 _LIT8( KMdsKeywordFreeText, "freetext" );
       
    71 _LIT8( KMdsKeywordRelation, "relation" );
       
    72 _LIT8( KMdsKeywordEvent,    "event" );
       
    73 
       
    74 _LIT8( KExportMetadataNewLine, "\r\n" );
       
    75 _LIT8( KExportMetadataSpace, " " );
       
    76 _LIT8( KExportMetadataQuotationMark, "\"" );
       
    77 _LIT8( KExportMetadataTimeFormat, "%04d%02d%02d%02d%02d%02d" );
       
    78 
       
    79 
       
    80 _LIT( KMdsKeywordMinValue, "min" );
       
    81 _LIT( KMdsKeywordMaxValue, "max" );
       
    82 _LIT( KMdsKeywordDefValue, "def" );
       
    83 
       
    84 /**
       
    85  * NewLC
       
    86  */
       
    87 CMdsImportExport* CMdsImportExport::NewLC()
       
    88 	{
       
    89 	CMdsImportExport* ret = new(ELeave) CMdsImportExport();
       
    90 	CleanupStack::PushL( ret );
       
    91 	ret->ConstructL();
       
    92 	return ret;
       
    93 	}
       
    94 	
       
    95 /**
       
    96  * NewL
       
    97  */
       
    98 CMdsImportExport* CMdsImportExport::NewL()
       
    99 	{
       
   100 	CMdsImportExport* ret = CMdsImportExport::NewLC();
       
   101 	CleanupStack::Pop( ret );
       
   102 	return ret;
       
   103 	}
       
   104 	
       
   105 /**
       
   106  * Constructor
       
   107  */
       
   108 CMdsImportExport::CMdsImportExport() : iLastDriveNumber ( -1 )
       
   109 	{
       
   110 	}
       
   111 	
       
   112 /**
       
   113  * Default destructor
       
   114  */
       
   115 CMdsImportExport::~CMdsImportExport()
       
   116 	{
       
   117    	delete iConverter;
       
   118 
       
   119     iLog.CloseLog(); 
       
   120     iLog.Close();
       
   121     iFs.Close();
       
   122 
       
   123    	delete iBuffer;
       
   124 
       
   125    	delete iSchema;
       
   126 	}
       
   127 
       
   128 /**
       
   129  * ConstructL
       
   130  */
       
   131 void CMdsImportExport::ConstructL()
       
   132 	{
       
   133 	iSchema = CMdsSchema::NewL();
       
   134     iConverter = CCnvCharacterSetConverter::NewL();
       
   135 
       
   136     User::LeaveIfError( iFs.Connect() );
       
   137     iConverter->PrepareToConvertToOrFromL( KCharacterSetIdentifierUtf8, iFs );
       
   138     
       
   139     User::LeaveIfError( iLog.Connect( ) );
       
   140     iLog.CreateLog( KMdsErrorLogDirectory, KMdsErrorLogFilename, EFileLoggingModeOverwrite );
       
   141     iLog.SetDateAndTime(EFalse, ETrue);
       
   142 
       
   143 	iBuffer = NULL;
       
   144     iLastObjectDef = NULL;
       
   145 	}
       
   146 
       
   147 void CMdsImportExport::ImportSchemaFromFileL( const TDesC& aFileName,
       
   148 							CMdsSchema& aSchema, TUint32 aVendorId )
       
   149     {
       
   150     iDefaultSchema = &aSchema;
       
   151     iVendorId = aVendorId;
       
   152 
       
   153     if ( !iDefaultSchema->iBaseObject )
       
   154     	{
       
   155     	// If the default schema doesn't already have a base object, add one to iSchema together
       
   156     	// with default namespace.
       
   157     	iSchema->AddDefaultObjectL();
       
   158 		iDefaultSchema->iBaseObject = iSchema->iBaseObject;
       
   159 		iSchema->AddDefaultNamespaceL();
       
   160     	}
       
   161     else
       
   162     	{
       
   163     	iSchema->iBaseObject = iDefaultSchema->iBaseObject;
       
   164     	}
       
   165 
       
   166 	iReadStream.PushL();
       
   167 	// Read the schema file.
       
   168 	TInt fileOpenStatus = iReadStream.Open( iFs, aFileName, EFileStreamText );
       
   169 	if (fileOpenStatus != KErrNone)
       
   170 		{
       
   171 	    iSchema->iBaseObject = NULL;
       
   172 	    iDefaultSchema = NULL;
       
   173 	    _LIT( KError, "Failed to open schema file" );
       
   174     	LogError( KError );
       
   175 		User::Leave( fileOpenStatus );
       
   176 		}
       
   177     iFileName.Copy( aFileName );
       
   178 
       
   179     iLineNumber = 0;
       
   180     iLastObjectDef = NULL;
       
   181     if ( aFileName == KSchemaImportFile || aFileName == KSchemaRomImportFile )
       
   182     	{
       
   183     	iVersionFlags = EVersionNone;
       
   184     	}
       
   185     else
       
   186     	{
       
   187     	iVersionFlags = EVersionAlreadyRead;
       
   188     	}
       
   189 
       
   190     // start reading lines from the schema file
       
   191     while( ETrue )
       
   192         {
       
   193         TRAPD( e, iReadStream.ReadL( iLine, KMdsLineFeed ) );
       
   194         if ( e == KErrEof ) break; // succesful exit
       
   195         else if ( e != KErrNone )
       
   196             {
       
   197 		    iSchema->iBaseObject = NULL;
       
   198 		    iDefaultSchema = NULL;
       
   199 		    _LIT( KError, "Failed to read line from schema file" );
       
   200  	   		LogError( KError );
       
   201 			User::Leave( e );
       
   202             }
       
   203 
       
   204         ++iLineNumber;
       
   205         if ( iLine.Length() > 0 )
       
   206             {
       
   207             // parse the line
       
   208             TLex8 parser( iLine );
       
   209             TRAP( e, ImportSchemaLineL( parser ) );
       
   210             if ( e != KErrNone )
       
   211             	{
       
   212 			    iSchema->iBaseObject = NULL;
       
   213 			    iDefaultSchema = NULL;
       
   214 			    _LIT( KError, "Schema corrupted" );
       
   215             	LogError( KError );
       
   216             	User::Leave( e );
       
   217             	}
       
   218             }
       
   219         }
       
   220     
       
   221     CleanupStack::PopAndDestroy( &iReadStream ); // Closes stream.
       
   222 
       
   223     TRAPD( err, aSchema.MergeNamespacesL( *iSchema ) );
       
   224 
       
   225     iSchema->iBaseObject = NULL;
       
   226     iDefaultSchema = NULL;
       
   227     iVendorId = 0;
       
   228 
       
   229     if ( err != KErrNone )
       
   230     	{
       
   231     	User::Leave( err );
       
   232     	}
       
   233     }
       
   234 
       
   235 /**
       
   236  * ImportL imports a single line of data
       
   237  */
       
   238 void CMdsImportExport::ImportSchemaLineL( TLex8& aParser )
       
   239     {
       
   240     TPtrC8 token = aParser.NextToken();
       
   241 
       
   242     // valid keywords in beginning of line
       
   243     if ( token.Length() == 0 || token.Left(2) == KMdsKeywordComment )
       
   244         {
       
   245         // ignore
       
   246         return;
       
   247         }
       
   248     else if ( token == KMdsKeywordVersion )
       
   249         {
       
   250         ImportSchemaVersionL( aParser );
       
   251         }
       
   252     else if ( !(iVersionFlags & EVersionAlreadyRead ) )
       
   253         {
       
   254         User::Leave( KErrCorrupt );
       
   255         }
       
   256     else if ( token == KMdsKeywordNamespace )
       
   257         {
       
   258         ImportSchemaNamespaceL( aParser );
       
   259         return;
       
   260         }
       
   261     else if ( token == KMdsKeywordObjectDef )
       
   262         {        
       
   263         ImportSchemaObjectDefL( aParser );
       
   264         }
       
   265     else if(token == KMdsKeywordPropertyDef )
       
   266     	{
       
   267     	ImportSchemaPropertyDefL( aParser );
       
   268     	}
       
   269     else if ( token == KMdsKeywordRelationDef )
       
   270         {
       
   271         ImportSchemaRelationDefL( aParser );
       
   272         }
       
   273     else if ( token == KMdsKeywordEventDef )
       
   274         {
       
   275         ImportSchemaEventDefL( aParser );
       
   276         }
       
   277     else
       
   278         {
       
   279         _LIT( KError, "Keyword not recognized" );
       
   280         LogError( KError );
       
   281         User::Leave( KErrCorrupt );
       
   282         }
       
   283     TPtrC8 tokenLast = aParser.NextToken();
       
   284     if ( tokenLast.Length() != 0 && tokenLast.Left(2) != KMdsKeywordComment )
       
   285     	{
       
   286     	_LIT( KMdsUnknownToken, "Undefined schema item" );
       
   287     	LogError( KMdsUnknownToken );
       
   288     	User::Leave( KErrCorrupt );
       
   289     	}
       
   290     }
       
   291 
       
   292 /**
       
   293  * Schema import checklist:
       
   294  *	1. Are all the namespaces new? If not, discard any duplicates
       
   295  *	2. Do all the (object/event/relation) defs about to be imported actually 
       
   296  *	   belong to a proper namespace (which is also not read-only)? If not, discard
       
   297  */
       
   298 // ------------------------------------------------
       
   299 // ImportSchemaNamespaceL
       
   300 // ------------------------------------------------
       
   301 //
       
   302 void CMdsImportExport::ImportSchemaNamespaceL( TLex8& aParser )
       
   303     {
       
   304     // namespace <name> <readonly>
       
   305     TBuf16<KMdsMaxUriLenght> name;
       
   306     User::LeaveIfError( ImportText( name, aParser ) );
       
   307     
       
   308     TInt ro = 0;
       
   309     TBool readOnly = EFalse;
       
   310     User::LeaveIfError( ImportNum( ro, aParser ) );
       
   311     readOnly = ro ? ETrue : EFalse;
       
   312 
       
   313     // Check out if the namespace already exists
       
   314 	if ( iSchema->GetNamespace( name ) )
       
   315 		{
       
   316 		return;
       
   317 		}
       
   318 	
       
   319 	// in case there is namespace in old schema
       
   320 	CMdsNamespaceDef* actualNamespace = iDefaultSchema->GetNamespace( name );
       
   321 	if ( actualNamespace )
       
   322 		{
       
   323 		iSchema->NamespaceAddL( actualNamespace->GetName(),
       
   324                 actualNamespace->GetReadOnly(), actualNamespace->GetVendorId(),
       
   325                 actualNamespace->GetId() );
       
   326 		return;
       
   327 		}
       
   328 
       
   329 	// Ok, the namespace is new
       
   330 	iSchema->NamespaceAddL( name, readOnly, iVendorId );
       
   331     }
       
   332 
       
   333 // ------------------------------------------------
       
   334 // ImportSchemaObjectDefL
       
   335 // ------------------------------------------------
       
   336 //
       
   337 void CMdsImportExport::ImportSchemaObjectDefL( TLex8& aParser )
       
   338     {
       
   339     // First read the name of the namespace.
       
   340     TBuf16<KMdsMaxUriLenght> name;
       
   341     User::LeaveIfError( ImportText( name, aParser ) );
       
   342 
       
   343 	CMdsNamespaceDef* actualNamespace = iSchema->GetNamespace( name );
       
   344 	if ( !actualNamespace )
       
   345 		{
       
   346         actualNamespace = iDefaultSchema->GetNamespace( name );
       
   347 		if ( !actualNamespace )
       
   348 			{
       
   349 			_LIT( KMdsNamespaceNotFound, "Namespace not found !!!" );
       
   350 			LogError( KMdsNamespaceNotFound );
       
   351 	    	User::Leave( KErrAccessDenied );
       
   352 			}
       
   353 		CMdsNamespaceDef* nmsp = iSchema->NamespaceAddL(
       
   354                 actualNamespace->GetName(), actualNamespace->GetReadOnly(),
       
   355 				actualNamespace->GetVendorId() );
       
   356 		if ( !actualNamespace->GetFirstRead() )
       
   357 			{
       
   358 			nmsp->UnsetFirstRead();
       
   359 			}
       
   360 		actualNamespace = nmsp;
       
   361 		}
       
   362 
       
   363     if ( actualNamespace->GetReadOnly() && !actualNamespace->GetFirstRead() )
       
   364     	{
       
   365     	iLastObjectDef = NULL;
       
   366     	_LIT( KError, "Namespace not allowed" );
       
   367     	LogError( KError );
       
   368     	User::Leave( KErrAccessDenied );
       
   369     	}
       
   370 
       
   371     // Next read the name of the object.
       
   372     TBuf16<KMdsMaxUriLenght> nameObject;
       
   373     User::LeaveIfError( ImportText( nameObject, aParser ) );
       
   374     if ( nameObject == MdeConstants::Object::KBaseObject )
       
   375     	{
       
   376     	_LIT( KError, "Cannot redefine Object" );
       
   377 		LogError( KError );
       
   378     	User::Leave( KErrArgument );
       
   379     	}
       
   380 
       
   381     // Next read the name of the parent object.
       
   382     User::LeaveIfError( ImportText( name, aParser ) );
       
   383 
       
   384     // Add new object definition to the DB.
       
   385     TRAPD( err, iLastObjectDef = actualNamespace->AddObjectDefL( nameObject, name, iDefaultSchema ) );
       
   386 
       
   387     if ( err != KErrNone && err != KErrAlreadyExists  )
       
   388    		{
       
   389    		User::Leave( err );
       
   390     	}
       
   391 
       
   392     // Finally read object flags (currently only two values: 0/1).
       
   393     TInt flags;
       
   394     CMdsObjectDef::TObjectDefFlags objFlags = CMdsObjectDef::EObjectDefFlagsNone;
       
   395     User::LeaveIfError( ImportNum(flags, aParser) );
       
   396     switch( flags )
       
   397     	{
       
   398     	case CMdsObjectDef::EObjectDefFlagsNone:
       
   399     		objFlags = CMdsObjectDef::EObjectDefFlagsNone;
       
   400     		break;
       
   401 
       
   402     	case CMdsObjectDef::EObjectDefFlagsContext:
       
   403     		objFlags = CMdsObjectDef::EObjectDefFlagsContext;
       
   404     		break;
       
   405 
       
   406     	default:
       
   407     		_LIT( KUnsupportedFlag, "Unsupported flag" );
       
   408     		LogError( KUnsupportedFlag );
       
   409     		User::Leave( KErrCorrupt );
       
   410     	}
       
   411     iLastObjectDef->SetFlags( objFlags );
       
   412     }
       
   413 
       
   414 // ------------------------------------------------
       
   415 // ImportSchemaPropertyDefL
       
   416 // ------------------------------------------------
       
   417 //
       
   418 void CMdsImportExport::ImportSchemaPropertyDefL( TLex8& aParser )
       
   419 	{
       
   420 	// property  <name>  <readonly> <mandatory>  <type> <minv> <maxv>
       
   421     _LIT( KMinMaxWrongValue, "Min value is bigger then max" );
       
   422     _LIT( KWrongValue,       "Min or max value is incorrect" );
       
   423     _LIT( KTextWrongValue,   "Min or max text value is incorrect" );
       
   424 
       
   425     // Property definitions always come immediately after object definitions in a schema file.
       
   426     // If there is no object definition before property definitions, it's an error.
       
   427 	if ( !iLastObjectDef )
       
   428 		{
       
   429 		_LIT( KNoLastObject, "Try to add to no existing object" );
       
   430 		LogError( KNoLastObject );
       
   431 		User::Leave( KErrNotFound );
       
   432 		}
       
   433 
       
   434 	// Read property name.
       
   435     TBuf16<KMdsMaxUriLenght> name;
       
   436     User::LeaveIfError( ImportText( name, aParser ) );
       
   437     if ( iLastObjectDef->GetProperty( name ) )
       
   438     	{
       
   439     	_LIT( KError, "Property already exists" );
       
   440 		LogError( KError );
       
   441 		User::Leave( KErrArgument );
       
   442     	}
       
   443 
       
   444     // Read read-only and mandatory flags.
       
   445     TBool readOnly, mandatory;
       
   446 	User::LeaveIfError( ImportNum( readOnly, aParser ) );
       
   447 	User::LeaveIfError( ImportNum( mandatory, aParser ) );
       
   448 
       
   449 	// Read property type.
       
   450     TPropertyType type;
       
   451     TInt32 readType;
       
   452     User::LeaveIfError( ImportNum( readType, aParser ) );
       
   453     type = static_cast<TPropertyType>(readType);
       
   454  
       
   455     // Depending on the property type read the next two parameters with the correct data type.
       
   456     TInt error = KErrNone;
       
   457     switch( type )	
       
   458     	{
       
   459     	case EPropertyBool:
       
   460     		{
       
   461     		TInt32  minVal32,
       
   462     		        maxVal32;
       
   463     		error = SetMinMaxDefValueL<TInt32>( CheckForConstant(aParser), minVal32, 0, 1, 0 );
       
   464        		if ( error < KErrNone )
       
   465     			{
       
   466     			User::LeaveIfError( ImportNum( minVal32, aParser ) );
       
   467     			}
       
   468     		error = SetMinMaxDefValueL<TInt32>( CheckForConstant(aParser), maxVal32, 0, 1, 1 );
       
   469        		if ( error < KErrNone )
       
   470     			{
       
   471     			User::LeaveIfError( ImportNum( maxVal32, aParser ) );
       
   472     			}
       
   473        		
       
   474        		CheckNoMoreNumericParametersL( aParser );
       
   475        		
       
   476     		// boolean cannot have different values
       
   477     		minVal32 = 0;
       
   478     		maxVal32 = 1;
       
   479     		// Add this property to the previously defined object.
       
   480     		iLastObjectDef->AddPropertyL( name, type, minVal32, maxVal32, readOnly, mandatory, EFalse );
       
   481     		break;
       
   482     		}
       
   483     	case EPropertyInt8:
       
   484     	case EPropertyUint8:
       
   485     	case EPropertyInt16:
       
   486     	case EPropertyUint16:
       
   487     	case EPropertyInt32:
       
   488     		{
       
   489     		TInt32  minVal32,
       
   490     		        maxVal32;
       
   491     		const TInt32 KMinVal32 = type == EPropertyInt8 ? KMinTInt8 :
       
   492     		                          type == EPropertyInt16 ? KMinTInt16 :
       
   493     		                           type == EPropertyInt32 ? KMinTInt32 : 0;
       
   494     		const TInt32 KMaxVal32 = type == EPropertyInt8 ? KMaxTInt8 :
       
   495     		                          type == EPropertyUint8 ? KMaxTUint8 :
       
   496     		                           type == EPropertyInt16 ? KMaxTInt16 :
       
   497     		                            type == EPropertyUint16 ? KMaxTUint16 : KMaxTInt32;
       
   498    			error = SetMinMaxDefValueL<TInt32>( CheckForConstant(aParser),
       
   499    					minVal32, KMinVal32, KMaxVal32, 0 );
       
   500        		if ( error < KErrNone )
       
   501     			{
       
   502     		    User::LeaveIfError( ImportNum( minVal32, aParser ) );
       
   503     			}
       
   504    			error = SetMinMaxDefValueL<TInt32>( CheckForConstant(aParser),
       
   505    					maxVal32, KMinVal32, KMaxVal32, KMaxVal32 );
       
   506        		if ( error < KErrNone )
       
   507     			{
       
   508         		User::LeaveIfError( ImportNum( maxVal32, aParser ) );
       
   509     			}
       
   510 		    if ( minVal32 > maxVal32 )
       
   511 		    	{
       
   512 		    	LogError( KMinMaxWrongValue );
       
   513 		    	User::Leave( KErrCorrupt );
       
   514 		    	}
       
   515 		    if ( ( type == EPropertyInt8 && ( minVal32 < KMinTInt8 || maxVal32 > KMaxTInt8 ) ) ||
       
   516 		         ( type == EPropertyUint8 && ( minVal32 < 0 || maxVal32 > KMaxTUint8 ) ) ||
       
   517 		         ( type == EPropertyInt16 && ( minVal32 < KMinTInt16 || maxVal32 > KMaxTInt16 ) ) ||
       
   518 		         ( type == EPropertyUint16 && ( minVal32 < 0 || maxVal32 > KMaxTUint16 ) ) )
       
   519 		    	{
       
   520 		    	LogError( KWrongValue );
       
   521 		    	User::Leave( KErrCorrupt );
       
   522 		    	}
       
   523 		    
       
   524 		    CheckNoMoreNumericParametersL( aParser );
       
   525     		// Add this property to the previously defined object.
       
   526     		iLastObjectDef->AddPropertyL( name, type, minVal32, maxVal32, readOnly, mandatory, EFalse );
       
   527     		break;
       
   528     		}
       
   529     	case EPropertyText:
       
   530     		{
       
   531     		TInt32  minVal32,
       
   532     		        maxVal32;
       
   533    			error = SetMinMaxDefValueL<TInt32>( CheckForConstant(aParser),
       
   534    					minVal32, 1, KSerializedDesMaxLength, 1 );
       
   535        		if ( error < KErrNone )
       
   536     			{
       
   537     			User::LeaveIfError( ImportNum( minVal32, aParser ) );
       
   538     			}
       
   539    			error = SetMinMaxDefValueL<TInt32>( CheckForConstant(aParser),
       
   540    					maxVal32, 1, KSerializedDesMaxLength, 256 );
       
   541        		if ( error < KErrNone )
       
   542     			{
       
   543     			User::LeaveIfError( ImportNum( maxVal32, aParser ) );
       
   544     			}
       
   545 		    if ( minVal32 > maxVal32 )
       
   546 		    	{
       
   547 		    	LogError( KMinMaxWrongValue );
       
   548 		    	User::Leave( KErrCorrupt );
       
   549 		    	}
       
   550 		    if ( minVal32 < 1 || minVal32 > KSerializedDesMaxLength ||
       
   551 		         maxVal32 < 1 || maxVal32 > KSerializedDesMaxLength )
       
   552 		    	{
       
   553 		    	LogError( KTextWrongValue );
       
   554 		    	User::Leave( KErrCorrupt );
       
   555 		    	}
       
   556 		    
       
   557 		    // Text properties may have an extra flag: index flag.
       
   558 		    TBool indexed( EFalse );
       
   559 		    ImportNum( indexed, aParser );
       
   560     		// Add this property to the previously defined object.
       
   561     		iLastObjectDef->AddPropertyL( name, type, minVal32, maxVal32, readOnly, mandatory, indexed );
       
   562     		break;
       
   563     		}
       
   564     	case EPropertyUint32:
       
   565     		{
       
   566     		TUint32  minVal32,
       
   567     		         maxVal32;
       
   568    			error = SetMinMaxDefValueL<TUint32>( CheckForConstant(aParser),
       
   569    					minVal32, 0, KMaxTUint32, 0 );
       
   570        		if ( error < KErrNone )
       
   571     			{
       
   572     			User::LeaveIfError( ImportUInt32( minVal32, aParser ) );
       
   573     			}
       
   574    			error = SetMinMaxDefValueL<TUint32>( CheckForConstant(aParser),
       
   575    					maxVal32, 0, KMaxTUint32, KMaxTUint32 );
       
   576        		if ( error < KErrNone )
       
   577     			{
       
   578     			User::LeaveIfError( ImportUInt32( maxVal32, aParser ) );
       
   579     			}
       
   580 		    if ( minVal32 > maxVal32 )
       
   581 		    	{
       
   582 		    	LogError( KMinMaxWrongValue );
       
   583 		    	User::Leave( KErrCorrupt );
       
   584 		    	}
       
   585 		    
       
   586 		    CheckNoMoreNumericParametersL( aParser );
       
   587     		// Add this property to the previously defined object.
       
   588     		iLastObjectDef->AddPropertyL( name, type, minVal32, maxVal32, readOnly, mandatory, EFalse );
       
   589     		break;
       
   590     		}
       
   591     	case EPropertyInt64:
       
   592     		{
       
   593     		TInt64 minVal64, maxVal64;
       
   594    			error = SetMinMaxDefValueL<TInt64>( CheckForConstant(aParser),
       
   595    					minVal64, KMinTInt64, KMaxTInt64, 0 );
       
   596        		if ( error < KErrNone )
       
   597        			{
       
   598        			User::LeaveIfError( ImportInt64( minVal64, aParser ) );
       
   599        			}
       
   600    			error = SetMinMaxDefValueL<TInt64>( CheckForConstant(aParser),
       
   601    					maxVal64, KMinTInt64, KMaxTInt64, KMaxTInt64 );
       
   602        		if ( error < KErrNone )
       
   603        			{
       
   604        			User::LeaveIfError( ImportInt64( maxVal64, aParser ) );
       
   605        			}
       
   606 		    if ( minVal64 > maxVal64 )
       
   607 		    	{
       
   608 		    	LogError( KMinMaxWrongValue );
       
   609 		    	User::Leave( KErrCorrupt );
       
   610 		    	}
       
   611 		    
       
   612 		    CheckNoMoreNumericParametersL( aParser );
       
   613     		// Add this property to the previously defined object.
       
   614     		iLastObjectDef->AddPropertyL( name, type, minVal64, maxVal64, readOnly, mandatory, EFalse );
       
   615     		break;
       
   616     		}
       
   617     	case EPropertyTime:
       
   618     		{
       
   619     		TTime minTime, maxTime;
       
   620    			error = SetMinMaxDefValueL<TTime>( CheckForConstant(aParser),
       
   621    					minTime, 0, KMaxTInt64, 0 );
       
   622        		if ( error < KErrNone )
       
   623        			{
       
   624        			User::LeaveIfError( ImportTime( minTime, aParser ) );
       
   625        			}
       
   626    			error = SetMinMaxDefValueL<TTime>( CheckForConstant(aParser),
       
   627    					maxTime, 0, KMaxTInt64, KMaxTInt64 );
       
   628        		if ( error < KErrNone )
       
   629        			{
       
   630        			User::LeaveIfError( ImportTime( maxTime, aParser ) );
       
   631        			}
       
   632 		    if ( minTime > maxTime )
       
   633 		    	{
       
   634 		    	LogError( KMinMaxWrongValue );
       
   635 		    	User::Leave( KErrCorrupt );
       
   636 		    	}
       
   637 		    
       
   638 		    CheckNoMoreNumericParametersL( aParser );
       
   639     		// Add this property to the previously defined object.
       
   640     		iLastObjectDef->AddPropertyL( name, type, minTime.Int64(), maxTime.Int64(), readOnly, 
       
   641     				mandatory, EFalse );
       
   642     		break;
       
   643     		}
       
   644     	case EPropertyReal32:
       
   645     		{
       
   646     		TReal32 minReal, maxReal;
       
   647    			error = SetMinMaxDefValueL<TReal32>( CheckForConstant(aParser),
       
   648    					minReal, -KMaxTReal32, KMaxTReal32, 0 );
       
   649        		if ( error < KErrNone )
       
   650        			{
       
   651        			User::LeaveIfError( ImportNum( minReal, aParser ) );
       
   652        			}
       
   653    			error = SetMinMaxDefValueL<TReal32>( CheckForConstant(aParser),
       
   654    					maxReal, -KMaxTReal32, KMaxTReal32, KMaxTReal32 );
       
   655        		if ( error < KErrNone )
       
   656        			{
       
   657        			User::LeaveIfError( ImportNum( maxReal, aParser ) );
       
   658        			}
       
   659 		    if ( minReal > maxReal )
       
   660 		    	{
       
   661 		    	LogError( KMinMaxWrongValue );
       
   662 		    	User::Leave( KErrCorrupt );
       
   663 		    	}
       
   664 		    
       
   665 		    CheckNoMoreNumericParametersL( aParser );
       
   666     		// Add this property to the previously defined object.
       
   667     		iLastObjectDef->AddPropertyL( name, type, minReal, maxReal, readOnly, mandatory, EFalse );
       
   668     		break;
       
   669     		}
       
   670     	case EPropertyReal64:
       
   671     		{
       
   672     		const TReal64 KMDSMaxTReal64( 1.79769313486200E+308 );
       
   673     		TReal64 minReal, maxReal;
       
   674    			error = SetMinMaxDefValueL<TReal64>( CheckForConstant(aParser),
       
   675    					minReal, -KMDSMaxTReal64, KMDSMaxTReal64, 0 );
       
   676        		if ( error < KErrNone )
       
   677        			{
       
   678        			User::LeaveIfError( ImportNum( minReal, aParser ) );
       
   679        			}
       
   680    			error = SetMinMaxDefValueL<TReal64>( CheckForConstant(aParser),
       
   681    					maxReal, -KMDSMaxTReal64, KMDSMaxTReal64, KMDSMaxTReal64 );
       
   682        		if ( error < KErrNone )
       
   683        			{
       
   684        			User::LeaveIfError( ImportNum( maxReal, aParser ) );
       
   685        			}
       
   686 		    if ( minReal > maxReal )
       
   687 		    	{
       
   688 		    	LogError( KMinMaxWrongValue );
       
   689 		    	User::Leave( KErrCorrupt );
       
   690 		    	}
       
   691 		    
       
   692 		    CheckNoMoreNumericParametersL( aParser );
       
   693     		// Add this property to the previously defined object.
       
   694     		iLastObjectDef->AddPropertyL( name, type, minReal, maxReal, readOnly, mandatory, EFalse );
       
   695     		break;
       
   696     		}
       
   697     	default:
       
   698     		User::Leave( KErrNotFound );
       
   699     	}
       
   700 	}
       
   701 
       
   702 // ------------------------------------------------
       
   703 // CheckNoIndexFlagL
       
   704 // ------------------------------------------------
       
   705 //
       
   706 void CMdsImportExport::CheckNoMoreNumericParametersL( TLex8& aParser )
       
   707 	{
       
   708 	// This function is used to check that indexing flag is not set for other than
       
   709 	// text properties.
       
   710 	TBool parameterFound( EFalse );
       
   711 	TInt err = ImportNum( parameterFound, aParser );
       
   712 	if ( err == KErrNone )
       
   713 		{
       
   714 		// Index boolean not supported for other property types than text.
       
   715 		User::Leave( KErrNotSupported );
       
   716 		}
       
   717 	}
       
   718 
       
   719 // ------------------------------------------------
       
   720 // ImportSchemaRelationDefL
       
   721 // ------------------------------------------------
       
   722 //
       
   723 void CMdsImportExport::ImportSchemaRelationDefL( TLex8& aParser )
       
   724     {
       
   725     // relationdef <ns> <name>
       
   726     TBuf16<KMdsMaxUriLenght> name;
       
   727     // read namespace
       
   728     User::LeaveIfError( ImportText( name, aParser ) );
       
   729 
       
   730 	CMdsNamespaceDef* actualNamespace = iSchema->GetNamespace( name );
       
   731 	if ( !actualNamespace )
       
   732 		{
       
   733 		_LIT( KMdsNamespaceNotFound, "Namespace not found !!!" );
       
   734 		LogError( KMdsNamespaceNotFound );
       
   735     	User::Leave( KErrAccessDenied );
       
   736 		}
       
   737 
       
   738     if( actualNamespace->GetReadOnly() && !actualNamespace->GetFirstRead() )
       
   739     	{
       
   740     	_LIT( KError, "Namespace not allowed" );
       
   741     	LogError( KError );
       
   742     	User::Leave( KErrAccessDenied );
       
   743     	}
       
   744 
       
   745     // read name
       
   746     User::LeaveIfError( ImportText( name, aParser ) );
       
   747 
       
   748 	actualNamespace->AddRelationDefL( name );
       
   749     }
       
   750 
       
   751 // ------------------------------------------------
       
   752 // ImportSchemaEventDefL
       
   753 // ------------------------------------------------
       
   754 //
       
   755 void CMdsImportExport::ImportSchemaEventDefL( TLex8& aParser )
       
   756     {
       
   757     // eventdef <ns> <name> <priority>
       
   758     TBuf16<KMdsMaxUriLenght> name;
       
   759     User::LeaveIfError( ImportText( name, aParser ) );
       
   760 
       
   761 	CMdsNamespaceDef* actualNamespace = iSchema->GetNamespace( name );
       
   762 	if ( !actualNamespace )
       
   763 		{
       
   764 		_LIT( KMdsNamespaceNotFound, "Namespace not found !!!" );
       
   765 		LogError( KMdsNamespaceNotFound );
       
   766     	User::Leave( KErrAccessDenied );
       
   767 		}
       
   768 
       
   769     if ( actualNamespace->GetReadOnly() && !actualNamespace->GetFirstRead() )
       
   770     	{
       
   771     	_LIT( KError, "Namespace not allowed" );
       
   772     	LogError( KError );
       
   773     	User::Leave( KErrAccessDenied );
       
   774     	}
       
   775 
       
   776     User::LeaveIfError( ImportText( name, aParser ) );
       
   777     
       
   778     TInt32 priority=0;
       
   779     User::LeaveIfError( ImportNum( priority, aParser ) );
       
   780 
       
   781 	actualNamespace->AddEventDefL( name, priority );
       
   782     }
       
   783 
       
   784 void CMdsImportExport::ImportSchemaVersionL( TLex8& aParser )
       
   785 	{
       
   786 	if ( iVersionFlags & EVersionAlreadyRead )
       
   787 		{
       
   788 		_LIT( KError, "Schema version redefined" );
       
   789 		LogError( KError );
       
   790 		User::Leave( KErrCorrupt );
       
   791 		}
       
   792     TBuf16<KMdsMaxUriLenght> version;
       
   793     User::LeaveIfError( ImportText( version, aParser ) );
       
   794 
       
   795 	// convert version to two numbers
       
   796 	TInt32 majorVersion, minorVersion;
       
   797 	TLex16 parser( version );
       
   798 	User::LeaveIfError( parser.BoundedVal( majorVersion, KMaxTInt ) );
       
   799 	parser.Get();
       
   800 	User::LeaveIfError( parser.BoundedVal( minorVersion, KMaxTInt ) );
       
   801 
       
   802 	if ( KSchemaFileMajorVersion != majorVersion )
       
   803 		{
       
   804 		_LIT( KError, "Schema version mismatch" );
       
   805 		LogError( KError );
       
   806 		User::Leave( KErrCorrupt );
       
   807 		}
       
   808 
       
   809     MMdsPreferences::InsertL( KMdsSchemaVersionName, MMdsPreferences::EPreferenceBothSet,
       
   810     		majorVersion, minorVersion );
       
   811 
       
   812 	iVersionFlags |= EVersionAlreadyRead;
       
   813 	}
       
   814 
       
   815 void CMdsImportExport::ImportNamespaceFromDBL()
       
   816 	{
       
   817 	_LIT( MdsQueryGetNamespaceDefs, "SELECT NamespaceDefID,ReadOnly,VendorId,Name FROM NamespaceDef;" );
       
   818 	TDefId namespaceDefId = KNoDefId;
       
   819 	TInt32 vendorId = 0;
       
   820 	TInt32 namespaceReadOnly = 0;
       
   821 	TPtrC namespaceName;
       
   822 
       
   823 	CMdSSqLiteConnection& connection = MMdSDbConnectionPool::GetDefaultDBL();
       
   824 
       
   825 	// importing namespaces
       
   826 	RRowData emptyData;
       
   827 	CleanupClosePushL( emptyData );
       
   828 	RRowData getData;
       
   829 	CleanupClosePushL( getData );
       
   830 	getData.AppendL( TColumn( namespaceDefId ) );
       
   831 	getData.AppendL( TColumn( namespaceReadOnly ) );
       
   832 	getData.AppendL( TColumn( vendorId ) );
       
   833 	getData.AppendL( TColumn( EColumnHBuf16 ) );
       
   834 	RMdsStatement query;
       
   835 	CleanupClosePushL( query );
       
   836 	connection.ExecuteQueryL( MdsQueryGetNamespaceDefs, query, emptyData );
       
   837 	
       
   838 	// read query results and add namespaces to the schema
       
   839 	while( connection.NextRowL( query, getData ) )
       
   840 		{
       
   841 		getData.Column( 0 ).Get( namespaceDefId );
       
   842 		getData.Column( 1 ).Get( namespaceReadOnly );
       
   843 		getData.Column( 2 ).Get( vendorId );
       
   844 		getData.Column( 3 ).Get( namespaceName );
       
   845 		CMdsNamespaceDef* nmsp = iSchema->NamespaceAddL( namespaceName,
       
   846 				namespaceReadOnly ? ETrue : EFalse, vendorId, namespaceDefId );
       
   847 		if ( !nmsp )
       
   848 			{
       
   849 			User::Leave( KErrGeneral );
       
   850 			}
       
   851 		nmsp->UnsetFirstRead();
       
   852 		getData.Column( 3 ).Free();
       
   853 		}
       
   854 	CleanupStack::PopAndDestroy( 3, &emptyData ); // query, getData, emptyData
       
   855 	}
       
   856 
       
   857 TBool CMdsImportExport::ImportCheckVersionInfoL()
       
   858 	{
       
   859 	TInt32 majorVersion = 0;
       
   860 	TInt64 minorVersion = 0;
       
   861 
       
   862 	// DB version
       
   863     MMdsPreferences::GetL( KMdsDBVersionName, MMdsPreferences::EPreferenceBothGet,
       
   864     						  majorVersion, &minorVersion );
       
   865 	if ( majorVersion != KMdSServMajorVersionNumber && (TInt)minorVersion != KMdSServMinorVersionNumber )
       
   866 		{
       
   867 		return EFalse;
       
   868 		}
       
   869 
       
   870 	// schema version
       
   871     MMdsPreferences::GetL( KMdsSchemaVersionName, MMdsPreferences::EPreferenceBothGet,
       
   872     						  majorVersion, &minorVersion );
       
   873 	if ( majorVersion == KSchemaFileMajorVersion )
       
   874 		{
       
   875 		return ETrue;
       
   876 		}
       
   877 
       
   878 	return EFalse;
       
   879 	}
       
   880 
       
   881 void CMdsImportExport::ImportSchemaFromDBL( CMdsSchema& aSchema )
       
   882 	{
       
   883 	// clear iSchema (we read everything from DB)
       
   884 	if ( !aSchema.iBaseObject )
       
   885 		{
       
   886 		iSchema->AddDefaultObjectL();
       
   887 		iSchema->iBaseObject->SetStoredEveryInDB();
       
   888 		aSchema.iBaseObject = iSchema->iBaseObject;
       
   889 		}
       
   890     else
       
   891     	{
       
   892     	iSchema->iBaseObject = aSchema.iBaseObject;
       
   893     	}
       
   894 	iSchema->Reset();
       
   895 
       
   896 	if ( !ImportCheckVersionInfoL() )
       
   897 		{
       
   898 	    iSchema->iBaseObject = NULL;
       
   899     	User::Leave( KErrCorrupt );
       
   900 		}
       
   901 
       
   902 	TRAPD( err, ImportNamespaceFromDBL() );
       
   903 	if ( err != KErrNone )
       
   904 		{
       
   905 	    iSchema->iBaseObject = NULL;
       
   906     	User::Leave( err );
       
   907 		}
       
   908 
       
   909 	const TInt count = iSchema->iNamespaceDefs.Count();
       
   910 	
       
   911 	for ( TInt i = 0; i < count; ++i )
       
   912 		{
       
   913 		CMdsNamespaceDef* namespaceDef = iSchema->iNamespaceDefs[i];
       
   914 		TRAP( err, namespaceDef->ImportFromDBL() );
       
   915 		if ( err != KErrNone )
       
   916 			{
       
   917 	    	iSchema->iBaseObject = NULL;
       
   918 	    	User::Leave( err );
       
   919 			}
       
   920 		}
       
   921 
       
   922     TRAP( err, aSchema.MergeNamespacesL( *iSchema ) );
       
   923    	iSchema->iBaseObject = NULL;
       
   924     if ( err != KErrNone )
       
   925     	{
       
   926     	User::Leave( err );
       
   927     	}
       
   928 	}
       
   929 
       
   930 
       
   931 TBool CMdsImportExport::ReadMetadataFileLineL()
       
   932 	{
       
   933 	if ( iLastLineProcessed )
       
   934 		{
       
   935 		TRAPD( e, iReadStream.ReadL( iLine, KMdsLineFeed ) );
       
   936 		if ( e == KErrEof )
       
   937             {
       
   938 			return EFalse; // succesful exit
       
   939             }
       
   940 		else if ( e != KErrNone )
       
   941 		    {
       
   942 		    iDefaultSchema = NULL;
       
   943 		    User::Leave( e );
       
   944 		    }
       
   945 	    iLastLineProcessed = EFalse;
       
   946 		}
       
   947     ++iLineNumber;
       
   948 	return ETrue;
       
   949 	}
       
   950 
       
   951 TInt CMdsImportExport::ImportMetadataL( CMdSSqlObjectManipulate& aManipulate,
       
   952     CMdsSchema& aSchemaNew, const TDesC16& aFileName )
       
   953 	{
       
   954 	iReadStream.PushL();
       
   955     User::LeaveIfError( iReadStream.Open( iFs, aFileName, EFileStreamText ) );
       
   956     iFileName.Copy( aFileName );
       
   957 
       
   958 	if ( !iBuffer )
       
   959         {
       
   960 		iBuffer = CMdCSerializationBuffer::NewL( 8192 ); // 8kB - should be enough
       
   961         }
       
   962 
       
   963 	iDefaultSchema = &aSchemaNew;
       
   964     iLineNumber = 0;
       
   965     iFailed = 0;
       
   966     while( ReadMetadataFileLineL() )
       
   967         {
       
   968         if ( iLine.Length() > 0 )
       
   969             {
       
   970             // parse the line
       
   971             TLex8 parser( iLine );
       
   972             TRAPD( e, ImportMetadataItemL( parser, aManipulate ) );
       
   973             if ( e != KErrNone )
       
   974             	{
       
   975 			    ++iFailed;
       
   976             	}
       
   977             }
       
   978 		else
       
   979         	iLastLineProcessed = ETrue;
       
   980         }
       
   981 
       
   982 	iDefaultSchema = NULL;
       
   983     CleanupStack::PopAndDestroy( &iReadStream ); // Closes stream.
       
   984     return iFailed;
       
   985 	}
       
   986 
       
   987 void CMdsImportExport::ImportMetadataItemL( TLex8& aParser, CMdSSqlObjectManipulate& aManipulate )
       
   988 	{
       
   989     TPtrC8 token = aParser.NextToken();
       
   990 
       
   991     // valid keywords in beginning of line
       
   992     if ( token.Length() == 0 || token.Left(2) == KMdsKeywordComment )
       
   993         {
       
   994         // ignore
       
   995         iLastLineProcessed = ETrue;
       
   996         return;
       
   997         }
       
   998     else if ( token == KMdsKeywordObject )
       
   999         {
       
  1000         TRAPD( err, ImportMetadataFileObjectL( aParser, aManipulate ) );
       
  1001         if (err != KErrNone)
       
  1002         	{
       
  1003         	_LIT( KError, "Object error" );
       
  1004      		LogError( KError );
       
  1005 			User::Leave( err );
       
  1006         	}
       
  1007         }
       
  1008     else if ( token == KMdsKeywordRelation )
       
  1009         {
       
  1010         TRAPD( err, ImportMetadataFileRelationL( aParser, aManipulate ) );
       
  1011         if (err != KErrNone)
       
  1012         	{
       
  1013         	_LIT( KError, "Relation error" );
       
  1014      		LogError( KError );
       
  1015 			User::Leave( err );
       
  1016         	}
       
  1017         }
       
  1018     else if ( token == KMdsKeywordEvent )
       
  1019         {
       
  1020 		TRAPD( err, ImportMetadataFileEventL( aParser, aManipulate ) );
       
  1021         if (err != KErrNone)
       
  1022         	{
       
  1023         	_LIT( KError, "Relation error" );
       
  1024      		LogError( KError );
       
  1025 			User::Leave( err );
       
  1026         	}
       
  1027         }
       
  1028     else
       
  1029         {
       
  1030         iLastLineProcessed = ETrue;
       
  1031         _LIT( KError, "Keyword not recognized" );
       
  1032         LogError( KError );
       
  1033         User::Leave( KErrCorrupt );
       
  1034         }
       
  1035     TPtrC8 tokenLast = aParser.NextToken();
       
  1036     if ( tokenLast.Length() != 0 && tokenLast.Left(2) != KMdsKeywordComment )
       
  1037     	{
       
  1038     	_LIT( KMdsUnknownToken, "Undefined metadata file item" );
       
  1039     	LogError( KMdsUnknownToken );
       
  1040     	User::Leave( KErrCorrupt );
       
  1041     	}
       
  1042 	}
       
  1043 
       
  1044 void CMdsImportExport::AddObjectToDBL( CMdSSqlObjectManipulate& aManipulate, CMdsNamespaceDef* aNamespaceDef )
       
  1045 	{
       
  1046 	iLastObjectDef = NULL;
       
  1047 	iBuffer->PositionL( KNoOffset );
       
  1048 	TItemId id = KNoId;
       
  1049 	aManipulate.SetNamespace( aNamespaceDef );
       
  1050 	RMdsStatement baseObjStmt;
       
  1051     CleanupClosePushL(baseObjStmt);
       
  1052 	RMdsStatement objStmt;
       
  1053 	CleanupClosePushL(objStmt);
       
  1054 	
       
  1055 	TRAPD( err, id = aManipulate.AddObjectL( MMdSDbConnectionPool::GetDefaultDBL(), *iBuffer, baseObjStmt, objStmt ) );
       
  1056 	
       
  1057 	CleanupStack::PopAndDestroy(&objStmt);
       
  1058 	CleanupStack::PopAndDestroy(&baseObjStmt);
       
  1059 	
       
  1060 	aManipulate.SetNamespace( NULL );
       
  1061 	if ( err != KErrNone || id == 0 )
       
  1062 		{
       
  1063 		User::Leave( err );
       
  1064 		}
       
  1065 	}
       
  1066 
       
  1067 void CMdsImportExport::ImportMetadataFileObjectL( TLex8& aParser, CMdSSqlObjectManipulate& aManipulate )
       
  1068 	{
       
  1069 	TInt error = KErrNone;
       
  1070 
       
  1071     if ( iLastObjectDef )
       
  1072     	{
       
  1073    		User::Leave( KErrCorrupt );
       
  1074     	}
       
  1075 	iLastLineProcessed = ETrue;
       
  1076 
       
  1077 	TMdCObject object;
       
  1078 	object.iId = KNoId;
       
  1079 	object.iFlags = EMdEObjectFlagModOpen;
       
  1080 	object.iUsageCount = 0;
       
  1081 	object.iGuidHigh = 0;
       
  1082 	object.iGuidLow = 0;
       
  1083 	object.iFreeTexts.iPtr.iCount = 0;
       
  1084 	object.iFreeTexts.iPtr.iOffset = KNoOffset;
       
  1085 
       
  1086 	TMdCOffset freespaceOffset = sizeof(TMdCObject);
       
  1087 	
       
  1088 	TBuf16<KMdsMaxUriLenght> textValue;
       
  1089 
       
  1090     // namespace
       
  1091     User::LeaveIfError( ImportText( textValue, aParser ) );
       
  1092 
       
  1093     CMdsNamespaceDef* namespaceDef = iDefaultSchema->GetNamespace( textValue );
       
  1094 	if ( !namespaceDef )
       
  1095 		{
       
  1096 		User::Leave( KErrNotFound );
       
  1097 		}
       
  1098 
       
  1099     // read object variables
       
  1100     // objectDef name
       
  1101     User::LeaveIfError( ImportText( textValue, aParser ) );
       
  1102     
       
  1103     iLastObjectDef = namespaceDef->GetObjectDef( textValue );
       
  1104     if ( !iLastObjectDef )
       
  1105     	{
       
  1106     	User::Leave( KErrNotFound );
       
  1107     	}
       
  1108     object.iDefId = iLastObjectDef->GetId();
       
  1109     
       
  1110 	// object uri
       
  1111 	User::LeaveIfError( ImportText( textValue, aParser ) );
       
  1112 	object.iUri.iPtr.iCount = textValue.Length();
       
  1113 	object.iUri.iPtr.iOffset = freespaceOffset;
       
  1114 	iBuffer->PositionL( freespaceOffset );
       
  1115 	freespaceOffset = iBuffer->InsertL( textValue );
       
  1116 
       
  1117 	// Object must not be context object and 
       
  1118 	// the length of the URI must be atleast 3 (X:\) 
       
  1119 	if ( !(iLastObjectDef->GetFlags() & CMdsObjectDef::EObjectDefFlagsContext) && 
       
  1120 			textValue.Length() >= 3 )
       
  1121 	    {
       
  1122 	    // possible drive letter
       
  1123 	    TChar driveLetter( textValue[0] );
       
  1124 	    driveLetter.UpperCase();
       
  1125 	    
       
  1126 	    // possible colon and backslash
       
  1127 	    _LIT( KColonBackslashMatch, ":\\" );
       
  1128 	    TPtrC beginUri = textValue.Mid( 1, KColonBackslashMatch.iTypeLength );
       
  1129 	    TBool validUri( ETrue );
       
  1130 	    
       
  1131 	    // URI must begin with "X:\"
       
  1132 	    if( 'A' <= driveLetter && driveLetter <= 'Z' && 
       
  1133 	    		beginUri.Compare( KColonBackslashMatch ) == 0 )
       
  1134 	    	{
       
  1135 			// check if uri exists
       
  1136 	        RFileReadStream tmpFile;
       
  1137 			TInt err = KErrNone;
       
  1138 			err = tmpFile.Open( iFs, textValue, EFileRead | EFileShareAny );
       
  1139 			tmpFile.Close();
       
  1140 			if ( err != KErrNone )
       
  1141 				{
       
  1142 				_LIT( KError, "uri is not real" );
       
  1143 				validUri = EFalse;
       
  1144 				LogError( KError );
       
  1145 				error = err;
       
  1146 				}
       
  1147 	    	}
       
  1148 	    else
       
  1149 	        {
       
  1150 	        validUri = EFalse;
       
  1151 	        }
       
  1152 	    
       
  1153 	    if( validUri )
       
  1154 	        {
       
  1155 	        User::LeaveIfError( ImportMediaId( object.iMediaId, aParser, driveLetter ) );
       
  1156 	        }
       
  1157 	    else
       
  1158 	        {
       
  1159 	        User::LeaveIfError( ImportUInt32( object.iMediaId, aParser ) );
       
  1160 	        }
       
  1161 	    }
       
  1162 	else
       
  1163 	    {
       
  1164 	    User::LeaveIfError( ImportUInt32( object.iMediaId, aParser ) );
       
  1165 	    }
       
  1166 
       
  1167     const TUint32 allPropCount = iLastObjectDef->GetAllPropertiesCount();
       
  1168     object.iProperties.iPtr.iCount = allPropCount;
       
  1169     object.iProperties.iPtr.iOffset = freespaceOffset;
       
  1170 
       
  1171     freespaceOffset += allPropCount * sizeof(TMdCProperty);
       
  1172    
       
  1173     // set property offset
       
  1174 	CDesC16ArrayFlat* freeTextBuffer = new(ELeave) CDesC16ArrayFlat(8);
       
  1175 	CleanupStack::PushL( freeTextBuffer );
       
  1176 
       
  1177 	TUint32 propertyCount = 0;
       
  1178 	while ( ReadMetadataFileLineL() )
       
  1179 		{
       
  1180 		TLex8 parser( iLine );
       
  1181 		TPtrC8 token = parser.NextToken();
       
  1182 
       
  1183 	    if ( iLine.Length() == 0 || token.Length() == 0 || token.Left(2) == KMdsKeywordComment )
       
  1184 	        {
       
  1185 	        // ignore line
       
  1186 	        iLastLineProcessed = ETrue;
       
  1187 	        }
       
  1188 		// now if exists there should be one or more properties		
       
  1189 		else if(token == KMdsKeywordProperty )
       
  1190 			{
       
  1191 			if ( object.iFreeTexts.iPtr.iOffset != KNoOffset || propertyCount >= allPropCount )
       
  1192 				{
       
  1193 				_LIT( KError, "Property after freetext" );
       
  1194 				LogError( KError );
       
  1195 				error = KErrCorrupt;
       
  1196 				}
       
  1197 			if (error != KErrNone)
       
  1198 				{
       
  1199 				// just fetch rest of object lines
       
  1200 				iLastLineProcessed = ETrue;
       
  1201 				}
       
  1202 			else
       
  1203 				{
       
  1204 				iBuffer->PositionL( object.iProperties.iPtr.iOffset
       
  1205 						+ propertyCount * sizeof(TMdCProperty) );
       
  1206 				TRAP( error, freespaceOffset = ImportMetadataFilePropertyL(
       
  1207 						parser, freespaceOffset ) );
       
  1208 				if (error != KErrNone)
       
  1209 					{
       
  1210 					_LIT( KError, "Property error" );
       
  1211 			        LogError( KError );
       
  1212 					}
       
  1213 				++propertyCount;
       
  1214 				}
       
  1215 			}
       
  1216 		// and after those there should be freetext
       
  1217 		else if ( token == KMdsKeywordFreeText )
       
  1218 		    {
       
  1219 			if (error != KErrNone)
       
  1220 				{
       
  1221 				// just fetch rest of object lines
       
  1222 				iLastLineProcessed = ETrue;
       
  1223 				}
       
  1224 			else
       
  1225 				{
       
  1226 			    if ( object.iFreeTexts.iPtr.iOffset == KNoOffset)
       
  1227 			    	{
       
  1228 			    	object.iFreeTexts.iPtr.iOffset = freespaceOffset;
       
  1229 			    	}
       
  1230 				else
       
  1231 					{
       
  1232 			    	TRAP( error, ImportMetadataFileFreeTextL( parser, *freeTextBuffer ) );
       
  1233 					if (error != KErrNone)
       
  1234 						{
       
  1235 						_LIT( KError, "Freetext error" );
       
  1236 				        LogError( KError );
       
  1237 						}
       
  1238 					}
       
  1239 				}
       
  1240 		    }
       
  1241 		else
       
  1242 			{
       
  1243 			if ( token == KMdsKeywordObject || token == KMdsKeywordRelation || token == KMdsKeywordEvent )
       
  1244 				{
       
  1245 				break;
       
  1246 				}
       
  1247 			iLastLineProcessed = ETrue;
       
  1248 			}
       
  1249 		}
       
  1250 
       
  1251 	if ( error != KErrNone )
       
  1252 		{
       
  1253 		iLastObjectDef = NULL;
       
  1254 		User::Leave( error );
       
  1255 		}
       
  1256 
       
  1257 	object.iProperties.iPtr.iCount = propertyCount;
       
  1258 	
       
  1259 	// add freetext
       
  1260 	object.iFreeTexts.iPtr.iCount = freeTextBuffer->Count();
       
  1261 	if ( object.iFreeTexts.iPtr.iCount > 0 )
       
  1262 		{
       
  1263 		// set flags
       
  1264 		object.iFlags |= EMdEObjectFlagFreetexts | EMdEObjectFlagModFreeText;
       
  1265 
       
  1266 		iBuffer->PositionL( object.iFreeTexts.iPtr.iOffset );
       
  1267 		for ( TInt32 i = 0; i < object.iFreeTexts.iPtr.iCount; ++i )
       
  1268 			{
       
  1269 			TPtrC16 word = (*freeTextBuffer)[i];
       
  1270 			iBuffer->InsertL( word );
       
  1271 			}
       
  1272 		}
       
  1273 	else
       
  1274 		{
       
  1275 		object.iFreeTexts.iPtr.iOffset = KNoOffset;
       
  1276 		}
       
  1277 
       
  1278 	iBuffer->PositionL( KNoOffset );
       
  1279 	object.SerializeL( *iBuffer );
       
  1280 	
       
  1281 	// add object to DB
       
  1282 	AddObjectToDBL(aManipulate, namespaceDef);
       
  1283 
       
  1284 	CleanupStack::PopAndDestroy( freeTextBuffer );
       
  1285 	}
       
  1286 
       
  1287 TMdCOffset CMdsImportExport::ImportMetadataFilePropertyL( TLex8& aParser, TMdCOffset aFreespaceOffset )
       
  1288 	{
       
  1289     if ( !iLastObjectDef )
       
  1290     	{
       
  1291     	User::Leave( KErrCorrupt );
       
  1292     	}
       
  1293 	iLastLineProcessed = ETrue;
       
  1294 	TBuf16<KMdsMaxUriLenght> textValue;
       
  1295 
       
  1296 	// property name
       
  1297     User::LeaveIfError( ImportText( textValue, aParser ) );
       
  1298     
       
  1299     _LIT( KGuidHigh, "GuidHigh" );
       
  1300     _LIT( KGuidLow, "GuidLow" );
       
  1301     
       
  1302     if( textValue == KGuidHigh || textValue == KGuidLow )
       
  1303     	{
       
  1304     	User::Leave( KErrCorrupt );
       
  1305     	}
       
  1306 
       
  1307     CMdsPropertyDef* propertyDef = iLastObjectDef->GetProperty( textValue );
       
  1308     if ( !propertyDef )
       
  1309     	{
       
  1310     	User::Leave( KErrCorrupt );
       
  1311     	}
       
  1312 
       
  1313     TMdCProperty property;
       
  1314     property.iModFlags = EMdEPropertyModChange;
       
  1315     property.iPropertyDefId = propertyDef->GetId();
       
  1316 
       
  1317     // find proper place to put property
       
  1318     const TMdCOffset propertyOffset = iBuffer->Position();
       
  1319 
       
  1320 	switch( propertyDef->GetType() )
       
  1321 		{
       
  1322     	case EPropertyBool:
       
  1323     		{
       
  1324     		TInt32 intValue;
       
  1325 		    User::LeaveIfError( ImportNum( intValue, aParser ) );
       
  1326     		TBool value = intValue ? ETrue : EFalse;
       
  1327     		property.iValue.iInt32 = value;
       
  1328     		break;
       
  1329     		}
       
  1330     	case EPropertyInt8:
       
  1331     		{
       
  1332     		TInt32 intValue;
       
  1333 		    User::LeaveIfError( ImportNum( intValue, aParser ) );
       
  1334     		property.iValue.iInt32 = intValue;
       
  1335     		break;
       
  1336     		}
       
  1337     	case EPropertyUint8:
       
  1338     		{
       
  1339     		TInt32 intValue;
       
  1340 		    User::LeaveIfError( ImportNum( intValue, aParser ) );
       
  1341     		property.iValue.iUint32 = intValue;
       
  1342     		break;
       
  1343     		}
       
  1344     	case EPropertyInt16:
       
  1345     		{
       
  1346     		TInt32 intValue;
       
  1347 		    User::LeaveIfError( ImportNum( intValue, aParser ) );
       
  1348     		property.iValue.iInt32 = intValue;
       
  1349     		break;
       
  1350     		}
       
  1351     	case EPropertyUint16:
       
  1352     		{
       
  1353     		TInt32 intValue;
       
  1354 		    User::LeaveIfError( ImportNum( intValue, aParser ) );
       
  1355     		property.iValue.iUint32 = intValue;
       
  1356     		break;
       
  1357     		}
       
  1358     	case EPropertyInt32:
       
  1359     		{
       
  1360     		TInt32 value;
       
  1361 		    User::LeaveIfError( ImportNum( value, aParser ) );
       
  1362     		property.iValue.iInt32 = value;
       
  1363     		break;
       
  1364     		}
       
  1365     	case EPropertyUint32:
       
  1366     		{
       
  1367     		TUint32 value;
       
  1368 		    User::LeaveIfError( ImportUInt32( value, aParser ) );
       
  1369     		property.iValue.iUint32 = value;
       
  1370     		break;
       
  1371     		}
       
  1372     	case EPropertyInt64:
       
  1373     		{
       
  1374     		TInt64 value;
       
  1375 		    User::LeaveIfError( ImportInt64( value, aParser ) );
       
  1376     		property.iValue.iInt64 = value;
       
  1377     		break;
       
  1378     		}
       
  1379     	case EPropertyTime:
       
  1380     		{
       
  1381     		TTime value;
       
  1382 		    User::LeaveIfError( ImportTime( value, aParser ) );
       
  1383     		property.iValue.iInt64 = value.Int64();
       
  1384     		break;
       
  1385     		}
       
  1386     	case EPropertyReal32:
       
  1387     		{
       
  1388     		TReal32 value;
       
  1389 		    User::LeaveIfError( ImportNum( value, aParser ) );
       
  1390     		property.iValue.iReal = value;
       
  1391     		break;
       
  1392     		}
       
  1393     	case EPropertyReal64:
       
  1394     		{
       
  1395     		TReal64 value;
       
  1396 		    User::LeaveIfError( ImportNum( value, aParser ) );
       
  1397     		property.iValue.iReal = value;
       
  1398     		break;
       
  1399     		}
       
  1400     	case EPropertyText:
       
  1401     		{
       
  1402 			TBuf16<256> value;
       
  1403     		User::LeaveIfError( ImportText( value, aParser ) );
       
  1404     		property.iValue.iPtr.iCount = value.Length();
       
  1405     		if (property.iValue.iPtr.iCount > 0)
       
  1406     			{
       
  1407     			property.iValue.iPtr.iOffset = aFreespaceOffset;
       
  1408     			iBuffer->PositionL( aFreespaceOffset );
       
  1409     			aFreespaceOffset = iBuffer->InsertL( value );
       
  1410     			}
       
  1411     		else
       
  1412     			{
       
  1413     			User::Leave( KErrCorrupt );
       
  1414     			}
       
  1415     		break;
       
  1416     		}
       
  1417     	default:
       
  1418     		User::Leave( KErrNotFound );
       
  1419 		}
       
  1420 
       
  1421 	iBuffer->PositionL( propertyOffset );
       
  1422 	property.SerializeL( *iBuffer );
       
  1423 	
       
  1424 	return aFreespaceOffset;
       
  1425 	}
       
  1426 
       
  1427 void CMdsImportExport::ImportMetadataFileFreeTextL( TLex8& aParser, CDesC16ArrayFlat& aFreeTextArray )
       
  1428 	{
       
  1429     if ( !iLastObjectDef )
       
  1430     	{
       
  1431     	User::Leave( KErrCorrupt );
       
  1432     	}
       
  1433 	iLastLineProcessed = ETrue;
       
  1434 
       
  1435 	TBuf16<256> freeText;
       
  1436 	while( ImportText( freeText, aParser ) == KErrNone )
       
  1437 		{
       
  1438 		aFreeTextArray.AppendL( freeText );
       
  1439 		}
       
  1440 	}
       
  1441 
       
  1442 void CMdsImportExport::ImportMetadataFileRelationL( TLex8& aParser, CMdSSqlObjectManipulate& aManipulate )
       
  1443 	{
       
  1444 	_LIT( KImportRelationGetObjectId, "SELECT ObjectId FROM Object%u WHERE URI=? LIMIT 1;" );
       
  1445     if(iLastObjectDef)
       
  1446     	{
       
  1447    		User::Leave( KErrCorrupt );
       
  1448     	}
       
  1449 	iLastLineProcessed = ETrue;
       
  1450 
       
  1451 	CMdsClauseBuffer* clauseBuffer = CMdsClauseBuffer::NewLC( KImportRelationGetObjectId.iTypeLength + 10 ); // one uint
       
  1452 
       
  1453 	TBuf16<KMdsMaxUriLenght> textValue;
       
  1454 
       
  1455 	// namespace
       
  1456     User::LeaveIfError( ImportText( textValue, aParser ) );
       
  1457 
       
  1458     CMdsNamespaceDef* namespaceDef = iDefaultSchema->GetNamespace( textValue );
       
  1459 	if ( !namespaceDef )
       
  1460 		{
       
  1461 		User::Leave( KErrNotFound );
       
  1462 		}
       
  1463 
       
  1464 	clauseBuffer->BufferL().Format( KImportRelationGetObjectId, namespaceDef->GetId() );
       
  1465 
       
  1466 	TMdCRelation relation;
       
  1467 	relation.iId = KNoId;
       
  1468 	relation.iGuidHigh = 0;
       
  1469 	relation.iGuidLow = 0;
       
  1470 	relation.iLastModifiedDate.UniversalTime();
       
  1471 
       
  1472     // read relation variables
       
  1473     // relationDef name
       
  1474     User::LeaveIfError( ImportText( textValue, aParser ) );
       
  1475     CMdsRelationDef* relationDef = namespaceDef->GetRelationDef( textValue );
       
  1476     if ( !relationDef )
       
  1477     	{
       
  1478     	User::Leave( KErrNotFound );
       
  1479     	}
       
  1480     relation.iDefId = relationDef->GetId();
       
  1481 
       
  1482 	RRowData dataRow;
       
  1483 	CleanupClosePushL( dataRow );
       
  1484 	RMdsStatement query;
       
  1485 	CleanupClosePushL( query );
       
  1486 
       
  1487 	CMdSSqLiteConnection& connection = MMdSDbConnectionPool::GetDefaultDBL();
       
  1488 
       
  1489 	// left object name
       
  1490 	User::LeaveIfError( ImportText( textValue, aParser ) );
       
  1491 	relation.iLeftObjectId = KNoId;
       
  1492 
       
  1493 	dataRow.AppendL( TColumn( textValue ) );
       
  1494 	connection.ExecuteQueryL( clauseBuffer->ConstBufferL(), query, dataRow );
       
  1495 	dataRow.Free();
       
  1496 	dataRow.Column( 0 ).Set( relation.iLeftObjectId );
       
  1497 	if( connection.NextRowL( query, dataRow ) )
       
  1498 		{
       
  1499 		dataRow.Column( 0 ).Get( relation.iLeftObjectId );
       
  1500 		}
       
  1501 	if (relation.iLeftObjectId == KNoId)
       
  1502 		{
       
  1503 		User::Leave( KErrNotFound );
       
  1504 		}
       
  1505 
       
  1506 	// right object name
       
  1507 	User::LeaveIfError( ImportText( textValue, aParser ) );
       
  1508 	relation.iRightObjectId = KNoId;
       
  1509 	dataRow.Column( 0 ).Set( textValue );
       
  1510 
       
  1511 	connection.ExecuteQueryL( clauseBuffer->ConstBufferL(), query, dataRow );
       
  1512 	dataRow.Free();
       
  1513 	dataRow.Column( 0 ).Set( relation.iLeftObjectId );
       
  1514 	if( connection.NextRowL( query, dataRow ) )
       
  1515 		{
       
  1516 		dataRow.Column( 0 ).Get( relation.iRightObjectId );
       
  1517 		}
       
  1518 	if (relation.iRightObjectId == KNoId)
       
  1519 		{
       
  1520 		User::Leave( KErrNotFound );
       
  1521 		}
       
  1522 
       
  1523 	CleanupStack::PopAndDestroy( 2, &dataRow ); // query, dataRow
       
  1524 
       
  1525 	relation.iParameter = 0;
       
  1526 	User::LeaveIfError( ImportNum( relation.iParameter, aParser ) );
       
  1527 
       
  1528 	iBuffer->PositionL( KNoOffset );
       
  1529 	relation.SerializeL( *iBuffer );
       
  1530 
       
  1531 	TItemId id = KNoId;
       
  1532 	iBuffer->PositionL( KNoOffset );
       
  1533 	aManipulate.SetNamespace( namespaceDef );
       
  1534 	TRAPD( err, id = aManipulate.AddRelationL( connection, *iBuffer ) );
       
  1535 	aManipulate.SetNamespace( NULL );
       
  1536 	if (err != KErrNone || id == KNoId)
       
  1537 		{
       
  1538 		User::Leave( err );
       
  1539 		}
       
  1540 	CleanupStack::PopAndDestroy( clauseBuffer ); // clauseBuffer
       
  1541 	}
       
  1542 
       
  1543 void CMdsImportExport::ImportMetadataFileEventL( TLex8& aParser, CMdSSqlObjectManipulate& aManipulate )
       
  1544 	{
       
  1545 	_LIT( KImportEventGetObjectId, "SELECT ObjectId FROM Object%u WHERE URI=? LIMIT 1;" );
       
  1546     if ( iLastObjectDef )
       
  1547     	{
       
  1548    		User::Leave( KErrCorrupt );
       
  1549     	}
       
  1550 	iLastLineProcessed = ETrue;
       
  1551 
       
  1552 	CMdsClauseBuffer* clauseBuffer = CMdsClauseBuffer::NewLC( KImportEventGetObjectId.iTypeLength + 10 ); // one uint
       
  1553 
       
  1554 	TBuf16<KMdsMaxUriLenght> textValue;
       
  1555 
       
  1556 	// namespace
       
  1557     User::LeaveIfError( ImportText( textValue, aParser ) );
       
  1558 
       
  1559     CMdsNamespaceDef* namespaceDef = iDefaultSchema->GetNamespace( textValue );
       
  1560 	if ( !namespaceDef )
       
  1561 		{
       
  1562 		User::Leave( KErrNotFound );
       
  1563 		}
       
  1564 
       
  1565 	clauseBuffer->BufferL().Format( KImportEventGetObjectId, namespaceDef->GetId() );
       
  1566 
       
  1567 	TMdCEvent event;
       
  1568 	event.iId = KNoId;
       
  1569 
       
  1570     // read event variables
       
  1571     // eventDef name
       
  1572     User::LeaveIfError( ImportText( textValue, aParser ) );
       
  1573     CMdsEventDef* eventDef = namespaceDef->GetEventDef( textValue );
       
  1574     if ( !eventDef )
       
  1575     	{
       
  1576     	User::Leave( KErrNotFound );
       
  1577     	}
       
  1578     event.iDefId = eventDef->GetId();
       
  1579 
       
  1580 	RRowData dataRow;
       
  1581 	CleanupClosePushL( dataRow );
       
  1582 	RMdsStatement query;
       
  1583 	CleanupClosePushL( query );
       
  1584 
       
  1585 	CMdSSqLiteConnection& connection = MMdSDbConnectionPool::GetDefaultDBL();
       
  1586 
       
  1587 	// object name
       
  1588 	User::LeaveIfError( ImportText( textValue, aParser ) );
       
  1589 	event.iObjectId = KNoId;
       
  1590 
       
  1591 	dataRow.AppendL( TColumn( textValue ) );
       
  1592 	connection.ExecuteQueryL( clauseBuffer->ConstBufferL(), query, dataRow );
       
  1593 	dataRow.Free();
       
  1594 	dataRow.Column( 0 ).Set( event.iObjectId );
       
  1595 	if ( connection.NextRowL( query, dataRow ) )
       
  1596 		{
       
  1597 		dataRow.Column( 0 ).Get( event.iObjectId );
       
  1598 		}
       
  1599 	if ( event.iObjectId == KNoId )
       
  1600 		{
       
  1601 		User::Leave( KErrNotFound );
       
  1602 		}
       
  1603 
       
  1604 	CleanupStack::PopAndDestroy( 2, &dataRow ); // query, dataRow
       
  1605 
       
  1606 	TMdCOffset freespaceOffset = sizeof(TMdCEvent);
       
  1607 	// source
       
  1608 	User::LeaveIfError( ImportText( textValue, aParser ) );
       
  1609 	event.iSourceText.iPtr.iCount = textValue.Length();
       
  1610 	if (event.iSourceText.iPtr.iCount > 0)
       
  1611 		{
       
  1612 		event.iSourceText.iPtr.iOffset = freespaceOffset;
       
  1613 		iBuffer->PositionL( freespaceOffset );
       
  1614 		freespaceOffset = iBuffer->InsertL( textValue );
       
  1615 		}
       
  1616 	else
       
  1617 		{
       
  1618 		event.iSourceText.iPtr.iOffset = KNoOffset;
       
  1619 		}
       
  1620 
       
  1621 	// participant
       
  1622 	User::LeaveIfError( ImportText( textValue, aParser ) );
       
  1623 	event.iParticipantText.iPtr.iCount = textValue.Length();
       
  1624 	if (event.iParticipantText.iPtr.iCount > 0)
       
  1625 		{
       
  1626 		event.iParticipantText.iPtr.iOffset = freespaceOffset;
       
  1627 		iBuffer->PositionL( freespaceOffset );
       
  1628 		freespaceOffset = iBuffer->InsertL( textValue );
       
  1629 		}
       
  1630 	else
       
  1631 		{
       
  1632 		event.iParticipantText.iPtr.iOffset = KNoOffset;
       
  1633 		}
       
  1634 
       
  1635 	// time
       
  1636 	User::LeaveIfError( ImportTime( event.iTime, aParser ) );
       
  1637 
       
  1638 	iBuffer->PositionL( KNoOffset );
       
  1639 	event.SerializeL( *iBuffer );
       
  1640 
       
  1641 	TItemId id = KNoId;
       
  1642 	iBuffer->PositionL( KNoOffset );
       
  1643 	aManipulate.SetNamespace( namespaceDef );
       
  1644 	TRAPD( err, id = aManipulate.AddEventL( connection, *iBuffer ) );
       
  1645 	aManipulate.SetNamespace( NULL );
       
  1646 	if (err != KErrNone || id == KNoId)
       
  1647 		{
       
  1648 		User::Leave( err );
       
  1649 		}
       
  1650 
       
  1651 	CleanupStack::PopAndDestroy( clauseBuffer ); // clauseBuffer
       
  1652 	}
       
  1653 
       
  1654 void CMdsImportExport::ExportMetadataL( CMdsSchema& aSchemaNew, const TDesC16& aFileName,
       
  1655 										CMdCSerializationBuffer& aItems )
       
  1656 	{
       
  1657 	iFs.PrivatePath( iFileName );
       
  1658 	if ( aFileName.Find(iFileName) != KErrNotFound )
       
  1659 		{
       
  1660 		User::Leave( KErrAccessDenied );
       
  1661 		}
       
  1662 
       
  1663 	CleanupClosePushL( iWriteStream );
       
  1664     User::LeaveIfError( iWriteStream.Replace( iFs, aFileName, EFileShareExclusive | EFileStreamText | EFileWrite ) );
       
  1665 
       
  1666 	// reading import "filters"
       
  1667 	aItems.PositionL( KNoOffset ); // start from the beginning of buffer
       
  1668 	const TMdCItemIds& itemIds = TMdCItemIds::GetFromBufferL( aItems ); // read item ids from buffer
       
  1669 	const CMdsNamespaceDef* namespaceDefRestrict = NULL;
       
  1670 	if ( itemIds.iNamespaceDefId != KNoDefId )
       
  1671 		{
       
  1672 		namespaceDefRestrict = aSchemaNew.GetNamespaceByIdL( itemIds.iNamespaceDefId );
       
  1673 		}
       
  1674 
       
  1675 	RPointerArray<CMdsObjectDef>   objectDefToExport;
       
  1676 	CleanupClosePushL( objectDefToExport );
       
  1677 	RPointerArray<CMdsEventDef>    eventDefToExport;
       
  1678 	CleanupClosePushL( eventDefToExport );
       
  1679 	RPointerArray<CMdsRelationDef> relationDefToExport;
       
  1680 	CleanupClosePushL( relationDefToExport );
       
  1681 
       
  1682 	// Get all object definitions from buffer.
       
  1683 	if ( itemIds.iObjectIds.iPtr.iCount > 0 )
       
  1684 		{
       
  1685 		if ( !namespaceDefRestrict )
       
  1686 			{
       
  1687 			User::Leave( KErrCorrupt );
       
  1688 			}
       
  1689 		objectDefToExport.ReserveL( itemIds.iObjectIds.iPtr.iCount );
       
  1690 		aItems.PositionL( itemIds.iObjectIds.iPtr.iOffset );
       
  1691 		TDefId objectDefId;
       
  1692 		for ( TInt i = 0; i < itemIds.iObjectIds.iPtr.iCount; ++i )
       
  1693 			{
       
  1694 			aItems.ReceiveL( objectDefId );
       
  1695 			const CMdsObjectDef* objectDef = namespaceDefRestrict->GetObjectByIdL( objectDefId );
       
  1696 			if (objectDef)
       
  1697 				{
       
  1698 				objectDefToExport.Append( objectDef );
       
  1699 				}
       
  1700 			}
       
  1701 		}
       
  1702 
       
  1703 	// Get all event definitions from buffer.
       
  1704 	if ( itemIds.iEventIds.iPtr.iCount > 0 )
       
  1705 		{
       
  1706 		if (!namespaceDefRestrict)
       
  1707 			{
       
  1708 			User::Leave( KErrCorrupt );
       
  1709 			}
       
  1710 		eventDefToExport.ReserveL( itemIds.iEventIds.iPtr.iCount );
       
  1711 		aItems.PositionL( itemIds.iEventIds.iPtr.iOffset );
       
  1712 		TDefId eventDefId;
       
  1713 		for ( TInt i = 0; i < itemIds.iEventIds.iPtr.iCount; ++i )
       
  1714 			{
       
  1715 			aItems.ReceiveL( eventDefId );
       
  1716 			const CMdsEventDef* eventDef = namespaceDefRestrict->GetEventByIdL( eventDefId );
       
  1717 			if (eventDef)
       
  1718 				{
       
  1719 				eventDefToExport.Append( eventDef );
       
  1720 				}
       
  1721 			}
       
  1722 		}
       
  1723 
       
  1724 	// Get all relation definitions from buffer.
       
  1725 	if ( itemIds.iRelationIds.iPtr.iCount > 0 )
       
  1726 		{
       
  1727 		if ( !namespaceDefRestrict )
       
  1728 			{
       
  1729 			User::Leave( KErrCorrupt );
       
  1730 			}
       
  1731 		relationDefToExport.ReserveL( itemIds.iRelationIds.iPtr.iCount );
       
  1732 		aItems.PositionL( itemIds.iRelationIds.iPtr.iOffset );
       
  1733 		TDefId relationDefId;
       
  1734 		for ( TInt i = 0; i < itemIds.iRelationIds.iPtr.iCount; ++i )
       
  1735 			{
       
  1736 			aItems.ReceiveL( relationDefId );
       
  1737 			const CMdsRelationDef* relationDef = namespaceDefRestrict->GetRelationByIdL( relationDefId );
       
  1738 			if ( relationDef )
       
  1739 				{
       
  1740 				relationDefToExport.Append( relationDef );
       
  1741 				}
       
  1742 			}
       
  1743 		}
       
  1744 
       
  1745 	CMdsClauseBuffer* clause = CMdsClauseBuffer::NewLC( 2048 );
       
  1746 	CMdsClauseBuffer* freeTextClause = CMdsClauseBuffer::NewLC( 512 );
       
  1747 
       
  1748 	RRowData dataRow;
       
  1749 	CleanupClosePushL( dataRow );
       
  1750 	RRowData freeTextRow;
       
  1751 	CleanupClosePushL( freeTextRow );
       
  1752 
       
  1753 	TInt j;
       
  1754 	
       
  1755 	const TInt namespaceCount = aSchemaNew.iNamespaceDefs.Count();
       
  1756 	
       
  1757 	for ( TInt i = 0; i < namespaceCount; ++i )
       
  1758 		{
       
  1759 		CMdsNamespaceDef* namespaceDef = aSchemaNew.iNamespaceDefs[i];
       
  1760 		if ( namespaceDefRestrict && namespaceDefRestrict != namespaceDef )
       
  1761 			{
       
  1762 			continue;
       
  1763 			}
       
  1764 
       
  1765 		ExportMetadataMakeFreeTextSqlClauseL( *namespaceDef, *freeTextClause, freeTextRow );
       
  1766 		// writing object information
       
  1767 		
       
  1768 		const TInt objectDefCount = namespaceDef->iObjectDefs.Count();
       
  1769 		
       
  1770 		for ( j = 0; j < objectDefCount; ++j )
       
  1771 			{
       
  1772 			CMdsObjectDef* objectDef = namespaceDef->iObjectDefs[j];
       
  1773 			if ( !namespaceDefRestrict || objectDefToExport.Count() == 0 || objectDefToExport.Find( objectDef ) != KErrNotFound )
       
  1774 				{
       
  1775 				ExportMetadataMakeSqlObjectClauseL( *namespaceDef, *objectDef, *clause, dataRow );
       
  1776 				ExportMetadataWriteObjectInfoL( *namespaceDef, *objectDef, *clause, dataRow, *freeTextClause, freeTextRow );
       
  1777 				}
       
  1778 			}
       
  1779 
       
  1780 		// writing relation information
       
  1781 		ExportMetadataMakeSqlRelationClauseL( *namespaceDef, *clause, dataRow );
       
  1782 		
       
  1783 		const TInt relationDefCount = namespaceDef->iRelationDefs.Count();
       
  1784 		
       
  1785 		for ( j = 0; j < relationDefCount; ++j )
       
  1786 			{
       
  1787 			CMdsRelationDef* relationDef = namespaceDef->iRelationDefs[j];
       
  1788 			if ( !namespaceDefRestrict || relationDefToExport.Count() == 0 || relationDefToExport.Find( relationDef ) != KErrNotFound )
       
  1789 				{
       
  1790 				ExportMetadataWriteRelationInfoL( *namespaceDef, *relationDef, *clause, dataRow );
       
  1791 				}
       
  1792 			if ( j == namespaceDef->iRelationDefs.Count() - 1 )
       
  1793 				{
       
  1794 				iWriteStream.WriteL( KExportMetadataNewLine );
       
  1795 				}
       
  1796 			}
       
  1797 
       
  1798 		// writing event information
       
  1799 		ExportMetadataMakeSqlEventClauseL( *namespaceDef, *clause, dataRow );
       
  1800 		
       
  1801 		const TInt eventDefCount = namespaceDef->iEventDefs.Count();
       
  1802 		
       
  1803 		for ( j = 0; j < eventDefCount; ++j )
       
  1804 			{
       
  1805 			CMdsEventDef* eventDef = namespaceDef->iEventDefs[j];
       
  1806 			if ( !namespaceDefRestrict || eventDefToExport.Count() == 0 || eventDefToExport.Find( eventDef ) != KErrNotFound )
       
  1807 				{
       
  1808 				ExportMetadataWriteEventInfoL( *namespaceDef, *eventDef, *clause, dataRow );
       
  1809 				}
       
  1810 			}
       
  1811 		}
       
  1812 
       
  1813     CleanupStack::PopAndDestroy( 8, &iWriteStream ); // freeTextRow, dataRow, freeTextClause, clause, relationDefToExport, eventDefToExport, objectDefToExport, iWriteStream
       
  1814 	}
       
  1815 
       
  1816 void CMdsImportExport::ExportMetadataMakeSqlObjectClauseL( const CMdsNamespaceDef& aNamespaceDef, const CMdsObjectDef& aObjectDef,
       
  1817 														  CMdsClauseBuffer& aClause, RRowData& aDataRow )
       
  1818 	{
       
  1819 	_LIT( KExportMetadataNotConfidential, " NOT (Flags&? OR Flags&? OR Flags&?);" );
       
  1820 	aClause.BufferL().Zero(); // reset clause
       
  1821 	aDataRow.Free(); // free and reset dataRow
       
  1822 	aDataRow.Reset();
       
  1823 	
       
  1824 	aClause.AppendL( KSelectPropertyFilterBegin );
       
  1825 	aDataRow.AppendL( TColumn( TItemId(0) ) ); // objectId
       
  1826 	aDataRow.AppendL( TColumn( TDefId(0) ) ); // objectDefId
       
  1827 	aDataRow.AppendL( TColumn( TUint32(0) ) ); // objectFlags
       
  1828 	aDataRow.AppendL( TColumn( TUint32(0) ) ); // objectMediaId
       
  1829 	aDataRow.AppendL( TColumn( TUint32(0) ) ); // usageCount
       
  1830 	aDataRow.AppendL( TColumn( TInt64(0) ) ); // objectGuidHigh
       
  1831 	aDataRow.AppendL( TColumn( TInt64(0) ) ); // objectGuidLow
       
  1832 	aDataRow.AppendL( TColumn( EColumnDes16 ) ); // objectURI
       
  1833 
       
  1834 	const TInt allPropertiesCount = aObjectDef.GetAllPropertiesCount();
       
  1835 	for ( TInt i = 0; i < allPropertiesCount; ++i )
       
  1836 		{
       
  1837 		const CMdsObjectDef::TMdsColumnOrder& column = aObjectDef.GetPropertyColumnL( i );
       
  1838 		const CMdsPropertyDef& property = column.iPropertyDef;
       
  1839 
       
  1840 		aClause.AppendL( KComma );
       
  1841 		aClause.AppendL( property.GetName() );
       
  1842 
       
  1843 		aDataRow.AppendL( TColumn( property.GetSqlType() ) );
       
  1844 		}
       
  1845 	aClause.AppendL( KSpace );
       
  1846 
       
  1847 	aClause.AppendL( KFromBaseObject, KMaxUintValueLength ); // + namespace id
       
  1848 	aClause.BufferL().AppendNum( aNamespaceDef.GetId() );
       
  1849 	aClause.AppendL( KAsBaseObject );
       
  1850 
       
  1851 	aClause.AppendL( KComma );
       
  1852 	aClause.AppendL( aObjectDef.GetName(), KMaxUintValueLength ); // + namespace id
       
  1853 	aClause.BufferL().AppendNum( aNamespaceDef.GetId() );
       
  1854 
       
  1855 	aClause.AppendL( KAsObjectOnEqual );
       
  1856 
       
  1857 	aClause.AppendL( KWhere );
       
  1858 	aClause.AppendL( KSpace );
       
  1859 	aClause.AppendL( KExportMetadataNotConfidential );
       
  1860 	}
       
  1861 
       
  1862 void CMdsImportExport::ExportMetadataMakeFreeTextSqlClauseL( const CMdsNamespaceDef& aNamespaceDef,
       
  1863 															CMdsClauseBuffer& aFreeTextClause, RRowData& aFreeTextRow )
       
  1864 	{
       
  1865 	_LIT( KExportMetadataFreeTextSearch,
       
  1866 		  "SELECT Word FROM TextSearchDictionary%u WHERE WordId IN (SELECT WordId FROM TextSearch%u WHERE ObjectId = ?);" );
       
  1867 
       
  1868 	aFreeTextClause.BufferL().Zero();
       
  1869 	aFreeTextClause.ReserveSpaceL( KExportMetadataFreeTextSearch.iTypeLength + 2*KMaxUintValueLength );
       
  1870 
       
  1871 	aFreeTextClause.BufferL().Format( KExportMetadataFreeTextSearch, aNamespaceDef.GetId(), aNamespaceDef.GetId() );
       
  1872 
       
  1873 	aFreeTextRow.Free();
       
  1874 	aFreeTextRow.Reset();
       
  1875 	aFreeTextRow.AppendL( TItemId(0) );
       
  1876 	}
       
  1877 
       
  1878 void CMdsImportExport::ExportMetadataWriteObjectInfoL( const CMdsNamespaceDef& aNamespaceDef, const CMdsObjectDef& aObjectDef,
       
  1879 													   CMdsClauseBuffer& aClause, RRowData& aDataRow,
       
  1880 													   CMdsClauseBuffer& aFreeTextClause, RRowData& aFreeTextRow )
       
  1881 	{
       
  1882 	TItemId objectId;
       
  1883 	TDefId objectDefId;
       
  1884 	TUint32 objectFlags, objectMediaId, usageCount;
       
  1885 	TInt64 objectGuidHigh, objectGuidLow;
       
  1886 	TPtrC16 objectURI;
       
  1887 
       
  1888 	RRowData confidentialFlagRow;
       
  1889 	CleanupClosePushL( confidentialFlagRow );
       
  1890 	confidentialFlagRow.AppendL( TColumn( EMdEObjectFlagRemoved ) );
       
  1891 	confidentialFlagRow.AppendL( TColumn( EMdEObjectFlagNotPresent ) );
       
  1892 	confidentialFlagRow.AppendL( TColumn( EMdEObjectFlagConfidential ) );
       
  1893 
       
  1894 	CMdSSqLiteConnection& connection = MMdSDbConnectionPool::GetDefaultDBL();
       
  1895 
       
  1896 	RMdsStatement query;
       
  1897 	CleanupClosePushL( query );
       
  1898 
       
  1899 	RMdsStatement freeTextQuery;
       
  1900 	CleanupClosePushL( freeTextQuery );
       
  1901 	RRowData textRow;
       
  1902 	CleanupClosePushL( textRow );
       
  1903 	textRow.AppendL( TColumn( EColumnDes16 ) );
       
  1904 
       
  1905 	RRowData queryResult;
       
  1906 	CleanupClosePushL( queryResult );
       
  1907 	queryResult.AppendColumnTypesL( aDataRow );
       
  1908 	connection.ExecuteQueryL( aClause.ConstBufferL(), query, confidentialFlagRow );
       
  1909 	while( connection.NextRowL( query, queryResult ) )
       
  1910 		{
       
  1911 		// get result from query
       
  1912 		queryResult.Column( 0 ).Get( objectId ); // objectId
       
  1913 		queryResult.Column( 1 ).Get( objectDefId ); // objectDefId
       
  1914 		__ASSERT_DEBUG( objectDefId == aObjectDef.GetId(), User::Panic( _L( "CMdsImportExport::ExportMetadataWriteObjectInfo" ), KErrGeneral ) );
       
  1915 		queryResult.Column( 2 ).Get( objectFlags ); // objectFlags
       
  1916 		queryResult.Column( 3 ).Get( objectMediaId ); // objectMediaId
       
  1917 		queryResult.Column( 4 ).Get( usageCount ); // usageCount
       
  1918 		queryResult.Column( 5 ).Get( objectGuidHigh ); // objectGuidHigh
       
  1919 		queryResult.Column( 6 ).Get( objectGuidLow ); // objectGuidLow
       
  1920 		queryResult.Column( 7 ).Get( objectURI ); // objectURI
       
  1921 
       
  1922 		// writing basic object information
       
  1923 		iWriteStream.WriteL( KMdsKeywordObject );
       
  1924 		iWriteStream.WriteL( KExportMetadataSpace );
       
  1925 		Conv16To8( aNamespaceDef.GetName(), iLine );
       
  1926 		iWriteStream.WriteL( iLine );
       
  1927 		iWriteStream.WriteL( KExportMetadataSpace );
       
  1928 		Conv16To8( aObjectDef.GetName(), iLine );
       
  1929 		iWriteStream.WriteL( iLine );
       
  1930 		iWriteStream.WriteL( KExportMetadataSpace );
       
  1931 		Conv16To8( objectURI, iLine );
       
  1932 		iLine.Insert( 0, KExportMetadataQuotationMark );
       
  1933 		iLine.Append( KExportMetadataQuotationMark );
       
  1934 		iWriteStream.WriteL( iLine );
       
  1935 		iWriteStream.WriteL( KExportMetadataSpace );
       
  1936 		iLine.Num( objectMediaId );
       
  1937 		iWriteStream.WriteL( iLine );
       
  1938 		iWriteStream.WriteL( KExportMetadataNewLine );
       
  1939 
       
  1940 		const TInt count = aObjectDef.GetAllPropertiesCount();
       
  1941 		
       
  1942 		// writing property information
       
  1943 		for ( TInt i = 0; i < count; ++i )
       
  1944 			{
       
  1945 			if ( queryResult.Column( i + KBaseObjectBasicValueColumnOffset ).IsNull() )
       
  1946 				{
       
  1947 				continue;
       
  1948 				}
       
  1949 
       
  1950 			const CMdsObjectDef::TMdsColumnOrder& column = aObjectDef.GetPropertyColumnL( i );
       
  1951 			const CMdsPropertyDef& property = column.iPropertyDef;
       
  1952 
       
  1953 			iWriteStream.WriteL( KMdsKeywordProperty );
       
  1954 			iWriteStream.WriteL( KExportMetadataSpace );
       
  1955 			Conv16To8( property.GetName(), iLine );
       
  1956 			iWriteStream.WriteL( iLine );
       
  1957 			iWriteStream.WriteL( KExportMetadataSpace );
       
  1958 
       
  1959 			switch( property.GetSqlType() )
       
  1960 				{
       
  1961 				case EColumnBool:
       
  1962 					{
       
  1963 					TBool value;
       
  1964 					queryResult.Column( i + KBaseObjectBasicValueColumnOffset ).Get( value );
       
  1965 					iLine.Num( value );
       
  1966 					break;
       
  1967 					}
       
  1968 				case EColumnInt32:
       
  1969 					{
       
  1970 					TInt32 value;
       
  1971 					queryResult.Column( i + KBaseObjectBasicValueColumnOffset ).Get( value );
       
  1972 					iLine.Num( value );
       
  1973 					break;
       
  1974 					}
       
  1975 				case EColumnUint32:
       
  1976 					{
       
  1977 					TUint32 value;
       
  1978 					queryResult.Column( i + KBaseObjectBasicValueColumnOffset ).Get( value );
       
  1979 					iLine.Num( value );
       
  1980 					break;
       
  1981 					}
       
  1982 				case EColumnInt64:
       
  1983 					{
       
  1984 					TInt64 value;
       
  1985 					queryResult.Column( i + KBaseObjectBasicValueColumnOffset ).Get( value );
       
  1986 					iLine.Num( value );
       
  1987 					break;
       
  1988 					}
       
  1989 				case EColumnTime:
       
  1990 					{
       
  1991 					TTime value;
       
  1992 					queryResult.Column( i + KBaseObjectBasicValueColumnOffset ).Get( value );
       
  1993 					TDateTime time = value.DateTime();
       
  1994 					iLine.Format( KExportMetadataTimeFormat, time.Year(), time.Month()+1, time.Day()+1, time.Hour(), time.Minute(), time.Second() );
       
  1995 					break;
       
  1996 					}
       
  1997 				case EColumnReal32:
       
  1998 					{
       
  1999 					TReal32 value;
       
  2000 					queryResult.Column( i + KBaseObjectBasicValueColumnOffset ).Get( value );
       
  2001 					TRealFormat realFormat;
       
  2002                 	realFormat.iType |= KAllowThreeDigitExp | KDoNotUseTriads;
       
  2003                 	realFormat.iPoint = TChar('.');
       
  2004 					iLine.Num( value, realFormat );
       
  2005 					break;
       
  2006 					}
       
  2007 				case EColumnReal64:
       
  2008 					{
       
  2009 					TReal64 value;
       
  2010 					queryResult.Column( i + KBaseObjectBasicValueColumnOffset ).Get( value );
       
  2011 					TRealFormat realFormat;
       
  2012                 	realFormat.iType |= KAllowThreeDigitExp | KDoNotUseTriads;
       
  2013                 	realFormat.iPoint = TChar('.');
       
  2014 					iLine.Num( value, realFormat );
       
  2015 					break;
       
  2016 					}
       
  2017 				case EColumnDes16:
       
  2018 					{
       
  2019 					TPtrC16 value;
       
  2020 					queryResult.Column( i + KBaseObjectBasicValueColumnOffset ).Get( value );
       
  2021 					Conv16To8( value, iLine );
       
  2022 					iLine.Insert( 0, KExportMetadataQuotationMark );
       
  2023 					iLine.Append( KExportMetadataQuotationMark );
       
  2024 					break;
       
  2025 					}
       
  2026 				default:
       
  2027 					{
       
  2028 					User::Leave( KErrCorrupt );
       
  2029 					}
       
  2030 				}
       
  2031 			iWriteStream.WriteL( iLine );
       
  2032 
       
  2033 			iWriteStream.WriteL( KExportMetadataNewLine );
       
  2034 			}
       
  2035 
       
  2036 		// restore query
       
  2037 		queryResult.AppendColumnTypesL( aDataRow );
       
  2038 
       
  2039 		// writing freetext
       
  2040 		// get freetext
       
  2041 		aFreeTextRow.Column( 0 ).Set( objectId );
       
  2042 		connection.ExecuteQueryL( aFreeTextClause.ConstBufferL(), freeTextQuery, aFreeTextRow );
       
  2043 		TBool freeTextPreamble = EFalse;
       
  2044 		TInt lineSize = KMdsKeywordFreeText().Size() + 3; // space + line ending
       
  2045 		while( connection.NextRowL( freeTextQuery, textRow ) )
       
  2046 			{
       
  2047 			// get result from query
       
  2048 			if ( !freeTextPreamble )
       
  2049 				{
       
  2050 				iWriteStream.WriteL( KMdsKeywordFreeText );
       
  2051 				iWriteStream.WriteL( KExportMetadataSpace );
       
  2052 				freeTextPreamble = ETrue;
       
  2053 				}
       
  2054 			TPtrC16 word;
       
  2055 			textRow.Column( 0 ).Get( word );
       
  2056 			Conv16To8( word, iLine );
       
  2057 			iLine.Insert( 0, KExportMetadataQuotationMark );
       
  2058 			iLine.Append( KExportMetadataQuotationMark );
       
  2059 			lineSize += iLine.Length() + 2;
       
  2060 			if ( lineSize >= KMdsMaxLineLenght )
       
  2061 				{
       
  2062 				iWriteStream.WriteL( KExportMetadataNewLine );
       
  2063 				iWriteStream.WriteL( KMdsKeywordFreeText );
       
  2064 				iWriteStream.WriteL( KExportMetadataSpace );
       
  2065 				lineSize = KMdsKeywordFreeText().Size() + 3; // space + line ending
       
  2066 				}
       
  2067 			iWriteStream.WriteL( iLine );
       
  2068 			iWriteStream.WriteL( KExportMetadataSpace );
       
  2069 			textRow.Free();
       
  2070 			}
       
  2071 		if ( freeTextPreamble )
       
  2072 			{
       
  2073 			iWriteStream.WriteL( KExportMetadataNewLine );
       
  2074 			}
       
  2075 
       
  2076 		iWriteStream.WriteL( KExportMetadataNewLine );
       
  2077 		}
       
  2078 
       
  2079     CleanupStack::PopAndDestroy( 5, &confidentialFlagRow ); // queryResult, textRow, freeTextQuery, query, confidentialFlagRow
       
  2080 	}
       
  2081 
       
  2082 
       
  2083 void CMdsImportExport::ExportMetadataMakeSqlRelationClauseL( const CMdsNamespaceDef& aNamespaceDef,
       
  2084 									  		  				CMdsClauseBuffer& aClause, RRowData& aDataRow )
       
  2085 	{
       
  2086 	_LIT( KExportMetadataRelationQuery, "SELECT LO.URI,RO.URI,Parameter FROM Relations%u AS R,Object%u AS LO ON LeftObjectId=LO.ObjectId JOIN Object%u AS RO ON RightObjectId=RO.ObjectId WHERE RelationDefId=? AND NOT R.Flags&? AND NOT R.Flags&?;" );
       
  2087 
       
  2088 	aClause.BufferL().Zero(); // reset clause
       
  2089 	aClause.ReserveSpaceL( KExportMetadataRelationQuery.iTypeLength + 30 );
       
  2090 	aClause.BufferL().Format( KExportMetadataRelationQuery, aNamespaceDef.GetId(), aNamespaceDef.GetId(), aNamespaceDef.GetId() );
       
  2091 
       
  2092 	aDataRow.Free(); // free and reset dataRow
       
  2093 	aDataRow.Reset();
       
  2094 	aDataRow.AppendL( TColumn( TDefId(0) ) ); // relationDefId
       
  2095 	aDataRow.AppendL( TColumn( EMdERelationFlagDeleted ) );
       
  2096 	aDataRow.AppendL( TColumn( EMdERelationFlagNotPresent ) );
       
  2097 	}
       
  2098 
       
  2099 void CMdsImportExport::ExportMetadataWriteRelationInfoL( const CMdsNamespaceDef& aNamespaceDef, const CMdsRelationDef& aRelationDef,
       
  2100 										  				CMdsClauseBuffer& aClause, RRowData& aDataRow )
       
  2101 	{
       
  2102 	CMdSSqLiteConnection& connection = MMdSDbConnectionPool::GetDefaultDBL();
       
  2103 
       
  2104 	RRowData resultRow;
       
  2105 	CleanupClosePushL( resultRow );
       
  2106 	resultRow.AppendL( TColumn( EColumnDes16 ) ); // LeftObjectIds URI
       
  2107 	resultRow.AppendL( TColumn( EColumnDes16 ) ); // RightObjectIds URI
       
  2108 	resultRow.AppendL( TColumn( TInt32(0) ) );  // RelationParameter
       
  2109 
       
  2110 	RMdsStatement query;
       
  2111 	CleanupClosePushL( query );
       
  2112 	RRowData resultRowGet;
       
  2113 	CleanupClosePushL( resultRowGet );
       
  2114 	resultRowGet.AppendColumnTypesL( resultRow );
       
  2115 
       
  2116 	aDataRow.Column( 0 ).Set( aRelationDef.GetId() );
       
  2117 	connection.ExecuteQueryL( aClause.ConstBufferL(), query, aDataRow );
       
  2118 	while( connection.NextRowL( query, resultRowGet ) )
       
  2119 		{
       
  2120 		iWriteStream.WriteL( KMdsKeywordRelation );
       
  2121 		iWriteStream.WriteL( KExportMetadataSpace );
       
  2122 		Conv16To8( aNamespaceDef.GetName(), iLine );
       
  2123 		iWriteStream.WriteL( iLine );
       
  2124 		iWriteStream.WriteL( KExportMetadataSpace );
       
  2125 		Conv16To8( aRelationDef.GetName(), iLine );
       
  2126 		iWriteStream.WriteL( iLine );
       
  2127 		iWriteStream.WriteL( KExportMetadataSpace );
       
  2128 
       
  2129 		TPtrC16 uri;
       
  2130 		resultRowGet.Column( 0 ).Get( uri );
       
  2131 		Conv16To8( uri, iLine );
       
  2132 		iLine.Insert( 0, KExportMetadataQuotationMark );
       
  2133 		iLine.Append( KExportMetadataQuotationMark );
       
  2134 		iWriteStream.WriteL( iLine );
       
  2135 		iWriteStream.WriteL( KExportMetadataSpace );
       
  2136 
       
  2137 		resultRowGet.Column( 1 ).Get( uri );
       
  2138 		Conv16To8( uri, iLine );
       
  2139 		iLine.Insert( 0, KExportMetadataQuotationMark );
       
  2140 		iLine.Append( KExportMetadataQuotationMark );
       
  2141 		iWriteStream.WriteL( iLine );
       
  2142 		iWriteStream.WriteL( KExportMetadataSpace );
       
  2143 
       
  2144 		TInt32 relationParameter;
       
  2145 		resultRowGet.Column( 2 ).Get( relationParameter );
       
  2146 		iLine.Num( relationParameter );
       
  2147 		iWriteStream.WriteL( iLine );
       
  2148 		iWriteStream.WriteL( KExportMetadataNewLine );
       
  2149 		
       
  2150 		resultRowGet.AppendColumnTypesL( resultRow );
       
  2151 		}
       
  2152 
       
  2153 	CleanupStack::PopAndDestroy( 3, &resultRow ); // query, resultRowGet, resultRow
       
  2154 	}
       
  2155 
       
  2156 
       
  2157 void CMdsImportExport::ExportMetadataMakeSqlEventClauseL( const CMdsNamespaceDef& aNamespaceDef,
       
  2158 									  	   				 CMdsClauseBuffer& aClause, RRowData& aDataRow )
       
  2159 	{
       
  2160 	_LIT( KExportMetadataEventQuery, "SELECT URI,Source,Participant,Timestamp FROM Event%u AS EL,Object%u AS O ON EL.ObjectId=O.ObjectId WHERE EventDefId=?;" );
       
  2161 
       
  2162 	aClause.BufferL().Zero(); // reset clause
       
  2163 	aClause.ReserveSpaceL( KExportMetadataEventQuery.iTypeLength + 20 );
       
  2164 	aClause.BufferL().Format( KExportMetadataEventQuery, aNamespaceDef.GetId(), aNamespaceDef.GetId() );
       
  2165 
       
  2166 	aDataRow.Free(); // free and reset dataRow
       
  2167 	aDataRow.Reset();
       
  2168 	aDataRow.AppendL( TColumn( TDefId(0) ) ); // eventDefId
       
  2169 	}
       
  2170 
       
  2171 void CMdsImportExport::ExportMetadataWriteEventInfoL( const CMdsNamespaceDef& aNamespaceDef, const CMdsEventDef& aEventDef,
       
  2172 													  CMdsClauseBuffer& aClause, RRowData& aDataRow )
       
  2173 	{
       
  2174 	CMdSSqLiteConnection& connection = MMdSDbConnectionPool::GetDefaultDBL();
       
  2175 
       
  2176 	RRowData resultRow;
       
  2177 	CleanupClosePushL( resultRow );
       
  2178 	resultRow.AppendL( TColumn( EColumnDes16 ) ); // target
       
  2179 	resultRow.AppendL( TColumn( EColumnDes16 ) ); // source
       
  2180 	resultRow.AppendL( TColumn( EColumnDes16 ) ); // participant
       
  2181 	resultRow.AppendL( TColumn( TTime(0) ) );     // time
       
  2182 
       
  2183 	RMdsStatement query;
       
  2184 	CleanupClosePushL( query );
       
  2185 
       
  2186 	RRowData resultRowGet;
       
  2187 	CleanupClosePushL( resultRowGet );
       
  2188 	resultRowGet.AppendColumnTypesL( resultRow );
       
  2189 
       
  2190 	aDataRow.Column( 0 ).Set( aEventDef.GetId() );
       
  2191 	connection.ExecuteQueryL( aClause.ConstBufferL(), query, aDataRow );
       
  2192 	while( connection.NextRowL( query, resultRowGet ) )
       
  2193 		{
       
  2194 		iWriteStream.WriteL( KMdsKeywordEvent );
       
  2195 		iWriteStream.WriteL( KExportMetadataSpace );
       
  2196 		Conv16To8( aNamespaceDef.GetName(), iLine );
       
  2197 		iWriteStream.WriteL( iLine );
       
  2198 		iWriteStream.WriteL( KExportMetadataSpace );
       
  2199 		Conv16To8( aEventDef.GetName(), iLine );
       
  2200 		iWriteStream.WriteL( iLine );
       
  2201 		iWriteStream.WriteL( KExportMetadataSpace );
       
  2202 
       
  2203 		TPtrC16 word;
       
  2204 		// target
       
  2205 		resultRowGet.Column( 0 ).Get( word );
       
  2206 		Conv16To8( word, iLine );
       
  2207 		iLine.Insert( 0, KExportMetadataQuotationMark );
       
  2208 		iLine.Append( KExportMetadataQuotationMark );
       
  2209 		iWriteStream.WriteL( iLine );
       
  2210 		iWriteStream.WriteL( KExportMetadataSpace );
       
  2211 
       
  2212 		// source
       
  2213 		resultRowGet.Column( 1 ).Get( word );
       
  2214 		Conv16To8( word, iLine );
       
  2215 		iLine.Insert( 0, KExportMetadataQuotationMark );
       
  2216 		iLine.Append( KExportMetadataQuotationMark );
       
  2217 		iWriteStream.WriteL( iLine );
       
  2218 		iWriteStream.WriteL( KExportMetadataSpace );
       
  2219 
       
  2220 		// participant
       
  2221 		resultRowGet.Column( 2 ).Get( word );
       
  2222 		Conv16To8( word, iLine );
       
  2223 		iLine.Insert( 0, KExportMetadataQuotationMark );
       
  2224 		iLine.Append( KExportMetadataQuotationMark );
       
  2225 		iWriteStream.WriteL( iLine );
       
  2226 		iWriteStream.WriteL( KExportMetadataSpace );
       
  2227 
       
  2228 		TTime value;
       
  2229 		resultRowGet.Column( 3 ).Get( value );
       
  2230 		TDateTime time = value.DateTime();
       
  2231 		iLine.Format( KExportMetadataTimeFormat, time.Year(), time.Month()+1, time.Day()+1, time.Hour(), time.Minute(), time.Second() );
       
  2232 		iWriteStream.WriteL( iLine );
       
  2233 		iWriteStream.WriteL( KExportMetadataNewLine );
       
  2234 		
       
  2235 		resultRowGet.AppendColumnTypesL( resultRow );
       
  2236 		}
       
  2237 
       
  2238 	CleanupStack::PopAndDestroy( 3, &resultRow ); // query, resultRowGet, resultRow
       
  2239 	}
       
  2240 
       
  2241 
       
  2242 // ---------------------------------------------------------------------------
       
  2243 // ---------------------------------------------------------------------------
       
  2244 //                         IMPORT HELPER FUNCTIONS
       
  2245 // ---------------------------------------------------------------------------
       
  2246 // ---------------------------------------------------------------------------
       
  2247 
       
  2248 
       
  2249 // ---------------------------------------------------------------------------
       
  2250 // ImportText imports text which may be quoted and escaped
       
  2251 // ------------------------------------------------
       
  2252 //
       
  2253 TInt CMdsImportExport::ImportText( TDes16& aBuffer, TLex8& aParser )
       
  2254     {
       
  2255     TPtrC8 token;
       
  2256     token.Set( aParser.NextToken() );
       
  2257 
       
  2258 	if ( token.Length() == 0 || token.Length() >= aBuffer.MaxLength() )
       
  2259         {
       
  2260         return KErrCorrupt;
       
  2261         }
       
  2262 
       
  2263     /**
       
  2264     *	The string may be enclosed in quotes. Unfortunately the parser always stops at 
       
  2265     *	whitespace, so we must loop with the NextToken() until we find a token that ends with
       
  2266     * 	an unescaped quotation mark. The bit below will then mark everything inside the quotes 
       
  2267     *	as a single uninterrupted token.
       
  2268     */
       
  2269     if ( token[0] == '\"' )
       
  2270     	{
       
  2271     	TInt currentTokenLength(token.Length());
       
  2272     	TInt start = aParser.Offset() - currentTokenLength;
       
  2273     	TInt end = aParser.Offset();
       
  2274     	TBool forceContinue( EFalse );
       
  2275     	while( ETrue )
       
  2276     		{
       
  2277 			// if there is a closing quote in the token see if is escaped
       
  2278 			if ( currentTokenLength > 1 )
       
  2279 				{
       
  2280 				// First skip any escaped dollar signs in the string
       
  2281 				// to avoid a false match in case the string is something
       
  2282 				// like "foo$$"
       
  2283 				TInt loc = token.Find(_L8("$$"));
       
  2284 				while( loc != KErrNotFound )
       
  2285 					{
       
  2286 					token.Set(token.Mid(loc+2));
       
  2287 					loc = token.Find(_L8("$$"));
       
  2288 					}
       
  2289 				// Now the token contains only non-escaped dollars
       
  2290 				currentTokenLength = token.Length();
       
  2291 				if ( currentTokenLength > 2 && token.Right(2) == _L8("$\"") )
       
  2292 					{
       
  2293 					forceContinue = ETrue;
       
  2294 					}
       
  2295 				}
       
  2296 				
       
  2297 			if(token[currentTokenLength - 1] == '\"' && !forceContinue)
       
  2298 				{
       
  2299 				// The token contains a closing quote which is not escaped, 
       
  2300 				// leave loop because the string is finished
       
  2301 				break;
       
  2302 				}
       
  2303     		forceContinue = EFalse;
       
  2304     		token.Set(aParser.NextToken());
       
  2305     		currentTokenLength = token.Length();
       
  2306     		end = aParser.Offset();
       
  2307     		if ( currentTokenLength == 0 || currentTokenLength >= aBuffer.MaxLength() - (end-start) )
       
  2308 			    {
       
  2309 			    return KErrCorrupt;
       
  2310 			    }
       
  2311 	  		}
       
  2312 	  	// We have the complete token length now, set the TPtrC accordingly
       
  2313     	token.Set(iLine.Mid(start + 1, (end-start) - 2)); // skip the quotes
       
  2314     	TBuf8<256> fp(token);
       
  2315     	}
       
  2316     // The token now contains the full string
       
  2317    	Conv8To16( token, aBuffer );
       
  2318 
       
  2319    	return KErrNone;
       
  2320     }
       
  2321     
       
  2322 // ------------------------------------------------
       
  2323 // ImportUInt32
       
  2324 // ------------------------------------------------
       
  2325 //
       
  2326 TInt CMdsImportExport::ImportUInt32( TUint32& aValue, TLex8& aParser )
       
  2327     {
       
  2328     TLex8 tokenParser( aParser.NextToken() );
       
  2329     aParser.SkipSpace();
       
  2330     if ( tokenParser.Val( aValue, EDecimal ) != KErrNone )
       
  2331         {
       
  2332         _LIT( KError, "Expecting a numeric value" );
       
  2333         LogError( KError );
       
  2334         return KErrCorrupt;
       
  2335         }
       
  2336     return KErrNone;
       
  2337     }
       
  2338 
       
  2339 // ------------------------------------------------
       
  2340 // ImportMediaId
       
  2341 // ------------------------------------------------
       
  2342 //
       
  2343 TInt CMdsImportExport::ImportMediaId( TUint32& aValue, TLex8& aParser, TChar& aDriveLetter )
       
  2344     {
       
  2345     TLex8 tokenParser( aParser.NextToken() );
       
  2346     aParser.SkipSpace();
       
  2347     if ( tokenParser.Val( aValue, EDecimal ) != KErrNone )
       
  2348         {
       
  2349         _LIT( KError, "Expecting a numeric value" );
       
  2350         LogError( KError );
       
  2351         return KErrCorrupt;
       
  2352         }
       
  2353 
       
  2354     TInt error( KErrNone );
       
  2355     TInt driveNumber( -1 );
       
  2356     error = iFs.CharToDrive( aDriveLetter, driveNumber );
       
  2357 
       
  2358     if ( error != KErrNone )
       
  2359         {
       
  2360         return error;
       
  2361         }
       
  2362         
       
  2363     if( driveNumber != iLastDriveNumber )
       
  2364         {
       
  2365         error = iFs.Volume( iLastVolumeInfo, driveNumber );
       
  2366             
       
  2367         if ( error != KErrNone )
       
  2368             {
       
  2369             return error;
       
  2370             }     
       
  2371             
       
  2372        iLastDriveNumber = driveNumber;
       
  2373        }
       
  2374         
       
  2375     aValue = iLastVolumeInfo.iUniqueID;
       
  2376         
       
  2377     return KErrNone;
       
  2378     }
       
  2379 
       
  2380 // ------------------------------------------------
       
  2381 // ImportInt64
       
  2382 // ------------------------------------------------
       
  2383 //
       
  2384 TInt CMdsImportExport::ImportInt64( Int64& aValue, TLex8& aParser )
       
  2385     {
       
  2386     // due to symbian int64 parser error
       
  2387     // for now we will use ImportNum version
       
  2388     ImportNum( aValue, aParser );
       
  2389 
       
  2390     return KErrNone;
       
  2391     }
       
  2392 
       
  2393 // ------------------------------------------------
       
  2394 // ImportTime
       
  2395 // ------------------------------------------------
       
  2396 //
       
  2397 TInt CMdsImportExport::ImportTime( TTime& aValue, TLex8& aParser )
       
  2398     {
       
  2399     // format: YYYYMMDDhhmmss
       
  2400     TPtrC8 token( aParser.NextToken() );
       
  2401     if ( token.Length() != 14 )
       
  2402     	{
       
  2403     	_LIT( KError, "Expecting a time value" );
       
  2404         LogError( KError );
       
  2405     	return KErrCorrupt;
       
  2406     	}
       
  2407     	
       
  2408     TLex8 year_p( token.Mid( 0, 4 ) );
       
  2409     TLex8 month_p( token.Mid( 4, 2 ) );
       
  2410     TLex8 day_p( token.Mid( 6, 2 ) );
       
  2411     TLex8 hour_p( token.Mid( 8, 2 ) );
       
  2412     TLex8 minute_p( token.Mid( 10, 2 ) );
       
  2413     TLex8 second_p( token.Mid( 12, 2 ) );
       
  2414     TInt year;
       
  2415     TInt month;
       
  2416     TInt day;
       
  2417     TInt hour;
       
  2418     TInt minute;
       
  2419     TInt second;
       
  2420 
       
  2421     year_p.Val( year );
       
  2422     month_p.Val( month );
       
  2423     day_p.Val( day );
       
  2424     hour_p.Val( hour );
       
  2425     minute_p.Val( minute );
       
  2426     second_p.Val( second );
       
  2427 
       
  2428     TDateTime datetime;
       
  2429     const TInt error = datetime.Set( year, (TMonth)(month-1), day-1, hour,
       
  2430     							minute, second, 0 );
       
  2431     if ( error != KErrNone )
       
  2432     	{
       
  2433     	return error;
       
  2434     	}
       
  2435 
       
  2436     aValue = datetime;
       
  2437     return KErrNone;
       
  2438     }
       
  2439 
       
  2440 // ------------------------------------------------
       
  2441 // Conv8To16
       
  2442 // ------------------------------------------------
       
  2443 //
       
  2444 TDesC16& CMdsImportExport::Conv8To16( const TDesC8& aUtf8, TDes16& aBuffer )
       
  2445     {
       
  2446     TInt conversionState = CCnvCharacterSetConverter::KStateDefault;
       
  2447     iConverter->ConvertToUnicode( aBuffer, aUtf8, conversionState );
       
  2448     return aBuffer;
       
  2449     }
       
  2450 
       
  2451 // ------------------------------------------------
       
  2452 // Conv16To8
       
  2453 // ------------------------------------------------
       
  2454 //
       
  2455 TDesC8& CMdsImportExport::Conv16To8( const TDesC16& aUnicode, TDes8& aBuffer )
       
  2456     {
       
  2457     iConverter->ConvertFromUnicode( aBuffer, aUnicode );
       
  2458     return aBuffer;
       
  2459     }
       
  2460 
       
  2461 // ------------------------------------------------
       
  2462 // LogError
       
  2463 // ------------------------------------------------
       
  2464 //
       
  2465 void CMdsImportExport::LogError( const TDesC& aMessage )
       
  2466     {
       
  2467     _LIT( KParseError, "Parse error: %S" );
       
  2468     _LIT( KCurrentFile, "Current file: %S" );
       
  2469     _LIT( KCurrentLineNum, "Current line number: %d" );
       
  2470     _LIT( KCurrentLine, "Current line: %S" );
       
  2471     iLog.WriteFormat( KParseError, &aMessage );
       
  2472     iLog.WriteFormat( KCurrentFile, &iFileName );
       
  2473     iLog.WriteFormat( KCurrentLineNum, iLineNumber );
       
  2474     TBuf16<KMdsMaxLogLineLenght> line16;
       
  2475     Conv8To16( iLine, line16 );
       
  2476     iLog.WriteFormat( KCurrentLine, &line16 );
       
  2477     }
       
  2478 
       
  2479 
       
  2480 // ------------------------------------------------
       
  2481 // CheckForConstant
       
  2482 // ------------------------------------------------
       
  2483 //
       
  2484 TInt CMdsImportExport::CheckForConstant( TLex8& aParser )
       
  2485 	{
       
  2486 	TInt ret = KErrNone;
       
  2487 	TBuf<32> buf;
       
  2488 	aParser.Mark();
       
  2489 	ret = ImportText( buf, aParser );
       
  2490 	if ( ret < KErrNone )
       
  2491 		{
       
  2492 		aParser.UnGetToMark();
       
  2493 		return ret;
       
  2494 		}
       
  2495 	if ( buf.CompareF(KMdsKeywordMinValue) == 0 )
       
  2496 		{
       
  2497 		return KPropertyMinValue;
       
  2498 		}
       
  2499 	else if ( buf.CompareF(KMdsKeywordMaxValue) == 0 )
       
  2500 		{
       
  2501 		return KPropertyMaxValue;
       
  2502 		}
       
  2503 	else if ( buf.CompareF(KMdsKeywordDefValue) == 0 )
       
  2504 		{
       
  2505 		return KPropertyDefValue;
       
  2506 		}
       
  2507 	aParser.UnGetToMark();
       
  2508 	return KErrNotFound;
       
  2509 	}