SQLite4
Check-in [6e0b04adb9]
Not logged in

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

Overview
SHA1 Hash:6e0b04adb9aba04a15a253908a19c6911b97bc54
Date: 2013-06-15 17:45:01
User: dan
Comment:Add tests to ensure that the collation_needed destructor is invoked as required.
Tags And Properties
Changes
Hide Diffs Unified Diffs 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
....
3975
3976
3977
3978
3979
3980
3981

3982
3983
3984
3985
3986
3987
3988
    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
................................................................................
#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







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







 







>







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
....
4054
4055
4056
4057
4058
4059
4060
4061
4062
4063
4064
4065
4066
4067
4068
    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
................................................................................
#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