metadataengine/server/src/mdsobjectdef.cpp
changeset 0 c53acadfccc6
child 14 646a02f170b9
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/metadataengine/server/src/mdsobjectdef.cpp	Mon Jan 18 20:34:07 2010 +0200
@@ -0,0 +1,543 @@
+/*
+* Copyright (c) 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 object and it's properties
+*
+*/
+
+#include "mdsobjectdef.h"
+
+#include "mdcdef.h"
+#include "mdspropertydef.h"
+#include "mdsdbconnectionpool.h"
+#include "mdcserializationbuffer.h"
+#include "mdsindexer.h"
+#include "mdeinternalerror.h"
+
+/**
+ * NewLC
+ */
+CMdsObjectDef* CMdsObjectDef::NewLC(const TDesC& aName, const CMdsObjectDef* aParent )
+	{
+	CMdsObjectDef* ret = new( ELeave ) CMdsObjectDef( aParent );
+	CleanupStack::PushL( ret );
+	ret->ConstructL( aName );
+	return ret;
+	}
+	
+/**
+ * NewL
+ */
+CMdsObjectDef* CMdsObjectDef::NewL( const TDesC& aName, const CMdsObjectDef* aParent )
+	{
+	CMdsObjectDef* ret = CMdsObjectDef::NewLC( aName, aParent );
+	CleanupStack::Pop( ret );
+	return ret;
+	}
+
+/**
+ * default constructor
+ */
+inline CMdsObjectDef::CMdsObjectDef( const CMdsObjectDef* aParent )
+	: iParent ( aParent ), iFlags( EObjectDefFlagsNone ), iMandatoryPropertyCount( 0 )
+	{}
+
+/**
+ * ConstructL
+ */
+void CMdsObjectDef::ConstructL( const TDesC& aName )
+	{
+	// check that only allowed characters (A-Z, a-z) are used
+	CheckAllowerCharatersL( aName, EFalse );
+
+	CMdsItemDef::ConstructL( aName );
+	}
+
+/**
+ * Destructor
+ */
+CMdsObjectDef::~CMdsObjectDef()
+	{
+	// deleting properties
+	iPropertyDefs.ResetAndDestroy();
+	iPropertyDefs.Close();
+
+	iCol2Prop.Close();
+	}
+
+void CMdsObjectDef::AddPropertyL( const TDesC& aName, TPropertyType aType,
+								  const TMdCValueUnion& aMinAdd, const TMdCValueUnion& aMaxAdd,
+								  TBool aReadOnly, TBool aMandatory, TBool aIndexed )
+	{
+	CMdsPropertyDef* newProp = CommonAddPropertyL( aName, aType, aReadOnly, aMandatory, aIndexed );
+	if (!newProp)
+		{
+		User::Leave( KErrMdEUnknownPropertyDef );
+		}
+	switch (aType)
+		{									
+		case EPropertyUint32:
+		case EPropertyText:
+		case EPropertyBool:		
+			{									
+			newProp->AddMinMaxValueL(aMinAdd.iUint32,aMaxAdd.iUint32);
+			break;
+			}
+		case EPropertyInt32:
+			{	
+			newProp->AddMinMaxValueL(aMinAdd.iInt32,aMaxAdd.iInt32);
+			break;
+			}
+		case EPropertyInt64:
+		case EPropertyTime:
+			{	
+			newProp->AddMinMaxValueL(aMinAdd.iInt64,aMaxAdd.iInt64);
+			break;
+			}
+		case EPropertyReal64:
+			{									
+			newProp->AddMinMaxValueL(aMinAdd.iReal,aMaxAdd.iReal);
+			break;
+			}
+
+	    default:
+	    	{
+#ifdef _DEBUG
+            User::Panic( _L("MdSODAdd") , KErrMdEUnknownPropertyType );
+#endif		    	
+	    	User::Leave( KErrMdEUnknownPropertyType );
+	    	}
+		}
+	}
+	
+/**
+ * AddPropertyL
+ */
+void CMdsObjectDef::AddPropertyL( const TDesC& aName, TPropertyType aType,
+	                              TInt32 aMinAdd, TInt32 aMaxAdd,
+	                              TBool aReadOnly, TBool aMandatory, TBool aIndexed )
+	{
+	CMdsPropertyDef* newProp = CommonAddPropertyL( aName, aType, aReadOnly, aMandatory, aIndexed );
+	newProp->AddMinMaxValueL( aMinAdd, aMaxAdd );
+	}
+
+/**
+ * AddPropertyL
+ */
+void CMdsObjectDef::AddPropertyL( const TDesC& aName, TPropertyType aType,
+	                              TUint32 aMinAdd, TUint32 aMaxAdd,
+	                              TBool aReadOnly, TBool aMandatory, TBool aIndexed )
+	{
+	CMdsPropertyDef* newProp = CommonAddPropertyL( aName, aType, aReadOnly, aMandatory, aIndexed );
+	newProp->AddMinMaxValueL( aMinAdd, aMaxAdd );
+	}
+
+/**
+ * AddPropertyL
+ */
+void CMdsObjectDef::AddPropertyL( const TDesC& aName, TPropertyType aType,
+	                              const TInt64& aMinAdd, const TInt64& aMaxAdd,
+	                              TBool aReadOnly, TBool aMandatory, TBool aIndexed )
+	{
+	CMdsPropertyDef* newProp = CommonAddPropertyL( aName, aType, aReadOnly, aMandatory, aIndexed );
+	newProp->AddMinMaxValueL( aMinAdd, aMaxAdd );
+	}
+
+/**
+ * AddPropertyL
+ */
+void CMdsObjectDef::AddPropertyL( const TDesC& aName, TPropertyType aType,
+	                              const TReal& aMinAdd, const TReal& aMaxAdd,
+	                              TBool aReadOnly, TBool aMandatory, TBool aIndexed )
+	{
+	CMdsPropertyDef* newProp = CommonAddPropertyL( aName, aType, aReadOnly, aMandatory, aIndexed );
+	newProp->AddMinMaxValueL( aMinAdd, aMaxAdd );
+	}
+
+/**
+ * CommonAddPropertyL
+ */
+CMdsPropertyDef* CMdsObjectDef::CommonAddPropertyL( const TDesC& aName, TPropertyType aType,
+		TBool aReadOnly, TBool aMandatory, TBool aIndexed )
+	{
+	CMdsPropertyDef* propertyDef = CMdsPropertyDef::NewLC( aName, aType, aReadOnly, aMandatory,
+			aIndexed );
+	iPropertyDefs.AppendL( propertyDef );
+	CleanupStack::Pop( propertyDef );
+	return propertyDef;
+	}
+
+CMdsPropertyDef* CMdsObjectDef::CommonAddPropertyL( const TDesC& aName, TPropertyType aType,
+		TUint32 aFlags, TDefId aId )
+	{
+	CMdsPropertyDef* propertyDef = CMdsPropertyDef::NewLC( aName, aType, aFlags );
+	propertyDef->SetId(aId);
+	iPropertyDefs.AppendL( propertyDef );
+	CleanupStack::Pop( propertyDef );
+	return propertyDef;
+	}
+
+CMdsPropertyDef* CMdsObjectDef::GetProperty( TUint32 aIndex ) const
+	{
+	return iPropertyDefs[aIndex];
+	}
+
+CMdsPropertyDef* CMdsObjectDef::GetProperty( const TDesC& aName ) const
+	{
+	const TInt count = iPropertyDefs.Count();
+	
+	for ( TInt i = 0; i < count; ++i )
+		{
+		if( iPropertyDefs[i]->GetName().Compare( aName ) == 0 )
+			{
+			return iPropertyDefs[i];
+			}
+		}
+	if ( iParent )
+		{
+		return iParent->GetProperty( aName );
+		}
+	return NULL;
+	}
+
+
+const CMdsPropertyDef* CMdsObjectDef::GetPropertyByIdL( TDefId aId ) const
+	{
+	const TInt propertyDefCount = iPropertyDefs.Count();
+	for ( TInt i = 0; i < propertyDefCount; ++i )
+		{
+		const CMdsPropertyDef* propDef = iPropertyDefs[i];
+		if( propDef->GetId() == aId )
+			{
+			return propDef;
+			}
+		}
+	if ( iParent )
+		{
+		return iParent->GetPropertyByIdL( aId );
+		}
+	return NULL;
+	}
+
+
+void CMdsObjectDef::StoreToDBL( TDefId aNamespaceDefId )
+	{
+	_LIT( KMdsSqlClauseTriggerObjectDef, "CREATE TRIGGER Delete%S%u DELETE ON Object%u BEGIN DELETE FROM %S%u WHERE ObjectId=OLD.ObjectId; END;" );
+	_LIT( KMdsSqlClauseAddObjectDef, "INSERT INTO ObjectDef(NamespaceDefId, ParentDefId, Flags, Name) Values(?,?,?,?);" );
+
+	RRowData rowData;
+    CleanupClosePushL( rowData );
+
+	if ( !GetStoredInDB() )
+		{
+		rowData.AppendL( TColumn( aNamespaceDefId ) );
+		rowData.AppendL( TColumn( iParent ? iParent->GetId() : KNoDefId ) );
+		rowData.AppendL( TColumn( (TInt32)iFlags ) );
+		rowData.AppendL( TColumn( GetName().AllocL() ) );
+
+		TDefId id = MMdSIndexer::ExecuteAndGetIndexL( KMdsSqlClauseAddObjectDef,rowData );
+
+	    SetId( id );
+       	SetStoredInDB();
+
+    	if ( GetId() != KBaseObjectDefId )
+    		{
+	    	// Create trigger
+	        HBufC* sqlQueryCreateTrigger = HBufC::NewLC( KMdsSqlClauseTriggerObjectDef().Size() + ( KMaxUintValueLength * 3 )  + ( GetName().Length() * 2 ) );
+            TPtr sqlPtr = sqlQueryCreateTrigger->Des();
+            sqlPtr.Format( KMdsSqlClauseTriggerObjectDef, &GetName(), aNamespaceDefId, aNamespaceDefId, &GetName(), aNamespaceDefId );
+            RRowData rowDataDummy;
+		    CleanupClosePushL( rowDataDummy );
+		    CMdSSqLiteConnection& connection = MMdSDbConnectionPool::GetDefaultDBL();
+            connection.ExecuteL( *sqlQueryCreateTrigger, rowDataDummy );
+            CleanupStack::PopAndDestroy( 2, sqlQueryCreateTrigger ); // rowDataDummy, sqlQueryCreateTrigger
+    		}
+		}
+
+	// add propertyDef to DB
+	for( TInt counter = 0; counter < iPropertyDefs.Count(); ++counter )
+		{
+		iPropertyDefs[counter]->StoreToDBL( GetId() );
+		}
+	
+	CleanupStack::PopAndDestroy( &rowData );
+	}
+
+CMdsPropertyDef* CMdsObjectDef::FindProperty( const TDesC& aName ) const
+	{
+	const TInt count = iPropertyDefs.Count();
+	
+	for ( TInt i = 0; i < count; ++i )
+		{
+		if ( iPropertyDefs[i]->GetName().Compare( aName ) == 0 )
+			{
+			return iPropertyDefs[i];
+			}
+		}
+	return NULL;
+	}
+
+void CMdsObjectDef::MergeL( CMdsObjectDef* aObjectDef, const TBool& /*aDryRun*/ )
+	{
+	const TInt count = aObjectDef->iPropertyDefs.Count();
+	
+	for ( TInt i = 0; i < count; ++i )
+		{
+		CMdsPropertyDef* lPropertyDef = FindProperty( aObjectDef->iPropertyDefs[i]->GetName() );
+		if ( lPropertyDef )
+			{
+			if ( *lPropertyDef != *(aObjectDef->iPropertyDefs[i]) )
+				{
+				User::Leave( KErrAlreadyExists );
+				}
+			}
+		else
+			{
+			User::Leave( KErrAccessDenied );
+			}
+		}
+	}
+
+void CMdsObjectDef::AddPropertyL( const TDefId aId, TPropertyType aType, TUint32 aFlags,
+	                              const TDesC& aMinAdd, const TDesC& aMaxAdd, const TDesC& aName )
+	{
+	CMdsPropertyDef* prop = CommonAddPropertyL( aName, aType, aFlags, aId );
+	prop->SetStoredInDB();
+	switch( aType )
+		{
+		case EPropertyBool: case EPropertyInt8: case EPropertyUint8: case EPropertyInt16:
+        case EPropertyUint16: case EPropertyInt32: case EPropertyText:
+        	{
+        	TInt32 minValue = 0;
+            TInt32 maxValue = 0;
+        	TLex lex( aMinAdd );
+        	lex.Val( minValue );
+        	lex.Assign( aMaxAdd );
+        	lex.Val( maxValue );
+        	prop->AddMinMaxValueL( minValue, maxValue );
+        	break;
+        	}
+        case EPropertyUint32:
+        	{
+        	TUint32 minValue = 0;
+        	TUint32 maxValue = 0;
+        	TLex lex( aMinAdd );
+        	lex.Val( (TInt64&)minValue );
+        	lex.Assign( aMaxAdd );
+        	lex.Val( (TInt64&)maxValue );
+        	prop->AddMinMaxValueL( minValue, maxValue );
+        	break;
+        	}
+        case EPropertyInt64:
+        case EPropertyTime:
+        	{
+        	TInt64 minValue, maxValue;
+        	TLex lex( aMinAdd );
+        	lex.Val( minValue );
+        	lex.Assign( aMaxAdd );
+        	lex.Val( maxValue );
+        	prop->AddMinMaxValueL( minValue, maxValue );
+        	break;
+        	}
+        case EPropertyReal32:
+        case EPropertyReal64:
+        	{
+        	TReal minValue, maxValue;
+        	TLex lex( aMinAdd );
+        	lex.Val( minValue );
+        	lex.Assign( aMaxAdd );
+        	lex.Val( maxValue );
+        	prop->AddMinMaxValueL( minValue, maxValue );
+        	break;
+        	}
+        default:
+        	{
+#ifdef _DEBUG
+            User::Panic( _L("MdSODAd2") , KErrMdEUnknownPropertyType );
+#endif		    	
+        	
+        	User::Leave( KErrMdEUnknownPropertyType );
+        	}
+		}
+	}
+
+
+void CMdsObjectDef::ImportFromDBL()
+	{
+	_LIT( KMdsQueryGetPropertyDefs, "SELECT PropertyDefId,Flags,Type,MinValue,MaxValue,Name FROM PropertyDef WHERE ObjectDefId=?;" );
+	_LIT( KMdsQueryGetCol2Prop,     "SELECT PropertyDefId,ColumnId FROM Col2Prop WHERE ObjectDefId=?;" );
+
+	RMdsStatement query;
+	CleanupClosePushL( query );
+
+	// importing properties
+	RRowData objectNumber;
+	CleanupClosePushL( objectNumber );
+	objectNumber.AppendL( TColumn( GetId() ) );
+
+	CMdSSqLiteConnection& connection = MMdSDbConnectionPool::GetDefaultDBL();
+	TDefId propertyDefId = 0;
+	TPropertyType type;
+	TInt32 typeValue = 0;
+	TUint32 propertyFlags = 0;
+	TPtrC16 name;
+    TPtrC16 minValue;
+    TPtrC16 maxValue;
+	RRowData getData;
+	CleanupClosePushL( getData );
+	getData.AppendL( TColumn( propertyDefId ) );
+	getData.AppendL( TColumn( propertyFlags ) );
+	getData.AppendL( TColumn( typeValue ) );
+	getData.AppendL( TColumn( EColumnHBuf16 ) );
+	getData.AppendL( TColumn( EColumnHBuf16 ) );
+	getData.AppendL( TColumn( EColumnHBuf16 ) );
+	connection.ExecuteQueryL( KMdsQueryGetPropertyDefs, query, objectNumber );
+	while( connection.NextRowL( query, getData ) )
+		{
+		getData.Column( 0 ).Get( propertyDefId );
+		getData.Column( 1 ).Get( propertyFlags );
+		getData.Column( 2 ).Get( typeValue );
+		type = (TPropertyType)typeValue;
+		getData.Column( 3 ).Get( minValue );
+		getData.Column( 4 ).Get( maxValue );
+		getData.Column( 5 ).Get( name );
+		AddPropertyL( propertyDefId, type, propertyFlags, minValue, maxValue, name );
+		getData.Column( 5 ).Free( );
+		getData.Column( 4 ).Free( );
+		getData.Column( 3 ).Free( );
+		}
+
+	iCol2Prop.Reset();
+	RMdsStatement queryCol;
+	CleanupClosePushL( queryCol );
+	RRowData getColData;
+	CleanupClosePushL( getColData );
+	TUint32 columnId = 0;
+	getColData.AppendL( TColumn( propertyDefId ) );
+	getColData.AppendL( TColumn( columnId ) );
+	connection.ExecuteQueryL( KMdsQueryGetCol2Prop, queryCol, objectNumber );
+	while( connection.NextRowL( queryCol, getColData ) )
+		{
+		getColData.Column( 0 ).Get( propertyDefId );
+		getColData.Column( 1 ).Get( columnId );
+		const CMdsPropertyDef* propertyDef = GetPropertyByIdL( propertyDefId );
+		
+		if( !propertyDef )
+			{
+			User::Leave( KErrMdEUnknownPropertyDef );
+			}
+
+		CMdsObjectDef::TMdsColumnOrder col = { columnId, *propertyDef };
+		iCol2Prop.AppendL( col );
+		
+		if( propertyDef->GetMandatory() )
+			{
+			++iMandatoryPropertyCount;
+			}
+		}
+
+	// everything is ok, so set the flags
+	SetStoredInDB();
+	SetTableStoredInDB();
+	SetC2PStoredInDB();
+
+	CleanupStack::PopAndDestroy( 5, &query ); // getColData, queryCol, getData, objectNumber, query
+	}
+	
+TUint32 CMdsObjectDef::RequiredBufferSize()
+	{
+	TUint32 bufferSize = sizeof(TMdCObjectDef) + CMdsItemDef::RequiredBufferSize();
+
+	// propertydefs
+	const TInt propertyDefsCount = iPropertyDefs.Count();
+	bufferSize += propertyDefsCount * sizeof(TMdCPropertyDef);
+	for ( TInt i = 0; i < propertyDefsCount; ++i )
+		{
+		bufferSize += iPropertyDefs[i]->RequiredBufferSize();
+		}
+
+	return bufferSize;
+	}
+
+TMdCOffset CMdsObjectDef::SerializeL( CMdCSerializationBuffer& aBuffer, TMdCOffset aFreeSpace )
+	{
+	const TMdCOffset objectDefOffset = aBuffer.Position();
+	TMdCObjectDef objectDef;
+	// get const data and store Name
+	objectDef.iDefId = GetId();
+	objectDef.iParentId = iParent ? iParent->GetId() : KNoDefId;
+	objectDef.iName.iPtr.iCount = GetName().Length();
+	objectDef.iName.iPtr.iOffset = aFreeSpace;
+	aBuffer.PositionL( aFreeSpace );
+	aFreeSpace = CMdsItemDef::SerializeL( aBuffer );
+
+	// calculate necessary stuff for propertyDefs
+	const TInt propertyDefsCount = iPropertyDefs.Count();
+	objectDef.iPropertyDefs.iPtr.iCount = propertyDefsCount;
+	objectDef.iPropertyDefs.iPtr.iOffset = aFreeSpace;
+
+	// create space for propertyDefs
+	aFreeSpace += propertyDefsCount * sizeof(TMdCPropertyDef);
+
+	for ( TInt i = 0; i < propertyDefsCount; ++i )
+		{
+		aBuffer.PositionL( objectDef.iPropertyDefs.iPtr.iOffset + i * sizeof(TMdCPropertyDef) );
+		// write object
+		aFreeSpace = iPropertyDefs[i]->SerializeL( aBuffer, aFreeSpace );
+		}
+
+	// store objectDef itself
+	aBuffer.PositionL( objectDefOffset );
+	objectDef.SerializeL( aBuffer );
+
+	return aFreeSpace;
+	}
+
+TInt CMdsObjectDef::GetAllPropertiesCount() const
+	{
+#ifdef _DEBUG
+	_LIT( KCountPanicError, "CMdsObjectDef::GetAllPropertiesCount()" );
+	TInt temp = iPropertyDefs.Count() + ( iParent ? iParent->GetAllPropertiesCount() : 0 );
+	__ASSERT_DEBUG( temp == iCol2Prop.Count(), User::Panic( KCountPanicError, KErrCorrupt ) );
+#endif
+	return iCol2Prop.Count();
+	}
+
+TInt CMdsObjectDef::GetMandatoryPropertyCount() const
+	{
+	return iMandatoryPropertyCount;
+	}
+
+void CMdsObjectDef::SetStoredEveryInDB()
+	{
+	SetStoredInDB();
+	
+	const TInt count = iPropertyDefs.Count();
+	
+	for ( TInt i = 0; i < count; ++i )
+		{
+		iPropertyDefs[i]->SetStoredInDB();
+		}
+	}
+
+void CMdsObjectDef::SetNotStoredEveryInDB()
+	{
+	SetAllNotStoredInDB();
+	
+	const TInt count = iPropertyDefs.Count();
+	
+	for ( TInt i = 0; i < count; ++i )
+		{
+		iPropertyDefs[i]->SetAllNotStoredInDB();
+		}
+	}