Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Add a destructor function to the collation_needed() API.
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 577089fa36634d211a106e40fa5c52c7e9580ab5
User & Date: dan 2013-06-14 20:03:20.942
Context
2013-06-15
17:45
Add tests to ensure that the collation_needed destructor is invoked as required. check-in: 6e0b04adb9 user: dan tags: trunk
2013-06-14
20:03
Add a destructor function to the collation_needed() API. check-in: 577089fa36 user: dan tags: trunk
18:28
Have sqlite4_authorizer_push() invoke any destructor passed to it if an error (i.e. a malloc failure) occurs. check-in: cb28262fc8 user: dan tags: trunk
Changes
Unified Diff Ignore Whitespace Patch
Changes to src/main.c.
405
406
407
408
409
410
411



412
413
414
415
416
417
418
  /* Free any authorizer callbacks */
  sqlite4AuthFreeAll(db);

  /* Tell the code in notify.c that the connection no longer holds any
  ** locks and does not require any further unlock-notify callbacks.
  */
  sqlite4ConnectionClosed(db);



  
  /* Delete tokenizers */
  sqlite4ShutdownFts5(db);

  assert( db->nDb<=2 );
  assert( db->aDb==db->aDbStatic );
  {







>
>
>







405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
  /* Free any authorizer callbacks */
  sqlite4AuthFreeAll(db);

  /* Tell the code in notify.c that the connection no longer holds any
  ** locks and does not require any further unlock-notify callbacks.
  */
  sqlite4ConnectionClosed(db);

  /* Delete any collation needed callback */
  sqlite4_collation_needed(db, 0, 0, 0);
  
  /* Delete tokenizers */
  sqlite4ShutdownFts5(db);

  assert( db->nDb<=2 );
  assert( db->aDb==db->aDbStatic );
  {
1355
1356
1357
1358
1359
1360
1361

1362
1363
1364
1365



1366

1367
1368
1369
1370
1371
1372
1373

/*
** Register a collation sequence factory callback with the database handle
** db. Replace any previously installed collation sequence factory.
*/
int sqlite4_collation_needed(
  sqlite4 *db, 

  void(*xCollNeeded)(void*,sqlite4*,const char*),
  void *pCollNeededArg
){
  sqlite4_mutex_enter(db->mutex);



  db->xCollNeeded = xCollNeeded;

  db->pCollNeededArg = pCollNeededArg;
  sqlite4_mutex_leave(db->mutex);
  return SQLITE4_OK;
}

/*
** Test to see whether or not the database connection is currently within







>

|


>
>
>

>







1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381

/*
** Register a collation sequence factory callback with the database handle
** db. Replace any previously installed collation sequence factory.
*/
int sqlite4_collation_needed(
  sqlite4 *db, 
  void *pCollNeededArg,
  void(*xCollNeeded)(void*,sqlite4*,const char*),
  void(*xDestroy)(void*)
){
  sqlite4_mutex_enter(db->mutex);
  if( db->xCollNeededDestroy ){
    db->xCollNeededDestroy(db->pCollNeededArg);
  }
  db->xCollNeeded = xCollNeeded;
  db->xCollNeededDestroy = xDestroy;
  db->pCollNeededArg = pCollNeededArg;
  sqlite4_mutex_leave(db->mutex);
  return SQLITE4_OK;
}

/*
** Test to see whether or not the database connection is currently within
Changes to src/sqlite.h.in.
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761




2762




2763






2764
2765
2766
2767
2768
2769
2770
2771



2772
2773






2774
2775
2776

2777
2778
2779
2780
2781
2782
2783
2784
2785
  int(*xMakeKey)(void*, sqlite4_value*, int, void*, int*),
  void(*xDestroy)(void*)
);

/*
** CAPIREF: Collation Needed Callbacks
**
** ^To avoid having to register all collation sequences before a database
** can be used, a single callback function may be registered with the
** [database connection] to be invoked whenever an undefined collation




** sequence is required.




**






** ^(When the callback is invoked, the first argument passed is a copy
** of the second argument to sqlite4_collation_needed() or
** sqlite4_collation_needed16().  The second argument is the database
** connection.  The third argument is one of [SQLITE4_UTF8], [SQLITE4_UTF16BE],
** or [SQLITE4_UTF16LE], indicating the most desirable form of the collation
** sequence function required.  The fourth parameter is the name of the
** required collation sequence.)^
**



** The callback function should register the desired collation using
** [sqlite4_create_collation()].






*/
int sqlite4_collation_needed(
  sqlite4*, 

  void(*)(void*,sqlite4*,const char*),
  void* 
);

/*
** CAPIREF: Suspend Execution For A Short Time
**
** The sqlite4_sleep() function causes the current thread to suspend execution
** for at least a number of milliseconds specified in its parameter.







|
<
|
>
>
>
>
|
>
>
>
>

>
>
>
>
>
>
|
|
|
|
<
|
|

>
>
>
|
|
>
>
>
>
>
>



>
|
|







2752
2753
2754
2755
2756
2757
2758
2759

2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780

2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
  int(*xMakeKey)(void*, sqlite4_value*, int, void*, int*),
  void(*xDestroy)(void*)
);

/*
** CAPIREF: Collation Needed Callbacks
**
** This function is used to register a callback that is invoked by

** the SQL compiler whenever an undefined collation sequence is defined.
** If the callback registers the required collation sequence with the
** database handle by calling [sqlite4_create_collation]() before returning, 
** then compilation of the statement proceeds. Otherwise, statement 
** compilation fails and an error is returned to the user.
**
** Each database handle may have at most one collation needed callback
** registered at a time. If this function is called on a database handle
** for which a collation needed callback has already been registered, the
** new callback replaces the old.
**
** The first argument to this function is the database handle to register
** the callback with. The second is a context pointer, a copy of which is
** passed as the first argument to the collation needed callback each time 
** it is invoked. The third argument is a pointer to the collation needed
** callback function to register.
**
** When the collation needed callback is invoked, the first argument is
** a copy of the context pointer passed to sqlite4_collation_needed(). The
** second is the database handle with which the callback should, if 
** possible, register the required collation. The third argument is a 

** pointer to a nul-terminated string containing the name of the required
** collation.
**
** If it is not NULL, the fourth argument passed to sqlite4_collation_needed()
** is a destructor function to be invoked when the callback is no longer
** required. In other words, when the database handle is closed or
** when the callback is overridden by a subsequent call to
** sqlite4_collation_needed().
**
** If an error occurs within this function, an error code is returned and
** the collation needed function is not registered with the database handle. 
** In this case the destructor function, if any, is invoked before the
** call to sqlite4_collation_needed() returns. If no error occurs, SQLITE4_OK
** is returned.
*/
int sqlite4_collation_needed(
  sqlite4*, 
  void*,
  void(*xFactory)(void*,sqlite4*,const char*),
  void(*xDestroy)(void*)
);

/*
** CAPIREF: Suspend Execution For A Short Time
**
** The sqlite4_sleep() function causes the current thread to suspend execution
** for at least a number of milliseconds specified in its parameter.
Changes to src/sqliteInt.h.
821
822
823
824
825
826
827

828
829
830
831
832
833
834
  void (*xProfile)(void*,const char*,u64);  /* Profiling function */
  void *pProfileArg;                        /* Argument to profile function */
#ifndef SQLITE4_OMIT_WAL
  int (*xWalCallback)(void *, sqlite4 *, const char *, int);
  void *pWalArg;
#endif
  void(*xCollNeeded)(void*,sqlite4*,const char*);

  void *pCollNeededArg;
  sqlite4_value *pErr;          /* Most recent error message */
  char *zErrMsg;                /* Most recent error message (UTF-8 encoded) */
  char *zErrMsg16;              /* Most recent error message (UTF-16 encoded) */
  union {
    volatile int isInterrupted; /* True if sqlite4_interrupt has been called */
    double notUsed1;            /* Spacer */







>







821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
  void (*xProfile)(void*,const char*,u64);  /* Profiling function */
  void *pProfileArg;                        /* Argument to profile function */
#ifndef SQLITE4_OMIT_WAL
  int (*xWalCallback)(void *, sqlite4 *, const char *, int);
  void *pWalArg;
#endif
  void(*xCollNeeded)(void*,sqlite4*,const char*);
  void(*xCollNeededDestroy)(void*);
  void *pCollNeededArg;
  sqlite4_value *pErr;          /* Most recent error message */
  char *zErrMsg;                /* Most recent error message (UTF-8 encoded) */
  char *zErrMsg16;              /* Most recent error message (UTF-16 encoded) */
  union {
    volatile int isInterrupted; /* True if sqlite4_interrupt has been called */
    double notUsed1;            /* Spacer */
Changes to src/tclsqlite.c.
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
      return TCL_ERROR;
    }
    if( pDb->pCollateNeeded ){
      Tcl_DecrRefCount(pDb->pCollateNeeded);
    }
    pDb->pCollateNeeded = Tcl_DuplicateObj(objv[2]);
    Tcl_IncrRefCount(pDb->pCollateNeeded);
    sqlite4_collation_needed(pDb->db, tclCollateNeeded, (void *)pDb);
    break;
  }

  /*    $db complete SQL
  **
  ** Return TRUE if SQL is a complete SQL statement.  Return FALSE if
  ** additional lines of input are needed.  This is similar to the







|







1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
      return TCL_ERROR;
    }
    if( pDb->pCollateNeeded ){
      Tcl_DecrRefCount(pDb->pCollateNeeded);
    }
    pDb->pCollateNeeded = Tcl_DuplicateObj(objv[2]);
    Tcl_IncrRefCount(pDb->pCollateNeeded);
    sqlite4_collation_needed(pDb->db, (void *)pDb, tclCollateNeeded, 0);
    break;
  }

  /*    $db complete SQL
  **
  ** Return TRUE if SQL is a complete SQL statement.  Return FALSE if
  ** additional lines of input are needed.  This is similar to the
Changes to test/collate7.test.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#
# 2007 May 7
#
# The author disclaims copyright to this source code.  In place of
# a legal notice, here is a blessing:
#
#    May you do good and not evil.
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#***********************************************************************
#
# This file implements regression tests for SQLite library. The
# focus of this script is the sqlite4_create_collation() API. More
# specifically, the focus is on testing that collation destructor
# functions are invoked correctly.
#

set testdir [file dirname $argv0]
source $testdir/tester.tcl
set ::testprefix collate7















|
|
|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#
# 2007 May 7
#
# The author disclaims copyright to this source code.  In place of
# a legal notice, here is a blessing:
#
#    May you do good and not evil.
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#***********************************************************************
#
# This file implements regression tests for SQLite library. The
# focus of this script is the sqlite4_create_collation() and 
# collation_needed() APIs. More specifically, the focus is on testing that 
# destructor callbacks are invoked correctly.
#

set testdir [file dirname $argv0]
source $testdir/tester.tcl
set ::testprefix collate7