summaryrefslogtreecommitdiff
authorbrad <brad>2004-04-11 12:43:55 (UTC)
committer brad <brad>2004-04-11 12:43:55 (UTC)
commit9716f8c5672a8596306a9b432d9fabc4361baea5 (patch) (unidiff)
tree2b4f23f7e1291ff9f3ff7788068918e31ed63bef
parent40c0415fe7afeeb03de7441e2f667495e81edfa7 (diff)
downloadopie-9716f8c5672a8596306a9b432d9fabc4361baea5.zip
opie-9716f8c5672a8596306a9b432d9fabc4361baea5.tar.gz
opie-9716f8c5672a8596306a9b432d9fabc4361baea5.tar.bz2
Fixes for sqlite regex driver. Function must be implemented as
rlike("pattern","match") instead of "where uid rlike("99")" you must use "where rlike("99",uid). My mistake. Also fixes for pointer math for context regex caching.
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--libopie2/opiedb/osqlitedriver.cpp19
-rw-r--r--libopie2/opiepim/backend/ocontactaccessbackend_sql.cpp4
2 files changed, 14 insertions, 9 deletions
diff --git a/libopie2/opiedb/osqlitedriver.cpp b/libopie2/opiedb/osqlitedriver.cpp
index ccac2f8..588fc8f 100644
--- a/libopie2/opiedb/osqlitedriver.cpp
+++ b/libopie2/opiedb/osqlitedriver.cpp
@@ -43,178 +43,183 @@
43namespace Opie { 43namespace Opie {
44namespace DB { 44namespace DB {
45namespace Internal { 45namespace Internal {
46 46
47namespace { 47namespace {
48 struct Query { 48 struct Query {
49 OSQLError::ValueList errors; 49 OSQLError::ValueList errors;
50 OSQLResultItem::ValueList items; 50 OSQLResultItem::ValueList items;
51 OSQLiteDriver *driver; 51 OSQLiteDriver *driver;
52 }; 52 };
53} 53}
54 54
55 55
56OSQLiteDriver::OSQLiteDriver( QLibrary *lib ) 56OSQLiteDriver::OSQLiteDriver( QLibrary *lib )
57 : OSQLDriver( lib ) 57 : OSQLDriver( lib )
58{ 58{
59 m_sqlite = 0l; 59 m_sqlite = 0l;
60} 60}
61 61
62 62
63OSQLiteDriver::~OSQLiteDriver() { 63OSQLiteDriver::~OSQLiteDriver() {
64 close(); 64 close();
65} 65}
66 66
67 67
68QString OSQLiteDriver::id()const { 68QString OSQLiteDriver::id()const {
69 return QString::fromLatin1("SQLite"); 69 return QString::fromLatin1("SQLite");
70} 70}
71 71
72void OSQLiteDriver::setUserName( const QString& ) {} 72void OSQLiteDriver::setUserName( const QString& ) {}
73 73
74 74
75void OSQLiteDriver::setPassword( const QString& ) {} 75void OSQLiteDriver::setPassword( const QString& ) {}
76 76
77 77
78void OSQLiteDriver::setUrl( const QString& url ) { 78void OSQLiteDriver::setUrl( const QString& url ) {
79 m_url = url; 79 m_url = url;
80} 80}
81 81
82 82
83void OSQLiteDriver::setOptions( const QStringList& ) { 83void OSQLiteDriver::setOptions( const QStringList& ) {
84} 84}
85 85
86/* 86/*
87 * Functions to patch a regex search into sqlite 87 * Functions to patch a regex search into sqlite
88 */ 88 */
89int sqliteRlikeCompare(const char *zPattern, const char *zString, sqregex *reg){ 89int sqliteRlikeCompare(const char *zPattern, const char *zString, sqregex *reg){
90 int res; 90 int res;
91
92 if (reg->regex_raw == NULL || (strcmp (zPattern, reg->regex_raw) != 0)){ 91 if (reg->regex_raw == NULL || (strcmp (zPattern, reg->regex_raw) != 0)){
93 if (reg->regex_raw != NULL) { 92 if (reg->regex_raw != NULL) {
94 free(reg->regex_raw); 93 free(reg->regex_raw);
95 regfree(&reg->regex_c); 94 regfree(&reg->regex_c);
96 } 95 }
97 reg->regex_raw = (char *)malloc(strlen(zPattern)+1); 96 reg->regex_raw = (char *)malloc(strlen(zPattern)+1);
98 strncpy(reg->regex_raw, zPattern, strlen(zPattern)+1); 97 strncpy(reg->regex_raw, zPattern, strlen(zPattern)+1);
99 res = regcomp(&reg->regex_c, zPattern, REG_EXTENDED); 98 res = regcomp(&reg->regex_c, zPattern, REG_EXTENDED);
100 if ( res != 0 ) { 99 if ( res != 0 ) {
101 printf("Regcomp failed with code %u on string %s\n",res,zPattern); 100 printf("Regcomp failed with code %u on string %s\n",res,zPattern);
102 free(reg->regex_raw); 101 free(reg->regex_raw);
103 reg->regex_raw=NULL; 102 reg->regex_raw=NULL;
104 return 0; 103 return 0;
105 } 104 }
106 } 105 }
107 res = (regexec(&reg->regex_c, zString, 0, NULL, 0)==0); 106 res = (regexec(&reg->regex_c, zString, 0, NULL, 0)==0);
108 return res; 107 return res;
109} 108}
110 109
111void rlikeFunc(sqlite_func *context, int arg, const char **argv){ 110void rlikeFunc(sqlite_func *context, int arg, const char **argv){
112 if( argv[0]==0 || argv[1]==0 || argv[2]==0){ 111 if( argv[0]==0 || argv[1]==0 ){
113 printf("One of arguments Null!!\n"); 112 printf("One of arguments Null!!\n");
114 return; 113 return;
115 } 114 }
116 sqlite_set_result_int(context, 115 sqlite_set_result_int(context,
117 sqliteRlikeCompare((const char*)argv[0], 116 sqliteRlikeCompare((const char*)argv[0],
118 (const char*)argv[1], (sqregex*)argv[2])); 117 (const char*)argv[1], (sqregex *)sqlite_user_data(context) ));
119} 118}
120 119
121/* 120/*
122 * try to open a db specified via setUrl 121 * try to open a db specified via setUrl
123 * and options 122 * and options
124 */ 123 */
125bool OSQLiteDriver::open() { 124bool OSQLiteDriver::open() {
126 char *error; 125 char *error;
127 qDebug("OSQLiteDriver::open: about to open"); 126
127 qDebug("OSQLiteDriver::open: about to open");
128 m_sqlite = sqlite_open(m_url.local8Bit(), 128 m_sqlite = sqlite_open(m_url.local8Bit(),
129 0, 129 0,
130 &error ); 130 &error );
131 131
132 /* failed to open */ 132 /* failed to open */
133 if (m_sqlite == 0l ) { 133 if (m_sqlite == 0l ) {
134 // FIXME set the last error 134 // FIXME set the last error
135 qWarning("OSQLiteDriver::open: %s", error ); 135 qWarning("OSQLiteDriver::open: %s", error );
136 free( error ); 136 free( error );
137 return false; 137 return false;
138 } 138 }
139 sqlite_create_function(m_sqlite,"rlike",3,rlikeFunc,&sqreg); 139 if (sqlite_create_function(m_sqlite,"rlike",2,rlikeFunc,&sqreg) != 0)
140 odebug << "Unable to create user defined function!" << oendl;
141 if (sqlite_function_type(m_sqlite,"rlike",SQLITE_NUMERIC) != 0)
142 odebug << "Unable to set rlike function result type!" << oendl;
143 sqreg.regex_raw = NULL;
140 return true; 144 return true;
141} 145}
142 146
143 147
144/* close the db 148/* close the db
145 * sqlite closes them without 149 * sqlite closes them without
146 * telling failure or success 150 * telling failure or success
147 */ 151 */
148bool OSQLiteDriver::close() { 152bool OSQLiteDriver::close() {
149 if (m_sqlite ) 153 if (m_sqlite )
150 sqlite_close( m_sqlite ), m_sqlite=0l; 154 sqlite_close( m_sqlite ), m_sqlite=0l;
151 if (sqreg.regex_raw != NULL){ 155 if (sqreg.regex_raw != NULL){
152 free(sqreg.regex_raw); 156 odebug << "Freeing regex on close" << oendl;
157 free(sqreg.regex_raw);
153 sqreg.regex_raw=NULL; 158 sqreg.regex_raw=NULL;
154 regfree(&sqreg.regex_c); 159 regfree(&sqreg.regex_c);
155 } 160 }
156 return true; 161 return true;
157} 162}
158 163
159 164
160/* Query */ 165/* Query */
161OSQLResult OSQLiteDriver::query( OSQLQuery* qu) { 166OSQLResult OSQLiteDriver::query( OSQLQuery* qu) {
162 if ( !m_sqlite ) { 167 if ( !m_sqlite ) {
163 // FIXME set error code 168 // FIXME set error code
164 OSQLResult result( OSQLResult::Failure ); 169 OSQLResult result( OSQLResult::Failure );
165 return result; 170 return result;
166 } 171 }
167 Query query; 172 Query query;
168 query.driver = this; 173 query.driver = this;
169 char *err; 174 char *err;
170 /* SQLITE_OK 0 if return code > 0 == failure */ 175 /* SQLITE_OK 0 if return code > 0 == failure */
171 if ( sqlite_exec(m_sqlite, qu->query(),&call_back, &query, &err) > 0 ) { 176 if ( sqlite_exec(m_sqlite, qu->query(),&call_back, &query, &err) > 0 ) {
172 qWarning("OSQLiteDriver::query: Error while executing"); 177 qWarning("OSQLiteDriver::query: Error while executing %s",err);
173 free(err ); 178 free(err );
174 // FixMe Errors 179 // FixMe Errors
175 } 180 }
176 181
177 OSQLResult result(OSQLResult::Success, 182 OSQLResult result(OSQLResult::Success,
178 query.items, 183 query.items,
179 query.errors ); 184 query.errors );
180 return result; 185 return result;
181} 186}
182 187
183 188
184OSQLTable::ValueList OSQLiteDriver::tables() const { 189OSQLTable::ValueList OSQLiteDriver::tables() const {
185 190
186} 191}
187 192
188 193
189OSQLError OSQLiteDriver::lastError() { 194OSQLError OSQLiteDriver::lastError() {
190 OSQLError error; 195 OSQLError error;
191 return error; 196 return error;
192}; 197};
193 198
194 199
195/* handle a callback add the row to the global 200/* handle a callback add the row to the global
196 * OSQLResultItem 201 * OSQLResultItem
197 */ 202 */
198int OSQLiteDriver::handleCallBack( int, char**, char** ) { 203int OSQLiteDriver::handleCallBack( int, char**, char** ) {
199 return 0; 204 return 0;
200} 205}
201 206
202 207
203/* callback_handler add the values to the list*/ 208/* callback_handler add the values to the list*/
204int OSQLiteDriver::call_back( void* voi, int argc, 209int OSQLiteDriver::call_back( void* voi, int argc,
205 char** argv, char** columns) { 210 char** argv, char** columns) {
206 Query* qu = (Query*)voi; 211 Query* qu = (Query*)voi;
207 212
208 //copy them over to a OSQLResultItem 213 //copy them over to a OSQLResultItem
209 QMap<QString, QString> tableString; 214 QMap<QString, QString> tableString;
210 QMap<int, QString> tableInt; 215 QMap<int, QString> tableInt;
211 for (int i = 0; i < argc; i++ ) { 216 for (int i = 0; i < argc; i++ ) {
212 217
213#ifdef __BUGGY_LOCAL8BIT_ 218#ifdef __BUGGY_LOCAL8BIT_
214 tableInt.insert( i, QString::fromLatin1( argv[i] ) ); 219 tableInt.insert( i, QString::fromLatin1( argv[i] ) );
215 tableString.insert( QString::fromLatin1( columns[i] ), 220 tableString.insert( QString::fromLatin1( columns[i] ),
216 QString::fromLatin1( argv[i] ) ); 221 QString::fromLatin1( argv[i] ) );
217#else 222#else
218 tableInt.insert( i, QString::fromLocal8Bit( argv[i] ) ); 223 tableInt.insert( i, QString::fromLocal8Bit( argv[i] ) );
219 tableString.insert( QString::fromLocal8Bit( columns[i] ), 224 tableString.insert( QString::fromLocal8Bit( columns[i] ),
220 QString::fromLocal8Bit( argv[i] ) ); 225 QString::fromLocal8Bit( argv[i] ) );
diff --git a/libopie2/opiepim/backend/ocontactaccessbackend_sql.cpp b/libopie2/opiepim/backend/ocontactaccessbackend_sql.cpp
index bb5c99b..401a3c1 100644
--- a/libopie2/opiepim/backend/ocontactaccessbackend_sql.cpp
+++ b/libopie2/opiepim/backend/ocontactaccessbackend_sql.cpp
@@ -556,110 +556,110 @@ QArray<int> OPimContactAccessBackend_SQL::queryByExample ( const OPimContact &qu
556 if ( ( settings & OPimContactAccess::DateDiff ) 556 if ( ( settings & OPimContactAccess::DateDiff )
557 || ( settings & OPimContactAccess::DateYear ) 557 || ( settings & OPimContactAccess::DateYear )
558 || ( settings & OPimContactAccess::DateMonth ) ) 558 || ( settings & OPimContactAccess::DateMonth ) )
559 searchQuery += " AND"; 559 searchQuery += " AND";
560 560
561 searchQuery += QString( " (\"%1\" LIKE '%-%-%2')" ) 561 searchQuery += QString( " (\"%1\" LIKE '%-%-%2')" )
562 .arg( *it ) 562 .arg( *it )
563 .arg( QString::number( endDate->day() ).rightJustify( 2, '0' ) ); 563 .arg( QString::number( endDate->day() ).rightJustify( 2, '0' ) );
564 } 564 }
565 565
566 break; 566 break;
567 default: 567 default:
568 // Switching between case sensitive and insensitive... 568 // Switching between case sensitive and insensitive...
569 // LIKE is not case sensitive, GLOB is case sensitive 569 // LIKE is not case sensitive, GLOB is case sensitive
570 // Do exist a better solution to switch this ? 570 // Do exist a better solution to switch this ?
571 if ( settings & OPimContactAccess::IgnoreCase ) 571 if ( settings & OPimContactAccess::IgnoreCase )
572 searchQuery += "(\"" + *it + "\"" + " LIKE " + "'" 572 searchQuery += "(\"" + *it + "\"" + " LIKE " + "'"
573 + queryStr.replace(QRegExp("\\*"),"%") + "'" + ")"; 573 + queryStr.replace(QRegExp("\\*"),"%") + "'" + ")";
574 else 574 else
575 searchQuery += "(\"" + *it + "\"" + " GLOB " + "'" 575 searchQuery += "(\"" + *it + "\"" + " GLOB " + "'"
576 + queryStr + "'" + ")"; 576 + queryStr + "'" + ")";
577 577
578 } 578 }
579 } 579 }
580 } 580 }
581 // Skip trailing "AND" 581 // Skip trailing "AND"
582 // if ( isAnyFieldSelected ) 582 // if ( isAnyFieldSelected )
583 // qu = qu.left( qu.length() - 4 ); 583 // qu = qu.left( qu.length() - 4 );
584 584
585 qu += searchQuery; 585 qu += searchQuery;
586 586
587 qDebug( "queryByExample query: %s", qu.latin1() ); 587 qDebug( "queryByExample query: %s", qu.latin1() );
588 588
589 // Execute query and return the received uid's 589 // Execute query and return the received uid's
590 OSQLRawQuery raw( qu ); 590 OSQLRawQuery raw( qu );
591 OSQLResult res = m_driver->query( &raw ); 591 OSQLResult res = m_driver->query( &raw );
592 if ( res.state() != OSQLResult::Success ){ 592 if ( res.state() != OSQLResult::Success ){
593 QArray<int> empty; 593 QArray<int> empty;
594 return empty; 594 return empty;
595 } 595 }
596 596
597 QArray<int> list = extractUids( res ); 597 QArray<int> list = extractUids( res );
598 598
599 return list; 599 return list;
600} 600}
601 601
602QArray<int> OPimContactAccessBackend_SQL::matchRegexp( const QRegExp &r ) const 602QArray<int> OPimContactAccessBackend_SQL::matchRegexp( const QRegExp &r ) const
603{ 603{
604#if 1 604#if 0
605 QArray<int> nix(0); 605 QArray<int> nix(0);
606 return nix; 606 return nix;
607 607
608#else 608#else
609 QString qu = "SELECT uid FROM addressbook WHERE ("; 609 QString qu = "SELECT uid FROM addressbook WHERE (";
610 QString searchlist; 610 QString searchlist;
611 611
612 QStringList fieldList = OPimContactFields::untrfields( false ); 612 QStringList fieldList = OPimContactFields::untrfields( false );
613 // QMap<QString, int> translate = OPimContactFields::untrFieldsToId(); 613 // QMap<QString, int> translate = OPimContactFields::untrFieldsToId();
614 for ( QStringList::Iterator it = ++fieldList.begin(); it != fieldList.end(); ++it ){ 614 for ( QStringList::Iterator it = ++fieldList.begin(); it != fieldList.end(); ++it ){
615 if ( !searchlist.isEmpty() ) 615 if ( !searchlist.isEmpty() )
616 searchlist += " OR "; 616 searchlist += " OR ";
617 searchlist += "\"" + *it + "\" rlike(\"" + r.pattern() + "\") "; 617 searchlist += " rlike(\""+ r.pattern() + "\",\"" + *it + "\") ";
618 } 618 }
619 619
620 qu = qu + searchlist + ")"; 620 qu = qu + searchlist + ")";
621 621
622 qDebug( "query: %s", qu.latin1() ); 622 qDebug( "query: %s", qu.latin1() );
623 623
624 OSQLRawQuery raw( qu ); 624 OSQLRawQuery raw( qu );
625 OSQLResult res = m_driver->query( &raw ); 625 OSQLResult res = m_driver->query( &raw );
626 626
627 return extractUids( res ); 627 return extractUids( res );
628 628
629 629
630#endif 630#endif
631} 631}
632 632
633const uint OPimContactAccessBackend_SQL::querySettings() 633const uint OPimContactAccessBackend_SQL::querySettings()
634{ 634{
635 return OPimContactAccess::IgnoreCase 635 return OPimContactAccess::IgnoreCase
636 | OPimContactAccess::WildCards 636 | OPimContactAccess::WildCards
637 | OPimContactAccess::DateDiff 637 | OPimContactAccess::DateDiff
638 | OPimContactAccess::DateYear 638 | OPimContactAccess::DateYear
639 | OPimContactAccess::DateMonth 639 | OPimContactAccess::DateMonth
640 | OPimContactAccess::DateDay 640 | OPimContactAccess::DateDay
641 ; 641 ;
642} 642}
643 643
644bool OPimContactAccessBackend_SQL::hasQuerySettings (uint querySettings) const 644bool OPimContactAccessBackend_SQL::hasQuerySettings (uint querySettings) const
645{ 645{
646 /* OPimContactAccess::IgnoreCase, DateDiff, DateYear, DateMonth, DateDay 646 /* OPimContactAccess::IgnoreCase, DateDiff, DateYear, DateMonth, DateDay
647 * may be added with any of the other settings. IgnoreCase should never used alone. 647 * may be added with any of the other settings. IgnoreCase should never used alone.
648 * Wildcards, RegExp, ExactMatch should never used at the same time... 648 * Wildcards, RegExp, ExactMatch should never used at the same time...
649 */ 649 */
650 650
651 // Step 1: Check whether the given settings are supported by this backend 651 // Step 1: Check whether the given settings are supported by this backend
652 if ( ( querySettings & ( 652 if ( ( querySettings & (
653 OPimContactAccess::IgnoreCase 653 OPimContactAccess::IgnoreCase
654 | OPimContactAccess::WildCards 654 | OPimContactAccess::WildCards
655 | OPimContactAccess::DateDiff 655 | OPimContactAccess::DateDiff
656 | OPimContactAccess::DateYear 656 | OPimContactAccess::DateYear
657 | OPimContactAccess::DateMonth 657 | OPimContactAccess::DateMonth
658 | OPimContactAccess::DateDay 658 | OPimContactAccess::DateDay
659 // | OPimContactAccess::RegExp 659 // | OPimContactAccess::RegExp
660 // | OPimContactAccess::ExactMatch 660 // | OPimContactAccess::ExactMatch
661 ) ) != querySettings ) 661 ) ) != querySettings )
662 return false; 662 return false;
663 663
664 // Step 2: Check whether the given combinations are ok.. 664 // Step 2: Check whether the given combinations are ok..
665 665