metadataengine/server/src/mdsnamespacedef.cpp
changeset 0 c53acadfccc6
child 15 3cebc1a84278
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/metadataengine/server/src/mdsnamespacedef.cpp	Mon Jan 18 20:34:07 2010 +0200
@@ -0,0 +1,619 @@
+/*
+* Copyright (c) 2005-2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  Class to hold description about one namespace and every object
+*                it holds.
+*
+*/
+
+#include "mdsnamespacedef.h"
+
+#include "mdcdef.h"
+#include "mdsobjectdef.h"
+#include "mdsrelationdef.h"
+#include "mdseventdef.h"
+#include "mdssqliteconnection.h"
+#include "mdsdbconnectionpool.h"
+#include "mdcserializationbuffer.h"
+#include "mdsschema.h"
+#include "mdsindexer.h"
+#include "mdeinternalerror.h"
+
+#include <uriutils.h>
+
+/**
+ * NewLC
+ */
+CMdsNamespaceDef* CMdsNamespaceDef::NewLC( TDefId aId,
+    const TDesC& aName, TBool aReadOnly, TUint32 aVendorId )
+	{
+	CMdsNamespaceDef* ret = new( ELeave ) CMdsNamespaceDef( aId, aReadOnly, aVendorId );
+	CleanupStack::PushL( ret );
+	ret->ConstructL( aName );
+	return ret;
+	}
+	
+/**
+ * NewL
+ */
+CMdsNamespaceDef* CMdsNamespaceDef::NewL( TDefId aId, const TDesC& aName,
+    TBool aReadOnly, TUint32 aVendorId )
+	{
+	CMdsNamespaceDef* ret = CMdsNamespaceDef::NewLC( aId, aName, aReadOnly, aVendorId );
+	CleanupStack::Pop( ret );
+	return ret;
+	}
+
+/**
+ * ConstructL
+ */
+void CMdsNamespaceDef::ConstructL( const TDesC& aName )
+	{
+	// validate the URI of namespace
+	TBool invalidChars = UriUtils::HasInvalidChars( aName );
+	if( invalidChars )
+		{
+		User::Leave( KErrGeneral );
+		}
+
+	CMdsItemDef::ConstructL( aName );
+	}
+
+/**
+ * Destructor
+ */
+CMdsNamespaceDef::~CMdsNamespaceDef()
+	{
+	// deleting objects
+	iObjectDefs.ResetAndDestroy();
+	iObjectDefs.Close();
+
+	// deleting relations...
+	iRelationDefs.ResetAndDestroy();
+   	iRelationDefs.Close();
+
+   	// deleting events...
+    iEventDefs.ResetAndDestroy();
+   	iEventDefs.Close();
+	}
+	
+/**
+ * AddObjectDefL
+ */
+CMdsObjectDef* CMdsNamespaceDef::AddObjectDefL( const TDesC& aObjectName, const TDesC& aParentName,
+                                                CMdsSchema* aDefaultSchema )
+	{
+	if ( GetObjectDef( aObjectName ) )
+		{
+		// duplicate object
+		User::Leave( KErrAlreadyExists );
+		}
+	CMdsObjectDef* parent = GetObjectDef( aParentName );
+	if ( !parent )
+		{
+		/* testing */
+		// found namespace in default schema
+		if ( aDefaultSchema )
+			{
+			CMdsNamespaceDef* namespaceDef = aDefaultSchema->GetNamespace( GetName() );
+			if ( !namespaceDef )
+				{
+				User::Leave( KErrMdEUnknownNamespaceDef );
+				}
+			parent = namespaceDef->GetObjectDef( aParentName );
+			}
+		if( !parent )
+			{
+			User::Leave( KErrNotFound );
+			}
+		}
+	CMdsObjectDef* object = CMdsObjectDef::NewLC( aObjectName, parent );
+	iObjectDefs.AppendL( object );
+	CleanupStack::Pop( object );
+	return object;
+	}
+
+/**
+ * AddObjectDefL (private - add from DB)
+ */
+void CMdsNamespaceDef::AddObjectDefL( TDefId aId, TDefId aParentId, TInt aFlags, const TDesC& aName )
+	{
+	const CMdsObjectDef* parent = GetObjectByIdL( aParentId );
+	if ( !parent )
+		{
+		User::Leave( KErrNotFound );
+		}
+	CMdsObjectDef* object = CMdsObjectDef::NewLC( aName, parent );
+	object->SetFlags( (CMdsObjectDef::TObjectDefFlags)aFlags );
+	iObjectDefs.AppendL( object );
+	object->SetId(aId);
+	object->SetStoredInDB();
+	CleanupStack::Pop( object );
+	}
+
+/**
+ * FindObjectDefParent
+ */
+CMdsObjectDef* CMdsNamespaceDef::GetObjectDef( const TDesC& aObjectName ) const
+	{
+	if ( iBaseObject->GetName().Compare( aObjectName ) == 0 )
+		{
+		return iBaseObject;
+		}
+
+	const TInt count = iObjectDefs.Count();
+	
+	for ( TInt i = 0; i < count; ++i )
+		{
+		if( iObjectDefs[i]->GetName().Compare( aObjectName ) == 0 )
+			{
+			return iObjectDefs[i];
+			}
+		}
+	return NULL;
+	}
+
+void CMdsNamespaceDef::AddRelationDefL( const TDesC& aRelationName )
+	{
+	if ( GetRelationDef( aRelationName ) )
+		{
+		User::Leave( KErrAlreadyExists );
+		}
+	CMdsRelationDef* relation = CMdsRelationDef::NewLC( aRelationName );
+	iRelationDefs.AppendL( relation );
+	CleanupStack::Pop( relation );
+	}
+
+
+void CMdsNamespaceDef::AddRelationDefL( TDefId aId, const TDesC& aRelationName )
+	{
+	CMdsRelationDef* relation = CMdsRelationDef::NewLC( aRelationName );
+	relation->SetId(aId);
+	iRelationDefs.AppendL( relation );
+	relation->SetStoredInDB();
+	CleanupStack::Pop( relation );
+	}
+
+
+CMdsRelationDef* CMdsNamespaceDef::GetRelationDef( const TDesC& aRelationName ) const
+	{
+	const TInt count = iRelationDefs.Count();
+	
+	for ( TInt i = 0; i < count; ++i )
+		{
+		if ( iRelationDefs[i]->GetName().Compare( aRelationName ) == 0 )
+			{
+			return iRelationDefs[i];
+			}
+		}
+	return NULL;
+	}
+
+void CMdsNamespaceDef::AddEventDefL( const TDesC& aEventName, TInt32 aPriority )
+	{
+	if ( GetEventDef( aEventName ) )
+		{
+		User::Leave( KErrAlreadyExists );
+		}
+	CMdsEventDef* event = CMdsEventDef::NewLC( aEventName, aPriority );
+	iEventDefs.AppendL( event );
+	CleanupStack::Pop( event );
+	}
+
+void CMdsNamespaceDef::AddEventDefL( TDefId aId, const TDesC& aEventName, TInt32 aPriority )
+	{
+	CMdsEventDef* event = CMdsEventDef::NewLC( aEventName, aPriority );
+	event->SetId(aId);
+	iEventDefs.AppendL( event );
+	event->SetStoredInDB();
+	CleanupStack::Pop( event );
+	}
+
+CMdsEventDef* CMdsNamespaceDef::GetEventDef( const TDesC& aEventName ) const
+	{
+	const TInt count = iEventDefs.Count();
+	
+	for ( TInt i = 0; i < count; ++i )
+		{
+		if ( iEventDefs[i]->GetName().Compare( aEventName ) == 0 )
+			{
+			return iEventDefs[i];
+			}
+		}
+	return NULL;
+	}
+
+const CMdsObjectDef* CMdsNamespaceDef::GetObjectByIdL( TDefId aId ) const
+	{
+	if ( aId == KBaseObjectDefId ) // BaseObject (hardcoded)
+		{
+		return iBaseObject;
+		}
+	
+	const TInt count = iObjectDefs.Count();
+	
+	for ( TInt i = 0; i < count; ++i )
+		{
+		if( iObjectDefs[i]->GetId() == aId )
+			{
+			return iObjectDefs[i];
+			}
+		}
+	return NULL;
+	}
+
+const CMdsEventDef* CMdsNamespaceDef::GetEventByIdL( TDefId aId ) const
+	{
+	const TInt count = iEventDefs.Count();
+	
+	for ( TInt i = 0; i < count; ++i )
+		{
+		if( iEventDefs[i]->GetId() == aId )
+			{
+			return iEventDefs[i];
+			}
+		}
+	return NULL;
+	}
+
+const CMdsRelationDef* CMdsNamespaceDef::GetRelationByIdL( TDefId aId ) const
+	{
+	const TInt count = iRelationDefs.Count();
+	
+	for ( TInt i = 0; i < count; ++i )
+		{
+		if( iRelationDefs[i]->GetId() == aId )
+			{
+			return iRelationDefs[i];
+			}
+		}
+	return NULL;
+	}
+
+void CMdsNamespaceDef::StoreToDBL( TBool aStoreOnlyNamespace )
+	{
+	_LIT( KMdsSqlClauseAddNamespaceDef, "INSERT INTO NamespaceDef(ReadOnly,VendorId,Name) Values(?,?,?);" );
+    RRowData rowData;
+    CleanupClosePushL( rowData );
+
+	if ( !GetStoredInDB() )
+		{
+		rowData.AppendL( TColumn( GetReadOnly() ) );
+		rowData.AppendL( TColumn( iVendorId ) );
+		rowData.AppendL( TColumn( GetName().AllocL() ) );
+
+		TDefId id = KNoDefId;
+		id = MMdSIndexer::ExecuteAndGetIndexL(KMdsSqlClauseAddNamespaceDef,rowData);
+		SetId( id );
+
+		SetStoredInDB();
+		}
+	
+	if (aStoreOnlyNamespace)
+		{
+		CleanupStack::PopAndDestroy( &rowData );
+		return;
+		}
+	
+	const TInt objectDefCount = iObjectDefs.Count();
+	
+	// add objectDef to DB
+	for( TInt i = 0; i < objectDefCount; ++i )
+		{
+		iObjectDefs[i]->StoreToDBL( GetId() );
+		}
+	
+	const TInt eventDefCount = iEventDefs.Count();
+	
+	// add relationDef to DB
+	for( TInt i = 0; i < eventDefCount; ++i )
+		{
+		iEventDefs[i]->StoreToDBL( GetId() );
+		}
+	
+	const TInt relationDefCount = iRelationDefs.Count();
+	
+	// add eventDef to DB
+	for( TInt i = 0; i < relationDefCount; ++i )
+		{
+		iRelationDefs[i]->StoreToDBL( GetId() );
+		}
+
+	CleanupStack::PopAndDestroy( &rowData );
+	}
+	
+
+void CMdsNamespaceDef::MergeObjectsL( CMdsNamespaceDef* aNamespace, const TBool& aDryRun )
+	{
+	const TInt count = aNamespace->iObjectDefs.Count();	
+	
+	for ( TInt i = 0; i < count; ++i )
+		{
+		CMdsObjectDef* lObjectDef = GetObjectDef( aNamespace->iObjectDefs[i]->GetName() );
+		if( lObjectDef )
+			{
+			lObjectDef->MergeL( aNamespace->iObjectDefs[i], aDryRun );
+			}
+		else if ( !aDryRun )
+			{
+			iObjectDefs.AppendL( aNamespace->iObjectDefs[i] );
+			aNamespace->iObjectDefs[i]->SetAllNotStoredInDB();
+			aNamespace->iObjectDefs[i] = NULL;
+			}
+		}
+	}
+	
+void CMdsNamespaceDef::MergeRelationsL( CMdsNamespaceDef* aNamespace, const TBool& aDryRun )
+	{
+	const TInt count = aNamespace->iRelationDefs.Count();	
+	
+	for ( TInt i = 0; i < count; ++i )
+		{
+		CMdsRelationDef* relation = GetRelationDef( aNamespace->iRelationDefs[i]->GetName() );
+		if ( relation )
+			{
+			if ( *aNamespace->iRelationDefs[i] != *relation )
+				{
+				User::Leave( KErrAlreadyExists );
+				}
+			}
+		else if ( !aDryRun )
+			{
+			iRelationDefs.AppendL( aNamespace->iRelationDefs[i] );
+			aNamespace->iRelationDefs[i]->SetAllNotStoredInDB();
+			aNamespace->iRelationDefs[i] = NULL;
+			}
+		}
+	}
+	
+void CMdsNamespaceDef::MergeEventsL( CMdsNamespaceDef* aNamespace, const TBool& aDryRun )
+	{
+	const TInt count = aNamespace->iEventDefs.Count();
+	
+	for ( TInt i = 0; i < count; ++i )
+		{
+		CMdsEventDef* event = GetEventDef( aNamespace->iEventDefs[i]->GetName() );
+		if ( event )
+			{
+			if ( *aNamespace->iEventDefs[i] != *event )
+				{
+				User::Leave( KErrAlreadyExists );
+				}
+			}
+		else if ( !aDryRun )
+			{
+			iEventDefs.AppendL( aNamespace->iEventDefs[i] );
+			aNamespace->iEventDefs[i]->SetAllNotStoredInDB();
+			aNamespace->iEventDefs[i] = NULL;
+			}
+		}
+	}
+
+void CMdsNamespaceDef::ImportFromDBL()
+	{
+	_LIT( KMdsQueryGetObjectDefs, "SELECT ObjectDefId,ParentDefId,Flags,Name FROM ObjectDef WHERE NamespaceDefId=?;" );
+	_LIT( KMdsQueryGetRelationDefs, "SELECT RelationDefId,Name FROM RelationDef WHERE NamespaceDefId=?;" );
+	_LIT( KMdsQueryGetEventDefs, "SELECT EventDefId,Priority,Name FROM EventDef WHERE NamespaceDefId=?;" );
+	TDefId eId = KNoDefId;
+	TInt32 objectParent = 0;
+	TInt32 flags = 0;
+	TPtrC name;
+
+	// importing namespaces
+	RRowData namespaceNumber;
+	CleanupClosePushL( namespaceNumber );
+	namespaceNumber.AppendL( TColumn( GetId() ) );
+	RRowData getData;
+	CleanupClosePushL( getData );
+
+	CMdSSqLiteConnection& connection = MMdSDbConnectionPool::GetDefaultDBL();
+
+	// OBJECTS
+	RMdsStatement queryObject;
+	CleanupClosePushL( queryObject );
+	getData.AppendL( TColumn( eId ) );
+	getData.AppendL( TColumn( objectParent ) );
+	getData.AppendL( TColumn( flags ) );
+	getData.AppendL( TColumn( EColumnHBuf16 ) );
+	connection.ExecuteQueryL( KMdsQueryGetObjectDefs, queryObject, namespaceNumber );
+	while( connection.NextRowL( queryObject, getData ) )
+		{
+		getData.Column( 0 ).Get( eId );
+		getData.Column( 1 ).Get( objectParent );
+		getData.Column( 2 ).Get( flags );
+		getData.Column( 3 ).Get( name );
+		AddObjectDefL( eId, objectParent, flags, name );
+		getData.Column( 3 ).Free( );
+		}
+	CleanupStack::PopAndDestroy( &queryObject );
+	getData.Reset();
+	
+	// RELATIONS
+	RMdsStatement queryRelation;
+	CleanupClosePushL( queryRelation );
+	getData.AppendL( TColumn( eId ) );
+	getData.AppendL( TColumn( EColumnHBuf16 ) );
+	connection.ExecuteQueryL( KMdsQueryGetRelationDefs, queryRelation, namespaceNumber );
+	while( connection.NextRowL( queryRelation, getData ) )
+		{
+		getData.Column( 0 ).Get( eId );
+		getData.Column( 1 ).Get( name );
+		AddRelationDefL( eId, name );
+		getData.Column( 1 ).Free( );
+		}
+	CleanupStack::PopAndDestroy( &queryRelation );
+	getData.Reset();
+	
+	// EVENTS
+	TInt32 priority = 0;
+	RMdsStatement queryEvent;
+	CleanupClosePushL( queryEvent );
+	getData.AppendL( TColumn( eId ) );
+	getData.AppendL( TColumn( priority ) );
+	getData.AppendL( TColumn( EColumnHBuf16 ) );
+	connection.ExecuteQueryL( KMdsQueryGetEventDefs, queryEvent, namespaceNumber );
+	while( connection.NextRowL( queryEvent, getData ) )
+		{
+		getData.Column( 0 ).Get( eId );
+		getData.Column( 1 ).Get( priority );
+		getData.Column( 2 ).Get( name );
+		AddEventDefL( eId, name, priority );
+		getData.Column( 2 ).Free( );
+		}
+	CleanupStack::PopAndDestroy( &queryEvent );
+
+	CleanupStack::PopAndDestroy( 2, &namespaceNumber ); // getData, namespaceNumber
+	
+	const TInt count = iObjectDefs.Count();
+	
+	for ( TInt i = 0; i < count; ++i )
+		{
+		iObjectDefs[i]->ImportFromDBL();
+		}
+
+	// everything is ok, so set the flags
+	SetStoredInDB();
+	SetTableStoredInDB();
+	}
+	
+TUint32 CMdsNamespaceDef::RequiredBufferSize()
+	{
+	TUint32 bufferSize = sizeof(TMdCNamespaceDef) + CMdsItemDef::RequiredBufferSize();
+
+	const TInt objectDefsCount = iObjectDefs.Count();
+	bufferSize += (objectDefsCount + 1) * sizeof( TMdCObjectDef);
+	// base object def
+	bufferSize += iBaseObject->RequiredBufferSize();
+
+	// objectdefs
+	for ( TInt i = 0; i < objectDefsCount; ++i )
+		{
+		bufferSize += iObjectDefs[i]->RequiredBufferSize();
+		}
+
+	// eventdefs
+	const TInt eventDefsCount = iEventDefs.Count();
+	bufferSize += eventDefsCount * sizeof( TMdCEventDef );
+	for ( TInt i = 0; i < iEventDefs.Count(); ++i )
+		{
+		bufferSize += iEventDefs[i]->RequiredBufferSize();
+		}
+
+	// relationdefs
+	const TInt relationDefsCount = iRelationDefs.Count();
+	bufferSize += relationDefsCount * sizeof( TMdCRelationDef);
+	for ( TInt i = 0; i < iRelationDefs.Count(); ++i )
+		{
+		bufferSize += iRelationDefs[i]->RequiredBufferSize();
+		}
+
+	return bufferSize;
+	}
+
+TMdCOffset CMdsNamespaceDef::SerializeL(CMdCSerializationBuffer& aBuffer, TMdCOffset aFreeSpace)
+	{
+	const TMdCOffset namespaceDefOffset = aBuffer.Position();
+	TMdCNamespaceDef namespaceDef;
+	// get const data and store Name
+	namespaceDef.iDefId = GetId();
+	namespaceDef.iReadOnly = GetReadOnly();
+	namespaceDef.iName.iPtr.iCount = GetName().Length();
+	namespaceDef.iName.iPtr.iOffset = aFreeSpace;
+	aBuffer.PositionL( aFreeSpace );
+	aFreeSpace = CMdsItemDef::SerializeL( aBuffer );
+
+	// calculate necessary stuff for objectDefs
+	const TInt objectDefsCount = iObjectDefs.Count(); 
+	namespaceDef.iObjectDefs.iPtr.iCount = objectDefsCount + 1; // one extra for base object def
+	namespaceDef.iObjectDefs.iPtr.iOffset = aFreeSpace;
+
+	// create space for objectDefs
+	aFreeSpace += (objectDefsCount + 1) * sizeof(TMdCObjectDef);
+	
+	aBuffer.PositionL( namespaceDef.iObjectDefs.iPtr.iOffset ); // one extra for base object def
+	aFreeSpace = iBaseObject->SerializeL( aBuffer, aFreeSpace );
+
+	for ( TInt i = 0; i < objectDefsCount; ++i )
+		{
+		aBuffer.PositionL( namespaceDef.iObjectDefs.iPtr.iOffset
+				+ (i+1) * sizeof(TMdCObjectDef) ); // one extra for base object def
+		// write object
+		aFreeSpace = iObjectDefs[i]->SerializeL( aBuffer, aFreeSpace );
+		}
+
+	// calculate necessary stuff for eventDefs
+	const TInt eventDefsCount = iEventDefs.Count();
+	namespaceDef.iEventDefs.iPtr.iCount = eventDefsCount;
+	namespaceDef.iEventDefs.iPtr.iOffset = aFreeSpace;
+
+	// create space for eventDefs
+	aFreeSpace += eventDefsCount * sizeof(TMdCEventDef);
+
+	for ( TInt i = 0; i < eventDefsCount; ++i )
+		{
+		aBuffer.PositionL( namespaceDef.iEventDefs.iPtr.iOffset + i * sizeof(TMdCEventDef) );
+		// write event
+		aFreeSpace = iEventDefs[i]->SerializeL( aBuffer, aFreeSpace );
+		}
+
+	// calculate necessary stuff for relationDefs
+	const TInt relationDefsCount = iRelationDefs.Count();
+	namespaceDef.iRelationDefs.iPtr.iCount = relationDefsCount;
+	namespaceDef.iRelationDefs.iPtr.iOffset = aFreeSpace;
+
+	// create space for eventDefs
+	aFreeSpace += relationDefsCount * sizeof(TMdCRelationDef);
+
+	for ( TInt i = 0; i < relationDefsCount; ++i )
+		{
+		aBuffer.PositionL( namespaceDef.iRelationDefs.iPtr.iOffset + i * sizeof(TMdCRelationDef) );
+		// write relation
+		aFreeSpace = iRelationDefs[i]->SerializeL( aBuffer, aFreeSpace );
+		}
+	
+	// store namespaceDef itself
+	aBuffer.PositionL( namespaceDefOffset );
+	namespaceDef.SerializeL( aBuffer );
+
+	return aFreeSpace;
+	}
+	
+
+const CMdsPropertyDef* CMdsNamespaceDef::GetPropertyL( TDefId aId ) const
+	{
+	const CMdsPropertyDef* propertyDef = iBaseObject->GetPropertyByIdL( aId );
+
+	if ( propertyDef )
+		{
+		return propertyDef;
+		}
+
+	const TInt count = iObjectDefs.Count();
+	
+	for ( TInt i = 0; i < count; ++i )
+		{
+		const CMdsPropertyDef* objectPropertyDef = iObjectDefs[i]->GetPropertyByIdL( aId );
+		if ( objectPropertyDef )
+			{
+			return objectPropertyDef;
+			}
+		}
+
+	return NULL;
+	}
+
+/**
+ * Initialize static variables
+ */
+
+CMdsObjectDef* CMdsNamespaceDef::iBaseObject = NULL;