connectivity/source/drivers/evoab2/EApi.cxx | 109 ++- connectivity/source/drivers/evoab2/EApi.h | 25 connectivity/source/drivers/evoab2/NDatabaseMetaData.cxx | 136 +++- connectivity/source/drivers/evoab2/NResultSet.cxx | 441 +++++++++------ connectivity/source/drivers/evoab2/NResultSet.hxx | 24 dbaccess/source/core/api/SingleSelectQueryComposer.cxx | 12 6 files changed, 510 insertions(+), 237 deletions(-)
New commits: commit cd5b03ecc1389806f92242dff8285ab8654231c9 Author: Caolán McNamara <caol...@redhat.com> Date: Thu Feb 7 17:01:57 2013 +0000 Fix busted multi-repeated column in evolution database view In the evolution address book where we have real column names of e.g. first_name, second_name and city. On parsing via OSQLParseTreeIterator::appendColumns that creates some labels using those real names but the evo XResultSet gives them proper labels of First Name, Second Name and City the munge means that here we have e.g. just "City" as a label because it matches, while the others don't The symptoms are to load the evolocal.odb and of the 128 columns column 5 is repeated until 128 This is all a horrible confusing mess. It seems safest to catch the mismatch of column counts and throw away the partial list and force a generate of a full list. Change-Id: I1d6e2a282bdd43acac63c366eb2a9d029aa17878 diff --git a/dbaccess/source/core/api/SingleSelectQueryComposer.cxx b/dbaccess/source/core/api/SingleSelectQueryComposer.cxx index f398a46..ca53291 100644 --- a/dbaccess/source/core/api/SingleSelectQueryComposer.cxx +++ b/dbaccess/source/core/api/SingleSelectQueryComposer.cxx @@ -937,6 +937,18 @@ Reference< XNameAccess > SAL_CALL OSingleSelectQueryComposer::getColumns( ) thr } while ( false ); + bool bMissingSomeColumnLabels = !aNames.empty() && aNames.size() != aSelectColumns->get().size(); + SAL_WARN_IF(bMissingSomeColumnLabels, "dbaccess", "We have column labels for *some* columns but not all"); + //^^this happens in the evolution address book where we have real column names of e.g. + //first_name, second_name and city. On parsing via + //OSQLParseTreeIterator::appendColumns it creates some labels using those real names + //but the evo address book gives them proper labels of First Name, Second Name and City + //the munge means that here we have e.g. just "City" as a label because it matches + // + //This is all a horrible mess + if (bMissingSomeColumnLabels) + aNames.clear(); + if ( aNames.empty() ) m_aCurrentColumns[ SelectColumns ] = OPrivateColumns::createWithIntrinsicNames( aSelectColumns, bCase, *this, m_aMutex ); else commit af3662e3e2172c3bc8178f7ce4042ef26eb2ac3a Author: Caolán McNamara <caol...@redhat.com> Date: Thu Feb 7 16:55:17 2013 +0000 deliberately continue to use addressbook human name as addressbox identifier because we identified the addressbook by their user name continue to do that for evo >= 3.6 even though that's got a better uid we could use. This way we can reuse the automatic mapping of fields in writer (search for Personal in officecfg) for mail merge Change-Id: I42e1d7aac9dd9640f0bb38e9224a393ac81481a1 diff --git a/connectivity/source/drivers/evoab2/NDatabaseMetaData.cxx b/connectivity/source/drivers/evoab2/NDatabaseMetaData.cxx index e5b504e..a83de24 100644 --- a/connectivity/source/drivers/evoab2/NDatabaseMetaData.cxx +++ b/connectivity/source/drivers/evoab2/NDatabaseMetaData.cxx @@ -1131,7 +1131,6 @@ Reference< XResultSet > SAL_CALL OEvoabDatabaseMetaData::getTables( if (eds_check_version(3, 6, 0) == NULL) { - fprintf(stderr, "OEvoabDatabaseMetaData::getTables\n"); GList *pSources = e_source_registry_list_sources(get_e_source_registry(), E_SOURCE_EXTENSION_ADDRESS_BOOK); for (GList* liter = pSources; liter; liter = liter->next) @@ -1158,13 +1157,16 @@ Reference< XResultSet > SAL_CALL OEvoabDatabaseMetaData::getTables( ODatabaseMetaDataResultSet::ORow aRow(3); aRow.reserve(6); - OUString aUID = OStringToOUString( e_source_get_uid( pSource ), + OUString aHumanName = OStringToOUString( e_source_get_display_name( pSource ), RTL_TEXTENCODING_UTF8 ); - aRow.push_back(new ORowSetValueDecorator(aUID)); + aRow.push_back(new ORowSetValueDecorator(aHumanName)); //tablename aRow.push_back(new ORowSetValueDecorator(aTable)); - OUString aHumanName = OStringToOUString( e_source_get_display_name( pSource ), + OUString aUID = OStringToOUString( e_source_get_uid( pSource ), RTL_TEXTENCODING_UTF8 ); - aRow.push_back(ODatabaseMetaDataResultSet::getEmptyValue()); + aRow.push_back(new ORowSetValueDecorator(aUID)); //comment + //I'd prefer to swap the comment and the human name and + //just use e_source_registry_ref_source(get_e_source_registry(), aUID); + //in open book rather than search for the name again aRows.push_back(aRow); } diff --git a/connectivity/source/drivers/evoab2/NResultSet.cxx b/connectivity/source/drivers/evoab2/NResultSet.cxx index 13a510d..4baf3ae 100644 --- a/connectivity/source/drivers/evoab2/NResultSet.cxx +++ b/connectivity/source/drivers/evoab2/NResultSet.cxx @@ -389,8 +389,26 @@ public: freeContacts(); } - virtual EBook* openBook(const char *id) + virtual EBook* openBook(const char *abname) { + //It would be better if here we had id to begin with, see + //NDatabaseMetaData.cxx + const char *id = NULL; + GList *pSources = e_source_registry_list_sources(get_e_source_registry(), E_SOURCE_EXTENSION_ADDRESS_BOOK); + for (GList* liter = pSources; liter; liter = liter->next) + { + ESource *pSource = E_SOURCE (liter->data); + + if (strcmp(abname, e_source_get_display_name( pSource )) == 0) + { + id = e_source_get_uid( pSource ); + break; + } + } + g_list_free_full (pSources, g_object_unref); + if (!id) + return NULL; + ESource *pSource = e_source_registry_ref_source(get_e_source_registry(), id); EBookClient *pBook = pSource ? e_book_client_new (pSource, NULL) : NULL; if (pBook && !e_client_open_sync (pBook, TRUE, NULL, NULL)) commit 157d94d3d2c9af9b9db41b8adc6162019aef4ef9 Author: Caolán McNamara <caol...@redhat.com> Date: Thu Feb 7 17:18:47 2013 +0000 make evolution-3.6 work with address book Change-Id: Ieffe1a374f3f94991ca63b6ccfbfb7bdc43255d6 diff --git a/connectivity/source/drivers/evoab2/EApi.cxx b/connectivity/source/drivers/evoab2/EApi.cxx index 84701e1..608b1f9 100644 --- a/connectivity/source/drivers/evoab2/EApi.cxx +++ b/connectivity/source/drivers/evoab2/EApi.cxx @@ -22,6 +22,7 @@ #define DECLARE_FN_POINTERS 1 #include "EApi.h" static const char *eBookLibNames[] = { + "libebook-1.2.so.14", // bumped again (evolution-3.6) "libebook-1.2.so.13", // bumped again (evolution-3.4) "libebook-1.2.so.12", // bumped again "libebook-1.2.so.10", // bumped again @@ -34,25 +35,23 @@ static const char *eBookLibNames[] = { typedef void (*SymbolFunc) (void); #define SYM_MAP(a) { #a, (SymbolFunc *)&a } - static struct { +struct ApiMap +{ const char *sym_name; SymbolFunc *ref_value; - } aApiMap[] = { +}; + +static ApiMap aCommonApiMap[] = +{ + SYM_MAP( eds_check_version ), SYM_MAP( e_contact_field_name ), SYM_MAP( e_contact_get ), SYM_MAP( e_contact_get_type ), SYM_MAP( e_contact_field_id ), - SYM_MAP( e_source_peek_name ), - SYM_MAP( e_source_get_property ), - SYM_MAP( e_source_list_peek_groups ), - SYM_MAP( e_source_group_peek_sources ), SYM_MAP( e_book_new ), SYM_MAP( e_book_open ), - SYM_MAP( e_book_get_uri ), SYM_MAP( e_book_get_source ), - SYM_MAP( e_book_get_addressbooks ), SYM_MAP( e_book_get_contacts ), - SYM_MAP( e_book_authenticate_user ), SYM_MAP( e_book_query_field_test ), SYM_MAP( e_book_query_and ), SYM_MAP( e_book_query_or ), @@ -61,26 +60,55 @@ typedef void (*SymbolFunc) (void); SYM_MAP( e_book_query_unref ), SYM_MAP( e_book_query_from_string ), SYM_MAP( e_book_query_to_string ), - SYM_MAP( e_book_query_field_exists ), - SYM_MAP( e_source_group_peek_base_uri) - }; + SYM_MAP( e_book_query_field_exists ) +}; + +//< 3-6 api +static ApiMap aOldApiMap[] = +{ + SYM_MAP( e_book_get_addressbooks ), + SYM_MAP( e_book_get_uri ), + SYM_MAP( e_book_authenticate_user ), + SYM_MAP( e_source_group_peek_base_uri), + SYM_MAP( e_source_peek_name ), + SYM_MAP( e_source_get_property ), + SYM_MAP( e_source_list_peek_groups ), + SYM_MAP( e_source_group_peek_sources ) +}; + +//>= 3-6 api +static ApiMap aNewApiMap[] = +{ + SYM_MAP( e_source_registry_list_sources ), + SYM_MAP( e_source_registry_new_sync ), + SYM_MAP( e_source_has_extension ), + SYM_MAP( e_source_get_extension ), + SYM_MAP( e_source_backend_get_backend_name ), + SYM_MAP( e_source_get_display_name ), + SYM_MAP( e_source_get_uid ), + SYM_MAP( e_source_registry_ref_source), + SYM_MAP( e_book_client_new ), + SYM_MAP( e_client_open_sync ), + SYM_MAP( e_client_get_source ), + SYM_MAP( e_book_client_get_contacts_sync ), + SYM_MAP( e_client_util_free_object_slist ) +}; #undef SYM_MAP static bool -tryLink( oslModule &aModule, const char *pName ) +tryLink( oslModule &aModule, const char *pName, ApiMap *pMap, guint nEntries ) { - for( guint i = 0; i < G_N_ELEMENTS( aApiMap ); i++ ) + for (guint i = 0; i < nEntries; ++i) { - SymbolFunc aMethod; - aMethod = (SymbolFunc) osl_getFunctionSymbol - ( aModule, rtl::OUString::createFromAscii ( aApiMap[ i ].sym_name ).pData ); - if( !aMethod ) - { - fprintf( stderr, "Warning: missing symbol '%s' in '%s'", - aApiMap[ i ].sym_name, pName ); - return false; - } - * aApiMap[ i ].ref_value = aMethod; + SymbolFunc aMethod = (SymbolFunc)osl_getFunctionSymbol + (aModule, OUString::createFromAscii ( pMap[ i ].sym_name ).pData); + if( !aMethod ) + { + fprintf( stderr, "Warning: missing symbol '%s' in '%s'\n", + pMap[ i ].sym_name, pName ); + return false; + } + *pMap[ i ].ref_value = aMethod; } return true; } @@ -96,8 +124,18 @@ bool EApiInit() SAL_LOADMODULE_DEFAULT ); if( aModule) { - if ( tryLink( aModule, eBookLibNames[ j ] ) ) - return true; + if (tryLink( aModule, eBookLibNames[ j ], aCommonApiMap, G_N_ELEMENTS(aCommonApiMap))) + { + if (eds_check_version(3, 6, 0) == NULL) + { + if (tryLink( aModule, eBookLibNames[ j ], aNewApiMap, G_N_ELEMENTS(aNewApiMap))) + return true; + } + else if (tryLink( aModule, eBookLibNames[ j ], aOldApiMap, G_N_ELEMENTS(aOldApiMap))) + { + return true; + } + } osl_unloadModule( aModule ); } } @@ -105,23 +143,4 @@ bool EApiInit() return false; } -#if 0 -// hjs: SOLARDEF does no longer exist please lookup the required -// defines in a regular compile line -/* - * Test code - enable & - * - * Compile with ( after source LinuxIntelEnv.Set.sh ) - gcc $SOLARDEF -I $SOLARVER/$UPD/$INPATH/inc \ - -I. `pkg-config --cflags --libs gobject-2.0` \ - -L $SOLARVER/$UPD/$INPATH/lib -luno_sal -lstdc++ EApi.cxx - */ - -int main( int argc, char **argv) -{ - return EApiInit(); -} - -#endif - /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/connectivity/source/drivers/evoab2/EApi.h b/connectivity/source/drivers/evoab2/EApi.h index bf3a901..8d188a9 100644 --- a/connectivity/source/drivers/evoab2/EApi.h +++ b/connectivity/source/drivers/evoab2/EApi.h @@ -130,6 +130,31 @@ typedef struct { char *code; char *country; } EContactAddress; + +#define E_SOURCE_EXTENSION_ADDRESS_BOOK "Address Book" +typedef void ESourceRegistry; +typedef void GCancellable; +typedef void ESourceBackend; +typedef void EClient; +typedef EClient EBookClient; +EAPI_EXTERN ESourceRegistry* (*e_source_registry_new_sync) (GCancellable *cancellable, GError **error); +EAPI_EXTERN GList* (*e_source_registry_list_sources) (ESourceRegistry *registry, const gchar *extension_name); +EAPI_EXTERN gboolean (*e_source_has_extension) (ESource *source, const gchar *extension_name); +EAPI_EXTERN gpointer (*e_source_get_extension) (ESource *source, const gchar *extension_name); +EAPI_EXTERN const gchar* (*e_source_backend_get_backend_name) (ESourceBackend *extension); +EAPI_EXTERN const gchar* (*e_source_get_display_name) (ESource *source); +EAPI_EXTERN const gchar* (*eds_check_version) (guint required_major, guint required_minor, guint required_micro); +EAPI_EXTERN const gchar* (*e_source_get_uid) (ESource *source); +EAPI_EXTERN ESource* (*e_source_registry_ref_source) (ESourceRegistry *registry, const gchar *uid); +EAPI_EXTERN EBookClient* (*e_book_client_new) (ESource *source, GError **error); +EAPI_EXTERN gboolean (*e_client_open_sync) (EClient *client, gboolean only_if_exists, GCancellable *cancellable, GError **error); +EAPI_EXTERN ESource* (*e_client_get_source) (EClient *client); +EAPI_EXTERN gboolean (*e_book_client_get_contacts_sync) (EBookClient *client, const gchar *sexp, GSList **contacts, GCancellable *cancellable, GError **error); +EAPI_EXTERN void (*e_client_util_free_object_slist) (GSList *objects); + +ESourceRegistry *get_e_source_registry(); +bool isSourceBackend(ESource *pSource, const char *backendname); + G_END_DECLS #endif diff --git a/connectivity/source/drivers/evoab2/NDatabaseMetaData.cxx b/connectivity/source/drivers/evoab2/NDatabaseMetaData.cxx index 8d0b802..e5b504e 100644 --- a/connectivity/source/drivers/evoab2/NDatabaseMetaData.cxx +++ b/connectivity/source/drivers/evoab2/NDatabaseMetaData.cxx @@ -1074,13 +1074,22 @@ Reference< XResultSet > SAL_CALL OEvoabDatabaseMetaData::getColumns( pResultSet->setRows( getColumnRows( columnNamePattern ) ); return xResultSet; } + +ESourceRegistry *get_e_source_registry() +{ + static ESourceRegistry *theInstance; + if (!theInstance) + theInstance = e_source_registry_new_sync(NULL, NULL); + return theInstance; +} + // ------------------------------------------------------------------------- -static bool isSourceBackend( ESource *pSource, const char *backendname) +bool isSourceBackend(ESource *pSource, const char *backendname) { - if (!pSource || e_source_has_extension (pSource, "Address Book")) // E_SOURCE_EXTENSION_ADDRESS_BOOK + if (!pSource || !e_source_has_extension (pSource, E_SOURCE_EXTENSION_ADDRESS_BOOK)) return false; - gpointer extension = e_source_get_extension (pSource, "Address Book"); // E_SOURCE_EXTENSION_ADDRESS_BOOK + gpointer extension = e_source_get_extension (pSource, E_SOURCE_EXTENSION_ADDRESS_BOOK); return extension && g_strcmp0 (e_source_backend_get_backend_name (extension), backendname) == 0; } @@ -1120,44 +1129,96 @@ Reference< XResultSet > SAL_CALL OEvoabDatabaseMetaData::getTables( ODatabaseMetaDataResultSet::ORows aRows; - GSList *pSources; - pSources = e_source_registry_list_sources (registry, "Address Book"); // E_SOURCE_EXTENSION_ADDRESS_BOOK - - GList *liter; - for( liter = pSources; liter; liter = liter->next) + if (eds_check_version(3, 6, 0) == NULL) { - ESource *pSource = E_SOURCE (liter->data); - bool can = false; - - switch (m_pConnection->getSDBCAddressType()) { - case SDBCAddress::EVO_GWISE: - can = isSourceBackend( pSource, "groupwise"); // not supported in evo/eds 3.6.x+, somehow - break; - case SDBCAddress::EVO_LOCAL: - can = isSourceBackend( pSource, "local"); - break; - case SDBCAddress::EVO_LDAP: - can = isSourceBackend( pSource, "ldap"); - break; - case SDBCAddress::Unknown: - break; - } + fprintf(stderr, "OEvoabDatabaseMetaData::getTables\n"); + GList *pSources = e_source_registry_list_sources(get_e_source_registry(), E_SOURCE_EXTENSION_ADDRESS_BOOK); - if (can) { - rtl::OUString aName = rtl::OStringToOUString( e_source_get_display_name( pSource ), - RTL_TEXTENCODING_UTF8 ); + for (GList* liter = pSources; liter; liter = liter->next) + { + ESource *pSource = E_SOURCE (liter->data); + bool can = false; + switch (m_pConnection->getSDBCAddressType()) + { + case SDBCAddress::EVO_GWISE: + can = isSourceBackend( pSource, "groupwise"); // not supported in evo/eds 3.6.x+, somehow + break; + case SDBCAddress::EVO_LOCAL: + can = isSourceBackend( pSource, "local"); + break; + case SDBCAddress::EVO_LDAP: + can = isSourceBackend( pSource, "ldap"); + break; + case SDBCAddress::Unknown: + can = true; + break; + } + if (!can) + continue; ODatabaseMetaDataResultSet::ORow aRow(3); aRow.reserve(6); - aRow.push_back(new ORowSetValueDecorator(aName)); + OUString aUID = OStringToOUString( e_source_get_uid( pSource ), + RTL_TEXTENCODING_UTF8 ); + aRow.push_back(new ORowSetValueDecorator(aUID)); aRow.push_back(new ORowSetValueDecorator(aTable)); + OUString aHumanName = OStringToOUString( e_source_get_display_name( pSource ), + RTL_TEXTENCODING_UTF8 ); aRow.push_back(ODatabaseMetaDataResultSet::getEmptyValue()); - // add also e_source_get_uid (pSource) aRows.push_back(aRow); } + + g_list_free_full (pSources, g_object_unref); + } + else + { + ESourceList *pSourceList; + if( !e_book_get_addressbooks (&pSourceList, NULL) ) + pSourceList = NULL; + + GSList *g; + for( g = e_source_list_peek_groups( pSourceList ); g; g = g->next) + { + GSList *s; + const char *p = e_source_group_peek_base_uri(E_SOURCE_GROUP(g->data)); + + switch (m_pConnection->getSDBCAddressType()) { + case SDBCAddress::EVO_GWISE: + if ( !strncmp( "groupwise://", p, 11 )) + break; + else + continue; + case SDBCAddress::EVO_LOCAL: + if ( !strncmp( "file://", p, 6 ) || + !strncmp( "local://", p, 6 ) ) + break; + else + continue; + case SDBCAddress::EVO_LDAP: + if ( !strncmp( "ldap://", p, 6 )) + break; + else + continue; + case SDBCAddress::Unknown: + break; + } + for (s = e_source_group_peek_sources (E_SOURCE_GROUP (g->data)); s; s = s->next) + { + ESource *pSource = E_SOURCE (s->data); + + rtl::OUString aName = rtl::OStringToOUString( e_source_peek_name( pSource ), + RTL_TEXTENCODING_UTF8 ); + + ODatabaseMetaDataResultSet::ORow aRow(3); + aRow.reserve(6); + aRow.push_back(new ORowSetValueDecorator(aName)); + aRow.push_back(new ORowSetValueDecorator(aTable)); + aRow.push_back(ODatabaseMetaDataResultSet::getEmptyValue()); + aRows.push_back(aRow); + } + } } - g_slist_free_full (pSources, g_object_unref); pResult->setRows(aRows); return xRef; diff --git a/connectivity/source/drivers/evoab2/NResultSet.cxx b/connectivity/source/drivers/evoab2/NResultSet.cxx index 589e580..13a510d 100644 --- a/connectivity/source/drivers/evoab2/NResultSet.cxx +++ b/connectivity/source/drivers/evoab2/NResultSet.cxx @@ -87,108 +87,17 @@ sal_Bool SAL_CALL OEvoabResultSet::supportsService( const ::rtl::OUString& _rSer return pSupported != pEnd; } -// ------------------------------------------------------------------------- -OEvoabResultSet::OEvoabResultSet( OCommonStatement* pStmt, OEvoabConnection *pConnection ) - :OResultSet_BASE(m_aMutex) - ,::comphelper::OPropertyContainer( OResultSet_BASE::rBHelper ) - ,m_pStatement(pStmt) - ,m_pConnection(pConnection) - ,m_xMetaData(NULL) - ,m_bWasNull(sal_True) - ,m_nFetchSize(0) - ,m_nResultSetType(ResultSetType::SCROLL_INSENSITIVE) - ,m_nFetchDirection(FetchDirection::FORWARD) - ,m_nResultSetConcurrency(ResultSetConcurrency::READ_ONLY) - ,m_pContacts(NULL) - ,m_nIndex(-1) - ,m_nLength(0) +struct ComparisonData { - #define REGISTER_PROP( id, member ) \ - registerProperty( \ - OMetaConnection::getPropMap().getNameByIndex( id ), \ - id, \ - PropertyAttribute::READONLY, \ - &member, \ - ::getCppuType( &member ) \ - ); + const SortDescriptor& rSortOrder; + IntlWrapper aIntlWrapper; - REGISTER_PROP( PROPERTY_ID_FETCHSIZE, m_nFetchSize ); - REGISTER_PROP( PROPERTY_ID_RESULTSETTYPE, m_nResultSetType ); - REGISTER_PROP( PROPERTY_ID_FETCHDIRECTION, m_nFetchDirection ); - REGISTER_PROP( PROPERTY_ID_RESULTSETCONCURRENCY, m_nResultSetConcurrency ); -} - -// ------------------------------------------------------------------------- -OEvoabResultSet::~OEvoabResultSet() -{ -} - -// ------------------------------------------------------------------------- - -static ESource * -findSource( const char *uid ) -{ - //ideally as - return e_source_registry_ref_source (registry, uid); - /*ESourceList *pSourceList = NULL; - - g_return_val_if_fail (name != NULL, NULL); - - if (!e_book_get_addressbooks (&pSourceList, NULL)) - pSourceList = NULL; - - for ( GSList *g = e_source_list_peek_groups (pSourceList); g; g = g->next) - { - for (GSList *s = e_source_group_peek_sources (E_SOURCE_GROUP (g->data)); s; s = s->next) - { - ESource *pSource = E_SOURCE (s->data); - if (!strcmp (e_source_peek_name (pSource), name)) - return pSource; - } - } - return NULL;*/ -} - -static EBookClient * -openBook( const char *abname ) -{ - ESource *pSource = findSource (abname); - EBookClient *pBook = NULL; - if (pSource) - pBook = e_book_client_new (pSource, NULL); - - if (pBook && !e_client_open_sync (pBook, TRUE, NULL, NULL)) + ComparisonData( const SortDescriptor& _rSortOrder, const Reference< XComponentContext >& _rxContext ) + :rSortOrder( _rSortOrder ) + ,aIntlWrapper( _rxContext, SvtSysLocale().GetLanguageTag() ) { - g_object_unref (G_OBJECT (pBook)); - pBook = NULL; } - - if (pSource) - g_object_unref (pSource); - - return pBook; -} - -static bool isBookBackend( EBookClient *pBook, const char *backendname) -{ - ESource *pSource = e_client_get_source ((EClient *) pBook); - - if (!pSource || e_source_has_extension (pSource, "Address Book")) // E_SOURCE_EXTENSION_ADDRESS_BOOK - return false; - - gpointer extension = e_source_get_extension (pSource, "Address Book"); // E_SOURCE_EXTENSION_ADDRESS_BOOK - return extension && g_strcmp0 (e_source_backend_get_backend_name (extension), backendname) == 0; -} - -static bool isLDAP( EBookClient *pBook ) -{ - return pBook && isBookBackend( pBook, "ldap" ); -} - -static bool isLocal( EBookClient *pBook ) -{ - return pBook && isBookBackend( pBook, "local" ); -} +}; static ::rtl::OUString valueToOUString( GValue& _rValue ) @@ -208,22 +117,6 @@ valueToBool( GValue& _rValue ) return bResult; } -static bool -executeQuery (EBookClient* pBook, EBookQuery* pQuery, GList **ppList, - rtl::OString &rPassword, GError **pError) -{ - bool bSuccess; - char *sexp; - - *ppList = NULL; - - sexp = e_book_query_to_string( pQuery ); - bSuccess = e_book_client_get_contacts_sync( pBook, sexp, ppList, pError ); - g_free (sexp); - - return bSuccess; -} - static int whichAddress(int value) { @@ -360,6 +253,7 @@ handleSplitAddress( EContact *pContact,GValue *pStackValue, int value ) return false; } + static bool getValue( EContact* pContact, sal_Int32 nColumnNum, GType nType, GValue* pStackValue, bool& _out_rWasNull ) { @@ -412,21 +306,6 @@ getValue( EContact* pContact, sal_Int32 nColumnNum, GType nType, GValue* pStackV return true; } -namespace -{ - struct ComparisonData - { - const SortDescriptor& rSortOrder; - IntlWrapper aIntlWrapper; - - ComparisonData( const SortDescriptor& _rSortOrder, const Reference< XComponentContext >& _rxContext ) - :rSortOrder( _rSortOrder ) - ,aIntlWrapper( _rxContext, SvtSysLocale().GetLanguageTag() ) - { - } - }; -} - extern "C" int CompareContacts( gconstpointer _lhs, gconstpointer _rhs, gpointer _userData ) { @@ -485,13 +364,260 @@ int CompareContacts( gconstpointer _lhs, gconstpointer _rhs, gpointer _userData return 0; } -static GList* -sortContacts( GList* _pContactList, const ComparisonData& _rCompData ) +OString OEvoabVersionHelper::getUserName( EBook *pBook ) { - OSL_ENSURE( !_rCompData.rSortOrder.empty(), "sortContacts: no need to call this without any sort order!" ); - ENSURE_OR_THROW( _rCompData.aIntlWrapper.getCaseCollator(), "no collator for comparing strings" ); + OString aName; + if( isLDAP( pBook ) ) + aName = e_source_get_property( e_book_get_source( pBook ), "binddn" ); + else + aName = e_source_get_property( e_book_get_source( pBook ), "user" ); + return aName; +} - return g_list_sort_with_data( _pContactList, &CompareContacts, const_cast< gpointer >( static_cast< gconstpointer >( &_rCompData ) ) ); +class OEvoabVersion36Helper : public OEvoabVersionHelper +{ +private: + GSList *m_pContacts; +public: + OEvoabVersion36Helper() + : m_pContacts(NULL) + { + } + + ~OEvoabVersion36Helper() + { + freeContacts(); + } + + virtual EBook* openBook(const char *id) + { + ESource *pSource = e_source_registry_ref_source(get_e_source_registry(), id); + EBookClient *pBook = pSource ? e_book_client_new (pSource, NULL) : NULL; + if (pBook && !e_client_open_sync (pBook, TRUE, NULL, NULL)) + { + g_object_unref (G_OBJECT (pBook)); + pBook = NULL; + } + if (pSource) + g_object_unref (pSource); + return pBook; + } + + bool isBookBackend( EBookClient *pBook, const char *backendname) + { + if (!pBook) + return false; + ESource *pSource = e_client_get_source ((EClient *) pBook); + return isSourceBackend(pSource, backendname); + } + + virtual bool isLDAP( EBook *pBook ) + { + return isBookBackend(pBook, "ldap"); + } + + virtual bool isLocal( EBook *pBook ) + { + return isBookBackend(pBook, "local"); + } + + virtual void freeContacts() + { + e_client_util_free_object_slist(m_pContacts); + m_pContacts = NULL; + } + + virtual bool executeQuery (EBook* pBook, EBookQuery* pQuery, OString &/*rPassword*/) + { + freeContacts(); + char *sexp = e_book_query_to_string( pQuery ); + bool bSuccess = e_book_client_get_contacts_sync( pBook, sexp, &m_pContacts, NULL, NULL ); + g_free (sexp); + return bSuccess; + } + + virtual EContact *getContact(sal_Int32 nIndex) + { + gpointer pData = g_slist_nth_data (m_pContacts, nIndex); + return pData ? E_CONTACT (pData) : NULL; + } + + virtual sal_Int32 getNumContacts() + { + return g_slist_length( m_pContacts ); + } + + virtual bool hasContacts() + { + return m_pContacts != NULL; + } + + virtual void sortContacts( const ComparisonData& _rCompData ) + { + OSL_ENSURE( !_rCompData.rSortOrder.empty(), "sortContacts: no need to call this without any sort order!" ); + ENSURE_OR_THROW( _rCompData.aIntlWrapper.getCaseCollator(), "no collator for comparing strings" ); + + m_pContacts = g_slist_sort_with_data( m_pContacts, &CompareContacts, + const_cast< gpointer >( static_cast< gconstpointer >( &_rCompData ) ) ); + } +}; + +class OEvoabVersion35Helper : public OEvoabVersionHelper +{ +private: + GList *m_pContacts; + + ESource * findSource( const char *id ) + { + ESourceList *pSourceList = NULL; + + g_return_val_if_fail (id != NULL, NULL); + + if (!e_book_get_addressbooks (&pSourceList, NULL)) + pSourceList = NULL; + + for ( GSList *g = e_source_list_peek_groups (pSourceList); g; g = g->next) + { + for (GSList *s = e_source_group_peek_sources (E_SOURCE_GROUP (g->data)); s; s = s->next) + { + ESource *pSource = E_SOURCE (s->data); + if (!strcmp (e_source_peek_name (pSource), id)) + return pSource; + } + } + return NULL; + } + + bool isAuthRequired( EBook *pBook ) + { + return e_source_get_property( e_book_get_source( pBook ), + "auth" ) != NULL; + } + +public: + OEvoabVersion35Helper() + : m_pContacts(NULL) + { + } + + ~OEvoabVersion35Helper() + { + freeContacts(); + } + + virtual EBook* openBook(const char *abname) + { + ESource *pSource = findSource (abname); + EBook *pBook = pSource ? e_book_new (pSource, NULL) : NULL; + if (pBook && !e_book_open (pBook, TRUE, NULL)) + { + g_object_unref (G_OBJECT (pBook)); + pBook = NULL; + } + return pBook; + } + + virtual bool isLDAP( EBook *pBook ) + { + return pBook && !strncmp( "ldap://", e_book_get_uri( pBook ), 6 ); + } + + virtual bool isLocal( EBook *pBook ) + { + return pBook && ( !strncmp( "file://", e_book_get_uri( pBook ), 6 ) || + !strncmp( "local:", e_book_get_uri( pBook ), 6 ) ); + } + + virtual void freeContacts() + { + g_list_free(m_pContacts); + m_pContacts = NULL; + } + + virtual bool executeQuery (EBook* pBook, EBookQuery* pQuery, OString &rPassword) + { + freeContacts(); + + ESource *pSource = e_book_get_source( pBook ); + bool bSuccess = false; + bool bAuthSuccess = true; + + if( isAuthRequired( pBook ) ) + { + rtl::OString aUser( getUserName( pBook ) ); + const char *pAuth = e_source_get_property( pSource, "auth" ); + bAuthSuccess = e_book_authenticate_user( pBook, aUser.getStr(), rPassword.getStr(), pAuth, NULL ); + } + + if (bAuthSuccess) + bSuccess = e_book_get_contacts( pBook, pQuery, &m_pContacts, NULL ); + + return bSuccess; + } + + virtual EContact *getContact(sal_Int32 nIndex) + { + gpointer pData = g_list_nth_data (m_pContacts, nIndex); + return pData ? E_CONTACT (pData) : NULL; + } + + virtual sal_Int32 getNumContacts() + { + return g_list_length( m_pContacts ); + } + + virtual bool hasContacts() + { + return m_pContacts != NULL; + } + + virtual void sortContacts( const ComparisonData& _rCompData ) + { + OSL_ENSURE( !_rCompData.rSortOrder.empty(), "sortContacts: no need to call this without any sort order!" ); + ENSURE_OR_THROW( _rCompData.aIntlWrapper.getCaseCollator(), "no collator for comparing strings" ); + + m_pContacts = g_list_sort_with_data( m_pContacts, &CompareContacts, + const_cast< gpointer >( static_cast< gconstpointer >( &_rCompData ) ) ); + } +}; + +OEvoabResultSet::OEvoabResultSet( OCommonStatement* pStmt, OEvoabConnection *pConnection ) + :OResultSet_BASE(m_aMutex) + ,::comphelper::OPropertyContainer( OResultSet_BASE::rBHelper ) + ,m_pStatement(pStmt) + ,m_pConnection(pConnection) + ,m_xMetaData(NULL) + ,m_bWasNull(sal_True) + ,m_nFetchSize(0) + ,m_nResultSetType(ResultSetType::SCROLL_INSENSITIVE) + ,m_nFetchDirection(FetchDirection::FORWARD) + ,m_nResultSetConcurrency(ResultSetConcurrency::READ_ONLY) + ,m_nIndex(-1) + ,m_nLength(0) +{ + if (eds_check_version(3, 6, 0) == NULL) + m_pVersionHelper = new OEvoabVersion36Helper; + else + m_pVersionHelper = new OEvoabVersion35Helper; + + #define REGISTER_PROP( id, member ) \ + registerProperty( \ + OMetaConnection::getPropMap().getNameByIndex( id ), \ + id, \ + PropertyAttribute::READONLY, \ + &member, \ + ::getCppuType( &member ) \ + ); + + REGISTER_PROP( PROPERTY_ID_FETCHSIZE, m_nFetchSize ); + REGISTER_PROP( PROPERTY_ID_RESULTSETTYPE, m_nResultSetType ); + REGISTER_PROP( PROPERTY_ID_FETCHDIRECTION, m_nFetchDirection ); + REGISTER_PROP( PROPERTY_ID_RESULTSETCONCURRENCY, m_nResultSetConcurrency ); +} + +// ------------------------------------------------------------------------- +OEvoabResultSet::~OEvoabResultSet() +{ } // ------------------------------------------------------------------------- @@ -499,17 +625,16 @@ void OEvoabResultSet::construct( const QueryData& _rData ) { ENSURE_OR_THROW( _rData.getQuery(), "internal error: no EBookQuery" ); - EBookClient *pBook = openBook(::rtl::OUStringToOString(_rData.sTable, RTL_TEXTENCODING_UTF8).getStr()); + EBook *pBook = m_pVersionHelper->openBook(OUStringToOString(_rData.sTable, RTL_TEXTENCODING_UTF8).getStr()); if ( !pBook ) m_pConnection->throwGenericSQLException( STR_CANNOT_OPEN_BOOK, *this ); - g_list_free(m_pContacts); - m_pContacts = NULL; + m_pVersionHelper->freeContacts(); bool bExecuteQuery = true; switch ( _rData.eFilterType ) { case eFilterNone: - if ( !isLocal( pBook ) ) + if ( !m_pVersionHelper->isLocal( pBook ) ) { SQLError aErrorFactory( comphelper::getComponentContext(m_pConnection->getDriver().getMSFactory()) ); SQLException aAsException = aErrorFactory.getSQLException( ErrorCondition::DATA_CANNOT_SELECT_UNFILTERED, *this ); @@ -533,16 +658,16 @@ void OEvoabResultSet::construct( const QueryData& _rData ) if ( bExecuteQuery ) { rtl::OString aPassword = m_pConnection->getPassword(); - executeQuery( pBook, _rData.getQuery(), &m_pContacts, aPassword, NULL ); + m_pVersionHelper->executeQuery(pBook, _rData.getQuery(), aPassword); m_pConnection->setPassword( aPassword ); - if ( m_pContacts && !_rData.aSortOrder.empty() ) + if ( m_pVersionHelper->hasContacts() && !_rData.aSortOrder.empty() ) { ComparisonData aCompData( _rData.aSortOrder, comphelper::getComponentContext(getConnection()->getDriver().getMSFactory()) ); - m_pContacts = sortContacts( m_pContacts, aCompData ); + m_pVersionHelper->sortContacts( aCompData ); } } - m_nLength = g_list_length( m_pContacts ); + m_nLength = m_pVersionHelper->getNumContacts(); OSL_TRACE( "Query return %d records", m_nLength ); m_nIndex = -1; @@ -559,10 +684,10 @@ void OEvoabResultSet::disposing(void) ::comphelper::OPropertyContainer::disposing(); ::osl::MutexGuard aGuard(m_aMutex); - g_list_free(m_pContacts); - m_pContacts = NULL; + delete m_pVersionHelper; + m_pVersionHelper = NULL; m_pStatement = NULL; -m_xMetaData.clear(); + m_xMetaData.clear(); } // ------------------------------------------------------------------------- Any SAL_CALL OEvoabResultSet::queryInterface( const Type & rType ) throw(RuntimeException) diff --git a/connectivity/source/drivers/evoab2/NResultSet.hxx b/connectivity/source/drivers/evoab2/NResultSet.hxx index fd049fd..c3d7ab4 100644 --- a/connectivity/source/drivers/evoab2/NResultSet.hxx +++ b/connectivity/source/drivers/evoab2/NResultSet.hxx @@ -45,6 +45,24 @@ namespace connectivity { namespace evoab { + class ComparisonData; + + class OEvoabVersionHelper + { + public: + virtual EBook* openBook(const char *abname) = 0; + virtual bool executeQuery (EBook* pBook, EBookQuery* pQuery, OString &rPassword) = 0; + virtual void freeContacts() = 0; + virtual bool isLDAP( EBook *pBook ) = 0; + virtual bool isLocal( EBook *pBook ) = 0; + virtual EContact *getContact(sal_Int32 nIndex) = 0; + virtual sal_Int32 getNumContacts() = 0; + virtual bool hasContacts() = 0; + virtual void sortContacts( const ComparisonData& _rCompData ) = 0; + OString getUserName( EBook *pBook ); + virtual ~OEvoabVersionHelper() {} + }; + typedef ::cppu::WeakComponentImplHelper8 < ::com::sun::star::sdbc::XResultSet , ::com::sun::star::sdbc::XRow , ::com::sun::star::sdbc::XResultSetMetaDataSupplier @@ -61,6 +79,8 @@ namespace connectivity ,public ::comphelper::OPropertyContainer ,public ::comphelper::OPropertyArrayUsageHelper<OEvoabResultSet> { + private: + OEvoabVersionHelper *m_pVersionHelper; protected: @@ -79,13 +99,11 @@ namespace connectivity // </properties> // Data & iteration - GList *m_pContacts; sal_Int32 m_nIndex; sal_Int32 m_nLength; EContact *getCur() { - gpointer pData = g_list_nth_data (m_pContacts, m_nIndex); - return pData ? E_CONTACT (pData) : NULL; + return m_pVersionHelper->getContact(m_nIndex); } // OPropertyArrayUsageHelper commit 0cf743b7921e88ed6ece7471daf121344fa78b3a Author: Milan Crha <mc...@redhat.com> Date: Thu Feb 7 17:18:09 2013 +0000 sketch out how to port to e-d-s 3.6 Change-Id: I04d2a4d7d1520567dd0eb929ffb5d9fa53d35dd4 diff --git a/connectivity/source/drivers/evoab2/NDatabaseMetaData.cxx b/connectivity/source/drivers/evoab2/NDatabaseMetaData.cxx index d0198e5..8d0b802 100644 --- a/connectivity/source/drivers/evoab2/NDatabaseMetaData.cxx +++ b/connectivity/source/drivers/evoab2/NDatabaseMetaData.cxx @@ -1075,6 +1075,15 @@ Reference< XResultSet > SAL_CALL OEvoabDatabaseMetaData::getColumns( return xResultSet; } // ------------------------------------------------------------------------- +static bool isSourceBackend( ESource *pSource, const char *backendname) +{ + if (!pSource || e_source_has_extension (pSource, "Address Book")) // E_SOURCE_EXTENSION_ADDRESS_BOOK + return false; + + gpointer extension = e_source_get_extension (pSource, "Address Book"); // E_SOURCE_EXTENSION_ADDRESS_BOOK + return extension && g_strcmp0 (e_source_backend_get_backend_name (extension), backendname) == 0; +} + Reference< XResultSet > SAL_CALL OEvoabDatabaseMetaData::getTables( const Any& /*catalog*/, const ::rtl::OUString& /*schemaPattern*/, const ::rtl::OUString& /*tableNamePattern*/, const Sequence< ::rtl::OUString >& types ) throw(SQLException, RuntimeException) @@ -1111,41 +1120,31 @@ Reference< XResultSet > SAL_CALL OEvoabDatabaseMetaData::getTables( ODatabaseMetaDataResultSet::ORows aRows; - ESourceList *pSourceList; - if( !e_book_get_addressbooks (&pSourceList, NULL) ) - pSourceList = NULL; + GSList *pSources; + pSources = e_source_registry_list_sources (registry, "Address Book"); // E_SOURCE_EXTENSION_ADDRESS_BOOK - GSList *g; - for( g = e_source_list_peek_groups( pSourceList ); g; g = g->next) + GList *liter; + for( liter = pSources; liter; liter = liter->next) { - GSList *s; - const char *p = e_source_group_peek_base_uri(E_SOURCE_GROUP(g->data)); + ESource *pSource = E_SOURCE (liter->data); + bool can = false; switch (m_pConnection->getSDBCAddressType()) { case SDBCAddress::EVO_GWISE: - if ( !strncmp( "groupwise://", p, 11 )) - break; - else - continue; + can = isSourceBackend( pSource, "groupwise"); // not supported in evo/eds 3.6.x+, somehow + break; case SDBCAddress::EVO_LOCAL: - if ( !strncmp( "file://", p, 6 ) || - !strncmp( "local://", p, 6 ) ) - break; - else - continue; + can = isSourceBackend( pSource, "local"); + break; case SDBCAddress::EVO_LDAP: - if ( !strncmp( "ldap://", p, 6 )) - break; - else - continue; + can = isSourceBackend( pSource, "ldap"); + break; case SDBCAddress::Unknown: break; } - for (s = e_source_group_peek_sources (E_SOURCE_GROUP (g->data)); s; s = s->next) - { - ESource *pSource = E_SOURCE (s->data); - rtl::OUString aName = rtl::OStringToOUString( e_source_peek_name( pSource ), + if (can) { + rtl::OUString aName = rtl::OStringToOUString( e_source_get_display_name( pSource ), RTL_TEXTENCODING_UTF8 ); ODatabaseMetaDataResultSet::ORow aRow(3); @@ -1153,10 +1152,12 @@ Reference< XResultSet > SAL_CALL OEvoabDatabaseMetaData::getTables( aRow.push_back(new ORowSetValueDecorator(aName)); aRow.push_back(new ORowSetValueDecorator(aTable)); aRow.push_back(ODatabaseMetaDataResultSet::getEmptyValue()); + // add also e_source_get_uid (pSource) aRows.push_back(aRow); } } + g_slist_free_full (pSources, g_object_unref); pResult->setRows(aRows); return xRef; diff --git a/connectivity/source/drivers/evoab2/NResultSet.cxx b/connectivity/source/drivers/evoab2/NResultSet.cxx index 9b220dc..589e580 100644 --- a/connectivity/source/drivers/evoab2/NResultSet.cxx +++ b/connectivity/source/drivers/evoab2/NResultSet.cxx @@ -126,9 +126,11 @@ OEvoabResultSet::~OEvoabResultSet() // ------------------------------------------------------------------------- static ESource * -findSource( const char *name ) +findSource( const char *uid ) { - ESourceList *pSourceList = NULL; + //ideally as + return e_source_registry_ref_source (registry, uid); + /*ESourceList *pSourceList = NULL; g_return_val_if_fail (name != NULL, NULL); @@ -144,51 +146,48 @@ findSource( const char *name ) return pSource; } } - return NULL; + return NULL;*/ } -static EBook * +static EBookClient * openBook( const char *abname ) { ESource *pSource = findSource (abname); - EBook *pBook = NULL; + EBookClient *pBook = NULL; if (pSource) - pBook = e_book_new (pSource, NULL); + pBook = e_book_client_new (pSource, NULL); - if (pBook && !e_book_open (pBook, TRUE, NULL)) + if (pBook && !e_client_open_sync (pBook, TRUE, NULL, NULL)) { g_object_unref (G_OBJECT (pBook)); pBook = NULL; } + if (pSource) + g_object_unref (pSource); + return pBook; } -static bool isLDAP( EBook *pBook ) +static bool isBookBackend( EBookClient *pBook, const char *backendname) { - return pBook && !strncmp( "ldap://", e_book_get_uri( pBook ), 6 ); -} + ESource *pSource = e_client_get_source ((EClient *) pBook); -static bool isLocal( EBook *pBook ) -{ - return pBook && ( !strncmp( "file://", e_book_get_uri( pBook ), 6 ) || - !strncmp( "local:", e_book_get_uri( pBook ), 6 ) ); + if (!pSource || e_source_has_extension (pSource, "Address Book")) // E_SOURCE_EXTENSION_ADDRESS_BOOK + return false; + + gpointer extension = e_source_get_extension (pSource, "Address Book"); // E_SOURCE_EXTENSION_ADDRESS_BOOK + return extension && g_strcmp0 (e_source_backend_get_backend_name (extension), backendname) == 0; } -static bool isAuthRequired( EBook *pBook ) +static bool isLDAP( EBookClient *pBook ) { - return e_source_get_property( e_book_get_source( pBook ), - "auth" ) != NULL; + return pBook && isBookBackend( pBook, "ldap" ); } -static rtl::OString getUserName( EBook *pBook ) +static bool isLocal( EBookClient *pBook ) { - rtl::OString aName; - if( isLDAP( pBook ) ) - aName = e_source_get_property( e_book_get_source( pBook ), "binddn" ); - else - aName = e_source_get_property( e_book_get_source( pBook ), "user" ); - return aName; + return pBook && isBookBackend( pBook, "local" ); } static ::rtl::OUString @@ -210,24 +209,17 @@ valueToBool( GValue& _rValue ) } static bool -executeQuery (EBook* pBook, EBookQuery* pQuery, GList **ppList, +executeQuery (EBookClient* pBook, EBookQuery* pQuery, GList **ppList, rtl::OString &rPassword, GError **pError) { - ESource *pSource = e_book_get_source( pBook ); - bool bSuccess = false; - bool bAuthSuccess = true; + bool bSuccess; + char *sexp; *ppList = NULL; - if( isAuthRequired( pBook ) ) - { - rtl::OString aUser( getUserName( pBook ) ); - const char *pAuth = e_source_get_property( pSource, "auth" ); - bAuthSuccess = e_book_authenticate_user( pBook, aUser.getStr(), rPassword.getStr(), pAuth, pError ); - } - - if (bAuthSuccess) - bSuccess = e_book_get_contacts( pBook, pQuery, ppList, pError ); + sexp = e_book_query_to_string( pQuery ); + bSuccess = e_book_client_get_contacts_sync( pBook, sexp, ppList, pError ); + g_free (sexp); return bSuccess; } @@ -507,7 +499,7 @@ void OEvoabResultSet::construct( const QueryData& _rData ) { ENSURE_OR_THROW( _rData.getQuery(), "internal error: no EBookQuery" ); - EBook *pBook = openBook(::rtl::OUStringToOString(_rData.sTable, RTL_TEXTENCODING_UTF8).getStr()); + EBookClient *pBook = openBook(::rtl::OUStringToOString(_rData.sTable, RTL_TEXTENCODING_UTF8).getStr()); if ( !pBook ) m_pConnection->throwGenericSQLException( STR_CANNOT_OPEN_BOOK, *this );
_______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/libreoffice-commits