1
0
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:
danielk1977
2007-05-07 09:32:45 +00:00
parent a58906a8dd
commit a9808b31a8
9 changed files with 216 additions and 48 deletions

View File

@@ -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);