mirror of
https://github.com/sqlite/sqlite.git
synced 2025-08-10 01:02:56 +03:00
Add the experimental create_collation_x() api. (CVS 3934)
FossilOrigin-Name: ff49d48f2f025898a0f4ace1fc227e1d367ea89f
This commit is contained in:
63
src/main.c
63
src/main.c
@@ -14,7 +14,7 @@
|
||||
** other files are for internal use by SQLite and should not be
|
||||
** accessed by users of the library.
|
||||
**
|
||||
** $Id: main.c,v 1.371 2007/05/06 16:04:12 danielk1977 Exp $
|
||||
** $Id: main.c,v 1.372 2007/05/07 09:32:45 danielk1977 Exp $
|
||||
*/
|
||||
#include "sqliteInt.h"
|
||||
#include "os.h"
|
||||
@@ -182,6 +182,12 @@ int sqlite3_close(sqlite3 *db){
|
||||
|
||||
for(i=sqliteHashFirst(&db->aCollSeq); i; i=sqliteHashNext(i)){
|
||||
CollSeq *pColl = (CollSeq *)sqliteHashData(i);
|
||||
/* Invoke any destructors registered for collation sequence user data. */
|
||||
for(j=0; j<3; j++){
|
||||
if( pColl[j].xDel ){
|
||||
pColl[j].xDel(pColl[j].pUser);
|
||||
}
|
||||
}
|
||||
sqliteFree(pColl);
|
||||
}
|
||||
sqlite3HashClear(&db->aCollSeq);
|
||||
@@ -825,7 +831,8 @@ static int createCollation(
|
||||
const char *zName,
|
||||
int enc,
|
||||
void* pCtx,
|
||||
int(*xCompare)(void*,int,const void*,int,const void*)
|
||||
int(*xCompare)(void*,int,const void*,int,const void*),
|
||||
void(*xDel)(void*)
|
||||
){
|
||||
CollSeq *pColl;
|
||||
int enc2;
|
||||
@@ -860,12 +867,33 @@ static int createCollation(
|
||||
return SQLITE_BUSY;
|
||||
}
|
||||
sqlite3ExpirePreparedStatements(db);
|
||||
|
||||
/* If collation sequence pColl was created directly by a call to
|
||||
** sqlite3_create_collation, and not generated by synthCollSeq(),
|
||||
** then any copies made by synthCollSeq() need to be invalidated.
|
||||
** Also, collation destructor - CollSeq.xDel() - function may need
|
||||
** to be called.
|
||||
*/
|
||||
if( (pColl->enc & ~SQLITE_UTF16_ALIGNED)==enc2 ){
|
||||
CollSeq *aColl = sqlite3HashFind(&db->aCollSeq, zName, strlen(zName));
|
||||
int j;
|
||||
for(j=0; j<3; j++){
|
||||
CollSeq *p = &aColl[j];
|
||||
if( p->enc==pColl->enc ){
|
||||
if( p->xDel ){
|
||||
p->xDel(p->pUser);
|
||||
}
|
||||
p->xCmp = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pColl = sqlite3FindCollSeq(db, (u8)enc2, zName, strlen(zName), 1);
|
||||
if( pColl ){
|
||||
pColl->xCmp = xCompare;
|
||||
pColl->pUser = pCtx;
|
||||
pColl->xDel = xDel;
|
||||
pColl->enc = enc2 | (enc & SQLITE_UTF16_ALIGNED);
|
||||
}
|
||||
sqlite3Error(db, SQLITE_OK, 0);
|
||||
@@ -915,9 +943,9 @@ static int openDatabase(
|
||||
** and UTF-16, so add a version for each to avoid any unnecessary
|
||||
** conversions. The only error that can occur here is a malloc() failure.
|
||||
*/
|
||||
if( createCollation(db, "BINARY", SQLITE_UTF8, 0, binCollFunc) ||
|
||||
createCollation(db, "BINARY", SQLITE_UTF16BE, 0, binCollFunc) ||
|
||||
createCollation(db, "BINARY", SQLITE_UTF16LE, 0, binCollFunc) ||
|
||||
if( createCollation(db, "BINARY", SQLITE_UTF8, 0, binCollFunc, 0) ||
|
||||
createCollation(db, "BINARY", SQLITE_UTF16BE, 0, binCollFunc, 0) ||
|
||||
createCollation(db, "BINARY", SQLITE_UTF16LE, 0, binCollFunc, 0) ||
|
||||
(db->pDfltColl = sqlite3FindCollSeq(db, SQLITE_UTF8, "BINARY", 6, 0))==0
|
||||
){
|
||||
assert( sqlite3MallocFailed() );
|
||||
@@ -926,7 +954,7 @@ static int openDatabase(
|
||||
}
|
||||
|
||||
/* Also add a UTF-8 case-insensitive collation sequence. */
|
||||
createCollation(db, "NOCASE", SQLITE_UTF8, 0, nocaseCollatingFunc);
|
||||
createCollation(db, "NOCASE", SQLITE_UTF8, 0, nocaseCollatingFunc, 0);
|
||||
|
||||
/* Set flags on the built-in collating sequences */
|
||||
db->pDfltColl->type = SQLITE_COLL_BINARY;
|
||||
@@ -986,7 +1014,7 @@ static int openDatabase(
|
||||
#endif
|
||||
|
||||
#ifdef SQLITE_ENABLE_ICU
|
||||
{
|
||||
if( !sqlite3MallocFailed() ){
|
||||
extern int sqlite3IcuInit(sqlite3*);
|
||||
sqlite3IcuInit(db);
|
||||
}
|
||||
@@ -1106,7 +1134,24 @@ int sqlite3_create_collation(
|
||||
){
|
||||
int rc;
|
||||
assert( !sqlite3MallocFailed() );
|
||||
rc = createCollation(db, zName, enc, pCtx, xCompare);
|
||||
rc = createCollation(db, zName, enc, pCtx, xCompare, 0);
|
||||
return sqlite3ApiExit(db, rc);
|
||||
}
|
||||
|
||||
/*
|
||||
** Register a new collation sequence with the database handle db.
|
||||
*/
|
||||
int sqlite3_create_collation_x(
|
||||
sqlite3* db,
|
||||
const char *zName,
|
||||
int enc,
|
||||
void* pCtx,
|
||||
int(*xCompare)(void*,int,const void*,int,const void*),
|
||||
void(*xDel)(void*)
|
||||
){
|
||||
int rc;
|
||||
assert( !sqlite3MallocFailed() );
|
||||
rc = createCollation(db, zName, enc, pCtx, xCompare, xDel);
|
||||
return sqlite3ApiExit(db, rc);
|
||||
}
|
||||
|
||||
@@ -1126,7 +1171,7 @@ int sqlite3_create_collation16(
|
||||
assert( !sqlite3MallocFailed() );
|
||||
zName8 = sqlite3utf16to8(zName, -1);
|
||||
if( zName8 ){
|
||||
rc = createCollation(db, zName8, enc, pCtx, xCompare);
|
||||
rc = createCollation(db, zName8, enc, pCtx, xCompare, 0);
|
||||
sqliteFree(zName8);
|
||||
}
|
||||
return sqlite3ApiExit(db, rc);
|
||||
|
Reference in New Issue
Block a user