diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/miranda32_10.vcxproj | 4 | ||||
| -rw-r--r-- | src/miranda32_10.vcxproj.filters | 6 | ||||
| -rw-r--r-- | src/modules/database/database.h | 49 | ||||
| -rw-r--r-- | src/modules/database/dbintf.cpp | 22 | ||||
| -rw-r--r-- | src/modules/database/mdatabasecache.cpp | 233 | 
5 files changed, 314 insertions, 0 deletions
diff --git a/src/miranda32_10.vcxproj b/src/miranda32_10.vcxproj index ca0f8ffa35..5707d30e91 100644 --- a/src/miranda32_10.vcxproj +++ b/src/miranda32_10.vcxproj @@ -244,6 +244,7 @@      <ClInclude Include="core\commonheaders.h" />
      <ClInclude Include="core\miranda.h" />
      <ClInclude Include="core\stdplug.h" />
 +    <ClInclude Include="modules\database\database.h" />
      <ClInclude Include="modules\database\profilemanager.h" />
      <ClInclude Include="modules\findadd\findadd.h" />
      <ClInclude Include="modules\json\internalJSONNode.h" />
 @@ -299,6 +300,9 @@      <ClCompile Include="modules\database\dbutils.cpp">
        <PrecompiledHeaderFile>..\..\core\commonheaders.h</PrecompiledHeaderFile>
      </ClCompile>
 +    <ClCompile Include="modules\database\mdatabasecache.cpp">
 +      <PrecompiledHeaderFile>..\..\core\commonheaders.h</PrecompiledHeaderFile>
 +    </ClCompile>
      <ClCompile Include="modules\database\profilemanager.cpp">
        <PrecompiledHeaderFile>..\..\core\commonheaders.h</PrecompiledHeaderFile>
      </ClCompile>
 diff --git a/src/miranda32_10.vcxproj.filters b/src/miranda32_10.vcxproj.filters index dd95088c4f..fb7f03cd6e 100644 --- a/src/miranda32_10.vcxproj.filters +++ b/src/miranda32_10.vcxproj.filters @@ -270,6 +270,9 @@      <ClInclude Include="..\include\m_db_int.h">
        <Filter>Modules\database</Filter>
      </ClInclude>
 +    <ClInclude Include="modules\database\database.h">
 +      <Filter>Modules\database</Filter>
 +    </ClInclude>
    </ItemGroup>
    <ItemGroup>
      <ClCompile Include="core\commonheaders.cpp">
 @@ -572,6 +575,9 @@      <ClCompile Include="modules\clist\contacts.cpp">
        <Filter>Modules\clist</Filter>
      </ClCompile>
 +    <ClCompile Include="modules\database\mdatabasecache.cpp">
 +      <Filter>Modules\database</Filter>
 +    </ClCompile>
    </ItemGroup>
    <ItemGroup>
      <ResourceCompile Include="resource.rc">
 diff --git a/src/modules/database/database.h b/src/modules/database/database.h new file mode 100644 index 0000000000..b0b5717e0b --- /dev/null +++ b/src/modules/database/database.h @@ -0,0 +1,49 @@ +/*
 +
 +Miranda NG: the free IM client for Microsoft* Windows*
 +
 +Copyright 2012 Miranda NG project,
 +all portions of this codebase are copyrighted to the people
 +listed in contributors.txt.
 +
 +This program is free software; you can redistribute it and/or
 +modify it under the terms of the GNU General Public License
 +as published by the Free Software Foundation; either version 2
 +of the License, or (at your option) any later version.
 +
 +This program is distributed in the hope that it will be useful,
 +but WITHOUT ANY WARRANTY; without even the implied warranty of
 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 +GNU General Public License for more details.
 +
 +You should have received a copy of the GNU General Public License
 +along with this program; if not, write to the Free Software
 +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 +*/
 +
 +class MDatabaseCache : public MIDatabaseCache, public MZeroedObject
 +{
 +	HANDLE m_hCacheHeap;
 +	char* m_lastSetting;
 +	DBCachedContact *m_lastVL;
 +
 +	LIST<DBCachedContact> m_lContacts;
 +	LIST<DBCachedGlobalValue> m_lGlobalSettings;
 +	LIST<char> m_lSettings;
 +
 +	void FreeCachedVariant(DBVARIANT* V);
 +
 +public:
 +	MDatabaseCache();
 +	~MDatabaseCache();
 +
 +protected:
 +	STDMETHODIMP_(DBCachedContact*) AddContactToCache(HANDLE hContact);
 +	STDMETHODIMP_(DBCachedContact*) GetCachedContact(HANDLE hContact);
 +	STDMETHODIMP_(void) FreeCachedContact(HANDLE hContact);
 +
 +	STDMETHODIMP_(char*) InsertCachedSetting(const char *szName, int);
 +	STDMETHODIMP_(char*) GetCachedSetting(const char *szModuleName, const char *szSettingName, int, int);
 +	STDMETHODIMP_(void)  SetCachedVariant(DBVARIANT *s, DBVARIANT *d);
 +	STDMETHODIMP_(DBVARIANT*) GetCachedValuePtr(HANDLE hContact, char *szSetting, int bAllocate);
 +};
 diff --git a/src/modules/database/dbintf.cpp b/src/modules/database/dbintf.cpp index 6c6371e6ec..da83e284d2 100644 --- a/src/modules/database/dbintf.cpp +++ b/src/modules/database/dbintf.cpp @@ -22,6 +22,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.  */
  #include "..\..\core\commonheaders.h"
 +#include "database.h"
  MIDatabase *currDb = NULL;
  DATABASELINK *currDblink = NULL;
 @@ -191,6 +192,24 @@ static INT_PTR srvGetCurrentDb(WPARAM wParam,LPARAM lParam)  	return (INT_PTR)currDb;
  }
 +static INT_PTR srvInitInstance(WPARAM wParam,LPARAM lParam)
 +{
 +	MIDatabase* pDb = (MIDatabase*)lParam;
 +	if (pDb != NULL)
 +		pDb->m_cache = new MDatabaseCache();
 +	return 0;
 +}
 +
 +static INT_PTR srvDestroyInstance(WPARAM wParam,LPARAM lParam)
 +{
 +	MIDatabase* pDb = (MIDatabase*)lParam;
 +	if (pDb != NULL) {
 +		delete pDb->m_cache;
 +		pDb->m_cache = NULL;
 +	}
 +	return 0;
 +}
 +
  ///////////////////////////////////////////////////////////////////////////////
  int LoadDbintfModule()
 @@ -232,5 +251,8 @@ int LoadDbintfModule()  	CreateServiceFunction(MS_DB_REGISTER_PLUGIN, srvRegisterPlugin);
  	CreateServiceFunction(MS_DB_FIND_PLUGIN, srvFindPlugin);
  	CreateServiceFunction(MS_DB_GET_CURRENT, srvGetCurrentDb);
 +
 +	CreateServiceFunction(MS_DB_INIT_INSTANCE, srvInitInstance);
 +	CreateServiceFunction(MS_DB_DESTROY_INSTANCE, srvDestroyInstance);
  	return 0;
  }
 diff --git a/src/modules/database/mdatabasecache.cpp b/src/modules/database/mdatabasecache.cpp new file mode 100644 index 0000000000..abb24dd0fe --- /dev/null +++ b/src/modules/database/mdatabasecache.cpp @@ -0,0 +1,233 @@ +/*
 +
 +Miranda IM: the free IM client for Microsoft* Windows*
 +
 +Copyright 2000-2010 Miranda ICQ/IM project,
 +all portions of this codebase are copyrighted to the people
 +listed in contributors.txt.
 +
 +This program is free software; you can redistribute it and/or
 +modify it under the terms of the GNU General Public License
 +as published by the Free Software Foundation; either version 2
 +of the License, or (at your option) any later version.
 +
 +This program is distributed in the hope that it will be useful,
 +but WITHOUT ANY WARRANTY; without even the implied warranty of
 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 +GNU General Public License for more details.
 +
 +You should have received a copy of the GNU General Public License
 +along with this program; if not, write to the Free Software
 +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 +*/
 +
 +#include "..\..\core\commonheaders.h"
 +#include "database.h"
 +
 +static int stringCompare(const char* p1, const char* p2)
 +{	return strcmp(p1+1, p2+1);
 +}
 +
 +static int compareGlobals(const DBCachedGlobalValue* p1, const DBCachedGlobalValue* p2)
 +{	return strcmp(p1->name, p2->name);
 +}
 +
 +MDatabaseCache::MDatabaseCache() :
 +	m_lSettings(100, stringCompare),
 +	m_lContacts(50, LIST<DBCachedContact>::FTSortFunc(HandleKeySort)),
 +	m_lGlobalSettings(50, compareGlobals)
 +{
 +	m_hCacheHeap = HeapCreate(0, 0, 0);
 +}
 +
 +MDatabaseCache::~MDatabaseCache()
 +{
 +	HeapDestroy(m_hCacheHeap);
 +	m_lContacts.destroy();
 +	m_lSettings.destroy();
 +	m_lGlobalSettings.destroy();
 +}
 +
 +/////////////////////////////////////////////////////////////////////////////////////////
 +
 +DBCachedContact* MDatabaseCache::AddContactToCache(HANDLE hContact)
 +{
 +	DBCachedContact* VL = (DBCachedContact*)HeapAlloc(m_hCacheHeap, HEAP_ZERO_MEMORY, sizeof(DBCachedContact));
 +	VL->hContact = hContact;
 +	m_lContacts.insert(VL);
 +	return VL;
 +}
 +
 +DBCachedContact* MDatabaseCache::GetCachedContact(HANDLE hContact)
 +{
 +	DBCachedContact VLtemp = { hContact };
 +	int index = m_lContacts.getIndex(&VLtemp);
 +	return (index == -1) ? NULL : m_lContacts[index];
 +}
 +
 +void MDatabaseCache::FreeCachedContact(HANDLE hContact)
 +{
 +	DBCachedContact VLtemp = { hContact };
 +	int index = m_lContacts.getIndex(&VLtemp);
 +	if (index == -1)
 +		return;
 +
 +	DBCachedContact* VL = m_lContacts[index];
 +	DBCachedContactValue* V = VL->first;
 +	while (V != NULL) {
 +		DBCachedContactValue* V1 = V->next;
 +		FreeCachedVariant(&V->value);
 +		HeapFree( m_hCacheHeap, 0, V );
 +		V = V1;
 +	}
 +	HeapFree( m_hCacheHeap, 0, VL );
 +
 +	m_lContacts.remove(index);
 +}
 +
 +/////////////////////////////////////////////////////////////////////////////////////////
 +
 +char* MDatabaseCache::InsertCachedSetting(const char* szName, int cbLen)
 +{
 +	char* newValue = (char*)HeapAlloc(m_hCacheHeap, 0, cbLen);
 +	*newValue = 0;
 +	strcpy(newValue+1, szName+1);
 +	m_lSettings.insert(newValue);
 +	return newValue;
 +}
 +
 +char* MDatabaseCache::GetCachedSetting(const char *szModuleName,const char *szSettingName, int moduleNameLen, int settingNameLen)
 +{
 +	char szFullName[512];
 +	strcpy(szFullName+1,szModuleName);
 +	szFullName[moduleNameLen+1] = '/';
 +	strcpy(szFullName+moduleNameLen+2,szSettingName);
 +
 +	if (m_lastSetting && strcmp(szFullName+1, m_lastSetting) == 0)
 +		return m_lastSetting;
 +
 +	int index = m_lSettings.getIndex(szFullName);
 +	if (index != -1)
 +		m_lastSetting = m_lSettings[index]+1;
 +	else
 +		m_lastSetting = InsertCachedSetting( szFullName, settingNameLen+moduleNameLen+3)+1;
 +
 +	return m_lastSetting;
 +}
 +
 +void MDatabaseCache::SetCachedVariant(DBVARIANT* s /* new */, DBVARIANT* d /* cached */ )
 +{
 +	char* szSave = ( d->type == DBVT_UTF8 || d->type == DBVT_ASCIIZ ) ? d->pszVal : NULL;
 +
 +	memcpy( d, s, sizeof( DBVARIANT ));
 +	if (( s->type == DBVT_UTF8 || s->type == DBVT_ASCIIZ ) && s->pszVal != NULL ) {
 +		if ( szSave != NULL )
 +			d->pszVal = (char*)HeapReAlloc(m_hCacheHeap,0,szSave,strlen(s->pszVal)+1);
 +		else
 +			d->pszVal = (char*)HeapAlloc(m_hCacheHeap,0,strlen(s->pszVal)+1);
 +		strcpy(d->pszVal,s->pszVal);
 +	}
 +	else if ( szSave != NULL )
 +		HeapFree(m_hCacheHeap,0,szSave);
 +
 +#ifdef DBLOGGING
 +	switch( d->type ) {
 +		case DBVT_BYTE:	log1( "set cached byte: %d", d->bVal ); break;
 +		case DBVT_WORD:	log1( "set cached word: %d", d->wVal ); break;
 +		case DBVT_DWORD:	log1( "set cached dword: %d", d->dVal ); break;
 +		case DBVT_UTF8:
 +		case DBVT_ASCIIZ: log1( "set cached string: '%s'", d->pszVal ); break;
 +		default:				log1( "set cached crap: %d", d->type ); break;
 +	}
 +#endif
 +}
 +
 +void MDatabaseCache::FreeCachedVariant(DBVARIANT* V)
 +{
 +	if (( V->type == DBVT_ASCIIZ || V->type == DBVT_UTF8 ) && V->pszVal != NULL )
 +		HeapFree(m_hCacheHeap,0,V->pszVal);
 +}
 +
 +STDMETHODIMP_(DBVARIANT*) MDatabaseCache::GetCachedValuePtr(HANDLE hContact, char *szSetting, int bAllocate)
 +{
 +	// a global setting
 +	if ( hContact == 0 ) {
 +		DBCachedGlobalValue Vtemp, *V;
 +		Vtemp.name = szSetting;
 +		int index = m_lGlobalSettings.getIndex(&Vtemp);
 +		if (index != -1) {
 +			V = m_lGlobalSettings[index];
 +			if ( bAllocate == -1 ) {
 +				FreeCachedVariant( &V->value );
 +				m_lGlobalSettings.remove(index);
 +				HeapFree(m_hCacheHeap,0,V);
 +				return NULL;
 +			}
 +		}
 +		else {
 +			if ( bAllocate != 1 )
 +				return NULL;
 +
 +			V = (DBCachedGlobalValue*)HeapAlloc(m_hCacheHeap,HEAP_ZERO_MEMORY,sizeof(DBCachedGlobalValue));
 +			V->name = szSetting;
 +			m_lGlobalSettings.insert(V);
 +		}
 +
 +		return &V->value;
 +	}
 +
 +	// a contact setting
 +	DBCachedContactValue *V, *V1;
 +	DBCachedContact VLtemp,*VL;
 +
 +	VLtemp.hContact = hContact;
 +
 +	int index = m_lContacts.getIndex(&VLtemp);
 +	if (index == -1) {
 +		if ( bAllocate != 1 )
 +			return NULL;
 +
 +		VL = AddContactToCache(hContact);
 +	}
 +	else VL = m_lContacts[index];
 +
 +	m_lastVL = VL;
 +
 +	for ( V = VL->first; V != NULL; V = V->next)
 +		if (V->name == szSetting)
 +			break;
 +
 +	if ( V == NULL ) {
 +		if ( bAllocate != 1 )
 +			return NULL;
 +
 +		V = (DBCachedContactValue *)HeapAlloc(m_hCacheHeap, HEAP_ZERO_MEMORY, sizeof(DBCachedContactValue));
 +		if (VL->last)
 +			VL->last->next = V;
 +		else
 +			VL->first = V;
 +		VL->last = V;
 +		V->name = szSetting;
 +	}
 +	else if ( bAllocate == -1 ) {
 +		m_lastVL = NULL;
 +		FreeCachedVariant(&V->value);
 +		if ( VL->first == V ) {
 +			VL->first = V->next;
 +			if (VL->last == V)
 +				VL->last = V->next; // NULL
 +		}
 +		else
 +			for ( V1 = VL->first; V1 != NULL; V1 = V1->next )
 +				if ( V1->next == V ) {
 +					V1->next = V->next;
 +					if (VL->last == V)
 +						VL->last = V1;
 +					break;
 +				}
 +		HeapFree(m_hCacheHeap,0,V);
 +		return NULL;
 +	}
 +
 +	return &V->value;
 +}
  | 
