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

Overview
Comment:Add tests to ensure that the collation_needed destructor is invoked as required.
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 6e0b04adb9aba04a15a253908a19c6911b97bc54
User & Date: dan 2013-06-15 17:45:01.643
Context
2013-06-15
19:47
Add destructors to the sqlite4_trace and sqlite4_profile routines. check-in: fd63f9cb75 user: dan tags: trunk
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
Changes
Unified Diff Ignore Whitespace Patch
Changes to test/collate7.test.
103
104
105
106
107
108
109

























110



111

112
  sqlite4_errmsg db 
} {unable to delete/modify collation sequence due to active statements}

do_test 3.5 { sqlite4_finalize $::stmt } {SQLITE4_OK}
do_test 3.6 { sqlite4_errcode db       } {SQLITE4_OK}
do_test 3.7 { sqlite4_errmsg db        } {not an error}


























finish_test













>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
>

>

103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
  sqlite4_errmsg db 
} {unable to delete/modify collation sequence due to active statements}

do_test 3.5 { sqlite4_finalize $::stmt } {SQLITE4_OK}
do_test 3.6 { sqlite4_errcode db       } {SQLITE4_OK}
do_test 3.7 { sqlite4_errmsg db        } {not an error}

#-------------------------------------------------------------------------
# The following tests verify that the collation needed destructor is
# invoked:
#
#   1. When it is overridden, and
#   2. When the database connection is closed.
#
# It would be good to test that if an error occurs within the 
# collation_needed() the destructor is invoked immediately (as the 
# documentation says). However there is currently no way to cause
# sqlite4_collation_needed() to fail. sqlite4_collation_needed() 
# currently *always* returns SQLITE4_OK.
#
do_test 4.1.1 {
  set ::coll_needed_del 0
  sqlite4_collation_needed db coll_needed {incr ::coll_needed_del}
  set ::coll_needed_del
} {0}

do_test 4.1.2 {
  set ::coll_needed_del2 0
  sqlite4_collation_needed db coll_needed {incr ::coll_needed_del2}
  list $::coll_needed_del $::coll_needed_del2
} {1 0}

do_test 4.2 {
  db close
  list $::coll_needed_del $::coll_needed_del2
} {1 1}

finish_test

Changes to test/test_main.c.
1483
1484
1485
1486
1487
1488
1489















































































1490
1491
1492
1493
1494
1495
1496
    return TCL_ERROR;
  }
  Tcl_ResetResult(interp);
  return TCL_OK;
}
/* End of [sqlite4_create_collation] implementation.
********************************************************************/
















































































/*
** USAGE: sqlite4_create_function_v2 DB NAME NARG ENC ?SWITCHES?
**
** Available switches are:
**
**   -func    SCRIPT







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
    return TCL_ERROR;
  }
  Tcl_ResetResult(interp);
  return TCL_OK;
}
/* End of [sqlite4_create_collation] implementation.
********************************************************************/

struct TestNeededX {
  Tcl_Interp *interp;
  Tcl_Obj *pNeeded;
  Tcl_Obj *pDel;
};
typedef struct TestNeededX TestNeededX;

static void testCollationNeeded(void *pCtx, sqlite4 *db, const char *zReq){
  TestNeededX *p = (TestCollationX *)pCtx;
  Tcl_Obj *pScript;
  int rc;

  pScript = Tcl_DuplicateObj(p->pNeeded);
  Tcl_IncrRefCount(pScript);
  Tcl_ListObjAppendElement(0, pScript, Tcl_NewStringObj(zReq, -1));
  rc = Tcl_EvalObjEx(p->interp, pScript, TCL_EVAL_DIRECT|TCL_EVAL_GLOBAL);
  Tcl_DecrRefCount(pScript);

  if( rc!=TCL_OK ){
    Tcl_BackgroundError(p->interp);
  }
}

static void testCollationNeededDel(void *pCtx){
  TestNeededX *p = (TestNeededX*)pCtx;
  int rc = Tcl_EvalObjEx(p->interp, p->pDel, TCL_EVAL_DIRECT|TCL_EVAL_GLOBAL);
  if( rc!=TCL_OK ){
    Tcl_BackgroundError(p->interp);
  }

  Tcl_DecrRefCount(p->pNeeded);
  Tcl_DecrRefCount(p->pDel);
  sqlite4_free(0, (void *)p);
}

/*
** Usage: sqlite4_collation_needed DB CALLBACK-PROC DEL-PROC
*/
static int test_collation_needed(
  ClientData clientData,          /* Not used */
  Tcl_Interp *interp,             /* The TCL interpreter */
  int objc,                       /* Number of arguments */
  Tcl_Obj *CONST objv[]           /* Command arguments */
){
  int nByte;                      /* Size of callback scripts in bytes */
  TestNeededX *p;                 /* New context object */
  sqlite4 *db;                    /* Database handle */
  int rc;                         /* create_collation() return code */

  if( objc!=4 ){
    Tcl_WrongNumArgs(interp, 1, objv, "DB CALLBACK-PROC DEL-PROC");
    return TCL_ERROR;
  }
  if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;

  Tcl_GetStringFromObj(objv[2], &nByte);
  if( nByte==0 ){
    rc = sqlite4_collation_needed(db, 0, 0, 0);
  }else{
    p = (TestNeededX*)sqlite4_malloc(0, sizeof(TestNeededX));
    p->pNeeded = objv[2];
    p->pDel = objv[3];
    p->interp = interp;
    Tcl_IncrRefCount(p->pNeeded);
    Tcl_IncrRefCount(p->pDel);

    rc = sqlite4_collation_needed(
        db, (void*)p, testCollationNeeded, testCollationNeededDel
    );
  }

  if( rc!=SQLITE4_OK ){
    Tcl_SetObjResult(interp, Tcl_NewStringObj(sqlite4TestErrorName(rc), -1));
    return TCL_ERROR;
  }
  Tcl_ResetResult(interp);
  return TCL_OK;
}

/*
** USAGE: sqlite4_create_function_v2 DB NAME NARG ENC ?SWITCHES?
**
** Available switches are:
**
**   -func    SCRIPT
3975
3976
3977
3978
3979
3980
3981

3982
3983
3984
3985
3986
3987
3988
#ifdef SQLITE4_ENABLE_COLUMN_METADATA
{ "sqlite4_column_database_name",test_stmt_utf8,(void*)sqlite4_column_database_name},
{ "sqlite4_column_table_name",test_stmt_utf8,(void*)sqlite4_column_table_name},
{ "sqlite4_column_origin_name",test_stmt_utf8,(void*)sqlite4_column_origin_name},
#endif

     { "sqlite4_create_collation",   test_create_collation, 0 },

     { "working_64bit_int",          working_64bit_int,   0   },
     { "sqlite4_create_function_v2", test_create_function_v2, 0 },

     /* Functions from os.h */
#ifndef SQLITE4_OMIT_UTF16
     { "add_test_function",       test_function, 0           },
#endif







>







4054
4055
4056
4057
4058
4059
4060
4061
4062
4063
4064
4065
4066
4067
4068
#ifdef SQLITE4_ENABLE_COLUMN_METADATA
{ "sqlite4_column_database_name",test_stmt_utf8,(void*)sqlite4_column_database_name},
{ "sqlite4_column_table_name",test_stmt_utf8,(void*)sqlite4_column_table_name},
{ "sqlite4_column_origin_name",test_stmt_utf8,(void*)sqlite4_column_origin_name},
#endif

     { "sqlite4_create_collation",   test_create_collation, 0 },
     { "sqlite4_collation_needed",   test_collation_needed, 0 },
     { "working_64bit_int",          working_64bit_int,   0   },
     { "sqlite4_create_function_v2", test_create_function_v2, 0 },

     /* Functions from os.h */
#ifndef SQLITE4_OMIT_UTF16
     { "add_test_function",       test_function, 0           },
#endif