15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 2006 January 09 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** The author disclaims copyright to this source code. In place of 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** a legal notice, here is a blessing: 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** May you do good and not evil. 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** May you find forgiveness for yourself and forgive others. 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** May you share freely, never taking more than you give. 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)************************************************************************* 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Code for testing the client/server version of the SQLite library. 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Derived from test4.c. 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sqliteInt.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "tcl.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** This test only works on UNIX with a SQLITE_THREADSAFE build that includes 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** the SQLITE_SERVER option. 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(SQLITE_SERVER) && !defined(SQLITE_OMIT_SHARED_CACHE) && \ 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SQLITE_OS_UNIX && SQLITE_THREADSAFE 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <stdlib.h> 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string.h> 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <pthread.h> 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <sched.h> 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <ctype.h> 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Interfaces defined in server.c 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int sqlite3_client_open(const char*, sqlite3**); 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int sqlite3_client_prepare(sqlite3*,const char*,int, 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3_stmt**,const char**); 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int sqlite3_client_step(sqlite3_stmt*); 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int sqlite3_client_reset(sqlite3_stmt*); 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int sqlite3_client_finalize(sqlite3_stmt*); 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int sqlite3_client_close(sqlite3*); 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int sqlite3_server_start(void); 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int sqlite3_server_stop(void); 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Each thread is controlled by an instance of the following 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** structure. 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef struct Thread Thread; 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct Thread { 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* The first group of fields are writable by the supervisor thread 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** and read-only to the client threads 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char *zFilename; /* Name of database file */ 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void (*xOp)(Thread*); /* next operation to do */ 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char *zArg; /* argument usable by xOp */ 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) volatile int opnum; /* Operation number */ 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) volatile int busy; /* True if this thread is in use */ 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* The next group of fields are writable by the client threads 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** but read-only to the superviser thread. 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) volatile int completed; /* Number of operations completed */ 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3 *db; /* Open database */ 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3_stmt *pStmt; /* Pending operation */ 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char *zErr; /* operation error */ 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char *zStaticErr; /* Static error message */ 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int rc; /* operation return code */ 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int argc; /* number of columns in result */ 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char *argv[100]; /* result columns */ 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char *colv[100]; /* result column names */ 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** There can be as many as 26 threads running at once. Each is named 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** by a capital letter: A, B, C, ..., Y, Z. 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define N_THREAD 26 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static Thread threadset[N_THREAD]; 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** The main loop for a thread. Threads use busy waiting. 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void *client_main(void *pArg){ 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Thread *p = (Thread*)pArg; 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( p->db ){ 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3_client_close(p->db); 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3_client_open(p->zFilename, &p->db); 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( SQLITE_OK!=sqlite3_errcode(p->db) ){ 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) p->zErr = strdup(sqlite3_errmsg(p->db)); 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3_client_close(p->db); 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) p->db = 0; 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) p->pStmt = 0; 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) p->completed = 1; 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while( p->opnum<=p->completed ) sched_yield(); 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while( p->xOp ){ 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( p->zErr && p->zErr!=p->zStaticErr ){ 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3_free(p->zErr); 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) p->zErr = 0; 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (*p->xOp)(p); 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) p->completed++; 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while( p->opnum<=p->completed ) sched_yield(); 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( p->pStmt ){ 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3_client_finalize(p->pStmt); 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) p->pStmt = 0; 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( p->db ){ 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3_client_close(p->db); 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) p->db = 0; 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( p->zErr && p->zErr!=p->zStaticErr ){ 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3_free(p->zErr); 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) p->zErr = 0; 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) p->completed++; 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef SQLITE_OMIT_DEPRECATED 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3_thread_cleanup(); 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0; 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Get a thread ID which is an upper case letter. Return the index. 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** If the argument is not a valid thread ID put an error message in 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** the interpreter and return -1. 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int parse_client_id(Tcl_Interp *interp, const char *zArg){ 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( zArg==0 || zArg[0]==0 || zArg[1]!=0 || !isupper((unsigned char)zArg[0]) ){ 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_AppendResult(interp, "thread ID must be an upper case letter", 0); 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return -1; 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return zArg[0] - 'A'; 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Usage: client_create NAME FILENAME 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** NAME should be an upper case letter. Start the thread running with 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** an open connection to the given database. 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int tcl_client_create( 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void *NotUsed, 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int argc, /* Number of arguments */ 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char **argv /* Text of each argument */ 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)){ 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int i; 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pthread_t x; 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int rc; 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( argc!=3 ){ 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " ID FILENAME", 0); 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TCL_ERROR; 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) i = parse_client_id(interp, argv[1]); 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( i<0 ) return TCL_ERROR; 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( threadset[i].busy ){ 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_AppendResult(interp, "thread ", argv[1], " is already running", 0); 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TCL_ERROR; 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) threadset[i].busy = 1; 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3_free(threadset[i].zFilename); 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) threadset[i].zFilename = sqlite3_mprintf("%s", argv[2]); 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) threadset[i].opnum = 1; 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) threadset[i].completed = 0; 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rc = pthread_create(&x, 0, client_main, &threadset[i]); 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( rc ){ 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_AppendResult(interp, "failed to create the thread", 0); 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3_free(threadset[i].zFilename); 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) threadset[i].busy = 0; 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TCL_ERROR; 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pthread_detach(x); 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3_server_start(); 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TCL_OK; 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Wait for a thread to reach its idle state. 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void client_wait(Thread *p){ 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while( p->opnum>p->completed ) sched_yield(); 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Usage: client_wait ID 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Wait on thread ID to reach its idle state. 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int tcl_client_wait( 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void *NotUsed, 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int argc, /* Number of arguments */ 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char **argv /* Text of each argument */ 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)){ 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int i; 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( argc!=2 ){ 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " ID", 0); 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TCL_ERROR; 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) i = parse_client_id(interp, argv[1]); 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( i<0 ) return TCL_ERROR; 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( !threadset[i].busy ){ 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_AppendResult(interp, "no such thread", 0); 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TCL_ERROR; 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) client_wait(&threadset[i]); 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TCL_OK; 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Stop a thread. 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void stop_thread(Thread *p){ 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) client_wait(p); 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) p->xOp = 0; 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) p->opnum++; 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) client_wait(p); 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3_free(p->zArg); 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) p->zArg = 0; 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3_free(p->zFilename); 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) p->zFilename = 0; 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) p->busy = 0; 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Usage: client_halt ID 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Cause a client thread to shut itself down. Wait for the shutdown to be 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** completed. If ID is "*" then stop all client threads. 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int tcl_client_halt( 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void *NotUsed, 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int argc, /* Number of arguments */ 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char **argv /* Text of each argument */ 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)){ 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int i; 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( argc!=2 ){ 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " ID", 0); 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TCL_ERROR; 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( argv[1][0]=='*' && argv[1][1]==0 ){ 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(i=0; i<N_THREAD; i++){ 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( threadset[i].busy ){ 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) stop_thread(&threadset[i]); 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else{ 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) i = parse_client_id(interp, argv[1]); 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( i<0 ) return TCL_ERROR; 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( !threadset[i].busy ){ 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_AppendResult(interp, "no such thread", 0); 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TCL_ERROR; 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) stop_thread(&threadset[i]); 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* If no client threads are still running, also stop the server */ 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(i=0; i<N_THREAD && threadset[i].busy==0; i++){} 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( i>=N_THREAD ){ 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3_server_stop(); 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TCL_OK; 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Usage: client_argc ID 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Wait on the most recent client_step to complete, then return the 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** number of columns in the result set. 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int tcl_client_argc( 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void *NotUsed, 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int argc, /* Number of arguments */ 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char **argv /* Text of each argument */ 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)){ 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int i; 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char zBuf[100]; 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( argc!=2 ){ 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " ID", 0); 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TCL_ERROR; 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) i = parse_client_id(interp, argv[1]); 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( i<0 ) return TCL_ERROR; 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( !threadset[i].busy ){ 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_AppendResult(interp, "no such thread", 0); 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TCL_ERROR; 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) client_wait(&threadset[i]); 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sprintf(zBuf, "%d", threadset[i].argc); 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_AppendResult(interp, zBuf, 0); 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TCL_OK; 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Usage: client_argv ID N 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Wait on the most recent client_step to complete, then return the 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** value of the N-th columns in the result set. 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int tcl_client_argv( 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void *NotUsed, 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int argc, /* Number of arguments */ 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char **argv /* Text of each argument */ 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)){ 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int i; 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int n; 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( argc!=3 ){ 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " ID N", 0); 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TCL_ERROR; 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) i = parse_client_id(interp, argv[1]); 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( i<0 ) return TCL_ERROR; 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( !threadset[i].busy ){ 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_AppendResult(interp, "no such thread", 0); 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TCL_ERROR; 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( Tcl_GetInt(interp, argv[2], &n) ) return TCL_ERROR; 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) client_wait(&threadset[i]); 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( n<0 || n>=threadset[i].argc ){ 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_AppendResult(interp, "column number out of range", 0); 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TCL_ERROR; 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_AppendResult(interp, threadset[i].argv[n], 0); 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TCL_OK; 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Usage: client_colname ID N 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Wait on the most recent client_step to complete, then return the 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** name of the N-th columns in the result set. 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int tcl_client_colname( 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void *NotUsed, 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int argc, /* Number of arguments */ 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char **argv /* Text of each argument */ 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)){ 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int i; 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int n; 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( argc!=3 ){ 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " ID N", 0); 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TCL_ERROR; 3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) i = parse_client_id(interp, argv[1]); 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( i<0 ) return TCL_ERROR; 3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( !threadset[i].busy ){ 3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_AppendResult(interp, "no such thread", 0); 3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TCL_ERROR; 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( Tcl_GetInt(interp, argv[2], &n) ) return TCL_ERROR; 3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) client_wait(&threadset[i]); 3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( n<0 || n>=threadset[i].argc ){ 3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_AppendResult(interp, "column number out of range", 0); 3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TCL_ERROR; 3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_AppendResult(interp, threadset[i].colv[n], 0); 3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TCL_OK; 3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Usage: client_result ID 3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Wait on the most recent operation to complete, then return the 3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** result code from that operation. 3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int tcl_client_result( 3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void *NotUsed, 3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ 3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int argc, /* Number of arguments */ 3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char **argv /* Text of each argument */ 3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)){ 3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int i; 3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char *zName; 3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( argc!=2 ){ 3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " ID", 0); 3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TCL_ERROR; 3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) i = parse_client_id(interp, argv[1]); 4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( i<0 ) return TCL_ERROR; 4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( !threadset[i].busy ){ 4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_AppendResult(interp, "no such thread", 0); 4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TCL_ERROR; 4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) client_wait(&threadset[i]); 4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch( threadset[i].rc ){ 4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case SQLITE_OK: zName = "SQLITE_OK"; break; 4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case SQLITE_ERROR: zName = "SQLITE_ERROR"; break; 4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case SQLITE_PERM: zName = "SQLITE_PERM"; break; 4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case SQLITE_ABORT: zName = "SQLITE_ABORT"; break; 4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case SQLITE_BUSY: zName = "SQLITE_BUSY"; break; 4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case SQLITE_LOCKED: zName = "SQLITE_LOCKED"; break; 4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case SQLITE_NOMEM: zName = "SQLITE_NOMEM"; break; 4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case SQLITE_READONLY: zName = "SQLITE_READONLY"; break; 4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case SQLITE_INTERRUPT: zName = "SQLITE_INTERRUPT"; break; 4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case SQLITE_IOERR: zName = "SQLITE_IOERR"; break; 4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case SQLITE_CORRUPT: zName = "SQLITE_CORRUPT"; break; 4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case SQLITE_FULL: zName = "SQLITE_FULL"; break; 4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case SQLITE_CANTOPEN: zName = "SQLITE_CANTOPEN"; break; 4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case SQLITE_PROTOCOL: zName = "SQLITE_PROTOCOL"; break; 4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case SQLITE_EMPTY: zName = "SQLITE_EMPTY"; break; 4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case SQLITE_SCHEMA: zName = "SQLITE_SCHEMA"; break; 4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case SQLITE_CONSTRAINT: zName = "SQLITE_CONSTRAINT"; break; 4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case SQLITE_MISMATCH: zName = "SQLITE_MISMATCH"; break; 4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case SQLITE_MISUSE: zName = "SQLITE_MISUSE"; break; 4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case SQLITE_NOLFS: zName = "SQLITE_NOLFS"; break; 4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case SQLITE_AUTH: zName = "SQLITE_AUTH"; break; 4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case SQLITE_FORMAT: zName = "SQLITE_FORMAT"; break; 4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case SQLITE_RANGE: zName = "SQLITE_RANGE"; break; 4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case SQLITE_ROW: zName = "SQLITE_ROW"; break; 4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case SQLITE_DONE: zName = "SQLITE_DONE"; break; 4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: zName = "SQLITE_Unknown"; break; 4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_AppendResult(interp, zName, 0); 4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TCL_OK; 4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Usage: client_error ID 4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Wait on the most recent operation to complete, then return the 4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** error string. 4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int tcl_client_error( 4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void *NotUsed, 4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ 4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int argc, /* Number of arguments */ 4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char **argv /* Text of each argument */ 4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)){ 4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int i; 4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( argc!=2 ){ 4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " ID", 0); 4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TCL_ERROR; 4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) i = parse_client_id(interp, argv[1]); 4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( i<0 ) return TCL_ERROR; 4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( !threadset[i].busy ){ 4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_AppendResult(interp, "no such thread", 0); 4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TCL_ERROR; 4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) client_wait(&threadset[i]); 4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_AppendResult(interp, threadset[i].zErr, 0); 4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TCL_OK; 4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** This procedure runs in the thread to compile an SQL statement. 4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void do_compile(Thread *p){ 4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( p->db==0 ){ 4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) p->zErr = p->zStaticErr = "no database is open"; 4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) p->rc = SQLITE_ERROR; 4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( p->pStmt ){ 4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3_client_finalize(p->pStmt); 4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) p->pStmt = 0; 4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) p->rc = sqlite3_client_prepare(p->db, p->zArg, -1, &p->pStmt, 0); 4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Usage: client_compile ID SQL 4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Compile a new virtual machine. 4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int tcl_client_compile( 4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void *NotUsed, 4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ 4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int argc, /* Number of arguments */ 4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char **argv /* Text of each argument */ 4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)){ 4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int i; 4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( argc!=3 ){ 4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " ID SQL", 0); 4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TCL_ERROR; 5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) i = parse_client_id(interp, argv[1]); 5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( i<0 ) return TCL_ERROR; 5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( !threadset[i].busy ){ 5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_AppendResult(interp, "no such thread", 0); 5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TCL_ERROR; 5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) client_wait(&threadset[i]); 5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) threadset[i].xOp = do_compile; 5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3_free(threadset[i].zArg); 5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) threadset[i].zArg = sqlite3_mprintf("%s", argv[2]); 5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) threadset[i].opnum++; 5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TCL_OK; 5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** This procedure runs in the thread to step the virtual machine. 5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void do_step(Thread *p){ 5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int i; 5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( p->pStmt==0 ){ 5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) p->zErr = p->zStaticErr = "no virtual machine available"; 5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) p->rc = SQLITE_ERROR; 5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) p->rc = sqlite3_client_step(p->pStmt); 5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( p->rc==SQLITE_ROW ){ 5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) p->argc = sqlite3_column_count(p->pStmt); 5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(i=0; i<sqlite3_data_count(p->pStmt); i++){ 5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) p->argv[i] = (char*)sqlite3_column_text(p->pStmt, i); 5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(i=0; i<p->argc; i++){ 5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) p->colv[i] = sqlite3_column_name(p->pStmt, i); 5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Usage: client_step ID 5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Advance the virtual machine by one step 5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int tcl_client_step( 5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void *NotUsed, 5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ 5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int argc, /* Number of arguments */ 5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char **argv /* Text of each argument */ 5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)){ 5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int i; 5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( argc!=2 ){ 5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " IDL", 0); 5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TCL_ERROR; 5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) i = parse_client_id(interp, argv[1]); 5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( i<0 ) return TCL_ERROR; 5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( !threadset[i].busy ){ 5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_AppendResult(interp, "no such thread", 0); 5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TCL_ERROR; 5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) client_wait(&threadset[i]); 5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) threadset[i].xOp = do_step; 5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) threadset[i].opnum++; 5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TCL_OK; 5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** This procedure runs in the thread to finalize a virtual machine. 5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void do_finalize(Thread *p){ 5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( p->pStmt==0 ){ 5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) p->zErr = p->zStaticErr = "no virtual machine available"; 5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) p->rc = SQLITE_ERROR; 5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) p->rc = sqlite3_client_finalize(p->pStmt); 5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) p->pStmt = 0; 5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Usage: client_finalize ID 5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Finalize the virtual machine. 5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int tcl_client_finalize( 5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void *NotUsed, 5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ 5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int argc, /* Number of arguments */ 5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char **argv /* Text of each argument */ 5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)){ 5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int i; 5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( argc!=2 ){ 5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " IDL", 0); 5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TCL_ERROR; 5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) i = parse_client_id(interp, argv[1]); 5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( i<0 ) return TCL_ERROR; 5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( !threadset[i].busy ){ 5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_AppendResult(interp, "no such thread", 0); 6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TCL_ERROR; 6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) client_wait(&threadset[i]); 6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) threadset[i].xOp = do_finalize; 6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3_free(threadset[i].zArg); 6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) threadset[i].zArg = 0; 6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) threadset[i].opnum++; 6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TCL_OK; 6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** This procedure runs in the thread to reset a virtual machine. 6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void do_reset(Thread *p){ 6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( p->pStmt==0 ){ 6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) p->zErr = p->zStaticErr = "no virtual machine available"; 6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) p->rc = SQLITE_ERROR; 6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) p->rc = sqlite3_client_reset(p->pStmt); 6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) p->pStmt = 0; 6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Usage: client_reset ID 6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Finalize the virtual machine. 6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int tcl_client_reset( 6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void *NotUsed, 6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ 6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int argc, /* Number of arguments */ 6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char **argv /* Text of each argument */ 6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)){ 6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int i; 6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( argc!=2 ){ 6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " IDL", 0); 6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TCL_ERROR; 6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) i = parse_client_id(interp, argv[1]); 6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( i<0 ) return TCL_ERROR; 6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( !threadset[i].busy ){ 6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_AppendResult(interp, "no such thread", 0); 6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TCL_ERROR; 6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) client_wait(&threadset[i]); 6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) threadset[i].xOp = do_reset; 6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3_free(threadset[i].zArg); 6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) threadset[i].zArg = 0; 6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) threadset[i].opnum++; 6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TCL_OK; 6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Usage: client_swap ID ID 6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Interchange the sqlite* pointer between two threads. 6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int tcl_client_swap( 6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void *NotUsed, 6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ 6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int argc, /* Number of arguments */ 6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char **argv /* Text of each argument */ 6645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)){ 6655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int i, j; 6665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3 *temp; 6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( argc!=3 ){ 6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " ID1 ID2", 0); 6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TCL_ERROR; 6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) i = parse_client_id(interp, argv[1]); 6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( i<0 ) return TCL_ERROR; 6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( !threadset[i].busy ){ 6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_AppendResult(interp, "no such thread", 0); 6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TCL_ERROR; 6775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) client_wait(&threadset[i]); 6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) j = parse_client_id(interp, argv[2]); 6805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( j<0 ) return TCL_ERROR; 6815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( !threadset[j].busy ){ 6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_AppendResult(interp, "no such thread", 0); 6835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TCL_ERROR; 6845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) client_wait(&threadset[j]); 6865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) temp = threadset[i].db; 6875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) threadset[i].db = threadset[j].db; 6885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) threadset[j].db = temp; 6895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TCL_OK; 6905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 6935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Register commands with the TCL interpreter. 6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 6955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int Sqlitetest7_Init(Tcl_Interp *interp){ 6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static struct { 6975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char *zName; 6985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_CmdProc *xProc; 6995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } aCmd[] = { 7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { "client_create", (Tcl_CmdProc*)tcl_client_create }, 7015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { "client_wait", (Tcl_CmdProc*)tcl_client_wait }, 7025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { "client_halt", (Tcl_CmdProc*)tcl_client_halt }, 7035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { "client_argc", (Tcl_CmdProc*)tcl_client_argc }, 7045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { "client_argv", (Tcl_CmdProc*)tcl_client_argv }, 7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { "client_colname", (Tcl_CmdProc*)tcl_client_colname }, 7065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { "client_result", (Tcl_CmdProc*)tcl_client_result }, 7075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { "client_error", (Tcl_CmdProc*)tcl_client_error }, 7085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { "client_compile", (Tcl_CmdProc*)tcl_client_compile }, 7095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { "client_step", (Tcl_CmdProc*)tcl_client_step }, 7105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { "client_reset", (Tcl_CmdProc*)tcl_client_reset }, 7115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { "client_finalize", (Tcl_CmdProc*)tcl_client_finalize }, 7125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { "client_swap", (Tcl_CmdProc*)tcl_client_swap }, 7135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 7145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int i; 7155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(i=0; i<sizeof(aCmd)/sizeof(aCmd[0]); i++){ 7175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_CreateCommand(interp, aCmd[i].zName, aCmd[i].xProc, 0, 0); 7185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TCL_OK; 7205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else 7225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int Sqlitetest7_Init(Tcl_Interp *interp){ return TCL_OK; } 7235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif /* SQLITE_OS_UNIX */ 724