SHA1 Hash: | d0305b305ad0a15a1aa38dbd1830bc9b7654eb69 |
---|---|
Date: | 2007-12-05 08:07:46 |
User: | aku |
Comment: | Merged mainline into my branch to get the newest application. |
Timelines: | ancestors | descendants | both | trunk |
Other Links: | files | ZIP archive | manifest |
- branch=trunk inherited from [a28c83647d]
- sym-trunk inherited from [a28c83647d]
Added Makefile.w32 version [c6249fceb5]
@@ -1,1 +1,48 @@ +#!/usr/bin/make +# +#### The toplevel directory of the source tree. Fossil can be built +# in a directory that is separate from the source tree. Just change +# the following to point from the build directory to the src/ folder. +# +SRCDIR = ../src + +#### C Compiler and options for use in building executables that +# will run on the platform that is doing the build. This is used +# to compile code-generator programs as part of the build process. +# See TCC below for the C compiler for building the finished binary. +# +BCC = gcc -g -O2 + +#### The suffix to add to executable files. ".exe" for windows. +# Nothing for unix. +# +E = + +#### C Compile and options for use in building executables that +# will run on the target platform. This is usually the same +# as BCC, unless you are cross-compiling. This C compiler builds +# the finished binary for fossil. The BCC compiler above is used +# for building intermediate code-generator tools. +# +#TCC = gcc -O6 +#TCC = gcc -g -O0 -Wall -fprofile-arcs -ftest-coverage +#TCC = gcc -g -Os -Wall +TCC = gcc -g -Os -Wall -DFOSSIL_I18N=0 -L/usr/local/lib -I/usr/local/include + +#### Extra arguments for linking the finished binary. Fossil needs +# to link against the Z-Lib compression library. There are no +# other dependencies. We sometimes add the -static option here +# so that we can build a static executable that will run in a +# chroot jail. +# +#LIB = -lz +LIB = -lz -lws2_32 + + +#### Tcl shell for use in running the fossil testsuite. +# +TCLSH = tclsh +# You should not need to change anything below this line +############################################################################### +include $(SRCDIR)/main.mk
Modified ideas.txt from [44635deb96] to [8ca41c63e4].
@@ -1,159 +1,150 @@ + Possible ticket file format: - "Ticket" - title: TEXT - ticketid: TEXT - exists-in: BASELINE -- 0 or more - fixed-in: BASELINE -- 0 or more - tag: TAG -- 0 or more - created: DATETIME - attachment: FILENAME DESCRIPTION - parent: UUID* - derived-from: TICKET-FILENAME - description: MULTILINE-TEXT - remarks: MULTILINE-TEXT - - * Things handles with tags: - created-by - assigned-to - priority - severity - target-release - status - resolution - type - subsystem - -Wiki header format: - "WikiPage" - parent: UUID* - title: TEXT - pagename: TEXT - mode: (readonly|appendonly|readwrite) - attachment: UUID name description - - * Header ends with a blank line. wiki content follows. - -Cluster format: - - M+ uuid - Z manifest-cksum - - * Cluster generated in server mode only. - * Embargo cluster that reference phantoms or other embargoed clusters. - * Never send or ihave an embargoed cluster - -New sync algorithm based on clusters: - - * Keep a table of unclustered artifacts. Strive to keep this table - less than 100 entries. - * Client sends content of unclustered table as ihaves to server - * Server builds a new cluster if size of cluster table >100. - * Server sends unclustered table to client - * Server sends gimme for all unknown ihave received from client - * Client sends gimme for all unknown ihave received from server - * Previous two steps repeat until no more gimmes - -Details of new push algorithm: - - * Table "unsent" contains all files never pushed - * TEMP table "wanted" contains files the server does not have - Loop: - * Client sends login and "push" record - * Client sends file message for all files in unsent and removes - those files from the table. - * Client sends file message for all files in wanted. - * Client sends ihave messages for each entry in unclustered - ------ - * Server receives file message - * Server creates phantoms for unknown ihaves - * Server sends gimme messages for all phantoms - ------ - * Client clears its unsent table - * For each gimme message add an entry to wanted - * Halt if the wanted table is empty - -Details on new pull algorithm: - - Loop: - * Client sends login and "pull" record - * Client sends "prior" message with repository id and max record number - * Client sends "gimme" for each phantom - -------- - * Server creates new clusters to get unclustered size below 100 - * If there is "prior" message with repository id that matches this - server, then send file messages for all record ids greater than - prior - * Server sends ihave messages for each entry in unclustered - * Server sends maxrid message - -------- - * Client receives file records - * Client creates phantoms for unknown ihaves - * If no phantoms exist, record maxrid for the server and halt - -Need a dephantomize algorithm - - -Auxiliary tables needed for new sync algorithm: - - * unsent: files that have never been sent to another repository - * unclustered: non-phantom files not mentioned by a cluster + A uuid name description + D datetime + J field value + K uuid + U user + Z md5sum + +FIELDs: + + comment cumulative text + title text + assignedto text + status enum + resolution enum + subsystem enum + type enum + priority enum + severity enum + deferuntil datetime + duedate datetime + derivedfrom add or subtract uuid + relatedversions add or subtract associate with manifest + presentin add or subtract uuid + fixedin add or subtract uuid + +Other table columns: + origintime + lastchange + + +Field Types: + + text width height + enum width valuelist + datetime width + cumulative-text width height + set-of-uuid width + set-of-checkin width + +Tables: + + tktrid(rid, tkid, mtime); index(tkid, mtime); + ticket(tkid, tkuuid UNIQUE, starttime, lastmod, ...); + tktfield(fieldname UNIQUE, type, width, other); + tktxref(tkid, mid); index(tkid); index(mid); + +Tktformat in the config table. + + * Three pages: creation, display, and edit + * Separate global and local versions of each page. Local overwrites + global if it exists. + * HTML + * [[field]] to substitute the appropriate form or display element + +Ticket Configuraiton File: + + * Format: + ticket-configuration + field <fieldname> <type> <param> ... + template <type> <delimiter> + <text> + * Each repository selects a single ticket config for its own use. + * Rescan all tickets following any config change + * Use the ticket-configuration tag must be on the file + +Todo: + + * Configuration file parser + + tkt-new-template + + tkt-view-template + + tkt-edit-template + + Reconstruct the ticket table schema + + Repopulate tktfield + * Ticket control file parser + + Create ticket entry if necessary + + Update fields. Ignore unrecognized fields. + * Transfer tkt control info to ticket table + * Setup pages for selecting and editing ticket configuration + * Ticket display + * New ticket creation display + * Ticket change screen + * Ticket query screens + + +------------------------------------------------------------------------ +Change to wiki: + + A uuid filename description + D datetime + P uuid ... + U user + W size \n text \n + Z cksum + +Hyperlinks: + + [lowercasehex] /info/lowercasehex + [attachment.gif] inline image + [tagname] /info/tagname + [wikipagename] /wiki/wikipagename + [/internal/page] /internal/page + [http:...] external link + +Markup: + + blank-line paragraph break + _*__ bullet + __ indentation + _#.__ enumeration + *text* bold + _text_ italic + + +------------------------------------------------------------------------ Random thoughts: - - * Changes to manifest to support: - + Trees of wiki pages and tickets - + The ability to cap or close a branch - + See "Extended Manifests" below - - * Add the concept of "clusters" to speed the transfer of "tips" - on a sync. - - * Auxiliary tables: - + tip - + phantom - + mlink - + plink - + branch - + tree * Plink.isprim changed to record: + child is the principal descendent of parent. (1) + child is a branch from parent (2) + child uses parent as a merge (0) - - * tree records - + type (code, wiki, ticket) - + name (for wiki and ticket only) - + treeid - - * branch records - + treeid - + origin_rid - + origin_time - + tip_rid - + tip_time - + color * website can toggle isprim between principal and branch. + How to preserve across rebuild. A new record type? + How to share with other repositories * isprim guessed using userid of parent and child. Change in id suggests a branch. Same id suggests principal. For a tie, go with the earliest check-in as the principal' * Autosync mode - + Set a preferred remote repository to use as a server - = Clone repository is the default - + On commit, first pull. If commit baseline is not a tip - prompt user to cancel or branch. Default is cancel. - + Push after commit - + Automatically pull prior to update. - + Need an "undo" capability - + Designed to avoid branching in highly collaborative - environments. + * Notes: + + Designed to avoid branching in highly collaborative + environments. + * Outstanding: + + On commit, first pull. If commit baseline is not a tip + prompt user to cancel or branch. Default is cancel. + + Need an "undo" capability + * Done: + * Set a preferred remote repository to use as a server + = Clone repository is the default + * Push after commit + * Automatically pull prior to update. * Archeological webpage improvements: + Use a small amount of CSS+javascript on timelines so that branching structure is displayed on mouseover. On mouseover of a checkin, highlight other checkins that are direct (non-merge) @@ -184,17 +175,16 @@ U user-login Z manifest-checksum * Accessory: A uuid|* attachment-uuid description - B (+|-)branchtag uuid D date-time E uuid new-comment G uuid appended-remark S repositoryid serial-number - U userid - V (+|-)versiontag uuid + T (+|-)tag uuid + U userid X uuid-to-surpress Z this-file-checksum * Change the comment on a version: -- always a leaf except in cluster D date-time @@ -225,25 +215,27 @@ C? comment D date-time V* (+|-) tag uuid -- + to set, - to clear. Z manifest-cksum -- Must have at least one B or V. - -- Tag "hidden" means do not sync - -- Tag "closed" means do not display as a leaf + -- Branch tag "hidden" means do not sync + -- Version tag "closed" means do not display as a leaf * A cluster M+ uuid Z manifest-cksum - * Complete set of cards in a manifest files: + + * Complete set of cards in a control file: A filename uuid B (+|-)branch-tag uuid C comment D date-time - E edited-comment + E uuid edited-comment F filename uuid + M uuid N name P uuid ... R repository-md5sum T uuid U user-login V (+|-)version-tag uuid W uuid Z manifest-checksum
Modified src/add.c from [771768ca0d] to [ce8cf09189].
@@ -50,11 +50,11 @@ char *zName; char *zPath; Blob pathname; int isDir; - zName = mprintf("%s", g.argv[i]); + zName = mprintf("%/", g.argv[i]); isDir = file_isdir(zName); if( isDir==1 ) continue; if( isDir==0 ){ fossil_fatal("not found: %s", zName); } @@ -63,10 +63,13 @@ } file_tree_name(zName, &pathname); zPath = blob_str(&pathname); if( strcmp(zPath, "manifest")==0 || strcmp(zPath, "_FOSSIL_")==0 ){ fossil_fatal("cannot add %s", zPath); + } + if( !file_is_simple_pathname(zPath) ){ + fossil_fatal("filename contains illegal characters: %s", zPath); } if( db_exists("SELECT 1 FROM vfile WHERE pathname=%Q", zPath) ){ db_multi_exec("UPDATE vfile SET deleted=0 WHERE pathname=%Q", zPath); }else{ db_multi_exec( @@ -100,11 +103,11 @@ for(i=2; i<g.argc; i++){ char *zName; char *zPath; Blob pathname; - zName = mprintf("%s", g.argv[i]); + zName = mprintf("%/", g.argv[i]); file_tree_name(zName, &pathname); zPath = blob_str(&pathname); if( !db_exists( "SELECT 1 FROM vfile WHERE pathname=%Q AND NOT deleted", zPath) ){ fossil_fatal("not in the repository: %s", zName);
Modified src/blob.c from [f2c016552c] to [e355ed75f1].
@@ -49,10 +49,17 @@ /* ** The buffer holding the blob data */ #define blob_buffer(X) ((X)->aData) +/* +** Seek whence parameter values +*/ +#define BLOB_SEEK_SET 1 +#define BLOB_SEEK_CUR 2 +#define BLOB_SEEK_END 3 + #endif /* INTERFACE */ /* ** Make sure a blob is initialized */ @@ -341,10 +348,37 @@ void blob_rewind(Blob *p){ p->iCursor = 0; } /* +** Seek the cursor in a blob to the indicated offset. +*/ +int blob_seek(Blob *p, int offset, int whence){ + if( whence==BLOB_SEEK_SET ){ + p->iCursor = offset; + }else if( whence==BLOB_SEEK_CUR ){ + p->iCursor += offset; + }else if( whence==BLOB_SEEK_END ){ + p->iCursor = p->nUsed + offset - 1; + } + if( p->iCursor<0 ){ + p->iCursor = 0; + } + if( p->iCursor>p->nUsed ){ + p->iCursor = p->nUsed; + } + return p->iCursor; +} + +/* +** Return the current offset into the blob +*/ +int blob_tell(Blob *p){ + return p->iCursor; +} + +/* ** Extract a single line of text from pFrom beginning at the current ** cursor location and use that line of text to initialize pTo. ** pTo will include the terminating \n. Return the number of bytes ** in the line including the \n at the end. 0 is returned at ** end-of-file. @@ -368,13 +402,31 @@ blob_extract(pFrom, i-pFrom->iCursor, pTo); return pTo->nUsed; } /* +** Trim whitespace off of the end of a blob. Return the number +** of characters remaining. +** +** All this does is reduce the length counter. This routine does +** not insert a new zero terminator. +*/ +int blob_trim(Blob *p){ + char *z = p->aData; + int n = p->nUsed; + while( n>0 && isspace(z[n-1]) ){ n--; } + p->nUsed = n; + return n; +} + +/* ** Extract a single token from pFrom and use it to initialize pTo. ** Return the number of bytes in the token. If no token is found, ** return 0. +** +** A token consists of one or more non-space characters. Leading +** whitespace is ignored. ** ** The cursor of pFrom is left pointing at the first character past ** the end of the token. ** ** pTo will be an ephermeral blob. If pFrom changes, it might alter @@ -401,10 +453,40 @@ int blob_tail(Blob *pFrom, Blob *pTo){ int iCursor = pFrom->iCursor; blob_extract(pFrom, pFrom->nUsed-pFrom->iCursor, pTo); pFrom->iCursor = iCursor; return pTo->nUsed; +} + +/* +** Copy N lines of text from pFrom into pTo. The copy begins at the +** current cursor position of pIn. The pIn cursor is left pointing +** at the first character past the last \n copied. +** +** If pTo==NULL then this routine simply skips over N lines. +*/ +void blob_copy_lines(Blob *pTo, Blob *pFrom, int N){ + char *z = pFrom->aData; + int i = pFrom->iCursor; + int n = pFrom->nUsed; + int cnt = 0; + + if( N==0 ) return; + while( i<n ){ + if( z[i]=='\n' ){ + cnt++; + if( cnt==N ){ + i++; + break; + } + } + i++; + } + if( pTo ){ + blob_append(pTo, &pFrom->aData[pFrom->iCursor], i - pFrom->iCursor); + } + pFrom->iCursor = i; } /* ** Return true if the blob contains a valid UUID_SIZE-digit base16 identifier. */ @@ -458,31 +540,20 @@ for(i=0; i<nToken && blob_token(pIn, &aToken[i]); i++){} return i; } /* -** This function implements the callback from vxprintf. -** -** This routine add nNewChar characters of text in zNewText to -** the Blob structure pointed to by "arg". -*/ -static void bout(void *arg, const char *zNewText, int nNewChar){ - Blob *pBlob = (Blob*)arg; - blob_append(pBlob, zNewText, nNewChar); -} - -/* ** Do printf-style string rendering and append the results to a blob. */ void blob_appendf(Blob *pBlob, const char *zFormat, ...){ va_list ap; va_start(ap, zFormat); - vxprintf(bout, pBlob, zFormat, ap); + vxprintf(pBlob, zFormat, ap); va_end(ap); } void blob_vappendf(Blob *pBlob, const char *zFormat, va_list ap){ - vxprintf(bout, pBlob, zFormat, ap); + vxprintf(pBlob, zFormat, ap); } /* ** Initalize a blob to the data on an input channel. Return ** the number of bytes read into the blob. Any prior content @@ -571,13 +642,24 @@ } nName = file_simplify_name(zName, nName); for(i=1; i<nName; i++){ if( zName[i]=='/' ){ zName[i] = 0; - if( file_mkdir(zName, 1) ){ - fossil_panic("unable to create directory %s", zName); +#ifdef __MINGW32__ + /* + ** On Windows, local path looks like: C:/develop/project/file.txt + ** The if stops us from trying to create a directory of a drive letter + ** C: in this example. + */ + if( !(i==2 && zName[1]==':') ){ +#endif + if( file_mkdir(zName, 1) ){ + fossil_panic("unable to create directory %s", zName); + } +#ifdef __MINGW32__ } +#endif zName[i] = '/'; } } out = fopen(zName, "wb"); if( out==0 ){
Added src/branch.c version [e4e607578f]
@@ -1,1 +1,199 @@ +/* +** Copyright (c) 2007 D. Richard Hipp +** +** This program is free software; you can redistribute it and/or +** modify it under the terms of the GNU General Public +** License version 2 as published by the Free Software Foundation. +** +** This program is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +** General Public License for more details. +** +** You should have received a copy of the GNU General Public +** License along with this library; if not, write to the +** Free Software Foundation, Inc., 59 Temple Place - Suite 330, +** Boston, MA 02111-1307, USA. +** +** Author contact information: +** drh@hwaci.com +** http://www.hwaci.com/drh/ +** +******************************************************************************* +** +** This file contains code used to create new branches within a repository. +*/ +#include "config.h" +#include "branch.h" +#include <assert.h> + +void branch_new(void){ + int vid, nvid, noSign; + Stmt q; + char *zBranch, *zUuid, *zDate, *zComment; + const char *zColor; + Blob manifest; + Blob mcksum; /* Self-checksum on the manifest */ + Blob cksum1, cksum2; /* Before and after commit checksums */ + Blob cksum1b; /* Checksum recorded in the manifest */ + + noSign = find_option("nosign","",0)!=0; + db_must_be_within_tree(); + noSign = db_get_int("omitsign", 0)|noSign; + zColor = find_option("bgcolor","c",1); + + verify_all_options(); + + /* fossil branch new name */ + if( g.argc<3 ){ + usage("branch new ?-bgcolor COLOR BRANCH-NAME"); + } + zBranch = g.argv[3]; + if( zBranch==0 || zBranch[0]==0 ){ + fossil_panic("branch name cannot be empty"); + } + + user_select(); + db_begin_transaction(); + if( unsaved_changes() ){ + fossil_panic("there are uncommitted changes. please commit first"); + } + + vid = db_lget_int("checkout", 0); + vfile_aggregate_checksum_disk(vid, &cksum1); + + /* Create our new manifest */ + blob_zero(&manifest); + zComment = mprintf("Branch created %s", zBranch); + blob_appendf(&manifest, "C %F\n", zComment); + zDate = db_text(0, "SELECT datetime('now')"); + zDate[10] = 'T'; + blob_appendf(&manifest, "D %s\n", zDate); + + db_prepare(&q, + "SELECT pathname, uuid FROM vfile JOIN blob ON vfile.mrid=blob.rid" + " WHERE NOT deleted AND vfile.vid=%d" + " ORDER BY 1", vid); + while( db_step(&q)==SQLITE_ROW ){ + const char *zName = db_column_text(&q, 0); + const char *zUuid = db_column_text(&q, 1); + blob_appendf(&manifest, "F %F %s\n", zName, zUuid); + } + db_finalize(&q); + + zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", vid); + blob_appendf(&manifest, "P %s\n", zUuid); + blob_appendf(&manifest, "R %b\n", &cksum1); + + if( zColor!=0 ){ + if( strcmp("bgcolor",zBranch)>=0 ){ + blob_appendf(&manifest, "T *%F *\n", zBranch); + blob_appendf(&manifest, "T *bgcolor * %F\n", zColor); + }else{ + blob_appendf(&manifest, "T *bgcolor * %F\n", zColor); + blob_appendf(&manifest, "T *%F *\n", zBranch); + } + }else{ + blob_appendf(&manifest, "T *%F *\n", zBranch); + } + + /* Cancel any tags that propagate */ + db_prepare(&q, + "SELECT tagname" + " FROM tagxref JOIN tag ON tagxref.tagid=tag.tagid" + " WHERE rid=%d AND tagtype=2", vid); + while( db_step(&q)==SQLITE_ROW ){ + const char *zTagname = db_column_text(&q, 0); + blob_appendf(&manifest, "T -%s *\n", zTagname); + } + db_finalize(&q); + + blob_appendf(&manifest, "U %F\n", g.zLogin); + md5sum_blob(&manifest, &mcksum); + blob_appendf(&manifest, "Z %b\n", &mcksum); + if( !noSign && clearsign(&manifest, &manifest) ){ + Blob ans; + blob_zero(&ans); + prompt_user("unable to sign manifest. continue [y/N]? ", &ans); + if( blob_str(&ans)[0]!='y' ){ + db_end_transaction(1); + exit(1); + } + } + + /*blob_write_to_file(&manifest, "manifest.new");*/ + + nvid = content_put(&manifest, 0, 0); + if( nvid==0 ){ + fossil_panic("trouble committing manifest: %s", g.zErrMsg); + } + db_multi_exec("INSERT OR IGNORE INTO unsent VALUES(%d)", nvid); + manifest_crosslink(nvid, &manifest); + content_deltify(vid, nvid, 0); + zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", nvid); + printf("Branch Version: %s\n", zUuid); + printf("\n"); + printf("Notice: working copy not updated to the new branch. If\n"); + printf(" you wish to work on the new branch, update to\n"); + printf(" that branch first:\n"); + printf("\n"); + printf(" fossil update %s\n", zBranch); + + /* Verify that the manifest checksum matches the expected checksum */ + vfile_aggregate_checksum_repository(nvid, &cksum2); + vfile_aggregate_checksum_manifest(nvid, &cksum2, &cksum1b); + if( blob_compare(&cksum1, &cksum1b) ){ + fossil_panic("manifest checksum does not agree with manifest: " + "%b versus %b", &cksum1, &cksum1b); + } + + /* Verify that the commit did not modify any disk images. */ + vfile_aggregate_checksum_disk(vid, &cksum2); + if( blob_compare(&cksum1, &cksum2) ){ + fossil_panic("tree checksums before and after commit do not match"); + } + + /* Clear the undo/redo stack */ + undo_reset(); + + /* Commit */ + db_end_transaction(0); + + /* Do an autosync push, if requested */ + autosync(0); +} +/* +** COMMAND: branch +** +** Usage: %fossil branch SUBCOMMAND ... ?-R|--repository FILE? +** +** Run various subcommands on the branches of the open repository o +** of the repository identified by the -R or --repository option. +** +** %fossil branch new ?-bgcolor COLOR BRANCH-NAME +** +** Create a new branch BRANCH-NAME. You can optionally give +** a commit message and branch color. +** +** %fossil branch list +** +** List all branches +** +*/ +void branch_cmd(void){ + int n; + db_find_and_open_repository(); + if( g.argc<3 ){ + usage("new|list ..."); + } + n = strlen(g.argv[2]); + if( n>=2 && strncmp(g.argv[2],"new",n)==0 ){ + branch_new(); + }else if( n>=2 && strncmp(g.argv[2],"list",n)==0 ){ + fossil_panic("branch list is not yet completed"); + }else{ + fossil_panic("branch subcommand should be one of: " + "new list"); + } +}
Modified src/cgi.c from [f25a72aeb6] to [1c05503871].
@@ -26,20 +26,27 @@ ** dispensing QUERY_STRING parameters and cookies, the "mprintf()" ** formatting function and its cousins, and routines to encode and ** decode strings in HTML or HTTP. */ #include "config.h" -#include <sys/socket.h> -#include <netinet/in.h> -#include <arpa/inet.h> -#include <time.h> -#include <sys/times.h> -#include <sys/time.h> -#include <sys/wait.h> +#ifdef __MINGW32__ +# include <windows.h> /* for Sleep once server works again */ +# include <winsock2.h> /* socket operations */ +# define sleep Sleep /* windows does not have sleep, but Sleep */ +# include <ws2tcpip.h> +#else +# include <sys/socket.h> +# include <netinet/in.h> +# include <arpa/inet.h> +# include <sys/times.h> +# include <sys/time.h> +# include <sys/wait.h> +# include <sys/select.h> +#endif +#include <time.h> #include <stdio.h> #include <stdlib.h> -#include <sys/select.h> #include <unistd.h> #include "cgi.h" #if INTERFACE /* @@ -143,11 +150,11 @@ const char *zName, /* Name of the cookie */ const char *zValue, /* Value of the cookie. Automatically escaped */ const char *zPath, /* Path cookie applies to. NULL means "/" */ int lifetime /* Expiration of the cookie in seconds from now */ ){ - if( zPath==0 ) zPath = "/"; + if( zPath==0 ) zPath = g.zTop; if( lifetime>0 ){ lifetime += (int)time(0); blob_appendf(&extraHeader, "Set-Cookie: %s=%t; Path=%s; expires=%s; Version=1\r\n", zName, zValue, zPath, cgi_rfc822_datestamp(lifetime)); @@ -288,20 +295,27 @@ */ void cgi_redirect(const char *zURL){ char *zLocation; CGIDEBUG(("redirect to %s\n", zURL)); if( strncmp(zURL,"http:",5)==0 || strncmp(zURL,"https:",6)==0 || *zURL=='/' ){ - cgi_panic("invalid redirect URL: %s", zURL); - } - zLocation = mprintf("Location: %s/%s\r\n", g.zBaseURL, zURL); + zLocation = mprintf("Location: %s\r\n", zURL); + }else{ + zLocation = mprintf("Location: %s/%s\r\n", g.zBaseURL, zURL); + } cgi_append_header(zLocation); cgi_reset_content(); cgi_printf("<html>\n<p>Redirect to %h</p>\n</html>\n", zURL); cgi_set_status(302, "Moved Temporarily"); free(zLocation); cgi_reply(); exit(0); +} +void cgi_redirectf(const char *zFormat, ...){ + va_list ap; + va_start(ap, zFormat); + cgi_redirect(vmprintf(zFormat, ap)); + va_end(ap); } /* ** Information about all query parameters and cookies are stored ** in these variables. @@ -322,11 +336,11 @@ ** is its fully decoded value. ** ** zName and zValue are not copied and must not change or be ** deallocated after this routine returns. */ -static void cgi_set_parameter_nocopy(const char *zName, const char *zValue){ +void cgi_set_parameter_nocopy(const char *zName, const char *zValue){ if( nAllocQP<=nUsedQP ){ nAllocQP = nAllocQP*2 + 10; aParamQP = realloc( aParamQP, nAllocQP*sizeof(aParamQP[0]) ); if( aParamQP==0 ) exit(1); } @@ -344,10 +358,22 @@ ** ** Copies are made of both the zName and zValue parameters. */ void cgi_set_parameter(const char *zName, const char *zValue){ cgi_set_parameter_nocopy(mprintf("%s",zName), mprintf("%s",zValue)); +} + +/* +** Replace a parameter with a new value. +*/ +void cgi_replace_parameter(const char *zName, const char *zValue){ + int i; + for(i=0; i<nUsedQP; i++){ + if( strcmp(aParamQP[i].zName,zName)==0 ){ + aParamQP[i].zValue = zValue; + } + } } /* ** Add a query parameter. The zName portion is fixed but a copy ** must be made of zValue. @@ -702,10 +728,22 @@ CGIDEBUG(("no-match [%s]\n", zName)); return zDefault; } /* +** Return the name of the i-th CGI parameter. Return NULL if there +** are fewer than i registered CGI parmaeters. +*/ +const char *cgi_parameter_name(int i){ + if( i>=0 && i<nUsedQP ){ + return aParamQP[i].zName; + }else{ + return 0; + } +} + +/* ** Print CGI debugging messages. */ void cgi_debug(const char *zFormat, ...){ va_list ap; if( g.fDebug ){ @@ -895,36 +933,26 @@ } cgi_printf("%*s</select>\n", in, ""); } /* -** This function implements the callback from vxprintf. -** -** This routine sends nNewChar characters of text in zNewText to -** CGI reply content buffer. -*/ -static void sout(void *NotUsed, const char *zNewText, int nNewChar){ - cgi_append_content(zNewText, nNewChar); -} - -/* ** This routine works like "printf" except that it has the ** extra formatting capabilities such as %h and %t. */ void cgi_printf(const char *zFormat, ...){ va_list ap; va_start(ap,zFormat); - vxprintf(sout,0,zFormat,ap); + vxprintf(&cgiContent,zFormat,ap); va_end(ap); } /* ** This routine works like "vprintf" except that it has the ** extra formatting capabilities such as %h and %t. */ void cgi_vprintf(const char *zFormat, va_list ap){ - vxprintf(sout,0,zFormat,ap); + vxprintf(&cgiContent,zFormat,ap); } /* ** Send a reply indicating that the HTTP request was malformed @@ -948,11 +976,11 @@ cgi_printf( "<html><body><h1>Internal Server Error</h1>\n" "<plaintext>" ); va_start(ap, zFormat); - vxprintf(sout,0,zFormat,ap); + vxprintf(&cgiContent,zFormat,ap); va_end(ap); cgi_reply(); exit(1); } @@ -1016,11 +1044,11 @@ cgi_setenv("REQUEST_URI", zToken); for(i=0; zToken[i] && zToken[i]!='?'; i++){} if( zToken[i] ) zToken[i++] = 0; cgi_setenv("PATH_INFO", zToken); cgi_setenv("QUERY_STRING", &zToken[i]); - if( getpeername(fileno(stdin), (struct sockaddr*)&remoteName, &size)>=0 ){ + if( getpeername(fileno(stdin), (struct sockaddr*)&remoteName, (socklen_t*)&size)>=0 ){ char *zIpAddr = inet_ntoa(remoteName.sin_addr); cgi_setenv("REMOTE_ADDR", zIpAddr); /* Set the Global.zIpAddr variable to the server we are talking to. ** This is used to populate the ipaddr column of the rcvfrom table, @@ -1076,10 +1104,14 @@ ** As new connections arrive, fork a child and let child return ** out of this procedure call. The child will handle the request. ** The parent never returns from this procedure. */ void cgi_http_server(int iPort){ +#ifdef __MINGW32__ + fprintf(stderr,"server not yet available in windows version of fossil\n"); + exit(1); +#else int listener; /* The server socket */ int connection; /* A socket for each individual connection */ fd_set readfds; /* Set of file descriptors for select() */ size_t lenaddr; /* Length of the inaddr structure */ int child; /* PID of the child process */ @@ -1115,11 +1147,11 @@ delay.tv_usec = 0; FD_ZERO(&readfds); FD_SET( listener, &readfds); if( select( listener+1, &readfds, 0, 0, &delay) ){ lenaddr = sizeof(inaddr); - connection = accept(listener, (struct sockaddr*)&inaddr, &lenaddr); + connection = accept(listener, (struct sockaddr*)&inaddr, (socklen_t*) &lenaddr); if( connection>=0 ){ child = fork(); if( child!=0 ){ if( child>0 ) nchildren++; close(connection); @@ -1142,10 +1174,11 @@ nchildren--; } } /* NOT REACHED */ exit(1); +#endif } /* ** Name of days and months. */
Modified src/checkin.c from [08fa2df4cf] to [5435deb841].
@@ -44,12 +44,15 @@ while( db_step(&q)==SQLITE_ROW ){ const char *zPathname = db_column_text(&q,0); int isDeleted = db_column_int(&q, 1); int isChnged = db_column_int(&q,2); int isNew = db_column_int(&q,3)==0; + char *zFullName = mprintf("%s/%s", g.zLocalRoot, zPathname); blob_append(report, zPrefix, nPrefix); - if( isNew ){ + if( access(zFullName, 0) ){ + blob_appendf(report, "MISSING %s\n", zPathname); + }else if( isNew ){ blob_appendf(report, "ADDED %s\n", zPathname); }else if( isDeleted ){ blob_appendf(report, "DELETED %s\n", zPathname); }else if( isChnged==2 ){ blob_appendf(report, "UPDATED_BY_MERGE %s\n", zPathname); @@ -56,10 +59,11 @@ }else if( isChnged==3 ){ blob_appendf(report, "ADDED_BY_MERGE %s\n", zPathname); }else{ blob_appendf(report, "EDITED %s\n", zPathname); } + free(zFullName); } db_finalize(&q); db_prepare(&q, "SELECT uuid FROM vmerge JOIN blob ON merge=rid" " WHERE id=0"); while( db_step(&q)==SQLITE_ROW ){ @@ -162,18 +166,24 @@ db_finalize(&q); } /* ** COMMAND: clean -** Usage: %fossil clean +** Usage: %fossil clean ?-all ** Delete all "extra" files in the source tree. "Extra" files are ** files that are not officially part of the checkout. See also -** the "extra" command. +** the "extra" command. This operation cannot be undone. +** +** You will be prompted before removing each file. If you are +** sure you wish to remove all "extra" files you can specify the +** optional -all flag. */ void clean_cmd(void){ + int allFlag; Blob path; Stmt q; + allFlag = find_option("all","a",0)!=0; db_must_be_within_tree(); db_multi_exec("CREATE TEMP TABLE sfile(x TEXT PRIMARY KEY)"); chdir(g.zLocalRoot); blob_zero(&path); vfile_scan(0, &path); @@ -180,11 +190,22 @@ db_prepare(&q, "SELECT %Q || x FROM sfile" " WHERE x NOT IN ('manifest','manifest.uuid','_FOSSIL_')" " ORDER BY 1", g.zLocalRoot); while( db_step(&q)==SQLITE_ROW ){ - unlink(db_column_text(&q, 0)); + if( allFlag ){ + unlink(db_column_text(&q, 0)); + }else{ + Blob ans; + char *prompt = mprintf("remove unmanaged file \"%s\" [y/N]? ", + db_column_text(&q, 0)); + blob_zero(&ans); + prompt_user(prompt, &ans); + if( blob_str(&ans)[0]=='y' ){ + unlink(db_column_text(&q, 0)); + } + } } db_finalize(&q); } /* @@ -205,11 +226,11 @@ blob_set(&text, "\n# Enter comments on this commit. Lines beginning with # are ignored\n" "#\n" ); status_report(&text, "# "); - zEditor = db_global_get("editor", 0); + zEditor = db_get("editor", 0); if( zEditor==0 ){ zEditor = getenv("VISUAL"); } if( zEditor==0 ){ zEditor = getenv("EDITOR"); @@ -218,11 +239,11 @@ zEditor = "ed"; } zFile = db_text(0, "SELECT '%qci-comment-' || hex(randomblob(6)) || '.txt'", g.zLocalRoot); blob_write_to_file(&text, zFile); - zCmd = mprintf("%s %s", zEditor, zFile); + zCmd = mprintf("%s \"%s\"", zEditor, zFile); printf("%s\n", zCmd); if( system(zCmd) ){ fossil_panic("editor aborted"); } blob_reset(&text); @@ -298,30 +319,37 @@ ** changed will be committed unless some subset of files is specified ** on the command line. */ void commit_cmd(void){ int rc; - int vid, nrid, nvid; + int vid, nrid, nvid, wouldFork=0; Blob comment; const char *zComment; Stmt q; Stmt q2; char *zUuid, *zDate; int noSign = 0; /* True to omit signing the manifest using GPG */ int isAMerge = 0; /* True if checking in a merge */ + int forceFlag = 0; /* Force a fork */ char *zManifestFile; /* Name of the manifest file */ Blob manifest; Blob muuid; /* Manifest uuid */ Blob mcksum; /* Self-checksum on the manifest */ Blob cksum1, cksum2; /* Before and after commit checksums */ Blob cksum1b; /* Checksum recorded in the manifest */ noSign = find_option("nosign","",0)!=0; zComment = find_option("comment","m",1); + forceFlag = find_option("force", "r", 0)!=0; db_must_be_within_tree(); - noSign = db_get_int("omit-ci-sig", 0)|noSign; + noSign = db_get_int("omitsign", 0)|noSign; verify_all_options(); + + /* + ** Autosync if requested. + */ + autosync(1); /* There are two ways this command may be executed. If there are ** no arguments following the word "commit", then all modified files ** in the checked out directory are committed. If one or more arguments ** follows "commit", then only those files are committed. @@ -338,11 +366,11 @@ } user_select(); db_begin_transaction(); rc = unsaved_changes(); - if( rc==0 && !isAMerge ){ + if( rc==0 && !isAMerge && !forceFlag ){ fossil_panic("nothing has changed"); } /* If one or more files that were named on the command line have not ** been modified, bail out now. @@ -358,10 +386,16 @@ fossil_panic("file %s has not changed", blob_str(&unmodified)); } } vid = db_lget_int("checkout", 0); + if( db_exists("SELECT 1 FROM plink WHERE pid=%d", vid) ){ + wouldFork=1; + if( forceFlag==0 && db_get_int("safemerge", 0)==0 ){ + fossil_fatal("would fork. use -f or --force"); + } + } vfile_aggregate_checksum_disk(vid, &cksum1); if( zComment ){ blob_zero(&comment); blob_append(&comment, zComment, -1); }else{ @@ -506,6 +540,18 @@ /* Clear the undo/redo stack */ undo_reset(); /* Commit */ db_end_transaction(0); + + if( wouldFork==0 ){ + /* Do an autosync push if requested. If wouldFork == 1, then they either + ** forced this commit or safe merge is on, and this commit did indeed + ** create a fork. In this case, we want the user to merge before sending + ** their new commit back to the rest of the world, so do not auto-push. + */ + autosync(0); + }else{ + printf("Warning: commit caused a fork to occur. Please merge and push\n"); + printf(" your changes as soon as possible.\n"); + } }
Modified src/clearsign.c from [b83f245b62] to [b8ecd2533f].
@@ -34,11 +34,11 @@ */ int clearsign(Blob *pIn, Blob *pOut){ char *zRand; char *zIn; char *zOut; - char *zBase = db_global_get("clear-sign", "gpg --clearsign -o "); + char *zBase = db_get("clear-sign", "gpg --clearsign -o "); char *zCmd; int rc; zRand = db_text(0, "SELECT hex(randomblob(10))"); zOut = mprintf("out-%s", zRand); zIn = mprintf("in-%z", zRand);
Modified src/clone.c from [9c95e6e8e6] to [f1103d57a0].
@@ -39,29 +39,32 @@ */ void clone_cmd(void){ if( g.argc!=4 ){ usage("FILE-OR-URL NEW-REPOSITORY"); } + db_open_config(); if( file_size(g.argv[3])>0 ){ fossil_panic("file already exists: %s", g.argv[3]); } url_parse(g.argv[2]); db_create_repository(g.argv[3]); db_open_repository(g.argv[3]); + db_begin_transaction(); + db_initial_setup(0, 0); user_select(); - db_set("content-schema", CONTENT_SCHEMA); - db_set("aux-schema", AUX_SCHEMA); + db_set("content-schema", CONTENT_SCHEMA, 0); + db_set("aux-schema", AUX_SCHEMA, 0); if( !g.urlIsFile ){ - db_set("last-sync-url", g.argv[2]); + db_set("last-sync-url", g.argv[2], 0); } db_multi_exec( - "INSERT INTO config(name,value) VALUES('server-code', hex(randomblob(20)));" + "INSERT INTO config(name,value)" + " VALUES('server-code', lower(hex(randomblob(20))));" ); if( g.urlIsFile ){ Stmt q; db_multi_exec("ATTACH DATABASE %Q AS orig", g.urlName); - db_begin_transaction(); db_prepare(&q, "SELECT name FROM orig.sqlite_master" " WHERE type='table'" ); while( db_step(&q)==SQLITE_ROW ){ @@ -68,10 +71,10 @@ const char *zTab = db_column_text(&q, 0); db_multi_exec("INSERT OR IGNORE INTO %Q SELECT * FROM orig.%Q", zTab, zTab); } db_finalize(&q); - db_end_transaction(0); }else{ client_sync(0,0,1); } + db_end_transaction(0); }
Modified src/construct.c from [10bb790daf] to [e55d0051c5].
@@ -140,11 +140,11 @@ db_create_repository(zRepository); db_open_repository(zRepository); db_open_config(); db_begin_transaction(); - db_initial_setup(0); + db_initial_setup(0, 1); printf("project-id: %s\n", db_get("project-code", 0)); printf("server-id: %s\n", db_get("server-code", 0)); printf("admin-user: %s (no password set yet!)\n", g.zLogin); printf("baseline: %s\n", db_text(0, "SELECT uuid FROM blob")); @@ -154,15 +154,15 @@ printf("imported: %d %s\n", fileCnt, fileCnt == 1 ? "file" : "files"); /* Finalize the repository, rebuild the derived tables */ - errCnt = rebuild_db (); + errCnt = rebuild_db(0, 0); if( errCnt ){ printf("%d %s. Rolling back changes.\n", errCnt, errCnt == 1 ? "error" : "errors"); db_end_transaction(1); }else{ db_end_transaction(0); } }
Modified src/content.c from [310f7c7a1f] to [1ea5bdca20].
@@ -44,15 +44,27 @@ int content_get(int rid, Blob *pBlob){ Stmt q; Blob src; int srcid; int rc = 0; + static Bag inProcess; assert( g.repositoryOpen ); srcid = findSrcid(rid); blob_zero(pBlob); if( srcid ){ + if( bag_find(&inProcess, srcid) ){ + db_multi_exec( + "UPDATE blob SET content=NULL, size=-1 WHERE rid=%d;" + "DELETE FROM delta WHERE rid=%d;" + "INSERT OR IGNORE INTO phantom VALUES(%d);", + srcid, srcid, srcid + ); + blob_zero(pBlob); + return 0; + } + bag_insert(&inProcess, srcid); if( content_get(srcid, &src) ){ db_prepare(&q, "SELECT content FROM blob WHERE rid=%d AND size>=0", rid); if( db_step(&q)==SQLITE_ROW ){ Blob delta; db_ephemeral_blob(&q, 0, &delta); @@ -63,10 +75,11 @@ rc = 1; } db_finalize(&q); blob_reset(&src); } + bag_remove(&inProcess, srcid); }else{ db_prepare(&q, "SELECT content FROM blob WHERE rid=%d AND size>=0", rid); if( db_step(&q)==SQLITE_ROW ){ db_ephemeral_blob(&q, 0, pBlob); blob_uncompress(pBlob, pBlob); @@ -73,10 +86,36 @@ rc = 1; } db_finalize(&q); } return rc; +} + +/* +** Get the contents of a file within a given revision. +*/ +int content_get_historical_file(const char *revision, const char *file, Blob *content){ + Blob mfile; + Manifest m; + int i, rid=0; + + rid = name_to_rid(revision); + content_get(rid, &mfile); + + if( manifest_parse(&m, &mfile) ){ + for(i=0; i<m.nFile; i++){ + if( strcmp(m.aFile[i].zName, file)==0 ){ + rid = uuid_to_rid(m.aFile[i].zUuid, 0); + return content_get(rid, content); + } + } + fossil_panic("file: %s does not exist in revision: %s", file, revision); + }else{ + fossil_panic("could not parse manifest for revision: %s", revision); + } + + return 0; } /* ** COMMAND: test-content-get **
Modified src/db.c from [7ab2af8add] to [dc61149835].
@@ -33,14 +33,16 @@ ** (3) A local checkout database named "FOSSIL" and located at the ** root of the local copy of the source tree. ** */ #include "config.h" +#ifndef __MINGW32__ +# include <pwd.h> +#endif #include <sqlite3.h> #include <sys/types.h> #include <sys/stat.h> -#include <pwd.h> #include <unistd.h> #include "db.h" #if INTERFACE /* @@ -70,36 +72,93 @@ }else{ fprintf(stderr, "%s: %s\n", g.argv[0], z); } db_force_rollback(); exit(1); - exit(1); } static int nBegin = 0; /* Nesting depth of BEGIN */ static int doRollback = 0; /* True to force a rollback */ +static int nCommitHook = 0; /* Number of commit hooks */ +static struct sCommitHook { + int (*xHook)(void); /* Functions to call at db_end_transaction() */ + int sequence; /* Call functions in sequence order */ +} aHook[5]; + +/* +** This routine is called by the SQLite commit-hook mechanism +** just prior to each omit. All this routine does is verify +** that nBegin really is zero. That insures that transactions +** cannot commit by any means other than by calling db_end_transaction() +** below. +** +** This is just a safety and sanity check. +*/ +static int db_verify_at_commit(void *notUsed){ + if( nBegin ){ + fossil_panic("illegal commit attempt"); + return 1; + } + return 0; +} /* ** Begin and end a nested transaction */ void db_begin_transaction(void){ - if( nBegin==0 ) db_multi_exec("BEGIN"); + if( nBegin==0 ){ + db_multi_exec("BEGIN"); + sqlite3_commit_hook(g.db, db_verify_at_commit, 0); + } nBegin++; } void db_end_transaction(int rollbackFlag){ if( rollbackFlag ) doRollback = 1; nBegin--; if( nBegin==0 ){ + int i; + for(i=0; doRollback==0 && i<nCommitHook; i++){ + doRollback |= aHook[i].xHook(); + } db_multi_exec(doRollback ? "ROLLBACK" : "COMMIT"); doRollback = 0; } } void db_force_rollback(void){ if( nBegin ){ sqlite3_exec(g.db, "ROLLBACK", 0, 0, 0); } nBegin = 0; +} + +/* +** Install a commit hook. Hooks are installed in sequence order. +** It is an error to install the same commit hook more than once. +** +** Each commit hook is called (in order of accending sequence) at +** each commit operation. If any commit hook returns non-zero, +** the subsequence commit hooks are omitted and the transaction +** rolls back rather than commit. It is the responsibility of the +** hooks themselves to issue any error messages. +*/ +void db_commit_hook(int (*x)(void), int sequence){ + int i; + assert( nCommitHook < sizeof(aHook)/sizeof(aHook[1]) ); + for(i=0; i<nCommitHook; i++){ + assert( x!=aHook[i].xHook ); + if( aHook[i].sequence>sequence ){ + int s = sequence; + int (*xS)(void) = x; + sequence = aHook[i].sequence; + x = aHook[i].xHook; + aHook[i].sequence = s; + aHook[i].xHook = xS; + } + } + aHook[nCommitHook].sequence = sequence; + aHook[nCommitHook].xHook = x; + nCommitHook++; } /* ** Prepare or reprepare the sqlite3 statement from the raw SQL text. */ @@ -163,10 +222,13 @@ int db_bind_int(Stmt *pStmt, const char *zParamName, int iValue){ return sqlite3_bind_int(pStmt->pStmt, paramIdx(pStmt, zParamName), iValue); } int db_bind_int64(Stmt *pStmt, const char *zParamName, i64 iValue){ return sqlite3_bind_int64(pStmt->pStmt, paramIdx(pStmt, zParamName), iValue); +} +int db_bind_double(Stmt *pStmt, const char *zParamName, double rValue){ + return sqlite3_bind_double(pStmt->pStmt, paramIdx(pStmt, zParamName), rValue); } int db_bind_text(Stmt *pStmt, const char *zParamName, const char *zValue){ return sqlite3_bind_text(pStmt->pStmt, paramIdx(pStmt, zParamName), zValue, -1, SQLITE_STATIC); } @@ -256,10 +318,16 @@ double db_column_double(Stmt *pStmt, int N){ return sqlite3_column_double(pStmt->pStmt, N); } const char *db_column_text(Stmt *pStmt, int N){ return (char*)sqlite3_column_text(pStmt->pStmt, N); +} +const char *db_column_name(Stmt *pStmt, int N){ + return (char*)sqlite3_column_name(pStmt->pStmt, N); +} +int db_column_count(Stmt *pStmt){ + return sqlite3_column_count(pStmt->pStmt); } char *db_column_malloc(Stmt *pStmt, int N){ return mprintf("%s", db_column_text(pStmt, N)); } void db_column_blob(Stmt *pStmt, int N, Blob *pBlob){ @@ -485,15 +553,31 @@ ** Open the user database in "~/.fossil". Create the database anew if ** it does not already exist. */ void db_open_config(void){ char *zDbName; - const char *zHome = getenv("HOME"); + const char *zHome; +#ifdef __MINGW32__ + zHome = getenv("LOCALAPPDATA"); + if( zHome==0 ){ + zHome = getenv("APPDATA"); + if( zHome==0 ){ + zHome = getenv("HOMEPATH"); + } + } +#else + zHome = getenv("HOME"); +#endif if( zHome==0 ){ db_err("cannot local home directory"); } +#ifdef __MINGW32__ + /* . filenames give some window systems problems and many apps problems */ + zDbName = mprintf("%s/_fossil", zHome); +#else zDbName = mprintf("%s/.fossil", zHome); +#endif if( g.configOpen ) return; if( file_size(zDbName)<1024*3 ){ db_init_database(zDbName, zConfigSchema, (char*)0); } db_open_or_attach(zDbName, "configdb"); @@ -531,15 +615,19 @@ ** it is attached to the open database connection too. */ int db_open_local(void){ int n; char zPwd[2000]; + char *zPwdConv; if( g.localOpen) return 1; if( getcwd(zPwd, sizeof(zPwd)-20)==0 ){ db_err("pwd too big: max %d", sizeof(zPwd)-20); } n = strlen(zPwd); + zPwdConv = mprintf("%/", zPwd); + strncpy(zPwd, zPwdConv, 2000-20); + free(zPwdConv); while( n>0 ){ if( access(zPwd, W_OK) ) break; strcpy(&zPwd[n], "/_FOSSIL_"); if( isValidLocalDb(zPwd) ){ /* Found a valid _FOSSIL_ file */ @@ -648,30 +736,40 @@ ** Fill an empty repository database with the basic information for a ** repository. This function is shared between 'create_repository_cmd' ** ('new') and 'reconstruct_cmd' ('reconstruct'), both of which create ** new repositories. ** -** The caller determines wheter the function inserts an empty root -** manifest (zRoot == TRUE), or not (zRoot == FALSE). +** The makeInitialVersion flag determines whether or not an initial +** manifest is created. The makeServerCodes flag determines whether or +** not server and project codes are invented for this repository. */ - -void db_initial_setup (int zRoot){ +void db_initial_setup (int makeInitialVersion, int makeServerCodes){ char *zDate; - char *zUser; + const char *zUser; Blob hash; Blob manifest; - db_set("content-schema", CONTENT_SCHEMA); - db_set("aux-schema", AUX_SCHEMA); - db_set_int("authenticate-localhost", 0); - db_multi_exec( - "INSERT INTO config(name,value) VALUES('server-code', hex(randomblob(20)));" - "INSERT INTO config(name,value) VALUES('project-code',hex(randomblob(20)));" - ); - zUser = db_global_get("default-user", 0); + db_set("content-schema", CONTENT_SCHEMA, 0); + db_set("aux-schema", AUX_SCHEMA, 0); + if( makeServerCodes ){ + db_multi_exec( + "INSERT INTO config(name,value)" + " VALUES('server-code', lower(hex(randomblob(20))));" + "INSERT INTO config(name,value)" + " VALUES('project-code', lower(hex(randomblob(20))));" + ); + } + if( !db_is_global("autosync") ) db_set_int("autosync", 1, 0); + if( !db_is_global("safemerge") ) db_set_int("safemerge", 0, 0); + if( !db_is_global("localauth") ) db_set_int("localauth", 0, 0); + zUser = db_get("default-user", 0); if( zUser==0 ){ +#ifdef __MINGW32__ + zUser = getenv("USERNAME"); +#else zUser = getenv("USER"); +#endif } if( zUser==0 ){ zUser = "root"; } db_multi_exec( @@ -684,11 +782,11 @@ "INSERT INTO user(login,pw,cap,info)" " VALUES('nobody','','jor','Nobody');" ); user_select(); - if (zRoot){ + if (makeInitialVersion){ blob_zero(&manifest); blob_appendf(&manifest, "C initial\\sempty\\sbaseline\n"); zDate = db_text(0, "SELECT datetime('now')"); zDate[10]='T'; blob_appendf(&manifest, "D %s\n", zDate); @@ -717,11 +815,11 @@ } db_create_repository(g.argv[2]); db_open_repository(g.argv[2]); db_open_config(); db_begin_transaction(); - db_initial_setup (1); + db_initial_setup(1, 1); db_end_transaction(0); printf("project-id: %s\n", db_get("project-code", 0)); printf("server-id: %s\n", db_get("server-code", 0)); printf("admin-user: %s (no password set yet!)\n", g.zLogin); printf("baseline: %s\n", db_text(0, "SELECT uuid FROM blob")); @@ -801,32 +899,81 @@ /* ** Get and set values from the CONFIG, GLOBAL_CONFIG and VVAR table in the ** repository and local databases. */ -char *db_get(const char *zName, const char *zDefault){ - return db_text((char*)zDefault, - "SELECT value FROM config WHERE name=%Q", zName); +char *db_get(const char *zName, char *zDefault){ + char *z = 0; + if( g.repositoryOpen ){ + z = db_text(0, "SELECT value FROM config WHERE name=%Q", zName); + } + if( z==0 && g.configOpen ){ + z = db_text(0, "SELECT value FROM global_config WHERE name=%Q", zName); + } + if( z==0 ){ + z = zDefault; + } + return z; +} +void db_set(const char *zName, const char *zValue, int globalFlag){ + db_begin_transaction(); + db_multi_exec("REPLACE INTO %sconfig(name,value) VALUES(%Q,%Q)", + globalFlag ? "global_" : "", zName, zValue); + if( globalFlag && g.repositoryOpen ){ + db_multi_exec("DELETE FROM config WHERE name=%Q", zName); + } + db_end_transaction(0); } -void db_set(const char *zName, const char *zValue){ - db_multi_exec("REPLACE INTO config(name,value) VALUES(%Q,%Q)", zName, zValue); +int db_is_global(const char *zName){ + if( g.configOpen ){ + return db_exists("SELECT 1 FROM global_config WHERE name=%Q", zName); + }else{ + return 0; + } } int db_get_int(const char *zName, int dflt){ - return db_int(dflt, "SELECT value FROM config WHERE name=%Q", zName); + int v; + int rc; + if( g.repositoryOpen ){ + Stmt q; + db_prepare(&q, "SELECT value FROM config WHERE name=%Q", zName); + rc = db_step(&q); + if( rc==SQLITE_ROW ){ + v = db_column_int(&q, 0); + } + db_finalize(&q); + }else{ + rc = SQLITE_DONE; + } + if( rc==SQLITE_DONE && g.configOpen ){ + v = db_int(dflt, "SELECT value FROM global_config WHERE name=%Q", zName); + } + return v; } -void db_set_int(const char *zName, int value){ - db_multi_exec("REPLACE INTO config(name,value) VALUES(%Q,%d)", zName, value); +void db_set_int(const char *zName, int value, int globalFlag){ + db_begin_transaction(); + db_multi_exec("REPLACE INTO %sconfig(name,value) VALUES(%Q,%d)", + globalFlag ? "global_" : "", zName, value); + if( globalFlag && g.repositoryOpen ){ + db_multi_exec("DELETE FROM config WHERE name=%Q", zName); + } + db_end_transaction(0); } -char *db_global_get(const char *zName, const char *zDefault){ - return db_text((char*)zDefault, - "SELECT value FROM global_config WHERE name=%Q", zName); +int db_get_boolean(const char *zName, int dflt){ + static const char *azOn[] = { "on", "yes", "true", "1" }; + static const char *azOff[] = { "off", "no", "false", "0" }; + int i; + char *zVal = db_get(zName, dflt ? "on" : "off"); + for(i=0; i<sizeof(azOn)/sizeof(azOn[0]); i++){ + if( strcmp(zVal,azOn[i])==0 ) return 1; + } + for(i=0; i<sizeof(azOff)/sizeof(azOff[0]); i++){ + if( strcmp(zVal,azOff[i])==0 ) return 0; + } + return dflt; } -void db_global_set(const char *zName, const char *zValue){ - db_multi_exec("REPLACE INTO global_config(name,value)" - "VALUES(%Q,%Q)", zName, zValue); -} -char *db_lget(const char *zName, const char *zDefault){ +char *db_lget(const char *zName, char *zDefault){ return db_text((char*)zDefault, "SELECT value FROM vvar WHERE name=%Q", zName); } void db_lset(const char *zName, const char *zValue){ db_multi_exec("REPLACE INTO vvar(name,value) VALUES(%Q,%Q)", zName, zValue); @@ -847,10 +994,12 @@ ** for the repository is created with its root at the working directory. ** See also the "close" command. */ void cmd_open(void){ Blob path; + int vid; + static char *azNewArgv[] = { 0, "update", "--latest", 0 }; if( g.argc!=3 ){ usage("REPOSITORY-FILENAME"); } if( db_open_local() ){ fossil_panic("already within an open tree rooted at %s", g.zLocalRoot); @@ -858,62 +1007,109 @@ file_canonical_name(g.argv[2], &path); db_open_repository(blob_str(&path)); db_init_database("./_FOSSIL_", zLocalSchema, (char*)0); db_open_local(); db_lset("repository", blob_str(&path)); - db_lset_int("checkout", 1); + vid = db_int(0, "SELECT pid FROM plink y" + " WHERE NOT EXISTS(SELECT 1 FROM plink x WHERE x.cid=y.pid)"); + if( vid==0 ){ + db_lset_int("checkout", 1); + }else{ + db_lset_int("checkout", vid); + g.argv = azNewArgv; + g.argc = 3; + update_cmd(); + } } /* -** COMMAND: config -** -** Usage: %fossil config NAME=VALUE ... -** -** List or change the global configuration settings. With no arguments, -** all settings are listed. Arguments of simply NAME cause that setting -** to be displayed. Arguments of the form NAME=VALUE change the value of -** a setting. Arguments of the form NAME= delete a setting. -** -** Recognized settings include: -** -** editor Text editor command used for check-in comments. -** -** clear-sign Command used to clear-sign manifests at check-in. -** The default is "gpg --clearsign -o ". +** Print the value of a setting named zName */ -void cmd_config(void){ - db_open_config(); - if( g.argc>2 ){ - int i; - db_begin_transaction(); - for(i=2; i<g.argc; i++){ - char *zName, *zValue; - int j; +static void print_setting(const char *zName){ + Stmt q; + db_prepare(&q, + "SELECT '(local)', value FROM config WHERE name=%Q" + " UNION ALL " + "SELECT '(global)', value FROM global_config WHERE name=%Q", + zName, zName + ); + if( db_step(&q)==SQLITE_ROW ){ + printf("%-20s %-8s %s\n", zName, db_column_text(&q, 0), + db_column_text(&q, 1)); + }else{ + printf("%-20s\n", zName); + } + db_finalize(&q); +} + - zName = mprintf("%s", g.argv[i]); - for(j=0; zName[j] && zName[j]!='='; j++){} - if( zName[j] ){ - zName[j] = 0; - zValue = &zName[j+1]; - if( zValue[0] ){ - db_global_set(zName, zValue); - }else{ - db_multi_exec("DELETE FROM global_config WHERE name=%Q", zName); - } - } - zValue = db_global_get(zName, 0); - if( zValue ){ - printf("%s=%s\n", zName, zValue); - }else{ - printf("%s is undefined\n", zName); - } +/* +** COMMAND: settings +** %fossil setting ?PROPERTY? ?VALUE? ?-global? +** +** With no arguments, list all properties and their values. With just +** a property name, show the value of that property. With a value +** argument, change the property for the current repository. +** +** autosync If enabled, automatically pull prior to +** commit or update and automatically push +** after commit or tag or branch creation. +** +** clearsign Command used to clear-sign manifests at check-in. +** The default is "gpg --clearsign -o ". +** +** editor Text editor command used for check-in comments. +** +** localauth If enabled, require that HTTP connections from +** 127.0.0.1 be authenticated by password. If +** false, all HTTP requests from localhost have +** unrestricted access to the repository. +** +** omitsign When enabled, fossil will not attempt to sign any +** commit with gpg. All commits will be unsigned. +** +** safemerge If enabled, when commit will cause a fork, the +** commit will not abort with warning. Also update +** will not be allowed if local changes exist. +** +** diff-command External command to run when performing a diff. +** If undefined, the internal text diff will be used. +** +** gdiff-command External command to run when performing a graphical +** diff. If undefined, text diff will be used. +*/ +void setting_cmd(void){ + static const char *azName[] = { + "autosync", + "clearsign", + "editor", + "localauth", + "omitsign", + "safemerge", + "diff-command", + "gdiff-command", + }; + int i; + int globalFlag = find_option("global","g",0)!=0; + db_find_and_open_repository(); + if( g.argc==2 ){ + for(i=0; i<sizeof(azName)/sizeof(azName[0]); i++){ + print_setting(azName[i]); + } + }else if( g.argc==3 || g.argc==4 ){ + const char *zName = g.argv[2]; + int n = strlen(zName); + for(i=0; i<sizeof(azName)/sizeof(azName[0]); i++){ + if( strncmp(azName[i], zName, n)==0 ) break; + } + if( i>=sizeof(azName)/sizeof(azName[0]) ){ + fossil_fatal("no such setting: %s", zName); + } + if( g.argc==4 ){ + db_set(azName[i], g.argv[3], globalFlag); + }else{ + print_setting(azName[i]); } - db_end_transaction(0); }else{ - Stmt q; - db_prepare(&q, "SELECT name, value FROM global_config ORDER BY name"); - while( db_step(&q)==SQLITE_ROW ){ - printf("%s=%s\n", db_column_text(&q, 0), db_column_text(&q, 1)); - } - db_finalize(&q); + usage("?PROPERTY? ?VALUE?"); } }
Modified src/delta.c from [e79479fc0f] to [c73001b47f].
@@ -334,11 +334,11 @@ ** literal sections of the delta. */ base = 0; /* We have already generated everything before zOut[base] */ while( base+NHASH<lenOut ){ int iSrc, iBlock; - unsigned int bestCnt, bestOfst, bestLitsz; + unsigned int bestCnt, bestOfst=0, bestLitsz=0; hash_init(&h, &zOut[base]); i = 0; /* Trying to match a landmark against zOut[base+i] */ bestCnt = 0; while( 1 ){ int hv;
Modified src/descendents.c from [fc1b9b6b12] to [57da1765de].
@@ -147,16 +147,14 @@ base = name_to_rid(g.argv[2]); } if( base==0 ) return; compute_leaves(base); db_prepare(&q, - "SELECT blob.rid, uuid, datetime(event.mtime,'localtime'), comment, 0," - " (SELECT count(*) FROM plink WHERE cid=blob.rid)" - " FROM leaves, blob, event" - " WHERE blob.rid=leaves.rid" - " AND event.objid=leaves.rid" - " ORDER BY event.mtime DESC" + "%s" + " AND event.objid IN (SELECT rid FROM leaves)" + " ORDER BY event.mtime DESC", + timeline_query_for_tty() ); print_timeline(&q, 20); db_finalize(&q); } @@ -169,18 +167,15 @@ void branches_cmd(void){ Stmt q; db_must_be_within_tree(); db_prepare(&q, - "SELECT blob.rid, blob.uuid, datetime(event.mtime,'localtime')," - " event.comment, 0," - " (SELECT count(*) FROM plink WHERE cid=blob.rid)" - " FROM blob, event" - " WHERE blob.rid IN" + "%s" + " AND blob.rid IN" " (SELECT cid FROM plink EXCEPT SELECT pid FROM plink)" - " AND event.objid=blob.rid" - " ORDER BY event.mtime DESC" + " ORDER BY event.mtime DESC", + timeline_query_for_tty() ); print_timeline(&q, 2000); db_finalize(&q); } @@ -195,17 +190,15 @@ login_check_credentials(); if( !g.okRead ){ login_needed(); return; } style_header("Leaves"); db_prepare(&q, - "SELECT blob.rid, blob.uuid, datetime(event.mtime,'localtime')," - " event.comment, event.user, 1, 1, 0" - " FROM blob, event" - " WHERE blob.rid IN" + "%s" + " AND blob.rid IN" " (SELECT cid FROM plink EXCEPT SELECT pid FROM plink)" - " AND event.objid=blob.rid" - " ORDER BY event.mtime DESC" + " ORDER BY event.mtime DESC", + timeline_query_for_www() ); www_print_timeline(&q, 0, 0, 0, 0); db_finalize(&q); @ <script> @ function xin(id){
Modified src/diff.c from [43924b3721] to [ec5d799613].
@@ -19,229 +19,493 @@ ** drh@hwaci.com ** http://www.hwaci.com/drh/ ** ******************************************************************************* ** -** This file contains code used to implement "diff" operators. +** This file contains code used to compute a "diff" between two +** text files. */ #include "config.h" #include "diff.h" #include <assert.h> + +#if 0 +#define DEBUG(X) X +#else +#define DEBUG(X) +#endif + /* ** Information about each line of a file being diffed. +** +** The lower 20 bits of the hash are the length of the +** line. If any line is longer than 1048575 characters, +** the file is considered binary. */ typedef struct DLine DLine; struct DLine { const char *z; /* The text of the line */ unsigned int h; /* Hash of the line */ }; +#define LENGTH_MASK 0x000fffff + /* -** Break a blob into lines by converting each \n into a \000 and -** creating pointers to the beginning of each line. +** Return an array of DLine objects containing a pointer to the +** start of each line and a hash of that line. The lower +** bits of the hash store the length of each line. +** +** Trailing whitespace is removed from each line. +** +** Return 0 if the file is binary or contains a line that is +** longer than 1048575 bytes. */ static DLine *break_into_lines(char *z, int *pnLine){ - int nLine, i, j; + int nLine, i, j, k, x; unsigned int h; DLine *a; - for(i=0, nLine=1; z[i]; i++){ - if( z[i]=='\n' ) nLine++; + + /* Count the number of lines. Allocate space to hold + ** the returned array. + */ + for(i=j=0, nLine=1; z[i]; i++, j++){ + int c = z[i]; + if( c==0 ){ + return 0; + } + if( c=='\n' && z[i+1]!=0 ){ + nLine++; + if( j>1048575 ){ + return 0; + } + j = 0; + } + } + if( j>1048575 ){ + return 0; } a = malloc( nLine*sizeof(a[0]) ); if( a==0 ) fossil_panic("out of memory"); - a[0].z = z; - for(i=0, j=0, h=0; z[i]; i++){ - if( z[i]=='\n' ){ - a[j].h = h; - j++; - a[j].z = &z[i+1]; - z[i] = 0; - h = 0; - }else{ - h = h ^ (h<<2) ^ z[i]; + + /* Fill in the array */ + for(i=0; i<nLine; i++){ + a[i].z = z; + for(j=0; z[j] && z[j]!='\n'; j++){} + for(k=j; k>0 && isspace(z[k-1]); k--){} + for(h=0, x=0; x<k; x++){ + h = h ^ (h<<2) ^ z[x]; } + a[i].h = (h<<20) | k;; + z += j+1; } - a[j].h = h; - *pnLine = j+1; + + /* Return results */ + *pnLine = nLine; return a; } /* ** Return true if two DLine elements are identical. */ static int same_dline(DLine *pA, DLine *pB){ - return pA->h==pB->h && strcmp(pA->z,pB->z)==0; + return pA->h==pB->h && memcmp(pA->z,pB->z,pA->h & LENGTH_MASK)==0; +} + +/* +** Append a single line of "diff" output to pOut. +*/ +static void appendDiffLine(Blob *pOut, char *zPrefix, DLine *pLine){ + blob_append(pOut, zPrefix, 1); + blob_append(pOut, pLine->z, pLine->h & LENGTH_MASK); + blob_append(pOut, "\n", 1); } + /* -** Generate a unified diff of two blobs. The text of the original -** two blobs is destroyed by the diffing process. +** Generate a report of the differences between files pA and pB. +** If pOut is not NULL then a unified diff is appended there. It +** is assumed that pOut has already been initialized. If pOut is +** NULL, then a pointer to an array of integers is returned. +** The integers come in triples. For each triple, +** the elements are the number of lines copied, the number of +** lines deleted, and the number of lines inserted. The vector +** is terminated by a triple of all zeros. +** +** This diff utility does not work on binary files. If a binary +** file is encountered, 0 is returned and pOut is written with +** text "cannot compute difference between binary files". +** +**************************************************************************** +** +** The core algorithm is a variation on the classic Wagner +** minimum edit distance with enhancements to reduce the runtime +** to be almost linear in the common case where the two files +** have a lot in common. For additional information see +** Eugene W. Myers, "An O(ND) Difference Algorithm And Its +** Variations" +** +** Consider comparing strings A and B. A=abcabba and B=cbabac +** We construct a "Wagner" matrix W with A along the X axis and +** B along the Y axis: +** +** c 6 * +** a 5 * +** b 4 * * +** a 3 * +** b 2 * +** B c 1 * +** 0 * * * +** 0 1 2 3 4 5 6 7 +** a b c a b b a +** A +** +** (Note: we draw this Wagner matrix with the origin at the lower +** left whereas Myers uses the origin at the upper left. Otherwise, +** they are the same.) +** +** Let Y be the maximum y value or the number of characters in B. +** 6 in this example. X is the maximum x value or the number of +** elements in A. Here 7. +** +** Our goal is to find a path from (0,0) to (X,Y). The path can +** use horizontal, vertical, or diagonal steps. A diagonal from +** (x-1,y-1) to (x,y) is only allowed if A[x]==B[y]. A vertical +** steps corresponds to an insertion. A horizontal step corresponds +** to a deletion. We want to find the path with the fewest +** horizontal and vertical steps. +** +** Diagonal k consists of all points such that x-y==k. Diagonal +** zero begins at the origin. Diagonal 1 begins at (1,0). +** Diagonal -1 begins at (0,1). All diagonals move up and to the +** right at 45 degrees. Diagonal number increase from upper left +** to lower right. +** +** Myers matrix M is a lower right triangular matrix with indices d +** along the bottom and i vertically: +** +** +** i=4 | +4 \ +** 3 | +3 +2 | +** 2 | +2 +1 0 |- k values. k = 2*i-d +** 1 | +1 0 -1 -2 | +** 0 | 0 -1 -2 -3 -4 / +** --------------- +** 0 1 2 3 4 = d +** +** Each element of the Myers matrix corresponds to a diagonal. +** The diagonal is k=2*i-d. The diagonal values are shown +** in the template above. +** +** Each entry in M represents the end-point on a path from (0,0). +** The end-point is on diagonal k. The value stored in M is +** q=x+y where (x,y) is the terminus of the path. A path +** to M[d][i] will come through either M[d-1][i-1] or +** though M[d-1][i], whichever holds the largest value of q. +** If both elements hold the same value, the path comes +** through M[d-1][i-1]. +** +** The value of d is the number of insertions and deletions +** made so far on the path. M grows progressively. So the +** size of the M matrix is proportional to d*d. For the +** common case where A and B are similar, d will be small +** compared to X and Y so little memory is required. The +** original Wagner algorithm requires X*Y memory, which for +** larger files (100K lines) is more memory than we have at +** hand. */ -void unified_diff(Blob *pA, Blob *pB, int nContext, Blob *pOut){ - DLine *pDA, *pDB, *A, *B; - int nA, nB, nAp1; - int x, y; - int cnt; - int i, iStart; - int *m; +int *text_diff( + Blob *pA_Blob, /* FROM file */ + Blob *pB_Blob, /* TO file */ + Blob *pOut, /* Write unified diff here if not NULL */ + int nContext /* Amount of context to unified diff */ +){ + DLine *A, *B; /* Files being compared */ + int X, Y; /* Number of elements in A and B */ + int x, y; /* Indices: A[x] and B[y] */ + int szM = 0; /* Number of rows and columns in M */ + int **M = 0; /* Myers matrix */ + int i, d; /* Indices on M. M[d][i] */ + int k, q; /* Diagonal number and distinct from (0,0) */ + int K, D; /* The diagonal and d for the final solution */ + int *R = 0; /* Result vector */ + int r; /* Loop variables */ + int go = 1; /* Outer loop control */ + int MAX; /* Largest of X and Y */ /* Break the two files being diffed into individual lines. ** Compute hashes on each line for fast comparison. */ - pDA = break_into_lines(blob_str(pA), &nA); - pDB = break_into_lines(blob_str(pB), &nB); - - /* Remove common prefix and suffix to help reduce the value - ** of N in the O(N^2) minimum edit distance algorithm. - */ - for(i=0; i<nA && i<nB && same_dline(&pDA[i],&pDB[i]); i++){} - i -= nContext; - if( i<0 ) i = 0; - iStart = i; - A = &pDA[iStart]; - B = &pDB[iStart]; - nA -= iStart; - nB -= iStart; - for(i=1; i<nA && i<nB && same_dline(&A[nA-i],&B[nB-i]); i++){} - i -= nContext; - if( i<1 ) i = 1; - i--; - nA -= i; - nB -= i; - - /* Create the matrix used for the minimum edit distance - ** calculation. - */ - nAp1 = nA + 1; - m = malloc( sizeof(m[0])*(nB+1)*nAp1 ); -# define M(X,Y) m[(Y)*nAp1+(X)] - - - /* Find the minimum edit distance using Wagner's algorithm. - */ - for(x=0; x<=nA; x++){ - M(x,0) = x; + A = break_into_lines(blob_str(pA_Blob), &X); + B = break_into_lines(blob_str(pB_Blob), &Y); + + if( A==0 || B==0 ){ + free(A); + free(B); + if( pOut ){ + blob_appendf(pOut, "cannot compute difference between binary files\n"); + } + return 0; + } + + szM = 0; + MAX = X>Y ? X : Y; + if( MAX>2000 ) MAX = 2000; + for(d=0; go && d<=MAX; d++){ + if( szM<d+1 ){ + szM += szM + 10; + M = realloc(M, sizeof(M[0])*szM); + if( M==0 ){ + fossil_panic("out of memory"); + } + } + M[d] = malloc( sizeof(M[d][0])*(d+1) ); + if( M[d]==0 ){ + fossil_panic("out of memory"); + } + for(i=0; i<=d; i++){ + k = 2*i - d; + if( d==0 ){ + q = 0; + }else if( i==0 ){ + q = M[d-1][0]; + }else if( i<d-1 && M[d-1][i-1] < M[d-1][i] ){ + q = M[d-1][i]; + }else{ + q = M[d-1][i-1]; + } + x = (k + q + 1)/2; + y = x - k; + if( x<0 || x>X || y<0 || y>Y ){ + x = y = 0; + }else{ + while( x<X && y<Y && same_dline(&A[x],&B[y]) ){ x++; y++; } + } + M[d][i] = x + y; + DEBUG( printf("M[%d][%i] = %d k=%d (%d,%d)\n", d, i, x+y, k, x, y); ) + if( x==X && y==Y ){ + go = 0; + break; + } + } } - for(y=0; y<=nB; y++){ - M(0,y) = y; - } - for(x=1; x<=nA; x++){ - for(y=1; y<=nB; y++){ - int e = M(x-1,y) + 1; - if( e>M(x,y-1)+1 ){ - e = M(x,y-1)+1; + if( d>MAX ){ + R = malloc( sizeof(R[0])*7 ); + R[0] = 0; + R[1] = X; + R[2] = Y; + R[3] = 0; + R[4] = 0; + R[5] = 0; + R[6] = 0; + }else{ + /* Reuse M[] as follows: + ** + ** M[d][1] = 1 if a line is inserted or 0 if a line is deleted. + ** M[d][0] = number of lines copied after the ins or del above. + ** + */ + D = d - 1; + K = X - Y; + for(d=D, i=(K+D)/2; d>0; d--){ + DEBUG( printf("d=%d i=%d\n", d, i); ) + if( i==d || (i>0 && M[d-1][i-1] > M[d-1][i]) ){ + M[d][0] = M[d][i] - M[d-1][i-1] - 1; + M[d][1] = 0; + i--; + }else{ + M[d][0] = M[d][i] - M[d-1][i] - 1; + M[d][1] = 1; + } + } + + DEBUG( + printf("---------------\nM[0][0] = %5d\n", M[0][0]); + for(d=1; d<=D; d++){ + printf("M[%d][0] = %5d M[%d][1] = %d\n",d,M[d][0],d,M[d][1]); + } + ) + + /* Allocate the output vector + */ + R = malloc( sizeof(R[0])*(D+2)*3 ); + if( R==0 ){ + fossil_fatal("out of memory"); + } + + /* Populate the output vector + */ + d = r = 0; + while( d<=D ){ + int n; + R[r++] = M[d++][0]/2; /* COPY */ + if( d>D ){ + R[r++] = 0; + R[r++] = 0; + break; } - if( e<=M(x-1,y-1) ){ - M(x,y) = e; - }else if( same_dline(&A[x-1], &B[y-1]) ){ - M(x,y) = M(x-1,y-1); + if( M[d][1]==0 ){ + n = 1; + while( M[d][0]==0 && d<D && M[d+1][1]==0 ){ + d++; + n++; + } + R[r++] = n; /* DELETE */ + if( d==D || M[d][0]>0 ){ + R[r++] = 0; /* INSERT */ + continue; + } + d++; }else{ - M(x,y) = e; + R[r++] = 0; /* DELETE */ + } + assert( M[d][1]==1 ); + n = 1; + while( M[d][0]==0 && d<D && M[d+1][1]==1 ){ + d++; + n++; } + R[r++] = n; /* INSERT */ } + R[r++] = 0; + R[r++] = 0; + R[r++] = 0; + } + + /* Free the Myers matrix */ + for(d=0; d<=D; d++){ + free(M[d]); } + free(M); - /* Walk backwards through the Wagner algorithm matrix to determine - ** the specific edits that give the minimum edit distance. Mark our - ** path through the matrix with -1. + /* If pOut is defined, construct a unified diff into pOut and + ** delete R */ - x = nA; - y = nB; - while( x>0 || y>0 ){ - int v = M(x,y); - M(x,y) = -1; - if( x==0 ){ - y--; - }else if( y==0 ){ - x--; - }else if( M(x,y-1)+1==v ){ - y--; - }else if( M(x-1,y)+1==v ){ - x--; - }else{ - x--; - y--; - } - } + if( pOut ){ + int a = 0; /* Index of next line in A[] */ + int b = 0; /* Index of next line in B[] */ + int nr; /* Number of COPY/DELETE/INSERT triples to process */ + int mxr; /* Maximum value for r */ + int na, nb; /* Number of lines shown from A and B */ + int i, j; /* Loop counters */ + int m; /* Number of lines to output */ + int skip; /* Number of lines to skip */ + + for(mxr=0; R[mxr+1] || R[mxr+2] || R[mxr+3]; mxr += 3){} + for(r=0; r<mxr; r += 3*nr){ + /* Figure out how many triples to show in a single block */ + for(nr=1; R[r+nr*3]>0 && R[r+nr*3]<nContext*2; nr++){} + DEBUG( printf("r=%d nr=%d\n", r, nr); ) + + /* For the current block comprising nr triples, figure out + ** how many lines of A and B are to be displayed + */ + if( R[r]>nContext ){ + na = nb = nContext; + skip = R[r] - nContext; + }else{ + na = nb = R[r]; + skip = 0; + } + for(i=0; i<nr; i++){ + na += R[r+i*3+1]; + nb += R[r+i*3+2]; + } + if( R[r+nr*3]>nContext ){ + na += nContext; + nb += nContext; + }else{ + na += R[r+nr*3]; + nb += R[r+nr*3]; + } + for(i=1; i<nr; i++){ + na += R[r+i*3]; + nb += R[r+i*3]; + } + blob_appendf(pOut,"@@ -%d,%d +%d,%d @@\n", a+skip+1, na, b+skip+1, nb); -#if 0 -for(y=0; y<=nB; y++){ - for(x=0; x<=nA; x++){ - printf(" %2d", M(x,y)); - } - printf("\n"); -} -#endif + /* Show the initial common area */ + a += skip; + b += skip; + m = R[r] - skip; + for(j=0; j<m; j++){ + appendDiffLine(pOut, " ", &A[a+j]); + } + a += m; + b += m; - x = y = 0; - cnt = nContext; - while( x<nA || y<nB ){ - int t1, t2; - if( (t1 = M(x+1,y))<0 || (t2 = M(x,y+1))<0 ){ - if( cnt>=nContext ){ - blob_appendf(pOut, "@@ -%d +%d @@\n", - x-nContext+iStart+2, y-nContext+iStart+2); - for(i=x-nContext+1; i<x; i++){ - if( i<0 ) continue; - blob_appendf(pOut, " %s\n", A[i].z); + /* Show the differences */ + for(i=0; i<nr; i++){ + m = R[r+i*3+1]; + for(j=0; j<m; j++){ + appendDiffLine(pOut, "-", &A[a+j]); + } + a += m; + m = R[r+i*3+2]; + for(j=0; j<m; j++){ + appendDiffLine(pOut, "+", &B[b+j]); + } + b += m; + if( i<nr-1 ){ + m = R[r+i*3+3]; + for(j=0; j<m; j++){ + appendDiffLine(pOut, " ", &B[b+j]); + } + b += m; + a += m; } } - } - if( t1<0 ){ - blob_appendf(pOut, "-%s\n", A[x].z); - x++; - cnt = 0; - }else if( t2<0 ){ - blob_appendf(pOut, "+%s\n", B[y].z); - y++; - cnt = 0; - }else{ - if( M(x+1,y+1)==(-1) && cnt<nContext ){ - blob_appendf(pOut, " %s\n", A[x].z); + + /* Show the final common area */ + assert( nr==i ); + m = R[r+nr*3]; + if( m>nContext ) m = nContext; + for(j=0; j<m; j++){ + appendDiffLine(pOut, " ", &B[b+j]); } - cnt++; - x++; - y++; } + free(R); + R = 0; } - /* Cleanup allocationed memory */ - free(m); - free(pDA); - free(pDB); + /* We no longer need the A[] and B[] vectors */ + free(A); + free(B); + + /* Return the result */ + return R; +} + +/* +** COMMAND: test-rawdiff +*/ +void test_rawdiff_cmd(void){ + Blob a, b; + int r; + int i; + int *R; + if( g.argc<4 ) usage("FILE1 FILE2 ..."); + blob_read_from_file(&a, g.argv[2]); + for(i=3; i<g.argc; i++){ + if( i>3 ) printf("-------------------------------\n"); + blob_read_from_file(&b, g.argv[i]); + R = text_diff(&a, &b, 0, 0); + for(r=0; R[r] || R[r+1] || R[r+2]; r += 3){ + printf(" copy %4d delete %4d insert %4d\n", R[r], R[r+1], R[r+2]); + } + /* free(R); */ + blob_reset(&b); + } } /* -** COMMAND: test-diff +** COMMAND: test-udiff */ -void test_diff_cmd(void){ +void test_udiff_cmd(void){ Blob a, b, out; if( g.argc!=4 ) usage("FILE1 FILE2"); blob_read_from_file(&a, g.argv[2]); blob_read_from_file(&b, g.argv[3]); blob_zero(&out); - unified_diff(&a, &b, 4, &out); - blob_reset(&a); - blob_reset(&b); - printf("%s", blob_str(&out)); - blob_reset(&out); -} -/* -** COMMAND: test-uuid-diff -*/ -void test_uuiddiff_cmd(void){ - Blob a, b, out; - int ridA, ridB; - if( g.argc!=4 ) usage("UUID2 UUID1"); - db_must_be_within_tree(); - ridA = name_to_rid(g.argv[2]); - content_get(ridA, &a); - ridB = name_to_rid(g.argv[3]); - content_get(ridB, &b); - blob_zero(&out); - unified_diff(&a, &b, 4, &out); - blob_reset(&a); - blob_reset(&b); - printf("%s", blob_str(&out)); - blob_reset(&out); + text_diff(&a, &b, &out, 3); + blob_write_to_file(&out, "-"); }
Modified src/diffcmd.c from [16a1f70543] to [a54672e2c8].
@@ -40,77 +40,106 @@ for(i=n+1; i<=n+k; i++){ if( z[i]=='"' ) z[i] = '_'; } } - - /* ** COMMAND: diff -** COMMAND: tkdiff +** COMMAND: gdiff ** -** Usage: %fossil diff|tkdiff FILE... +** Usage: %fossil diff|gdiff ?-i? ?-r REVISION? FILE... +** ** Show the difference between the current version of a file (as it -** exists on disk) and that same file as it was checked out. Use -** either "diff -u" or "tkdiff". +** exists on disk) and that same file as it was checked out. +** +** diff will show a textual diff while gdiff will attempt to run a +** graphical diff command that you have setup. If the choosen command +** is not yet configured, the internal textual diff command will be +** used. +** +** If -i is supplied for either diff or gdiff, the internal textual +** diff command will be executed. +** +** Here are a few external diff command settings, for example: +** +** %fossil setting diff-command diff +** +** %fossil setting gdiff-command tkdiff +** %fossil setting gdiff-command eskill22 +** %fossil setting gdiff-command tortoisemerge +** %fossil setting gdiff-command meld +** %fossil setting gdiff-command xxdiff +** %fossil setting gdiff-command kdiff3 */ void diff_cmd(void){ - const char *zFile; + const char *zFile, *zRevision; Blob cmd; Blob fname; - int i; - char *zV1 = 0; - char *zV2 = 0; + Blob vname; + Blob record; + int cnt=0,internalDiff; + + internalDiff = find_option("internal","i",0)!=0; + zRevision = find_option("revision", "r", 1); + verify_all_options(); if( g.argc<3 ){ usage("?OPTIONS? FILE"); } db_must_be_within_tree(); - blob_zero(&cmd); - blob_appendf(&cmd, "%s ", g.argv[1]); - for(i=2; i<g.argc-1; i++){ - const char *z = g.argv[i]; - if( (strcmp(z,"-v")==0 || strcmp(z,"--version")==0) && i<g.argc-2 ){ - if( zV1==0 ){ - zV1 = g.argv[i+1]; - }else if( zV2==0 ){ - zV2 = g.argv[i+1]; - }else{ - fossil_panic("too many versions"); - } + + if( internalDiff==0 ){ + const char *zExternalCommand; + if( strcmp(g.argv[1], "diff")==0 ){ + zExternalCommand = db_get("diff-command", 0); }else{ - blob_appendf(&cmd, "%s ", z); + zExternalCommand = db_get("gdiff-command", 0); + } + if( zExternalCommand==0 ){ + internalDiff=1; } + blob_zero(&cmd); + blob_appendf(&cmd, "%s ", zExternalCommand); } zFile = g.argv[g.argc-1]; if( !file_tree_name(zFile, &fname) ){ fossil_panic("unknown file: %s", zFile); } - if( zV1==0 ){ - int rid = db_int(0, "SELECT rid FROM vfile WHERE pathname=%B", &fname); - Blob record; - Blob vname; - int cnt = 0; + + blob_zero(&vname); + do{ + blob_reset(&vname); + blob_appendf(&vname, "%s~%d", zFile, cnt++); + }while( access(blob_str(&vname),0)==0 ); + if( zRevision==0 ){ + int rid = db_int(0, "SELECT rid FROM vfile WHERE pathname=%B", &fname); if( rid==0 ){ fossil_panic("no history for file: %b", &fname); } - blob_zero(&vname); - do{ - blob_reset(&vname); - blob_appendf(&vname, "%s~%d", zFile, cnt++); - }while( access(blob_str(&vname),0)==0 ); content_get(rid, &record); + }else{ + historical_version_of_file(zRevision, zFile, &record); + } + if( internalDiff==1 ){ + Blob out; + Blob current; + blob_zero(¤t); + blob_read_from_file(¤t, zFile); + blob_zero(&out); + text_diff(&record, ¤t, &out, 5); + printf("%s\n", blob_str(&out)); + blob_reset(¤t); + blob_reset(&out); + }else{ blob_write_to_file(&record, blob_str(&vname)); blob_reset(&record); shell_escape(&cmd, blob_str(&vname)); blob_appendf(&cmd, " "); shell_escape(&cmd, zFile); system(blob_str(&cmd)); unlink(blob_str(&vname)); blob_reset(&vname); blob_reset(&cmd); - }else{ - fossil_panic("not yet implemented"); } blob_reset(&fname); }
Modified src/encode.c from [6c31150f72] to [e65fd74ba6].
@@ -402,12 +402,12 @@ ** and non-zero if there is an error. */ int encode16(const unsigned char *pIn, unsigned char *zOut, int N){ int i; for(i=0; i<N; i++){ - *(zOut++) = zEncode[pIn[0]>>4]; - *(zOut++) = zEncode[pIn[0]&0xf]; + *(zOut++) = zEncode[pIn[i]>>4]; + *(zOut++) = zEncode[pIn[i]&0xf]; } *zOut = 0; return 0; }
Modified src/file.c from [43aa6bdf65] to [be58713833].
@@ -105,11 +105,15 @@ if( rc==2 ){ if( !forceFlag ) return 1; unlink(zName); } if( rc!=1 ){ +#ifdef __MINGW32__ + return mkdir(zName); +#else return mkdir(zName, 0755); +#endif } return 0; } /* @@ -178,21 +182,22 @@ ** Remove redundant / characters ** Remove all /./ path elements. ** Convert /A/../ to just / */ void file_canonical_name(const char *zOrigName, Blob *pOut){ - if( zOrigName[0]=='/' ){ + if( zOrigName[0]=='/' + || (strlen(zOrigName)>3 && zOrigName[1]==':' && zOrigName[2]=='\\') ){ blob_set(pOut, zOrigName); blob_materialize(pOut); }else{ char zPwd[2000]; if( getcwd(zPwd, sizeof(zPwd)-20)==0 ){ - fprintf(stderr, "pwd too big: max %d\n", sizeof(zPwd)-20); + fprintf(stderr, "pwd too big: max %d\n", (int)sizeof(zPwd)-20); exit(1); } blob_zero(pOut); - blob_appendf(pOut, "%s/%s", zPwd, zOrigName); + blob_appendf(pOut, "%//%/", zPwd, zOrigName); } blob_resize(pOut, file_simplify_name(blob_buffer(pOut), blob_size(pOut))); } /* @@ -223,11 +228,11 @@ if( zPath[0]=='/' ){ int i, j; Blob tmp; char zPwd[2000]; if( getcwd(zPwd, sizeof(zPwd)-20)==0 ){ - fprintf(stderr, "pwd too big: max %d\n", sizeof(zPwd)-20); + fprintf(stderr, "pwd too big: max %d\n", (int)sizeof(zPwd)-20); exit(1); } for(i=1; zPath[i] && zPwd[i]==zPath[i]; i++){} if( zPath[i]==0 ){ blob_reset(pOut);
Modified src/http.c from [43986095c4] to [1a73d6f088].
@@ -23,22 +23,55 @@ ** ** This file contains code that implements the client-side HTTP protocol */ #include "config.h" #include "http.h" +#ifdef __MINGW32__ +# include <windows.h> +# include <winsock2.h> +#else +# include <arpa/inet.h> +# include <sys/socket.h> +# include <netdb.h> +# include <netinet/in.h> +#endif #include <assert.h> -#include <arpa/inet.h> -#include <sys/types.h> -#include <sys/socket.h> -#include <netdb.h> -#include <netinet/in.h> +#include <sys/types.h> #include <signal.h> /* ** Persistent information about the HTTP connection. */ -static FILE *pSocket = 0; /* The socket on which we talk to the server */ + +#ifdef __MINGW32__ +static WSADATA ws_info; +static int pSocket = 0; /* The socket on which we talk to the server on */ +#else +static FILE *pSocket = 0; /* The socket filehandle on which we talk to the server */ +#endif + +/* +** Winsock must be initialize before use. This helper method allows us to +** always call ws_init in our code regardless of platform but only actually +** initialize winsock on the windows platform. +*/ +static void ws_init(){ +#ifdef __MINGW32__ + if (WSAStartup(MAKEWORD(2,0), &ws_info) != 0){ + fossil_panic("can't initialize winsock"); + } +#endif +} + +/* +** Like ws_init, winsock must also be cleaned up after. +*/ +static void ws_cleanup(){ +#ifdef __MINGW32__ + WSACleanup(); +#endif +} /* ** Open a socket connection to the server. Return 0 on success and ** non-zero if an error occurs. */ @@ -45,11 +78,14 @@ static int http_open_socket(void){ static struct sockaddr_in addr; /* The server address */ static int addrIsInit = 0; /* True once addr is initialized */ int s; + ws_init(); + if( !addrIsInit ){ + addr.sin_family = AF_INET; addr.sin_port = htons(g.urlPort); *(int*)&addr.sin_addr = inet_addr(g.urlName); if( -1 == *(int*)&addr.sin_addr ){ #ifndef FOSSIL_STATIC_LINK @@ -76,14 +112,67 @@ fossil_panic("cannot create a socket"); } if( connect(s,(struct sockaddr*)&addr,sizeof(addr))<0 ){ fossil_panic("cannot connect to host %s:%d", g.urlName, g.urlPort); } +#ifdef __MINGW32__ + pSocket = s; +#else pSocket = fdopen(s,"r+"); signal(SIGPIPE, SIG_IGN); +#endif return 0; } + +#ifdef __MINGW32__ +/* +** Read the socket until a newline '\n' is found. Return the number +** of characters read. pSockId contains the socket handel. pOut +** contains a pointer to the buffer to write to. pOutSize contains +** the maximum size of the line that pOut can handle. +*/ +static int socket_recv_line(int pSockId, char* pOut, int pOutSize){ + int received=0; + char letter; + memset(pOut,0,pOutSize); + for(; received<pOutSize-1;received++){ + if( recv(pSockId,(char*)&letter,1,0)>0 ){ + pOut[received]=letter; + if( letter=='\n' ){ + break; + } + }else{ + break; + } + } + return received; +} + +/* +** Initialize a blob to the data on an input socket. return +** the number of bytes read into the blob. Any prior content +** of the blob is discarded, not freed. +** +** The function was placed here in http.c due to it's socket +** nature and we did not want to introduce socket headers into +** the socket netural blob.c file. +*/ +int socket_read_blob(Blob *pBlob, int pSockId, int nToRead){ + int i=0,read=0; + char rbuf[50]; + blob_zero(pBlob); + while ( i<nToRead ){ + read = recv(pSockId, rbuf, 50, 0); + i += read; + if( read<0 ){ + return 0; + } + blob_append(pBlob, rbuf, read); + } + return blob_size(pBlob); +} +#endif /* ** Make a single attempt to talk to the server. Return TRUE on success ** and FALSE on a failure. ** @@ -93,40 +182,78 @@ ** ** If an error occurs, this routine return false, resets pReply and ** closes the persistent connection, if any. */ static int http_send_recv(Blob *pHeader, Blob *pPayload, Blob *pReply){ - int rc; - int closeConnection; + int closeConnection=1; /* default to closing the connection */ + int rc; int iLength; int iHttpVersion; int i; int nRead; char zLine[2000]; if( pSocket==0 && http_open_socket() ){ return 0; } + iLength = -1; +#ifdef __MINGW32__ + /* + ** Use recv/send on the windows platform as winsock does not allow + ** sockets to be used as FILE handles, thus fdopen, fwrite, fgets + ** does not function on windows for sockets. + */ + rc = send(pSocket, blob_buffer(pHeader), blob_size(pHeader), 0); + if( rc!=blob_size(pHeader) ) goto write_err; + rc = send(pSocket, blob_buffer(pPayload), blob_size(pPayload), 0); + if( rc!=blob_size(pPayload) ) goto write_err; + + /* Read the response */ + while( socket_recv_line(pSocket, zLine, 2000) ){ + for( i=0; zLine[i] && zLine[i]!='\n' && zLine[i]!='\r'; i++ ){} + if( i==0 ) break; + zLine[i] = 0; + if( strncasecmp(zLine, "http/1.", 7)==0 ){ + if( sscanf(zLine, "HTTP/1.%d %d", &iHttpVersion, &rc)!=2 ) goto write_err; + if( rc!=200 ) goto write_err; + if( iHttpVersion==0 ){ + closeConnection = 1; + }else{ + closeConnection = 0; + } + } else if( strncasecmp(zLine, "content-length:", 15)==0 ){ + iLength = atoi(&zLine[16]); + }else if( strncasecmp(zLine, "connection:", 11)==0 ){ + for(i=12; isspace(zLine[i]); i++){} + if( zLine[i]=='c' || zLine[i]=='C' ){ + closeConnection = 1; + }else if( zLine[i]=='k' || zLine[i]=='K' ){ + closeConnection = 0; + } + } + } + if( iLength<0 ) goto write_err; + nRead = socket_read_blob(pReply, pSocket, iLength); +#else rc = fwrite(blob_buffer(pHeader), 1, blob_size(pHeader), pSocket); if( rc!=blob_size(pHeader) ) goto write_err; rc = fwrite(blob_buffer(pPayload), 1, blob_size(pPayload), pSocket); if( rc!=blob_size(pPayload) ) goto write_err; if( fflush(pSocket) ) goto write_err; if( fgets(zLine, sizeof(zLine), pSocket)==0 ) goto write_err; if( sscanf(zLine, "HTTP/1.%d %d", &iHttpVersion, &rc)!=2 ) goto write_err; if( rc!=200 ) goto write_err; if( iHttpVersion==0 ){ - closeConnection = 1; + closeConnection = 1; /* Connection: close */ }else{ - closeConnection = 0; - } - iLength = -1; + closeConnection = 0; /* Connection: keep-alive */ + } while( fgets(zLine, sizeof(zLine), pSocket) ){ for(i=0; zLine[i] && zLine[i]!='\n' && zLine[i]!='\r'; i++){} if( i==0 ) break; zLine[i] = 0; - if( strncasecmp(zLine, "content-length:",15)==0 ){ + if( strncasecmp(zLine,"content-length:",15)==0 ){ iLength = atoi(&zLine[16]); }else if( strncasecmp(zLine, "connection:", 11)==0 ){ for(i=12; isspace(zLine[i]); i++){} if( zLine[i]=='c' || zLine[i]=='C' ){ closeConnection = 1; /* Connection: close */ @@ -135,10 +262,11 @@ } } } if( iLength<0 ) goto write_err; nRead = blob_read_from_channel(pReply, pSocket, iLength); +#endif if( nRead!=iLength ){ blob_reset(pReply); goto write_err; } if( closeConnection ){ @@ -260,9 +388,21 @@ /* ** Make sure the socket to the HTTP server is closed */ void http_close(void){ if( pSocket ){ +#ifdef __MINGW32__ + closesocket(pSocket); +#else fclose(pSocket); +#endif pSocket = 0; } + /* + ** This is counter productive. Each time we open a connection we initialize + ** winsock and then when closing we cleanup. It would be better to + ** initialize winsock once at application start when we know we are going to + ** use the socket interface and then cleanup once at application exit when + ** we are all done with all socket operations. + */ + ws_cleanup(); }
Modified src/info.c from [1d02bccab4] to [21bbd4bc04].
@@ -114,11 +114,12 @@ static int showDescendents(int pid, int depth, const char *zTitle){ Stmt q; int cnt = 0; db_prepare(&q, "SELECT plink.cid, blob.uuid, datetime(plink.mtime, 'localtime')," - " event.user, event.comment" + " coalesce(event.euser,event.user)," + " coalesce(event.comment,event.ecomment)" " FROM plink, blob, event" " WHERE plink.pid=%d" " AND blob.rid=plink.cid" " AND event.objid=plink.cid" " ORDER BY plink.mtime ASC", @@ -132,17 +133,17 @@ const char *zUser = db_column_text(&q, 3); const char *zCom = db_column_text(&q, 4); cnt++; if( cnt==1 ){ if( zTitle ){ - @ <h2>%s(zTitle)</h2> + @ <div class="section">%s(zTitle)</div> } @ <ul> } @ <li> hyperlink_to_uuid(zUuid); - @ %s(zCom) (by %s(zUser) on %s(zDate)) + @ %w(zCom) (by %s(zUser) on %s(zDate)) if( depth ){ n = showDescendents(cid, depth-1, 0); }else{ n = db_int(0, "SELECT 1 FROM plink WHERE pid=%d", cid); } @@ -149,10 +150,11 @@ if( n==0 ){ db_multi_exec("DELETE FROM leaves WHERE rid=%d", cid); @ <b>leaf</b> } } + db_finalize(&q); if( cnt ){ @ </ul> } return cnt; } @@ -164,11 +166,12 @@ static void showAncestors(int pid, int depth, const char *zTitle){ Stmt q; int cnt = 0; db_prepare(&q, "SELECT plink.pid, blob.uuid, datetime(event.mtime, 'localtime')," - " event.user, event.comment" + " coalesce(event.euser,event.user)," + " coalesce(event.comment,event.ecomment)" " FROM plink, blob, event" " WHERE plink.cid=%d" " AND blob.rid=plink.pid" " AND event.objid=plink.pid" " ORDER BY event.mtime DESC", @@ -181,21 +184,22 @@ const char *zUser = db_column_text(&q, 3); const char *zCom = db_column_text(&q, 4); cnt++; if( cnt==1 ){ if( zTitle ){ - @ <h2>%s(zTitle)</h2> + @ <div class="section">%s(zTitle)</div> } @ <ul> } @ <li> hyperlink_to_uuid(zUuid); - @ %s(zCom) (by %s(zUser) on %s(zDate)) + @ %w(zCom) (by %s(zUser) on %s(zDate)) if( depth ){ showAncestors(cid, depth-1, 0); } } + db_finalize(&q); if( cnt ){ @ </ul> } } @@ -206,14 +210,14 @@ static void showLeaves(void){ Stmt q; int cnt = 0; db_prepare(&q, "SELECT blob.uuid, datetime(event.mtime, 'localtime')," - " event.user, event.comment" - " FROM leaves, plink, blob, event" - " WHERE plink.cid=leaves.rid" - " AND blob.rid=leaves.rid" + " coalesce(event.euser, event.user)," + " coalesce(event.ecomment,event.comment)" + " FROM leaves, blob, event" + " WHERE blob.rid=leaves.rid" " AND event.objid=leaves.rid" " ORDER BY event.mtime DESC" ); while( db_step(&q)==SQLITE_ROW ){ const char *zUuid = db_column_text(&q, 0); @@ -220,39 +224,89 @@ const char *zDate = db_column_text(&q, 1); const char *zUser = db_column_text(&q, 2); const char *zCom = db_column_text(&q, 3); cnt++; if( cnt==1 ){ - @ <h2>Leaves</h2> + @ <div class="section">Leaves</div> @ <ul> } @ <li> hyperlink_to_uuid(zUuid); - @ %s(zCom) (by %s(zUser) on %s(zDate)) - } + @ %w(zCom) (by %s(zUser) on %s(zDate)) + } + db_finalize(&q); + if( cnt ){ + @ </ul> + } +} + +/* +** Show information about all tags on a given node. +*/ +static void showTags(int rid){ + Stmt q; + int cnt = 0; + db_prepare(&q, + "SELECT tag.tagid, tagname, srcid, blob.uuid, value," + " datetime(tagxref.mtime,'localtime'), tagtype" + " FROM tagxref JOIN tag ON tagxref.tagid=tag.tagid" + " LEFT JOIN blob ON blob.rid=tagxref.srcid" + " WHERE tagxref.rid=%d" + " ORDER BY tagname", rid + ); + while( db_step(&q)==SQLITE_ROW ){ + const char *zTagname = db_column_text(&q, 1); + int srcid = db_column_int(&q, 2); + const char *zUuid = db_column_text(&q, 3); + const char *zValue = db_column_text(&q, 4); + const char *zDate = db_column_text(&q, 5); + int tagtype = db_column_int(&q, 6); + cnt++; + if( cnt==1 ){ + @ <div class="section">Tags And Properties</div> + @ <ul> + } + @ <li> + @ <b>%h(zTagname)</b> + if( zValue ){ + @ = %h(zValue)<i> + }else if( tagtype==0 ){ + @ <i>Cancelled + }else{ + @ <i> + } + if( srcid==0 ){ + @ Inherited + }else if( zUuid ){ + @ From + hyperlink_to_uuid(zUuid); + } + @ on %s(zDate)</i> + } + db_finalize(&q); if( cnt ){ @ </ul> } } /* ** WEBPAGE: vinfo +** URL: /vinfo?name=RID|UUID ** -** Return information about a version. The version number is contained -** in g.zExtra. +** Return information about a version. */ void vinfo_page(void){ Stmt q; int rid; int isLeaf; login_check_credentials(); if( !g.okHistory ){ login_needed(); return; } - style_header("Version Information"); - rid = name_to_rid(g.zExtra); + rid = name_to_rid(PD("name","0")); if( rid==0 ){ + style_header("Version Information Error"); @ No such object: %h(g.argv[2]) style_footer(); return; } isLeaf = !db_exists("SELECT 1 FROM plink WHERE pid=%d", rid); @@ -263,25 +317,38 @@ " AND event.objid=%d", rid, rid ); if( db_step(&q)==SQLITE_ROW ){ const char *zUuid = db_column_text(&q, 0); - @ <h2>Version %s(zUuid)</h2> - @ <ul> - @ <li><b>Date:</b> %s(db_column_text(&q, 1))</li> - @ <li><b>User:</b> %s(db_column_text(&q, 2))</li> - @ <li><b>Comment:</b> %s(db_column_text(&q, 3))</li> - @ <li><a href="%s(g.zBaseURL)/vdiff/%d(rid)">diff</a></li> - @ <li><a href="%s(g.zBaseURL)/zip/%s(zUuid).zip">ZIP archive</a></li> - @ <li><a href="%s(g.zBaseURL)/fview/%d(rid)">manifest</a></li> + char *zTitle = mprintf("Version: [%.10s]", zUuid); + style_header(zTitle); + free(zTitle); + /*@ <h2>Version %s(zUuid)</h2>*/ + @ <div class="section">Overview</div> + @ <p><table class="label-value"> + @ <tr><th>Version:</th><td>%s(zUuid)</td></tr> + @ <tr><th>Date:</th><td>%s(db_column_text(&q, 1))</td></tr> if( g.okSetup ){ - @ <li><b>Record ID:</b> %d(rid)</li> + @ <tr><th>Record ID:</th><td>%d(rid)</td></tr> } - @ </ul> + @ <tr><th>Original User:</th><td>%h(db_column_text(&q, 2))</td></tr> + @ <tr><th>Original Comment:</th><td>%w(db_column_text(&q,3))</td></tr> + @ </td></tr> + @ <tr><th>Commands:</th> + @ <td> + @ <a href="%s(g.zBaseURL)/vdiff/%d(rid)">diff</a> + @ | <a href="%s(g.zBaseURL)/zip/%s(zUuid).zip">ZIP archive</a> + @ | <a href="%s(g.zBaseURL)/fview/%d(rid)">manifest</a> + @ </td> + @ </tr> + @ </table></p> + }else{ + style_header("Version Information"); } db_finalize(&q); - @ <p><h2>Changes:</h2> + showTags(rid); + @ <div class="section">Changes</div> @ <ul> db_prepare(&q, "SELECT name, pid, fid" " FROM mlink, filename" " WHERE mid=%d" @@ -298,11 +365,11 @@ }else if( fid ){ @ <b>Added:</b> }else{ @ <b>Deleted:</b> } - @ <a href="%s(g.zBaseURL)/finfo/%T(zName)">%h(zName)</a></li> + @ <a href="%s(g.zBaseURL)/finfo?name=%T(zName)">%h(zName)</a></li> } @ </ul> compute_leaves(rid); showDescendents(rid, 2, "Descendents"); showLeaves(); @@ -309,35 +376,99 @@ showAncestors(rid, 2, "Ancestors"); style_footer(); } /* +** WEBPAGE: winfo +** URL: /winfo?name=RID +** +** Return information about a wiki page. +*/ +void winfo_page(void){ + Stmt q; + int rid; + + login_check_credentials(); + if( !g.okHistory ){ login_needed(); return; } + rid = name_to_rid(PD("name","0")); + if( rid==0 ){ + style_header("Wiki Page Information Error"); + @ No such object: %h(g.argv[2]) + style_footer(); + return; + } + db_prepare(&q, + "SELECT substr(tagname, 6, 1000), uuid," + " datetime(event.mtime, 'localtime'), user" + " FROM tagxref, tag, blob, event" + " WHERE tagxref.rid=%d" + " AND tag.tagid=tagxref.tagid" + " AND tag.tagname LIKE 'wiki-%%'" + " AND blob.rid=%d" + " AND event.objid=%d", + rid, rid, rid + ); + if( db_step(&q)==SQLITE_ROW ){ + const char *zName = db_column_text(&q, 0); + const char *zUuid = db_column_text(&q, 1); + char *zTitle = mprintf("Wiki Page %s", zName); + style_header(zTitle); + free(zTitle); + @ <div class="section">Overview</div> + @ <p><table class="label-value"> + @ <tr><th>Version:</th><td>%s(zUuid)</td></tr> + @ <tr><th>Date:</th><td>%s(db_column_text(&q, 2))</td></tr> + if( g.okSetup ){ + @ <tr><th>Record ID:</th><td>%d(rid)</td></tr> + } + @ <tr><th>Original User:</th><td>%s(db_column_text(&q, 3))</td></tr> + @ <tr><th>Commands:</th> + @ <td> +/* @ <a href="%s(g.zBaseURL)/wdiff/%d(rid)">diff</a> | */ + @ <a href="%s(g.zBaseURL)/whistory?page=%t(zName)">history</a> + @ | <a href="%s(g.zBaseURL)/fview/%d(rid)">raw-text</a> + @ </td> + @ </tr> + @ </table></p> + }else{ + style_header("Wiki Information"); + } + db_finalize(&q); + showTags(rid); + style_footer(); +} + +/* ** WEBPAGE: finfo +** URL: /finfo?name=FILENAME ** -** Show the complete change history for a single file. The name -** of the file is in g.zExtra +** Show the complete change history for a single file. */ void finfo_page(void){ Stmt q; + const char *zFilename; char zPrevDate[20]; login_check_credentials(); if( !g.okHistory ){ login_needed(); return; } style_header("File History"); zPrevDate[0] = 0; + zFilename = PD("name",""); db_prepare(&q, "SELECT a.uuid, substr(b.uuid,1,10), datetime(event.mtime,'localtime')," - " event.comment, event.user, mlink.pid, mlink.fid" + " coalesce(event.ecomment, event.comment)," + " coalesce(event.euser, event.user)," + " mlink.pid, mlink.fid" " FROM mlink, blob a, blob b, event" " WHERE mlink.fnid=(SELECT fnid FROM filename WHERE name=%Q)" " AND a.rid=mlink.mid" " AND b.rid=mlink.fid" " AND event.objid=mlink.mid" " ORDER BY event.mtime DESC", - g.zExtra + zFilename ); - @ <h2>History of %h(g.zExtra)</h2> + @ <h2>History of %h(zFilename)</h2> @ <table cellspacing=0 border=0 cellpadding=0> while( db_step(&q)==SQLITE_ROW ){ const char *zVers = db_column_text(&q, 0); const char *zUuid = db_column_text(&q, 1); const char *zDate = db_column_text(&q, 2); @@ -361,11 +492,13 @@ @ <td valign="top" align="left"> hyperlink_to_uuid(zVers); @ %h(zCom) (By: %h(zUser)) @ Id: %s(zUuid)/%d(frid) @ <a href="%s(g.zBaseURL)/fview/%d(frid)">[view]</a> - @ <a href="%s(g.zBaseURL)/fdiff?v1=%d(fpid)&v2=%d(frid)">[diff]</a> + if( fpid ){ + @ <a href="%s(g.zBaseURL)/fdiff?v1=%d(fpid)&v2=%d(frid)">[diff]</a> + } @ </td> } db_finalize(&q); @ </table> style_footer(); @@ -378,21 +511,22 @@ static void append_diff(int fromid, int toid){ Blob from, to, out; content_get(fromid, &from); content_get(toid, &to); blob_zero(&out); - unified_diff(&from, &to, 5, &out); + text_diff(&from, &to, &out, 5); @ %h(blob_str(&out)) blob_reset(&from); blob_reset(&to); blob_reset(&out); } /* ** WEBPAGE: vdiff +** URL: /vdiff?name=RID ** -** Show all differences for a particular check-in specified by g.zExtra +** Show all differences for a particular check-in. */ void vdiff_page(void){ int rid; Stmt q; char *zUuid; @@ -399,11 +533,11 @@ login_check_credentials(); if( !g.okHistory ){ login_needed(); return; } style_header("Version Diff"); - rid = name_to_rid(g.zExtra); + rid = name_to_rid(PD("name","")); if( rid==0 ){ cgi_redirect("index"); } db_prepare(&q, "SELECT pid, fid, name" @@ -419,11 +553,11 @@ @ </h2> while( db_step(&q)==SQLITE_ROW ){ int pid = db_column_int(&q,0); int fid = db_column_int(&q,1); const char *zName = db_column_text(&q,2); - @ <p><a href="%s(g.zBaseURL)/finfo/%T(zName)">%h(zName)</a></p> + @ <p><a href="%s(g.zBaseURL)/finfo?name=%T(zName)">%h(zName)</a></p> @ <blockquote><pre> append_diff(pid, fid); @ </pre></blockquote> } db_finalize(&q); @@ -447,13 +581,16 @@ ** * Comment & user */ static void object_description(int rid, int linkToView){ Stmt q; int cnt = 0; + int nWiki = 0; db_prepare(&q, "SELECT filename.name, datetime(event.mtime), substr(a.uuid,1,10)," - " event.comment, event.user, b.uuid" + " coalesce(event.comment,event.ecomment)," + " coalesce(event.euser,event.user)," + " b.uuid" " FROM mlink, filename, event, blob a, blob b" " WHERE filename.fnid=mlink.fnid" " AND event.objid=mlink.mid" " AND a.rid=mlink.fid" " AND b.rid=mlink.mid" @@ -465,37 +602,63 @@ const char *zDate = db_column_text(&q, 1); const char *zFuuid = db_column_text(&q, 2); const char *zCom = db_column_text(&q, 3); const char *zUser = db_column_text(&q, 4); const char *zVers = db_column_text(&q, 5); - @ File <a href="%s(g.zBaseURL)/finfo/%T(zName)">%h(zName)</a> + @ File <a href="%s(g.zBaseURL)/finfo?name=%T(zName)">%h(zName)</a> @ uuid %s(zFuuid) part of check-in hyperlink_to_uuid(zVers); - @ %s(zCom) by %s(zUser) on %s(zDate). + @ %w(zCom) by %h(zUser) on %s(zDate) cnt++; } db_finalize(&q); db_prepare(&q, - "SELECT datetime(mtime), user, comment, uuid" - " FROM event, blob" - " WHERE event.objid=%d" - " AND blob.rid=%d", - rid, rid + "SELECT substr(tagname, 6, 10000), datetime(event.mtime)," + " coalesce(event.euser, event.user), uuid" + " FROM tagxref, tag, event, blob" + " WHERE tagxref.rid=%d" + " AND tag.tagid=tagxref.tagid" + " AND tag.tagname LIKE 'wiki-%%'" + " AND event.objid=tagxref.rid" + " AND blob.rid=tagxref.rid", + rid ); while( db_step(&q)==SQLITE_ROW ){ - const char *zDate = db_column_text(&q, 0); + const char *zPagename = db_column_text(&q, 0); + const char *zDate = db_column_text(&q, 1); + const char *zUser = db_column_text(&q, 2); const char *zUuid = db_column_text(&q, 3); - const char *zCom = db_column_text(&q, 2); - const char *zUser = db_column_text(&q, 1); - @ Version - hyperlink_to_uuid(zUuid); - @ %s(zCom) by %s(zUser) on %s(zDate). + @ Wiki page + @ [<a href="%s(g.zBaseURL)/wiki?page=%t(zPagename)">%h(zPagename)</a>] + @ uuid %s(zUuid) by %h(zUser) on %s(zDate) + nWiki++; cnt++; } db_finalize(&q); + if( nWiki==0 ){ + db_prepare(&q, + "SELECT datetime(mtime), user, comment, uuid" + " FROM event, blob" + " WHERE event.objid=%d" + " AND blob.rid=%d", + rid, rid + ); + while( db_step(&q)==SQLITE_ROW ){ + const char *zDate = db_column_text(&q, 0); + const char *zUuid = db_column_text(&q, 3); + const char *zUser = db_column_text(&q, 1); + const char *zCom = db_column_text(&q, 2); + @ Manifest of version + hyperlink_to_uuid(zUuid); + @ %w(zCom) by %h(zUser) on %s(zDate) + cnt++; + } + db_finalize(&q); + } if( cnt==0 ){ - @ Empty file + char *zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", rid); + @ Control file %s(zUuid). }else if( linkToView ){ @ <a href="%s(g.zBaseURL)/fview/%d(rid)">[view]</a> } } @@ -504,12 +667,12 @@ ** ** Two arguments, v1 and v2, are integers. Show the difference between ** the two records. */ void diff_page(void){ - int v1 = atoi(PD("v1","0")); - int v2 = atoi(PD("v2","0")); + int v1 = name_to_rid(PD("v1","0")); + int v2 = name_to_rid(PD("v2","0")); Blob c1, c2, diff; login_check_credentials(); if( !g.okHistory ){ login_needed(); return; } style_header("Diff"); @@ -524,11 +687,11 @@ @ <hr> @ <blockquote><pre> content_get(v1, &c1); content_get(v2, &c2); blob_zero(&diff); - unified_diff(&c1, &c2, 4, &diff); + text_diff(&c1, &c2, &diff, 4); blob_reset(&c1); blob_reset(&c2); @ %h(blob_str(&diff)) @ </pre></blockquote> blob_reset(&diff); @@ -535,22 +698,33 @@ style_footer(); } /* ** WEBPAGE: fview -** URL: /fview/UUID +** URL: /fview?name=UUID ** ** Show the complete content of a file identified by UUID ** as preformatted text. */ void fview_page(void){ int rid; Blob content; - rid = name_to_rid(g.zExtra); + rid = name_to_rid(PD("name","0")); login_check_credentials(); if( !g.okHistory ){ login_needed(); return; } + if( g.zPath[0]=='i' ){ + if( db_exists("SELECT 1 FROM tagxref JOIN tag USING(tagid)" + " WHERE rid=%d AND tagname LIKE 'wiki-%%'", rid) ){ + winfo_page(); + return; + } + if( db_exists("SELECT 1 FROM plink WHERE cid=%d", rid) ){ + vinfo_page(); + return; + } + } style_header("File Content"); @ <h2>Content Of:</h2> @ <blockquote> object_description(rid, 0); @ </blockquote> @@ -559,6 +733,91 @@ content_get(rid, &content); @ %h(blob_str(&content)) @ </pre></blockquote> blob_reset(&content); style_footer(); +} + +/* +** WEBPAGE: info +** URL: info/UUID +** +** The argument is a UUID which might be a baseline or a file or +** a ticket or something else. It might also be a wiki page name. +** Figure out what the UUID is an jump to it. If there is ambiguity, +** draw a page and let the user select the interpretation. +*/ +void info_page(void){ + const char *zName; + int rc, nName, cnt; + Stmt q; + + zName = P("name"); + if( zName==0 ) cgi_redirect("index"); + nName = strlen(zName); + if( nName<4 || nName>UUID_SIZE || !validate16(zName, nName) ){ + cgi_redirect("index"); + } + db_multi_exec( + "CREATE TEMP TABLE refs(type,link);" + "INSERT INTO refs " + " SELECT 'f', rid FROM blob WHERE uuid GLOB '%s*'" + " UNION ALL" + " SELECT 'w', substr(tagname,6) FROM tag" + " WHERE tagname='wiki-%q'" + " UNION ALL" + " SELECT 't', tkt_uuid FROM ticket WHERE tkt_uuid GLOB '%s*';", + zName, zName, zName + ); + cnt = db_int(0, "SELECT count(*) FROM refs"); + if( cnt==0 ){ + style_header("Broken Link"); + @ <p>No such object: %h(zName)</p> + style_footer(); + return; + } + db_prepare(&q, "SELECT type, link FROM refs"); + db_step(&q); + if( cnt==1 ){ + int type = *db_column_text(&q, 0); + int rid = db_column_int(&q, 1); + db_finalize(&q); + if( type=='w' ){ + wiki_page(); + }else if( type=='t' ){ + tktview_page(); + }else{ + cgi_replace_parameter("name", mprintf("%d", rid)); + if( db_exists("SELECT 1 FROM mlink WHERE mid=%d", rid) ){ + vinfo_page(); + }else{ + finfo_page(); + } + } + return; + } + /* Multiple objects */ + style_header("Ambiguous Link"); + @ <h2>Ambiguous Link: %h(zName)</h2> + @ <ul> + while( rc==SQLITE_ROW ){ + int type = *db_column_text(&q, 0); + if( type=='f' ){ + @ <li><p> + object_description(db_column_int(&q, 1), 1); + @ </p></li> + }else if( type=='w' ){ + @ <li><p> + @ Wiki page <a href="%s(g.zBaseURL)/wiki?name=%s(zName)">%s(zName)</a>. + @ </li><p> + }else if( type=='t' ){ + const char *zUuid = db_column_text(&q, 1); + @ <li><p> + @ Ticket <a href="%s(g.zBaseURL)/tktview?name=%s(zUuid)">%s(zUuid)</a>. + @ </li><p> + } + rc = db_step(&q); + } + @ </ul> + style_footer(); + db_finalize(&q); }
Modified src/login.c from [4e89d2580b] to [0851edc1ca].
@@ -44,17 +44,29 @@ ** logs and downloading diffs of very version of the archive that ** has ever existed, and things like that. */ #include "config.h" #include "login.h" +#ifdef __MINGW32__ +# include <windows.h> /* for Sleep */ +# define sleep Sleep /* windows does not have sleep, but Sleep */ +#endif #include <time.h> /* ** Return the name of the login cookie */ static char *login_cookie_name(void){ - return "fossil_login"; + static char *zCookieName = 0; + if( zCookieName==0 ){ + int n = strlen(g.zTop); + zCookieName = malloc( n*2+16 ); + /* 0123456789 12345 */ + strcpy(zCookieName, "fossil_login_"); + encode16((unsigned char*)g.zTop, (unsigned char*)&zCookieName[13], n); + } + return zCookieName; } /* ** WEBPAGE: /login ** WEBPAGE: /logout @@ -224,12 +236,11 @@ /* If the HTTP connection is coming over 127.0.0.1 and if ** local login is disabled, then there is no need to check ** user credentials. */ zRemoteAddr = PD("REMOTE_ADDR","nil"); - if( strcmp(zRemoteAddr, "127.0.0.1")==0 - && db_get_int("authenticate-localhost",1)==0 ){ + if( strcmp(zRemoteAddr, "127.0.0.1")==0 && db_get_int("localauth",0)==0 ){ uid = db_int(0, "SELECT uid FROM user WHERE cap LIKE '%%s%%'"); g.zLogin = db_text("?", "SELECT login FROM user WHERE uid=%d", uid); zCap = "s"; g.noPswd = 1; } @@ -284,14 +295,15 @@ */ void login_set_capabilities(const char *zCap){ int i; for(i=0; zCap[i]; i++){ switch( zCap[i] ){ - case 's': g.okSetup = g.okDelete = 1; + case 's': g.okSetup = 1; case 'a': g.okAdmin = g.okRdTkt = g.okWrTkt = g.okQuery = - g.okRdWiki = g.okWrWiki = g.okHistory = - g.okNewTkt = g.okPassword = g.okClone = 1; + g.okRdWiki = g.okWrWiki = g.okNewWiki = + g.okApndWiki = g.okHistory = g.okClone = + g.okNewTkt = g.okPassword = g.okRdAddr = 1; case 'i': g.okRead = g.okWrite = 1; break; case 'o': g.okRead = 1; break; case 'd': g.okDelete = 1; break; case 'h': g.okHistory = 1; break; @@ -302,17 +314,53 @@ case 'j': g.okRdWiki = 1; break; case 'k': g.okWrWiki = g.okRdWiki = g.okApndWiki =1; break; case 'm': g.okApndWiki = 1; break; case 'f': g.okNewWiki = 1; break; + case 'e': g.okRdAddr = 1; break; case 'r': g.okRdTkt = 1; break; case 'n': g.okNewTkt = 1; break; case 'w': g.okWrTkt = g.okRdTkt = g.okNewTkt = g.okApndTkt = 1; break; case 'c': g.okApndTkt = 1; break; } } +} + +/* +** If the current login lacks any of the capabilities listed in +** the input, then return 0. If all capabilities are present, then +** return 1. +*/ +int login_has_capability(const char *zCap, int nCap){ + int i; + int rc = 1; + if( nCap<0 ) nCap = strlen(zCap); + for(i=0; i<nCap && rc && zCap[i]; i++){ + switch( zCap[i] ){ + case 'a': rc = g.okAdmin; break; + case 'c': rc = g.okApndTkt; break; + case 'd': rc = g.okDelete; break; + case 'e': rc = g.okRdAddr; break; + case 'f': rc = g.okNewWiki; break; + case 'g': rc = g.okClone; break; + case 'h': rc = g.okHistory; break; + case 'i': rc = g.okWrite; break; + case 'j': rc = g.okRdWiki; break; + case 'k': rc = g.okWrWiki; break; + case 'm': rc = g.okApndWiki; break; + case 'n': rc = g.okNewTkt; break; + case 'o': rc = g.okRead; break; + case 'p': rc = g.okPassword; break; + case 'q': rc = g.okQuery; break; + case 'r': rc = g.okRdTkt; break; + case 's': rc = g.okSetup; break; + case 'w': rc = g.okWrTkt; break; + default: rc = 0; break; + } + } + return rc; } /* ** Call this routine when the credential check fails. It causes ** a redirect to the "login" page.
Modified src/main.c from [17322e8c2b] to [cfe3d68152].
@@ -59,10 +59,11 @@ int fSqlPrint; /* True if -sqlprint flag is present */ int fHttpTrace; /* Trace outbound HTTP requests */ char *zPath; /* Name of webpage being served */ char *zExtra; /* Extra path information past the webpage name */ char *zBaseURL; /* Full text of the URL being served */ + char *zTop; /* Parent directory of zPath */ const char *zContentType; /* The content type of the input HTTP request */ int iErrPriority; /* Priority of current error message */ char *zErrMsg; /* Text of an error message */ Blob cgiIn; /* Input to an xfer www method */ int cgiPanic; /* Write error messages to CGI */ @@ -102,10 +103,11 @@ int okWrWiki; /* k: edit wiki via web */ int okRdTkt; /* r: view tickets via web */ int okNewTkt; /* n: create new tickets */ int okApndTkt; /* c: append to tickets via the web */ int okWrTkt; /* w: make changes to tickets via web */ + int okRdAddr; /* e: read email addresses on tickets */ FILE *fDebug; /* Write debug information here, if the file exists */ }; /* @@ -385,11 +387,11 @@ int rc, idx; const char *z; if( g.argc!=3 ){ printf("Usage: %s help COMMAND.\nAvailable COMMANDs:\n", g.argv[0]); cmd_cmd_list(); - printf("You are running fossil baseline " MANIFEST_UUID "\n"); + printf("This is fossil version " MANIFEST_VERSION " " MANIFEST_DATE "\n"); return; } rc = name_search(g.argv[2], aCommand, count(aCommand), &idx); if( rc==1 ){ fossil_fatal("unknown command: %s", g.argv[2]); @@ -412,15 +414,15 @@ } putchar('\n'); } /* -** RSS feeds need to reference absolute URLs so we need to calculate -** the base URL onto which we add components. This is basically -** cgi_redirect() stripped down and always returning an absolute URL. +** Set the g.zBaseURL value to the full URL for the toplevel of +** the fossil tree. Set g.zHomeURL to g.zBaseURL without the +** leading "http://" and the host and port. */ -static char *get_base_url(void){ +void set_base_url(void){ int i; const char *zHost = PD("HTTP_HOST",""); const char *zMode = PD("HTTPS","off"); const char *zCur = PD("REQUEST_URI","/"); @@ -436,19 +438,22 @@ } while( i>0 && zCur[i-1]!='/' ){ i--; } while( i>0 && zCur[i-1]=='/' ){ i--; } if( strcmp(zMode,"on")==0 ){ - return mprintf("https://%s%.*s", zHost, i, zCur); - } - return mprintf("http://%s%.*s", zHost, i, zCur); + g.zBaseURL = mprintf("https://%s%.*s", zHost, i, zCur); + g.zTop = &g.zBaseURL[8+strlen(zHost)]; + }else{ + g.zBaseURL = mprintf("http://%s%.*s", zHost, i, zCur); + g.zTop = &g.zBaseURL[7+strlen(zHost)]; + } } /* ** Preconditions: ** -** * Environment various are set up according to the CGI standard. +** * Environment variables are set up according to the CGI standard. ** * The respository database has been located and opened. ** ** Process the webpage specified by the PATH_INFO or REQUEST_URI ** environment variable. */ @@ -462,18 +467,14 @@ ** page. */ zPathInfo = P("PATH_INFO"); if( zPathInfo==0 || zPathInfo[0]==0 ){ const char *zUri; - char *zBase; zUri = PD("REQUEST_URI","/"); for(i=0; zUri[i] && zUri[i]!='?' && zUri[i]!='#'; i++){} for(j=i; j>0 && zUri[j-1]!='/'; j--){} - zBase = mprintf("%.*s/index", i-j, &zUri[j]); - cgi_redirect(zBase); - cgi_reply(); - return; + cgi_redirectf("%.*s/index", i, zUri); }else{ zPath = mprintf("%s", zPathInfo); } /* Remove the leading "/" at the beginning of the path. @@ -481,19 +482,21 @@ g.zPath = &zPath[1]; for(i=1; zPath[i] && zPath[i]!='/'; i++){} if( zPath[i]=='/' ){ zPath[i] = 0; g.zExtra = &zPath[i+1]; - + }else{ + g.zExtra = 0; + } + set_base_url(); + if( g.zExtra ){ /* CGI parameters get this treatment elsewhere, but places like getfile ** will use g.zExtra directly. */ dehttpize(g.zExtra); - }else{ - g.zExtra = 0; - } - g.zBaseURL = get_base_url(); + cgi_set_parameter_nocopy("name", g.zExtra); + } /* Prevent robots from indexing this site. */ if( strcmp(g.zPath, "robots.txt")==0 ){ cgi_set_content_type("text/plain"); @@ -595,10 +598,19 @@ }else{ db_must_be_within_tree(); } cgi_handle_http_request(); process_one_web_page(); +} + +/* +** COMMAND: test-http +** Works like the http command but gives setup permission to all users. +*/ +void cmd_test_http(void){ + login_set_capabilities("s"); + cmd_http(); } /* ** COMMAND: server **
Modified src/main.mk from [0a50945960] to [e26748a323].
@@ -14,10 +14,11 @@ SRC = \ $(SRCDIR)/add.c \ $(SRCDIR)/bag.c \ $(SRCDIR)/blob.c \ + $(SRCDIR)/branch.c \ $(SRCDIR)/cgi.c \ $(SRCDIR)/checkin.c \ $(SRCDIR)/checkout.c \ $(SRCDIR)/clearsign.c \ $(SRCDIR)/clone.c \ @@ -43,16 +44,22 @@ $(SRCDIR)/name.c \ $(SRCDIR)/pivot.c \ $(SRCDIR)/pqueue.c \ $(SRCDIR)/printf.c \ $(SRCDIR)/rebuild.c \ + $(SRCDIR)/rss.c \ $(SRCDIR)/schema.c \ $(SRCDIR)/setup.c \ $(SRCDIR)/sha1.c \ $(SRCDIR)/style.c \ + $(SRCDIR)/subscript.c \ $(SRCDIR)/sync.c \ + $(SRCDIR)/tag.c \ $(SRCDIR)/timeline.c \ + $(SRCDIR)/tkt.c \ + $(SRCDIR)/tktconfig.c \ + $(SRCDIR)/tktsetup.c \ $(SRCDIR)/undo.c \ $(SRCDIR)/update.c \ $(SRCDIR)/url.c \ $(SRCDIR)/user.c \ $(SRCDIR)/verify.c \ @@ -64,10 +71,11 @@ TRANS_SRC = \ add_.c \ bag_.c \ blob_.c \ + branch_.c \ cgi_.c \ checkin_.c \ checkout_.c \ clearsign_.c \ clone_.c \ @@ -93,16 +101,22 @@ name_.c \ pivot_.c \ pqueue_.c \ printf_.c \ rebuild_.c \ + rss_.c \ schema_.c \ setup_.c \ sha1_.c \ style_.c \ + subscript_.c \ sync_.c \ + tag_.c \ timeline_.c \ + tkt_.c \ + tktconfig_.c \ + tktsetup_.c \ undo_.c \ update_.c \ url_.c \ user_.c \ verify_.c \ @@ -114,10 +128,11 @@ OBJ = \ add.o \ bag.o \ blob.o \ + branch.o \ cgi.o \ checkin.o \ checkout.o \ clearsign.o \ clone.o \ @@ -143,16 +158,22 @@ name.o \ pivot.o \ pqueue.o \ printf.o \ rebuild.o \ + rss.o \ schema.o \ setup.o \ sha1.o \ style.o \ + subscript.o \ sync.o \ + tag.o \ timeline.o \ + tkt.o \ + tktconfig.o \ + tktsetup.o \ undo.o \ update.o \ url.o \ user.o \ verify.o \ @@ -184,23 +205,25 @@ # build is done from, i.e. the checkout belongs to. Do not sync/push # the repository after running the tests. test: $(APPNAME) $(TCLSH) test/tester.tcl $(APPNAME) -VERSION.h: $(SRCDIR)/../manifest.uuid +VERSION.h: $(SRCDIR)/../manifest.uuid $(SRCDIR)/../manifest awk '{ printf "#define MANIFEST_UUID \"%s\"\n", $$1}' $(SRCDIR)/../manifest.uuid >VERSION.h + awk '{ printf "#define MANIFEST_VERSION \"[%.10s]\"\n", $$1}' $(SRCDIR)/../manifest.uuid >>VERSION.h + awk '$$1=="D"{printf "#define MANIFEST_DATE \"%s %s\"\n", substr($$2,1,10),substr($$2,12)}' $(SRCDIR)/../manifest >>VERSION.h $(APPNAME): headers $(OBJ) sqlite3.o $(TCC) -o $(APPNAME) $(OBJ) sqlite3.o $(LIB) clean: rm -f *.o *_.c $(APPNAME) VERSION.h rm -f translate makeheaders mkindex page_index.h headers - rm -f add.h bag.h blob.h cgi.h checkin.h checkout.h clearsign.h clone.h comformat.h construct.h content.h db.h delta.h deltacmd.h descendents.h diff.h diffcmd.h encode.h file.h http.h info.h login.h main.h manifest.h md5.h merge.h merge3.h name.h pivot.h pqueue.h printf.h rebuild.h schema.h setup.h sha1.h style.h sync.h timeline.h undo.h update.h url.h user.h verify.h vfile.h wiki.h wikiformat.h xfer.h zip.h + rm -f add.h bag.h blob.h branch.h cgi.h checkin.h checkout.h clearsign.h clone.h comformat.h construct.h content.h db.h delta.h deltacmd.h descendents.h diff.h diffcmd.h encode.h file.h http.h info.h login.h main.h manifest.h md5.h merge.h merge3.h name.h pivot.h pqueue.h printf.h rebuild.h rss.h schema.h setup.h sha1.h style.h subscript.h sync.h tag.h timeline.h tkt.h tktconfig.h tktsetup.h undo.h update.h url.h user.h verify.h vfile.h wiki.h wikiformat.h xfer.h zip.h headers: makeheaders mkindex $(TRANS_SRC) ./VERSION.h - ./makeheaders add_.c:add.h bag_.c:bag.h blob_.c:blob.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h sync_.c:sync.h timeline_.c:timeline.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h ./VERSION.h + ./makeheaders add_.c:add.h bag_.c:bag.h blob_.c:blob.h branch_.c:branch.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h rss_.c:rss.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h subscript_.c:subscript.h sync_.c:sync.h tag_.c:tag.h timeline_.c:timeline.h tkt_.c:tkt.h tktconfig_.c:tktconfig.h tktsetup_.c:tktsetup.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h ./VERSION.h ./mkindex $(TRANS_SRC) >page_index.h touch headers add_.c: $(SRCDIR)/add.c $(SRCDIR)/VERSION translate ./translate $(SRCDIR)/add.c | sed -f $(SRCDIR)/VERSION >add_.c @@ -207,481 +230,551 @@ add.o: add_.c add.h $(SRCDIR)/config.h $(XTCC) -o add.o -c add_.c add.h: makeheaders - ./makeheaders add_.c:add.h bag_.c:bag.h blob_.c:blob.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h sync_.c:sync.h timeline_.c:timeline.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h ./VERSION.h + ./makeheaders add_.c:add.h bag_.c:bag.h blob_.c:blob.h branch_.c:branch.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h rss_.c:rss.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h subscript_.c:subscript.h sync_.c:sync.h tag_.c:tag.h timeline_.c:timeline.h tkt_.c:tkt.h tktconfig_.c:tktconfig.h tktsetup_.c:tktsetup.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h ./VERSION.h touch headers bag_.c: $(SRCDIR)/bag.c $(SRCDIR)/VERSION translate ./translate $(SRCDIR)/bag.c | sed -f $(SRCDIR)/VERSION >bag_.c bag.o: bag_.c bag.h $(SRCDIR)/config.h $(XTCC) -o bag.o -c bag_.c bag.h: makeheaders - ./makeheaders add_.c:add.h bag_.c:bag.h blob_.c:blob.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h sync_.c:sync.h timeline_.c:timeline.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h ./VERSION.h + ./makeheaders add_.c:add.h bag_.c:bag.h blob_.c:blob.h branch_.c:branch.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h rss_.c:rss.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h subscript_.c:subscript.h sync_.c:sync.h tag_.c:tag.h timeline_.c:timeline.h tkt_.c:tkt.h tktconfig_.c:tktconfig.h tktsetup_.c:tktsetup.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h ./VERSION.h touch headers blob_.c: $(SRCDIR)/blob.c $(SRCDIR)/VERSION translate ./translate $(SRCDIR)/blob.c | sed -f $(SRCDIR)/VERSION >blob_.c blob.o: blob_.c blob.h $(SRCDIR)/config.h $(XTCC) -o blob.o -c blob_.c blob.h: makeheaders - ./makeheaders add_.c:add.h bag_.c:bag.h blob_.c:blob.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h sync_.c:sync.h timeline_.c:timeline.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h ./VERSION.h + ./makeheaders add_.c:add.h bag_.c:bag.h blob_.c:blob.h branch_.c:branch.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h rss_.c:rss.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h subscript_.c:subscript.h sync_.c:sync.h tag_.c:tag.h timeline_.c:timeline.h tkt_.c:tkt.h tktconfig_.c:tktconfig.h tktsetup_.c:tktsetup.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h ./VERSION.h + touch headers + +branch_.c: $(SRCDIR)/branch.c $(SRCDIR)/VERSION translate + ./translate $(SRCDIR)/branch.c | sed -f $(SRCDIR)/VERSION >branch_.c + +branch.o: branch_.c branch.h $(SRCDIR)/config.h + $(XTCC) -o branch.o -c branch_.c + +branch.h: makeheaders + ./makeheaders add_.c:add.h bag_.c:bag.h blob_.c:blob.h branch_.c:branch.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h rss_.c:rss.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h subscript_.c:subscript.h sync_.c:sync.h tag_.c:tag.h timeline_.c:timeline.h tkt_.c:tkt.h tktconfig_.c:tktconfig.h tktsetup_.c:tktsetup.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h ./VERSION.h touch headers cgi_.c: $(SRCDIR)/cgi.c $(SRCDIR)/VERSION translate ./translate $(SRCDIR)/cgi.c | sed -f $(SRCDIR)/VERSION >cgi_.c cgi.o: cgi_.c cgi.h $(SRCDIR)/config.h $(XTCC) -o cgi.o -c cgi_.c cgi.h: makeheaders - ./makeheaders add_.c:add.h bag_.c:bag.h blob_.c:blob.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h sync_.c:sync.h timeline_.c:timeline.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h ./VERSION.h + ./makeheaders add_.c:add.h bag_.c:bag.h blob_.c:blob.h branch_.c:branch.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h rss_.c:rss.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h subscript_.c:subscript.h sync_.c:sync.h tag_.c:tag.h timeline_.c:timeline.h tkt_.c:tkt.h tktconfig_.c:tktconfig.h tktsetup_.c:tktsetup.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h ./VERSION.h touch headers checkin_.c: $(SRCDIR)/checkin.c $(SRCDIR)/VERSION translate ./translate $(SRCDIR)/checkin.c | sed -f $(SRCDIR)/VERSION >checkin_.c checkin.o: checkin_.c checkin.h $(SRCDIR)/config.h $(XTCC) -o checkin.o -c checkin_.c checkin.h: makeheaders - ./makeheaders add_.c:add.h bag_.c:bag.h blob_.c:blob.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h sync_.c:sync.h timeline_.c:timeline.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h ./VERSION.h + ./makeheaders add_.c:add.h bag_.c:bag.h blob_.c:blob.h branch_.c:branch.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h rss_.c:rss.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h subscript_.c:subscript.h sync_.c:sync.h tag_.c:tag.h timeline_.c:timeline.h tkt_.c:tkt.h tktconfig_.c:tktconfig.h tktsetup_.c:tktsetup.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h ./VERSION.h touch headers checkout_.c: $(SRCDIR)/checkout.c $(SRCDIR)/VERSION translate ./translate $(SRCDIR)/checkout.c | sed -f $(SRCDIR)/VERSION >checkout_.c checkout.o: checkout_.c checkout.h $(SRCDIR)/config.h $(XTCC) -o checkout.o -c checkout_.c checkout.h: makeheaders - ./makeheaders add_.c:add.h bag_.c:bag.h blob_.c:blob.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h sync_.c:sync.h timeline_.c:timeline.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h ./VERSION.h + ./makeheaders add_.c:add.h bag_.c:bag.h blob_.c:blob.h branch_.c:branch.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h rss_.c:rss.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h subscript_.c:subscript.h sync_.c:sync.h tag_.c:tag.h timeline_.c:timeline.h tkt_.c:tkt.h tktconfig_.c:tktconfig.h tktsetup_.c:tktsetup.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h ./VERSION.h touch headers clearsign_.c: $(SRCDIR)/clearsign.c $(SRCDIR)/VERSION translate ./translate $(SRCDIR)/clearsign.c | sed -f $(SRCDIR)/VERSION >clearsign_.c clearsign.o: clearsign_.c clearsign.h $(SRCDIR)/config.h $(XTCC) -o clearsign.o -c clearsign_.c clearsign.h: makeheaders - ./makeheaders add_.c:add.h bag_.c:bag.h blob_.c:blob.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h sync_.c:sync.h timeline_.c:timeline.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h ./VERSION.h + ./makeheaders add_.c:add.h bag_.c:bag.h blob_.c:blob.h branch_.c:branch.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h rss_.c:rss.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h subscript_.c:subscript.h sync_.c:sync.h tag_.c:tag.h timeline_.c:timeline.h tkt_.c:tkt.h tktconfig_.c:tktconfig.h tktsetup_.c:tktsetup.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h ./VERSION.h touch headers clone_.c: $(SRCDIR)/clone.c $(SRCDIR)/VERSION translate ./translate $(SRCDIR)/clone.c | sed -f $(SRCDIR)/VERSION >clone_.c clone.o: clone_.c clone.h $(SRCDIR)/config.h $(XTCC) -o clone.o -c clone_.c clone.h: makeheaders - ./makeheaders add_.c:add.h bag_.c:bag.h blob_.c:blob.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h sync_.c:sync.h timeline_.c:timeline.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h ./VERSION.h + ./makeheaders add_.c:add.h bag_.c:bag.h blob_.c:blob.h branch_.c:branch.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h rss_.c:rss.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h subscript_.c:subscript.h sync_.c:sync.h tag_.c:tag.h timeline_.c:timeline.h tkt_.c:tkt.h tktconfig_.c:tktconfig.h tktsetup_.c:tktsetup.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h ./VERSION.h touch headers comformat_.c: $(SRCDIR)/comformat.c $(SRCDIR)/VERSION translate ./translate $(SRCDIR)/comformat.c | sed -f $(SRCDIR)/VERSION >comformat_.c comformat.o: comformat_.c comformat.h $(SRCDIR)/config.h $(XTCC) -o comformat.o -c comformat_.c comformat.h: makeheaders - ./makeheaders add_.c:add.h bag_.c:bag.h blob_.c:blob.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h sync_.c:sync.h timeline_.c:timeline.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h ./VERSION.h + ./makeheaders add_.c:add.h bag_.c:bag.h blob_.c:blob.h branch_.c:branch.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h rss_.c:rss.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h subscript_.c:subscript.h sync_.c:sync.h tag_.c:tag.h timeline_.c:timeline.h tkt_.c:tkt.h tktconfig_.c:tktconfig.h tktsetup_.c:tktsetup.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h ./VERSION.h touch headers construct_.c: $(SRCDIR)/construct.c $(SRCDIR)/VERSION translate ./translate $(SRCDIR)/construct.c | sed -f $(SRCDIR)/VERSION >construct_.c construct.o: construct_.c construct.h $(SRCDIR)/config.h $(XTCC) -o construct.o -c construct_.c construct.h: makeheaders - ./makeheaders add_.c:add.h bag_.c:bag.h blob_.c:blob.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h sync_.c:sync.h timeline_.c:timeline.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h ./VERSION.h + ./makeheaders add_.c:add.h bag_.c:bag.h blob_.c:blob.h branch_.c:branch.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h rss_.c:rss.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h subscript_.c:subscript.h sync_.c:sync.h tag_.c:tag.h timeline_.c:timeline.h tkt_.c:tkt.h tktconfig_.c:tktconfig.h tktsetup_.c:tktsetup.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h ./VERSION.h touch headers content_.c: $(SRCDIR)/content.c $(SRCDIR)/VERSION translate ./translate $(SRCDIR)/content.c | sed -f $(SRCDIR)/VERSION >content_.c content.o: content_.c content.h $(SRCDIR)/config.h $(XTCC) -o content.o -c content_.c content.h: makeheaders - ./makeheaders add_.c:add.h bag_.c:bag.h blob_.c:blob.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h sync_.c:sync.h timeline_.c:timeline.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h ./VERSION.h + ./makeheaders add_.c:add.h bag_.c:bag.h blob_.c:blob.h branch_.c:branch.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h rss_.c:rss.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h subscript_.c:subscript.h sync_.c:sync.h tag_.c:tag.h timeline_.c:timeline.h tkt_.c:tkt.h tktconfig_.c:tktconfig.h tktsetup_.c:tktsetup.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h ./VERSION.h touch headers db_.c: $(SRCDIR)/db.c $(SRCDIR)/VERSION translate ./translate $(SRCDIR)/db.c | sed -f $(SRCDIR)/VERSION >db_.c db.o: db_.c db.h $(SRCDIR)/config.h $(XTCC) -o db.o -c db_.c db.h: makeheaders - ./makeheaders add_.c:add.h bag_.c:bag.h blob_.c:blob.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h sync_.c:sync.h timeline_.c:timeline.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h ./VERSION.h + ./makeheaders add_.c:add.h bag_.c:bag.h blob_.c:blob.h branch_.c:branch.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h rss_.c:rss.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h subscript_.c:subscript.h sync_.c:sync.h tag_.c:tag.h timeline_.c:timeline.h tkt_.c:tkt.h tktconfig_.c:tktconfig.h tktsetup_.c:tktsetup.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h ./VERSION.h touch headers delta_.c: $(SRCDIR)/delta.c $(SRCDIR)/VERSION translate ./translate $(SRCDIR)/delta.c | sed -f $(SRCDIR)/VERSION >delta_.c delta.o: delta_.c delta.h $(SRCDIR)/config.h $(XTCC) -o delta.o -c delta_.c delta.h: makeheaders - ./makeheaders add_.c:add.h bag_.c:bag.h blob_.c:blob.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h sync_.c:sync.h timeline_.c:timeline.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h ./VERSION.h + ./makeheaders add_.c:add.h bag_.c:bag.h blob_.c:blob.h branch_.c:branch.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h rss_.c:rss.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h subscript_.c:subscript.h sync_.c:sync.h tag_.c:tag.h timeline_.c:timeline.h tkt_.c:tkt.h tktconfig_.c:tktconfig.h tktsetup_.c:tktsetup.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h ./VERSION.h touch headers deltacmd_.c: $(SRCDIR)/deltacmd.c $(SRCDIR)/VERSION translate ./translate $(SRCDIR)/deltacmd.c | sed -f $(SRCDIR)/VERSION >deltacmd_.c deltacmd.o: deltacmd_.c deltacmd.h $(SRCDIR)/config.h $(XTCC) -o deltacmd.o -c deltacmd_.c deltacmd.h: makeheaders - ./makeheaders add_.c:add.h bag_.c:bag.h blob_.c:blob.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h sync_.c:sync.h timeline_.c:timeline.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h ./VERSION.h + ./makeheaders add_.c:add.h bag_.c:bag.h blob_.c:blob.h branch_.c:branch.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h rss_.c:rss.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h subscript_.c:subscript.h sync_.c:sync.h tag_.c:tag.h timeline_.c:timeline.h tkt_.c:tkt.h tktconfig_.c:tktconfig.h tktsetup_.c:tktsetup.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h ./VERSION.h touch headers descendents_.c: $(SRCDIR)/descendents.c $(SRCDIR)/VERSION translate ./translate $(SRCDIR)/descendents.c | sed -f $(SRCDIR)/VERSION >descendents_.c descendents.o: descendents_.c descendents.h $(SRCDIR)/config.h $(XTCC) -o descendents.o -c descendents_.c descendents.h: makeheaders - ./makeheaders add_.c:add.h bag_.c:bag.h blob_.c:blob.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h sync_.c:sync.h timeline_.c:timeline.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h ./VERSION.h + ./makeheaders add_.c:add.h bag_.c:bag.h blob_.c:blob.h branch_.c:branch.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h rss_.c:rss.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h subscript_.c:subscript.h sync_.c:sync.h tag_.c:tag.h timeline_.c:timeline.h tkt_.c:tkt.h tktconfig_.c:tktconfig.h tktsetup_.c:tktsetup.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h ./VERSION.h touch headers diff_.c: $(SRCDIR)/diff.c $(SRCDIR)/VERSION translate ./translate $(SRCDIR)/diff.c | sed -f $(SRCDIR)/VERSION >diff_.c diff.o: diff_.c diff.h $(SRCDIR)/config.h $(XTCC) -o diff.o -c diff_.c diff.h: makeheaders - ./makeheaders add_.c:add.h bag_.c:bag.h blob_.c:blob.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h sync_.c:sync.h timeline_.c:timeline.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h ./VERSION.h + ./makeheaders add_.c:add.h bag_.c:bag.h blob_.c:blob.h branch_.c:branch.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h rss_.c:rss.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h subscript_.c:subscript.h sync_.c:sync.h tag_.c:tag.h timeline_.c:timeline.h tkt_.c:tkt.h tktconfig_.c:tktconfig.h tktsetup_.c:tktsetup.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h ./VERSION.h touch headers diffcmd_.c: $(SRCDIR)/diffcmd.c $(SRCDIR)/VERSION translate ./translate $(SRCDIR)/diffcmd.c | sed -f $(SRCDIR)/VERSION >diffcmd_.c diffcmd.o: diffcmd_.c diffcmd.h $(SRCDIR)/config.h $(XTCC) -o diffcmd.o -c diffcmd_.c diffcmd.h: makeheaders - ./makeheaders add_.c:add.h bag_.c:bag.h blob_.c:blob.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h sync_.c:sync.h timeline_.c:timeline.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h ./VERSION.h + ./makeheaders add_.c:add.h bag_.c:bag.h blob_.c:blob.h branch_.c:branch.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h rss_.c:rss.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h subscript_.c:subscript.h sync_.c:sync.h tag_.c:tag.h timeline_.c:timeline.h tkt_.c:tkt.h tktconfig_.c:tktconfig.h tktsetup_.c:tktsetup.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h ./VERSION.h touch headers encode_.c: $(SRCDIR)/encode.c $(SRCDIR)/VERSION translate ./translate $(SRCDIR)/encode.c | sed -f $(SRCDIR)/VERSION >encode_.c encode.o: encode_.c encode.h $(SRCDIR)/config.h $(XTCC) -o encode.o -c encode_.c encode.h: makeheaders - ./makeheaders add_.c:add.h bag_.c:bag.h blob_.c:blob.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h sync_.c:sync.h timeline_.c:timeline.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h ./VERSION.h + ./makeheaders add_.c:add.h bag_.c:bag.h blob_.c:blob.h branch_.c:branch.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h rss_.c:rss.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h subscript_.c:subscript.h sync_.c:sync.h tag_.c:tag.h timeline_.c:timeline.h tkt_.c:tkt.h tktconfig_.c:tktconfig.h tktsetup_.c:tktsetup.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h ./VERSION.h touch headers file_.c: $(SRCDIR)/file.c $(SRCDIR)/VERSION translate ./translate $(SRCDIR)/file.c | sed -f $(SRCDIR)/VERSION >file_.c file.o: file_.c file.h $(SRCDIR)/config.h $(XTCC) -o file.o -c file_.c file.h: makeheaders - ./makeheaders add_.c:add.h bag_.c:bag.h blob_.c:blob.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h sync_.c:sync.h timeline_.c:timeline.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h ./VERSION.h + ./makeheaders add_.c:add.h bag_.c:bag.h blob_.c:blob.h branch_.c:branch.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h rss_.c:rss.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h subscript_.c:subscript.h sync_.c:sync.h tag_.c:tag.h timeline_.c:timeline.h tkt_.c:tkt.h tktconfig_.c:tktconfig.h tktsetup_.c:tktsetup.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h ./VERSION.h touch headers http_.c: $(SRCDIR)/http.c $(SRCDIR)/VERSION translate ./translate $(SRCDIR)/http.c | sed -f $(SRCDIR)/VERSION >http_.c http.o: http_.c http.h $(SRCDIR)/config.h $(XTCC) -o http.o -c http_.c http.h: makeheaders - ./makeheaders add_.c:add.h bag_.c:bag.h blob_.c:blob.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h sync_.c:sync.h timeline_.c:timeline.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h ./VERSION.h + ./makeheaders add_.c:add.h bag_.c:bag.h blob_.c:blob.h branch_.c:branch.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h rss_.c:rss.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h subscript_.c:subscript.h sync_.c:sync.h tag_.c:tag.h timeline_.c:timeline.h tkt_.c:tkt.h tktconfig_.c:tktconfig.h tktsetup_.c:tktsetup.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h ./VERSION.h touch headers info_.c: $(SRCDIR)/info.c $(SRCDIR)/VERSION translate ./translate $(SRCDIR)/info.c | sed -f $(SRCDIR)/VERSION >info_.c info.o: info_.c info.h $(SRCDIR)/config.h $(XTCC) -o info.o -c info_.c info.h: makeheaders - ./makeheaders add_.c:add.h bag_.c:bag.h blob_.c:blob.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h sync_.c:sync.h timeline_.c:timeline.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h ./VERSION.h + ./makeheaders add_.c:add.h bag_.c:bag.h blob_.c:blob.h branch_.c:branch.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h rss_.c:rss.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h subscript_.c:subscript.h sync_.c:sync.h tag_.c:tag.h timeline_.c:timeline.h tkt_.c:tkt.h tktconfig_.c:tktconfig.h tktsetup_.c:tktsetup.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h ./VERSION.h touch headers login_.c: $(SRCDIR)/login.c $(SRCDIR)/VERSION translate ./translate $(SRCDIR)/login.c | sed -f $(SRCDIR)/VERSION >login_.c login.o: login_.c login.h $(SRCDIR)/config.h $(XTCC) -o login.o -c login_.c login.h: makeheaders - ./makeheaders add_.c:add.h bag_.c:bag.h blob_.c:blob.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h sync_.c:sync.h timeline_.c:timeline.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h ./VERSION.h + ./makeheaders add_.c:add.h bag_.c:bag.h blob_.c:blob.h branch_.c:branch.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h rss_.c:rss.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h subscript_.c:subscript.h sync_.c:sync.h tag_.c:tag.h timeline_.c:timeline.h tkt_.c:tkt.h tktconfig_.c:tktconfig.h tktsetup_.c:tktsetup.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h ./VERSION.h touch headers main_.c: $(SRCDIR)/main.c $(SRCDIR)/VERSION translate ./translate $(SRCDIR)/main.c | sed -f $(SRCDIR)/VERSION >main_.c main.o: main_.c main.h page_index.h $(SRCDIR)/config.h $(XTCC) -o main.o -c main_.c main.h: makeheaders - ./makeheaders add_.c:add.h bag_.c:bag.h blob_.c:blob.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h sync_.c:sync.h timeline_.c:timeline.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h ./VERSION.h + ./makeheaders add_.c:add.h bag_.c:bag.h blob_.c:blob.h branch_.c:branch.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h rss_.c:rss.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h subscript_.c:subscript.h sync_.c:sync.h tag_.c:tag.h timeline_.c:timeline.h tkt_.c:tkt.h tktconfig_.c:tktconfig.h tktsetup_.c:tktsetup.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h ./VERSION.h touch headers manifest_.c: $(SRCDIR)/manifest.c $(SRCDIR)/VERSION translate ./translate $(SRCDIR)/manifest.c | sed -f $(SRCDIR)/VERSION >manifest_.c manifest.o: manifest_.c manifest.h $(SRCDIR)/config.h $(XTCC) -o manifest.o -c manifest_.c manifest.h: makeheaders - ./makeheaders add_.c:add.h bag_.c:bag.h blob_.c:blob.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h sync_.c:sync.h timeline_.c:timeline.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h ./VERSION.h + ./makeheaders add_.c:add.h bag_.c:bag.h blob_.c:blob.h branch_.c:branch.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h rss_.c:rss.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h subscript_.c:subscript.h sync_.c:sync.h tag_.c:tag.h timeline_.c:timeline.h tkt_.c:tkt.h tktconfig_.c:tktconfig.h tktsetup_.c:tktsetup.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h ./VERSION.h touch headers md5_.c: $(SRCDIR)/md5.c $(SRCDIR)/VERSION translate ./translate $(SRCDIR)/md5.c | sed -f $(SRCDIR)/VERSION >md5_.c md5.o: md5_.c md5.h $(SRCDIR)/config.h $(XTCC) -o md5.o -c md5_.c md5.h: makeheaders - ./makeheaders add_.c:add.h bag_.c:bag.h blob_.c:blob.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h sync_.c:sync.h timeline_.c:timeline.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h ./VERSION.h + ./makeheaders add_.c:add.h bag_.c:bag.h blob_.c:blob.h branch_.c:branch.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h rss_.c:rss.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h subscript_.c:subscript.h sync_.c:sync.h tag_.c:tag.h timeline_.c:timeline.h tkt_.c:tkt.h tktconfig_.c:tktconfig.h tktsetup_.c:tktsetup.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h ./VERSION.h touch headers merge_.c: $(SRCDIR)/merge.c $(SRCDIR)/VERSION translate ./translate $(SRCDIR)/merge.c | sed -f $(SRCDIR)/VERSION >merge_.c merge.o: merge_.c merge.h $(SRCDIR)/config.h $(XTCC) -o merge.o -c merge_.c merge.h: makeheaders - ./makeheaders add_.c:add.h bag_.c:bag.h blob_.c:blob.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h sync_.c:sync.h timeline_.c:timeline.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h ./VERSION.h + ./makeheaders add_.c:add.h bag_.c:bag.h blob_.c:blob.h branch_.c:branch.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h rss_.c:rss.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h subscript_.c:subscript.h sync_.c:sync.h tag_.c:tag.h timeline_.c:timeline.h tkt_.c:tkt.h tktconfig_.c:tktconfig.h tktsetup_.c:tktsetup.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h ./VERSION.h touch headers merge3_.c: $(SRCDIR)/merge3.c $(SRCDIR)/VERSION translate ./translate $(SRCDIR)/merge3.c | sed -f $(SRCDIR)/VERSION >merge3_.c merge3.o: merge3_.c merge3.h $(SRCDIR)/config.h $(XTCC) -o merge3.o -c merge3_.c merge3.h: makeheaders - ./makeheaders add_.c:add.h bag_.c:bag.h blob_.c:blob.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h sync_.c:sync.h timeline_.c:timeline.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h ./VERSION.h + ./makeheaders add_.c:add.h bag_.c:bag.h blob_.c:blob.h branch_.c:branch.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h rss_.c:rss.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h subscript_.c:subscript.h sync_.c:sync.h tag_.c:tag.h timeline_.c:timeline.h tkt_.c:tkt.h tktconfig_.c:tktconfig.h tktsetup_.c:tktsetup.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h ./VERSION.h touch headers name_.c: $(SRCDIR)/name.c $(SRCDIR)/VERSION translate ./translate $(SRCDIR)/name.c | sed -f $(SRCDIR)/VERSION >name_.c name.o: name_.c name.h $(SRCDIR)/config.h $(XTCC) -o name.o -c name_.c name.h: makeheaders - ./makeheaders add_.c:add.h bag_.c:bag.h blob_.c:blob.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h sync_.c:sync.h timeline_.c:timeline.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h ./VERSION.h + ./makeheaders add_.c:add.h bag_.c:bag.h blob_.c:blob.h branch_.c:branch.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h rss_.c:rss.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h subscript_.c:subscript.h sync_.c:sync.h tag_.c:tag.h timeline_.c:timeline.h tkt_.c:tkt.h tktconfig_.c:tktconfig.h tktsetup_.c:tktsetup.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h ./VERSION.h touch headers pivot_.c: $(SRCDIR)/pivot.c $(SRCDIR)/VERSION translate ./translate $(SRCDIR)/pivot.c | sed -f $(SRCDIR)/VERSION >pivot_.c pivot.o: pivot_.c pivot.h $(SRCDIR)/config.h $(XTCC) -o pivot.o -c pivot_.c pivot.h: makeheaders - ./makeheaders add_.c:add.h bag_.c:bag.h blob_.c:blob.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h sync_.c:sync.h timeline_.c:timeline.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h ./VERSION.h + ./makeheaders add_.c:add.h bag_.c:bag.h blob_.c:blob.h branch_.c:branch.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h rss_.c:rss.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h subscript_.c:subscript.h sync_.c:sync.h tag_.c:tag.h timeline_.c:timeline.h tkt_.c:tkt.h tktconfig_.c:tktconfig.h tktsetup_.c:tktsetup.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h ./VERSION.h touch headers pqueue_.c: $(SRCDIR)/pqueue.c $(SRCDIR)/VERSION translate ./translate $(SRCDIR)/pqueue.c | sed -f $(SRCDIR)/VERSION >pqueue_.c pqueue.o: pqueue_.c pqueue.h $(SRCDIR)/config.h $(XTCC) -o pqueue.o -c pqueue_.c pqueue.h: makeheaders - ./makeheaders add_.c:add.h bag_.c:bag.h blob_.c:blob.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h sync_.c:sync.h timeline_.c:timeline.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h ./VERSION.h + ./makeheaders add_.c:add.h bag_.c:bag.h blob_.c:blob.h branch_.c:branch.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h rss_.c:rss.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h subscript_.c:subscript.h sync_.c:sync.h tag_.c:tag.h timeline_.c:timeline.h tkt_.c:tkt.h tktconfig_.c:tktconfig.h tktsetup_.c:tktsetup.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h ./VERSION.h touch headers printf_.c: $(SRCDIR)/printf.c $(SRCDIR)/VERSION translate ./translate $(SRCDIR)/printf.c | sed -f $(SRCDIR)/VERSION >printf_.c printf.o: printf_.c printf.h $(SRCDIR)/config.h $(XTCC) -o printf.o -c printf_.c printf.h: makeheaders - ./makeheaders add_.c:add.h bag_.c:bag.h blob_.c:blob.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h sync_.c:sync.h timeline_.c:timeline.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h ./VERSION.h + ./makeheaders add_.c:add.h bag_.c:bag.h blob_.c:blob.h branch_.c:branch.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h rss_.c:rss.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h subscript_.c:subscript.h sync_.c:sync.h tag_.c:tag.h timeline_.c:timeline.h tkt_.c:tkt.h tktconfig_.c:tktconfig.h tktsetup_.c:tktsetup.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h ./VERSION.h touch headers rebuild_.c: $(SRCDIR)/rebuild.c $(SRCDIR)/VERSION translate ./translate $(SRCDIR)/rebuild.c | sed -f $(SRCDIR)/VERSION >rebuild_.c rebuild.o: rebuild_.c rebuild.h $(SRCDIR)/config.h $(XTCC) -o rebuild.o -c rebuild_.c rebuild.h: makeheaders - ./makeheaders add_.c:add.h bag_.c:bag.h blob_.c:blob.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h sync_.c:sync.h timeline_.c:timeline.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h ./VERSION.h + ./makeheaders add_.c:add.h bag_.c:bag.h blob_.c:blob.h branch_.c:branch.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h rss_.c:rss.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h subscript_.c:subscript.h sync_.c:sync.h tag_.c:tag.h timeline_.c:timeline.h tkt_.c:tkt.h tktconfig_.c:tktconfig.h tktsetup_.c:tktsetup.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h ./VERSION.h + touch headers + +rss_.c: $(SRCDIR)/rss.c $(SRCDIR)/VERSION translate + ./translate $(SRCDIR)/rss.c | sed -f $(SRCDIR)/VERSION >rss_.c + +rss.o: rss_.c rss.h $(SRCDIR)/config.h + $(XTCC) -o rss.o -c rss_.c + +rss.h: makeheaders + ./makeheaders add_.c:add.h bag_.c:bag.h blob_.c:blob.h branch_.c:branch.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h rss_.c:rss.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h subscript_.c:subscript.h sync_.c:sync.h tag_.c:tag.h timeline_.c:timeline.h tkt_.c:tkt.h tktconfig_.c:tktconfig.h tktsetup_.c:tktsetup.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h ./VERSION.h touch headers schema_.c: $(SRCDIR)/schema.c $(SRCDIR)/VERSION translate ./translate $(SRCDIR)/schema.c | sed -f $(SRCDIR)/VERSION >schema_.c schema.o: schema_.c schema.h $(SRCDIR)/config.h $(XTCC) -o schema.o -c schema_.c schema.h: makeheaders - ./makeheaders add_.c:add.h bag_.c:bag.h blob_.c:blob.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h sync_.c:sync.h timeline_.c:timeline.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h ./VERSION.h + ./makeheaders add_.c:add.h bag_.c:bag.h blob_.c:blob.h branch_.c:branch.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h rss_.c:rss.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h subscript_.c:subscript.h sync_.c:sync.h tag_.c:tag.h timeline_.c:timeline.h tkt_.c:tkt.h tktconfig_.c:tktconfig.h tktsetup_.c:tktsetup.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h ./VERSION.h touch headers setup_.c: $(SRCDIR)/setup.c $(SRCDIR)/VERSION translate ./translate $(SRCDIR)/setup.c | sed -f $(SRCDIR)/VERSION >setup_.c setup.o: setup_.c setup.h $(SRCDIR)/config.h $(XTCC) -o setup.o -c setup_.c setup.h: makeheaders - ./makeheaders add_.c:add.h bag_.c:bag.h blob_.c:blob.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h sync_.c:sync.h timeline_.c:timeline.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h ./VERSION.h + ./makeheaders add_.c:add.h bag_.c:bag.h blob_.c:blob.h branch_.c:branch.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h rss_.c:rss.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h subscript_.c:subscript.h sync_.c:sync.h tag_.c:tag.h timeline_.c:timeline.h tkt_.c:tkt.h tktconfig_.c:tktconfig.h tktsetup_.c:tktsetup.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h ./VERSION.h touch headers sha1_.c: $(SRCDIR)/sha1.c $(SRCDIR)/VERSION translate ./translate $(SRCDIR)/sha1.c | sed -f $(SRCDIR)/VERSION >sha1_.c sha1.o: sha1_.c sha1.h $(SRCDIR)/config.h $(XTCC) -o sha1.o -c sha1_.c sha1.h: makeheaders - ./makeheaders add_.c:add.h bag_.c:bag.h blob_.c:blob.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h sync_.c:sync.h timeline_.c:timeline.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h ./VERSION.h + ./makeheaders add_.c:add.h bag_.c:bag.h blob_.c:blob.h branch_.c:branch.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h rss_.c:rss.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h subscript_.c:subscript.h sync_.c:sync.h tag_.c:tag.h timeline_.c:timeline.h tkt_.c:tkt.h tktconfig_.c:tktconfig.h tktsetup_.c:tktsetup.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h ./VERSION.h touch headers style_.c: $(SRCDIR)/style.c $(SRCDIR)/VERSION translate ./translate $(SRCDIR)/style.c | sed -f $(SRCDIR)/VERSION >style_.c style.o: style_.c style.h $(SRCDIR)/config.h $(XTCC) -o style.o -c style_.c style.h: makeheaders - ./makeheaders add_.c:add.h bag_.c:bag.h blob_.c:blob.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h sync_.c:sync.h timeline_.c:timeline.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h ./VERSION.h + ./makeheaders add_.c:add.h bag_.c:bag.h blob_.c:blob.h branch_.c:branch.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h rss_.c:rss.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h subscript_.c:subscript.h sync_.c:sync.h tag_.c:tag.h timeline_.c:timeline.h tkt_.c:tkt.h tktconfig_.c:tktconfig.h tktsetup_.c:tktsetup.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h ./VERSION.h + touch headers + +subscript_.c: $(SRCDIR)/subscript.c $(SRCDIR)/VERSION translate + ./translate $(SRCDIR)/subscript.c | sed -f $(SRCDIR)/VERSION >subscript_.c + +subscript.o: subscript_.c subscript.h $(SRCDIR)/config.h + $(XTCC) -o subscript.o -c subscript_.c + +subscript.h: makeheaders + ./makeheaders add_.c:add.h bag_.c:bag.h blob_.c:blob.h branch_.c:branch.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h rss_.c:rss.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h subscript_.c:subscript.h sync_.c:sync.h tag_.c:tag.h timeline_.c:timeline.h tkt_.c:tkt.h tktconfig_.c:tktconfig.h tktsetup_.c:tktsetup.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h ./VERSION.h touch headers sync_.c: $(SRCDIR)/sync.c $(SRCDIR)/VERSION translate ./translate $(SRCDIR)/sync.c | sed -f $(SRCDIR)/VERSION >sync_.c sync.o: sync_.c sync.h $(SRCDIR)/config.h $(XTCC) -o sync.o -c sync_.c sync.h: makeheaders - ./makeheaders add_.c:add.h bag_.c:bag.h blob_.c:blob.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h sync_.c:sync.h timeline_.c:timeline.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h ./VERSION.h + ./makeheaders add_.c:add.h bag_.c:bag.h blob_.c:blob.h branch_.c:branch.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h rss_.c:rss.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h subscript_.c:subscript.h sync_.c:sync.h tag_.c:tag.h timeline_.c:timeline.h tkt_.c:tkt.h tktconfig_.c:tktconfig.h tktsetup_.c:tktsetup.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h ./VERSION.h + touch headers + +tag_.c: $(SRCDIR)/tag.c $(SRCDIR)/VERSION translate + ./translate $(SRCDIR)/tag.c | sed -f $(SRCDIR)/VERSION >tag_.c + +tag.o: tag_.c tag.h $(SRCDIR)/config.h + $(XTCC) -o tag.o -c tag_.c + +tag.h: makeheaders + ./makeheaders add_.c:add.h bag_.c:bag.h blob_.c:blob.h branch_.c:branch.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h rss_.c:rss.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h subscript_.c:subscript.h sync_.c:sync.h tag_.c:tag.h timeline_.c:timeline.h tkt_.c:tkt.h tktconfig_.c:tktconfig.h tktsetup_.c:tktsetup.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h ./VERSION.h touch headers timeline_.c: $(SRCDIR)/timeline.c $(SRCDIR)/VERSION translate ./translate $(SRCDIR)/timeline.c | sed -f $(SRCDIR)/VERSION >timeline_.c timeline.o: timeline_.c timeline.h $(SRCDIR)/config.h $(XTCC) -o timeline.o -c timeline_.c timeline.h: makeheaders - ./makeheaders add_.c:add.h bag_.c:bag.h blob_.c:blob.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h sync_.c:sync.h timeline_.c:timeline.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h ./VERSION.h + ./makeheaders add_.c:add.h bag_.c:bag.h blob_.c:blob.h branch_.c:branch.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h rss_.c:rss.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h subscript_.c:subscript.h sync_.c:sync.h tag_.c:tag.h timeline_.c:timeline.h tkt_.c:tkt.h tktconfig_.c:tktconfig.h tktsetup_.c:tktsetup.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h ./VERSION.h + touch headers + +tkt_.c: $(SRCDIR)/tkt.c $(SRCDIR)/VERSION translate + ./translate $(SRCDIR)/tkt.c | sed -f $(SRCDIR)/VERSION >tkt_.c + +tkt.o: tkt_.c tkt.h $(SRCDIR)/config.h + $(XTCC) -o tkt.o -c tkt_.c + +tkt.h: makeheaders + ./makeheaders add_.c:add.h bag_.c:bag.h blob_.c:blob.h branch_.c:branch.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h rss_.c:rss.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h subscript_.c:subscript.h sync_.c:sync.h tag_.c:tag.h timeline_.c:timeline.h tkt_.c:tkt.h tktconfig_.c:tktconfig.h tktsetup_.c:tktsetup.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h ./VERSION.h + touch headers + +tktconfig_.c: $(SRCDIR)/tktconfig.c $(SRCDIR)/VERSION translate + ./translate $(SRCDIR)/tktconfig.c | sed -f $(SRCDIR)/VERSION >tktconfig_.c + +tktconfig.o: tktconfig_.c tktconfig.h $(SRCDIR)/config.h + $(XTCC) -o tktconfig.o -c tktconfig_.c + +tktconfig.h: makeheaders + ./makeheaders add_.c:add.h bag_.c:bag.h blob_.c:blob.h branch_.c:branch.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h rss_.c:rss.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h subscript_.c:subscript.h sync_.c:sync.h tag_.c:tag.h timeline_.c:timeline.h tkt_.c:tkt.h tktconfig_.c:tktconfig.h tktsetup_.c:tktsetup.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h ./VERSION.h + touch headers + +tktsetup_.c: $(SRCDIR)/tktsetup.c $(SRCDIR)/VERSION translate + ./translate $(SRCDIR)/tktsetup.c | sed -f $(SRCDIR)/VERSION >tktsetup_.c + +tktsetup.o: tktsetup_.c tktsetup.h $(SRCDIR)/config.h + $(XTCC) -o tktsetup.o -c tktsetup_.c + +tktsetup.h: makeheaders + ./makeheaders add_.c:add.h bag_.c:bag.h blob_.c:blob.h branch_.c:branch.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h rss_.c:rss.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h subscript_.c:subscript.h sync_.c:sync.h tag_.c:tag.h timeline_.c:timeline.h tkt_.c:tkt.h tktconfig_.c:tktconfig.h tktsetup_.c:tktsetup.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h ./VERSION.h touch headers undo_.c: $(SRCDIR)/undo.c $(SRCDIR)/VERSION translate ./translate $(SRCDIR)/undo.c | sed -f $(SRCDIR)/VERSION >undo_.c undo.o: undo_.c undo.h $(SRCDIR)/config.h $(XTCC) -o undo.o -c undo_.c undo.h: makeheaders - ./makeheaders add_.c:add.h bag_.c:bag.h blob_.c:blob.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h sync_.c:sync.h timeline_.c:timeline.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h ./VERSION.h + ./makeheaders add_.c:add.h bag_.c:bag.h blob_.c:blob.h branch_.c:branch.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h rss_.c:rss.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h subscript_.c:subscript.h sync_.c:sync.h tag_.c:tag.h timeline_.c:timeline.h tkt_.c:tkt.h tktconfig_.c:tktconfig.h tktsetup_.c:tktsetup.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h ./VERSION.h touch headers update_.c: $(SRCDIR)/update.c $(SRCDIR)/VERSION translate ./translate $(SRCDIR)/update.c | sed -f $(SRCDIR)/VERSION >update_.c update.o: update_.c update.h $(SRCDIR)/config.h $(XTCC) -o update.o -c update_.c update.h: makeheaders - ./makeheaders add_.c:add.h bag_.c:bag.h blob_.c:blob.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h sync_.c:sync.h timeline_.c:timeline.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h ./VERSION.h + ./makeheaders add_.c:add.h bag_.c:bag.h blob_.c:blob.h branch_.c:branch.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h rss_.c:rss.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h subscript_.c:subscript.h sync_.c:sync.h tag_.c:tag.h timeline_.c:timeline.h tkt_.c:tkt.h tktconfig_.c:tktconfig.h tktsetup_.c:tktsetup.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h ./VERSION.h touch headers url_.c: $(SRCDIR)/url.c $(SRCDIR)/VERSION translate ./translate $(SRCDIR)/url.c | sed -f $(SRCDIR)/VERSION >url_.c url.o: url_.c url.h $(SRCDIR)/config.h $(XTCC) -o url.o -c url_.c url.h: makeheaders - ./makeheaders add_.c:add.h bag_.c:bag.h blob_.c:blob.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h sync_.c:sync.h timeline_.c:timeline.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h ./VERSION.h + ./makeheaders add_.c:add.h bag_.c:bag.h blob_.c:blob.h branch_.c:branch.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h rss_.c:rss.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h subscript_.c:subscript.h sync_.c:sync.h tag_.c:tag.h timeline_.c:timeline.h tkt_.c:tkt.h tktconfig_.c:tktconfig.h tktsetup_.c:tktsetup.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h ./VERSION.h touch headers user_.c: $(SRCDIR)/user.c $(SRCDIR)/VERSION translate ./translate $(SRCDIR)/user.c | sed -f $(SRCDIR)/VERSION >user_.c user.o: user_.c user.h $(SRCDIR)/config.h $(XTCC) -o user.o -c user_.c user.h: makeheaders - ./makeheaders add_.c:add.h bag_.c:bag.h blob_.c:blob.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h sync_.c:sync.h timeline_.c:timeline.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h ./VERSION.h + ./makeheaders add_.c:add.h bag_.c:bag.h blob_.c:blob.h branch_.c:branch.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h rss_.c:rss.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h subscript_.c:subscript.h sync_.c:sync.h tag_.c:tag.h timeline_.c:timeline.h tkt_.c:tkt.h tktconfig_.c:tktconfig.h tktsetup_.c:tktsetup.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h ./VERSION.h touch headers verify_.c: $(SRCDIR)/verify.c $(SRCDIR)/VERSION translate ./translate $(SRCDIR)/verify.c | sed -f $(SRCDIR)/VERSION >verify_.c verify.o: verify_.c verify.h $(SRCDIR)/config.h $(XTCC) -o verify.o -c verify_.c verify.h: makeheaders - ./makeheaders add_.c:add.h bag_.c:bag.h blob_.c:blob.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h sync_.c:sync.h timeline_.c:timeline.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h ./VERSION.h + ./makeheaders add_.c:add.h bag_.c:bag.h blob_.c:blob.h branch_.c:branch.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h rss_.c:rss.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h subscript_.c:subscript.h sync_.c:sync.h tag_.c:tag.h timeline_.c:timeline.h tkt_.c:tkt.h tktconfig_.c:tktconfig.h tktsetup_.c:tktsetup.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h ./VERSION.h touch headers vfile_.c: $(SRCDIR)/vfile.c $(SRCDIR)/VERSION translate ./translate $(SRCDIR)/vfile.c | sed -f $(SRCDIR)/VERSION >vfile_.c vfile.o: vfile_.c vfile.h $(SRCDIR)/config.h $(XTCC) -o vfile.o -c vfile_.c vfile.h: makeheaders - ./makeheaders add_.c:add.h bag_.c:bag.h blob_.c:blob.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h sync_.c:sync.h timeline_.c:timeline.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h ./VERSION.h + ./makeheaders add_.c:add.h bag_.c:bag.h blob_.c:blob.h branch_.c:branch.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h rss_.c:rss.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h subscript_.c:subscript.h sync_.c:sync.h tag_.c:tag.h timeline_.c:timeline.h tkt_.c:tkt.h tktconfig_.c:tktconfig.h tktsetup_.c:tktsetup.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h ./VERSION.h touch headers wiki_.c: $(SRCDIR)/wiki.c $(SRCDIR)/VERSION translate ./translate $(SRCDIR)/wiki.c | sed -f $(SRCDIR)/VERSION >wiki_.c wiki.o: wiki_.c wiki.h $(SRCDIR)/config.h $(XTCC) -o wiki.o -c wiki_.c wiki.h: makeheaders - ./makeheaders add_.c:add.h bag_.c:bag.h blob_.c:blob.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h sync_.c:sync.h timeline_.c:timeline.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h ./VERSION.h + ./makeheaders add_.c:add.h bag_.c:bag.h blob_.c:blob.h branch_.c:branch.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h rss_.c:rss.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h subscript_.c:subscript.h sync_.c:sync.h tag_.c:tag.h timeline_.c:timeline.h tkt_.c:tkt.h tktconfig_.c:tktconfig.h tktsetup_.c:tktsetup.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h ./VERSION.h touch headers wikiformat_.c: $(SRCDIR)/wikiformat.c $(SRCDIR)/VERSION translate ./translate $(SRCDIR)/wikiformat.c | sed -f $(SRCDIR)/VERSION >wikiformat_.c wikiformat.o: wikiformat_.c wikiformat.h $(SRCDIR)/config.h $(XTCC) -o wikiformat.o -c wikiformat_.c wikiformat.h: makeheaders - ./makeheaders add_.c:add.h bag_.c:bag.h blob_.c:blob.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h sync_.c:sync.h timeline_.c:timeline.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h ./VERSION.h + ./makeheaders add_.c:add.h bag_.c:bag.h blob_.c:blob.h branch_.c:branch.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h rss_.c:rss.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h subscript_.c:subscript.h sync_.c:sync.h tag_.c:tag.h timeline_.c:timeline.h tkt_.c:tkt.h tktconfig_.c:tktconfig.h tktsetup_.c:tktsetup.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h ./VERSION.h touch headers xfer_.c: $(SRCDIR)/xfer.c $(SRCDIR)/VERSION translate ./translate $(SRCDIR)/xfer.c | sed -f $(SRCDIR)/VERSION >xfer_.c xfer.o: xfer_.c xfer.h $(SRCDIR)/config.h $(XTCC) -o xfer.o -c xfer_.c xfer.h: makeheaders - ./makeheaders add_.c:add.h bag_.c:bag.h blob_.c:blob.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h sync_.c:sync.h timeline_.c:timeline.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h ./VERSION.h + ./makeheaders add_.c:add.h bag_.c:bag.h blob_.c:blob.h branch_.c:branch.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h rss_.c:rss.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h subscript_.c:subscript.h sync_.c:sync.h tag_.c:tag.h timeline_.c:timeline.h tkt_.c:tkt.h tktconfig_.c:tktconfig.h tktsetup_.c:tktsetup.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h ./VERSION.h touch headers zip_.c: $(SRCDIR)/zip.c $(SRCDIR)/VERSION translate ./translate $(SRCDIR)/zip.c | sed -f $(SRCDIR)/VERSION >zip_.c zip.o: zip_.c zip.h $(SRCDIR)/config.h $(XTCC) -o zip.o -c zip_.c zip.h: makeheaders - ./makeheaders add_.c:add.h bag_.c:bag.h blob_.c:blob.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h sync_.c:sync.h timeline_.c:timeline.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h ./VERSION.h + ./makeheaders add_.c:add.h bag_.c:bag.h blob_.c:blob.h branch_.c:branch.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h rss_.c:rss.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h subscript_.c:subscript.h sync_.c:sync.h tag_.c:tag.h timeline_.c:timeline.h tkt_.c:tkt.h tktconfig_.c:tktconfig.h tktsetup_.c:tktsetup.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h ./VERSION.h touch headers sqlite3.o: $(SRCDIR)/sqlite3.c - $(XTCC) -DSQLITE_OMIT_LOAD_EXTENSION=1 -DSQLITE_PRIVATE= -DTHREADSAFE=0 -DSQLITE_DEFAULT_FILE_FORMAT=4 -c $(SRCDIR)/sqlite3.c -o sqlite3.o + $(XTCC) -DSQLITE_OMIT_LOAD_EXTENSION=1 -DSQLITE_PRIVATE= -DSQLITE_THREADSAFE=0 -DSQLITE_DEFAULT_FILE_FORMAT=4 -DSQLITE_ENABLE_FTS3=1 -c $(SRCDIR)/sqlite3.c -o sqlite3.o
Modified src/makemake.tcl from [7db41ee41d] to [32b8cb3f29].
@@ -7,10 +7,11 @@ # set src { add bag blob + branch cgi checkin checkout clearsign clone @@ -36,16 +37,22 @@ name pivot pqueue printf rebuild + rss schema setup sha1 style + subscript sync + tag timeline + tkt + tktconfig + tktsetup undo update url user verify @@ -111,13 +118,18 @@ # build is done from, i.e. the checkout belongs to. Do not sync/push # the repository after running the tests. test: $(APPNAME) $(TCLSH) test/tester.tcl $(APPNAME) -VERSION.h: $(SRCDIR)/../manifest.uuid +VERSION.h: $(SRCDIR)/../manifest.uuid $(SRCDIR)/../manifest awk '{ printf "#define MANIFEST_UUID \"%s\"\n", $$1}' \ $(SRCDIR)/../manifest.uuid >VERSION.h + awk '{ printf "#define MANIFEST_VERSION \"[%.10s]\"\n", $$1}' \ + $(SRCDIR)/../manifest.uuid >>VERSION.h + awk '$$1=="D"{printf "#define MANIFEST_DATE \"%s %s\"\n",\ + substr($$2,1,10),substr($$2,12)}' \ + $(SRCDIR)/../manifest >>VERSION.h $(APPNAME): headers $(OBJ) sqlite3.o $(TCC) -o $(APPNAME) $(OBJ) sqlite3.o $(LIB) clean: @@ -150,7 +162,8 @@ } puts "sqlite3.o:\t\$(SRCDIR)/sqlite3.c" set opt {-DSQLITE_OMIT_LOAD_EXTENSION=1 -DSQLITE_PRIVATE=} -append opt " -DTHREADSAFE=0 -DSQLITE_DEFAULT_FILE_FORMAT=4" +append opt " -DSQLITE_THREADSAFE=0 -DSQLITE_DEFAULT_FILE_FORMAT=4" +append opt " -DSQLITE_ENABLE_FTS3=1" puts "\t\$(XTCC) $opt -c \$(SRCDIR)/sqlite3.c -o sqlite3.o\n"
Modified src/manifest.c from [3b8a4242be] to [9573b5d563].
@@ -19,26 +19,51 @@ ** drh@hwaci.com ** http://www.hwaci.com/drh/ ** ******************************************************************************* ** -** This file contains code used to cross link manifests +** This file contains code used to cross link control files and +** manifests. The file is named "manifest.c" because it was +** original only used to parse manifests. Then later clusters +** and control files and wiki pages and tickets were added. */ #include "config.h" #include "manifest.h" #include <assert.h> #if INTERFACE /* +** Types of control files +*/ +#define CFTYPE_MANIFEST 1 +#define CFTYPE_CLUSTER 2 +#define CFTYPE_CONTROL 3 +#define CFTYPE_WIKI 4 +#define CFTYPE_TICKET 5 + +/* +** Mode parameter values +*/ +#define CFMODE_READ 1 +#define CFMODE_APPEND 2 +#define CFMODE_WRITE 3 + +/* ** A parsed manifest or cluster. */ struct Manifest { Blob content; /* The original content blob */ + int type; /* Type of file */ + int mode; /* Access mode */ char *zComment; /* Decoded comment */ + char zUuid[UUID_SIZE+1]; /* Self UUID */ double rDate; /* Time in the "D" line */ char *zUser; /* Name of the user */ char *zRepoCksum; /* MD5 checksum of the baseline content */ + char *zWiki; /* Text of the wiki page */ + char *zWikiTitle; /* Name of the wiki page */ + char *zTicketUuid; /* UUID for a ticket */ int nFile; /* Number of F lines */ int nFileAlloc; /* Slots allocated in aFile[] */ struct { char *zName; /* Name of a file */ char *zUuid; /* UUID of the file */ @@ -47,10 +72,30 @@ int nParentAlloc; /* Slots allocated in azParent[] */ char **azParent; /* UUIDs of parents */ int nCChild; /* Number of cluster children */ int nCChildAlloc; /* Number of closts allocated in azCChild[] */ char **azCChild; /* UUIDs of referenced objects in a cluster */ + int nTag; /* Number of T lines */ + int nTagAlloc; /* Slots allocated in aTag[] */ + struct { + char *zName; /* Name of the tag */ + char *zUuid; /* UUID that the tag is applied to */ + char *zValue; /* Value if the tag is really a property */ + } *aTag; + int nField; /* Number of J lines */ + int nFieldAlloc; /* Slots allocated in aField[] */ + struct { + char *zName; /* Key or field name */ + char *zValue; /* Value of the field */ + } *aField; + int nAttach; /* Number of A lines */ + int nAttachAlloc; /* Slots allocated in aAttach[] */ + struct { + char *zUuid; /* UUID of the attachment */ + char *zName; /* Name of the attachment */ + char *zDesc; /* Description of the attachment */ + } *aAttach; }; #endif /* @@ -59,42 +104,65 @@ void manifest_clear(Manifest *p){ blob_reset(&p->content); free(p->aFile); free(p->azParent); free(p->azCChild); + free(p->aTag); + free(p->aField); + free(p->aAttach); memset(p, 0, sizeof(*p)); } /* -** Parse a manifest blob into a Manifest object. The Manifest -** object takes over the input blob and will free it when the +** Parse a blob into a Manifest object. The Manifest object +** takes over the input blob and will free it when the ** Manifest object is freed. Zeros are inserted into the blob ** as string terminators so that blob should not be used again. ** -** Return TRUE if the content really is a manifest. Return FALSE -** if there are syntax errors. +** Return TRUE if the content really is a control file of some +** kind. Return FALSE if there are syntax errors. +** +** This routine is strict about the format of a control file. +** The format must match exactly or else it is rejected. This +** rule minimizes the risk that a content file will be mistaken +** for a control file simply because they look the same. ** ** The pContent is reset. If TRUE is returned, then pContent will ** be reset when the Manifest object is cleared. If FALSE is ** returned then the Manifest object is cleared automatically ** and pContent is reset before the return. +** +** The entire file can be PGP clear-signed. The signature is ignored. +** The file consists of zero or more cards, one card per line. +** (Except: the content of the W card can extend of multiple lines.) +** Each card is divided into tokens by a single space character. +** The first token is a single upper-case letter which is the card type. +** The card type determines the other parameters to the card. +** Cards must occur in lexicographical order. */ int manifest_parse(Manifest *p, Blob *pContent){ int seenHeader = 0; - int i; + int seenZ = 0; + int i, lineNo=0; Blob line, token, a1, a2, a3; + Blob selfuuid; + char cPrevType = 0; memset(p, 0, sizeof(*p)); memcpy(&p->content, pContent, sizeof(p->content)); + sha1sum_blob(&p->content, &selfuuid); + memcpy(p->zUuid, blob_buffer(&selfuuid), UUID_SIZE); + p->zUuid[UUID_SIZE] = 0; blob_zero(pContent); pContent = &p->content; blob_zero(&a1); blob_zero(&a2); md5sum_init(); while( blob_line(pContent, &line) ){ char *z = blob_buffer(&line); + lineNo++; if( z[0]=='-' ){ if( strncmp(z, "-----BEGIN PGP ", 15)!=0 ){ goto manifest_syntax_error; } if( seenHeader ){ @@ -102,120 +170,489 @@ } while( blob_line(pContent, &line)>2 ){} if( blob_line(pContent, &line)==0 ) break; z = blob_buffer(&line); } + if( z[0]<cPrevType ){ + /* Lines of a manifest must occur in lexicographical order */ + goto manifest_syntax_error; + } + cPrevType = z[0]; seenHeader = 1; if( blob_token(&line, &token)!=1 ) goto manifest_syntax_error; - if( z[0]=='F' ){ - char *zName, *zUuid; - md5sum_step_text(blob_buffer(&line), blob_size(&line)); - if( blob_token(&line, &a1)==0 ) goto manifest_syntax_error; - if( blob_token(&line, &a2)==0 ) goto manifest_syntax_error; - if( blob_token(&line, &a3)!=0 ) goto manifest_syntax_error; - zName = blob_terminate(&a1); - zUuid = blob_terminate(&a2); - if( blob_size(&a2)!=UUID_SIZE ) goto manifest_syntax_error; - if( !validate16(zUuid, UUID_SIZE) ) goto manifest_syntax_error; - defossilize(zName); - if( !file_is_simple_pathname(zName) ){ - goto manifest_syntax_error; - } - if( p->nFile>=p->nFileAlloc ){ - p->nFileAlloc = p->nFileAlloc*2 + 10; - p->aFile = realloc(p->aFile, p->nFileAlloc*sizeof(p->aFile[0]) ); - if( p->aFile==0 ) fossil_panic("out of memory"); - } - i = p->nFile++; - p->aFile[i].zName = zName; - p->aFile[i].zUuid = zUuid; - if( i>0 && strcmp(p->aFile[i-1].zName, zName)>=0 ){ - goto manifest_syntax_error; - } - }else if( z[0]=='C' ){ - md5sum_step_text(blob_buffer(&line), blob_size(&line)); - if( p->zComment!=0 ) goto manifest_syntax_error; - if( blob_token(&line, &a1)==0 ) goto manifest_syntax_error; - if( blob_token(&line, &a2)!=0 ) goto manifest_syntax_error; - p->zComment = blob_terminate(&a1); - defossilize(p->zComment); - }else if( z[0]=='D' ){ - char *zDate; - md5sum_step_text(blob_buffer(&line), blob_size(&line)); - if( p->rDate!=0.0 ) goto manifest_syntax_error; - if( blob_token(&line, &a1)==0 ) goto manifest_syntax_error; - if( blob_token(&line, &a2)!=0 ) goto manifest_syntax_error; - zDate = blob_terminate(&a1); - p->rDate = db_double(0.0, "SELECT julianday(%Q)", zDate); - }else if( z[0]=='M' ){ - char *zUuid; - md5sum_step_text(blob_buffer(&line), blob_size(&line)); - if( blob_token(&line, &a1)==0 ) goto manifest_syntax_error; - zUuid = blob_terminate(&a1); - if( blob_size(&a1)!=UUID_SIZE ) goto manifest_syntax_error; - if( !validate16(zUuid, UUID_SIZE) ) goto manifest_syntax_error; - if( p->nCChild>=p->nCChildAlloc ){ - p->nCChildAlloc = p->nCChildAlloc*2 + 10; - p->azCChild = - realloc(p->azCChild, p->nCChildAlloc*sizeof(p->azCChild[0]) ); - if( p->azCChild==0 ) fossil_panic("out of memory"); - } - i = p->nCChild++; - p->azCChild[i] = zUuid; - if( i>0 && strcmp(p->azCChild[i-1], zUuid)>=0 ){ - goto manifest_syntax_error; - } - }else if( z[0]=='U' ){ - md5sum_step_text(blob_buffer(&line), blob_size(&line)); - if( p->zUser!=0 ) goto manifest_syntax_error; - if( blob_token(&line, &a1)==0 ) goto manifest_syntax_error; - if( blob_token(&line, &a2)!=0 ) goto manifest_syntax_error; - p->zUser = blob_terminate(&a1); - defossilize(p->zUser); - }else if( z[0]=='R' ){ - md5sum_step_text(blob_buffer(&line), blob_size(&line)); - if( p->zRepoCksum!=0 ) goto manifest_syntax_error; - if( blob_token(&line, &a1)==0 ) goto manifest_syntax_error; - if( blob_token(&line, &a2)!=0 ) goto manifest_syntax_error; - if( blob_size(&a1)!=32 ) goto manifest_syntax_error; - p->zRepoCksum = blob_terminate(&a1); - if( !validate16(p->zRepoCksum, 32) ) goto manifest_syntax_error; - }else if( z[0]=='P' ){ - md5sum_step_text(blob_buffer(&line), blob_size(&line)); - while( blob_token(&line, &a1) ){ + switch( z[0] ){ + /* + ** A <uuid> <filename> <description> + ** + ** Identifies an attachment to either a wiki page or a ticket. + ** <uuid> is the artifact that is the attachment. + */ + case 'A': { + char *zName, *zUuid, *zDesc; + md5sum_step_text(blob_buffer(&line), blob_size(&line)); + if( blob_token(&line, &a1)==0 ) goto manifest_syntax_error; + if( blob_token(&line, &a2)==0 ) goto manifest_syntax_error; + if( blob_token(&line, &a3)==0 ) goto manifest_syntax_error; + zUuid = blob_terminate(&a1); + zName = blob_terminate(&a2); + zDesc = blob_terminate(&a3); + if( blob_size(&a1)!=UUID_SIZE ) goto manifest_syntax_error; + if( !validate16(zUuid, UUID_SIZE) ) goto manifest_syntax_error; + defossilize(zName); + if( !file_is_simple_pathname(zName) ){ + goto manifest_syntax_error; + } + defossilize(zDesc); + if( p->nAttach>=p->nAttachAlloc ){ + p->nAttachAlloc = p->nAttachAlloc*2 + 10; + p->aAttach = realloc(p->aAttach, + p->nAttachAlloc*sizeof(p->aAttach[0]) ); + if( p->aAttach==0 ) fossil_panic("out of memory"); + } + i = p->nAttach++; + p->aAttach[i].zUuid = zUuid; + p->aAttach[i].zName = zName; + p->aAttach[i].zDesc = zDesc; + if( i>0 && strcmp(p->aAttach[i-1].zUuid, zUuid)>=0 ){ + goto manifest_syntax_error; + } + break; + } + + /* + ** C <comment> + ** + ** Comment text is fossil-encoded. There may be no more than + ** one C line. C lines are required for manifests and are + ** disallowed on all other control files. + */ + case 'C': { + md5sum_step_text(blob_buffer(&line), blob_size(&line)); + if( p->zComment!=0 ) goto manifest_syntax_error; + if( blob_token(&line, &a1)==0 ) goto manifest_syntax_error; + if( blob_token(&line, &a2)!=0 ) goto manifest_syntax_error; + p->zComment = blob_terminate(&a1); + defossilize(p->zComment); + break; + } + + /* + ** D <timestamp> + ** + ** The timestamp should be ISO 8601. YYYY-MM-DDtHH:MM:SS + ** There can be no more than 1 D line. D lines are required + ** for all control files except for clusters. + */ + case 'D': { + char *zDate; + md5sum_step_text(blob_buffer(&line), blob_size(&line)); + if( p->rDate!=0.0 ) goto manifest_syntax_error; + if( blob_token(&line, &a1)==0 ) goto manifest_syntax_error; + if( blob_token(&line, &a2)!=0 ) goto manifest_syntax_error; + zDate = blob_terminate(&a1); + p->rDate = db_double(0.0, "SELECT julianday(%Q)", zDate); + break; + } + + /* + ** E <mode> + ** + ** Access mode. <mode> can be one of "read", "append", + ** or "write". + */ + case 'E': { + md5sum_step_text(blob_buffer(&line), blob_size(&line)); + if( p->mode!=0 ) goto manifest_syntax_error; + if( blob_token(&line, &a1)==0 ) goto manifest_syntax_error; + if( blob_token(&line, &a2)!=0 ) goto manifest_syntax_error; + if( blob_eq(&a1, "write") ){ + p->mode = CFMODE_WRITE; + }else if( blob_eq(&a1, "append") ){ + p->mode = CFMODE_APPEND; + }else if( blob_eq(&a1, "read") ){ + p->mode = CFMODE_READ; + }else{ + goto manifest_syntax_error; + } + break; + } + + /* + ** F <filename> <uuid> + ** + ** Identifies a file in a manifest. Multiple F lines are + ** allowed in a manifest. F lines are not allowed in any + ** other control file. The filename is fossil-encoded. + */ + case 'F': { + char *zName, *zUuid; + md5sum_step_text(blob_buffer(&line), blob_size(&line)); + if( blob_token(&line, &a1)==0 ) goto manifest_syntax_error; + if( blob_token(&line, &a2)==0 ) goto manifest_syntax_error; + if( blob_token(&line, &a3)!=0 ) goto manifest_syntax_error; + zName = blob_terminate(&a1); + zUuid = blob_terminate(&a2); + if( blob_size(&a2)!=UUID_SIZE ) goto manifest_syntax_error; + if( !validate16(zUuid, UUID_SIZE) ) goto manifest_syntax_error; + defossilize(zName); + if( !file_is_simple_pathname(zName) ){ + goto manifest_syntax_error; + } + if( p->nFile>=p->nFileAlloc ){ + p->nFileAlloc = p->nFileAlloc*2 + 10; + p->aFile = realloc(p->aFile, p->nFileAlloc*sizeof(p->aFile[0]) ); + if( p->aFile==0 ) fossil_panic("out of memory"); + } + i = p->nFile++; + p->aFile[i].zName = zName; + p->aFile[i].zUuid = zUuid; + if( i>0 && strcmp(p->aFile[i-1].zName, zName)>=0 ){ + goto manifest_syntax_error; + } + break; + } + + /* + ** J '+'?<name> <value> + ** + ** Specifies a name value pair for ticket. If the first character + ** of <name> is "+" then the value is appended to any preexisting + ** value. + */ + case 'J': { + char *zName, *zValue; + md5sum_step_text(blob_buffer(&line), blob_size(&line)); + if( blob_token(&line, &a1)==0 ) goto manifest_syntax_error; + if( blob_token(&line, &a2)==0 ) goto manifest_syntax_error; + if( blob_token(&line, &a3)!=0 ) goto manifest_syntax_error; + zName = blob_terminate(&a1); + zValue = blob_terminate(&a2); + defossilize(zValue); + if( p->nField>=p->nFieldAlloc ){ + p->nFieldAlloc = p->nFieldAlloc*2 + 10; + p->aField = realloc(p->aField, + p->nFieldAlloc*sizeof(p->aField[0]) ); + if( p->aField==0 ) fossil_panic("out of memory"); + } + i = p->nField++; + p->aField[i].zName = zName; + p->aField[i].zValue = zValue; + if( i>0 && strcmp(p->aField[i-1].zName, zName)>=0 ){ + goto manifest_syntax_error; + } + break; + } + + + /* + ** K <uuid> + ** + ** A K-line gives the UUID for the ticket which this control file + ** is amending. + */ + case 'K': { + char *zUuid; + md5sum_step_text(blob_buffer(&line), blob_size(&line)); + if( blob_token(&line, &a1)==0 ) goto manifest_syntax_error; + zUuid = blob_terminate(&a1); + if( blob_size(&a1)!=UUID_SIZE ) goto manifest_syntax_error; + if( !validate16(zUuid, UUID_SIZE) ) goto manifest_syntax_error; + if( p->zTicketUuid!=0 ) goto manifest_syntax_error; + p->zTicketUuid = zUuid; + break; + } + + /* + ** L <wikititle> + ** + ** The wiki page title is fossil-encoded. There may be no more than + ** one L line. + */ + case 'L': { + md5sum_step_text(blob_buffer(&line), blob_size(&line)); + if( p->zWikiTitle!=0 ) goto manifest_syntax_error; + if( blob_token(&line, &a1)==0 ) goto manifest_syntax_error; + if( blob_token(&line, &a2)!=0 ) goto manifest_syntax_error; + p->zWikiTitle = blob_terminate(&a1); + defossilize(p->zWikiTitle); + if( !wiki_name_is_wellformed(p->zWikiTitle) ){ + goto manifest_syntax_error; + } + break; + } + + /* + ** M <uuid> + ** + ** An M-line identifies another artifact by its UUID. M-lines + ** occur in clusters only. + */ + case 'M': { char *zUuid; - if( blob_size(&a1)!=UUID_SIZE ) goto manifest_syntax_error; + md5sum_step_text(blob_buffer(&line), blob_size(&line)); + if( blob_token(&line, &a1)==0 ) goto manifest_syntax_error; zUuid = blob_terminate(&a1); + if( blob_size(&a1)!=UUID_SIZE ) goto manifest_syntax_error; if( !validate16(zUuid, UUID_SIZE) ) goto manifest_syntax_error; - if( p->nParent>=p->nParentAlloc ){ - p->nParentAlloc = p->nParentAlloc*2 + 5; - p->azParent = realloc(p->azParent, p->nParentAlloc*sizeof(char*)); - if( p->azParent==0 ) fossil_panic("out of memory"); + if( p->nCChild>=p->nCChildAlloc ){ + p->nCChildAlloc = p->nCChildAlloc*2 + 10; + p->azCChild = + realloc(p->azCChild, p->nCChildAlloc*sizeof(p->azCChild[0]) ); + if( p->azCChild==0 ) fossil_panic("out of memory"); + } + i = p->nCChild++; + p->azCChild[i] = zUuid; + if( i>0 && strcmp(p->azCChild[i-1], zUuid)>=0 ){ + goto manifest_syntax_error; + } + break; + } + + /* + ** P <uuid> ... + ** + ** Specify one or more other artifacts where are the parents of + ** this artifact. The first parent is the primary parent. All + ** others are parents by merge. + */ + case 'P': { + md5sum_step_text(blob_buffer(&line), blob_size(&line)); + while( blob_token(&line, &a1) ){ + char *zUuid; + if( blob_size(&a1)!=UUID_SIZE ) goto manifest_syntax_error; + zUuid = blob_terminate(&a1); + if( !validate16(zUuid, UUID_SIZE) ) goto manifest_syntax_error; + if( p->nParent>=p->nParentAlloc ){ + p->nParentAlloc = p->nParentAlloc*2 + 5; + p->azParent = realloc(p->azParent, p->nParentAlloc*sizeof(char*)); + if( p->azParent==0 ) fossil_panic("out of memory"); + } + i = p->nParent++; + p->azParent[i] = zUuid; + } + break; + } + + /* + ** R <md5sum> + ** + ** Specify the MD5 checksum of the entire baseline in a + ** manifest. + */ + case 'R': { + md5sum_step_text(blob_buffer(&line), blob_size(&line)); + if( p->zRepoCksum!=0 ) goto manifest_syntax_error; + if( blob_token(&line, &a1)==0 ) goto manifest_syntax_error; + if( blob_token(&line, &a2)!=0 ) goto manifest_syntax_error; + if( blob_size(&a1)!=32 ) goto manifest_syntax_error; + p->zRepoCksum = blob_terminate(&a1); + if( !validate16(p->zRepoCksum, 32) ) goto manifest_syntax_error; + break; + } + + /* + ** T (+|*|-)<tagname> <uuid> ?<value>? + ** + ** Create or cancel a tag or property. The tagname is fossil-encoded. + ** The first character of the name must be either "+" to create a + ** singleton tag, "*" to create a propagating tag, or "-" to create + ** anti-tag that undoes a prior "+" or blocks propagation of of + ** a "*". + ** + ** The tag is applied to <uuid>. If <uuid> is "*" then the tag is + ** applied to the current manifest. If <value> is provided then + ** the tag is really a property with the given value. + ** + ** Tags are not allowed in clusters. Multiple T lines are allowed. + */ + case 'T': { + char *zName, *zUuid, *zValue; + md5sum_step_text(blob_buffer(&line), blob_size(&line)); + if( blob_token(&line, &a1)==0 ){ + goto manifest_syntax_error; + } + if( blob_token(&line, &a2)==0 ){ + goto manifest_syntax_error; + } + zName = blob_terminate(&a1); + zUuid = blob_terminate(&a2); + if( blob_token(&line, &a3)==0 ){ + zValue = 0; + }else{ + zValue = blob_terminate(&a3); + defossilize(zValue); + } + if( blob_size(&a2)==UUID_SIZE && validate16(zUuid, UUID_SIZE) ){ + /* A valid uuid */ + }else if( blob_size(&a2)==1 && zUuid[0]=='*' ){ + zUuid = p->zUuid; + }else{ + goto manifest_syntax_error; + } + defossilize(zName); + if( zName[0]!='-' && zName[0]!='+' && zName[0]!='*' ){ + goto manifest_syntax_error; + } + if( validate16(&zName[1], strlen(&zName[1])) ){ + /* Do not allow tags whose names look like UUIDs */ + goto manifest_syntax_error; + } + if( p->nTag>=p->nTagAlloc ){ + p->nTagAlloc = p->nTagAlloc*2 + 10; + p->aTag = realloc(p->aTag, p->nTagAlloc*sizeof(p->aTag[0]) ); + if( p->aTag==0 ) fossil_panic("out of memory"); + } + i = p->nTag++; + p->aTag[i].zName = zName; + p->aTag[i].zUuid = zUuid; + p->aTag[i].zValue = zValue; + if( i>0 && strcmp(p->aTag[i-1].zName, zName)>=0 ){ + goto manifest_syntax_error; + } + break; + } + + /* + ** U <login> + ** + ** Identify the user who created this control file by their + ** login. Only one U line is allowed. Prohibited in clusters. + */ + case 'U': { + md5sum_step_text(blob_buffer(&line), blob_size(&line)); + if( p->zUser!=0 ) goto manifest_syntax_error; + if( blob_token(&line, &a1)==0 ) goto manifest_syntax_error; + if( blob_token(&line, &a2)!=0 ) goto manifest_syntax_error; + p->zUser = blob_terminate(&a1); + defossilize(p->zUser); + break; + } + + /* + ** W <size> + ** + ** The next <size> bytes of the file contain the text of the wiki + ** page. There is always an extra \n before the start of the next + ** record. + */ + case 'W': { + int size; + Blob wiki; + md5sum_step_text(blob_buffer(&line), blob_size(&line)); + if( blob_token(&line, &a1)==0 ) goto manifest_syntax_error; + if( blob_token(&line, &a2)!=0 ) goto manifest_syntax_error; + if( !blob_is_int(&a1, &size) ) goto manifest_syntax_error; + if( size<0 ) goto manifest_syntax_error; + if( p->zWiki!=0 ) goto manifest_syntax_error; + blob_zero(&wiki); + if( blob_extract(pContent, size+1, &wiki)!=size+1 ){ + goto manifest_syntax_error; } - i = p->nParent++; - p->azParent[i] = zUuid; + p->zWiki = blob_buffer(&wiki); + md5sum_step_text(p->zWiki, size+1); + if( p->zWiki[size]!='\n' ) goto manifest_syntax_error; + p->zWiki[size] = 0; + break; + } + + + /* + ** Z <md5sum> + ** + ** MD5 checksum on this control file. The checksum is over all + ** lines (other than PGP-signature lines) prior to the current + ** line. This must be the last record. + ** + ** This card is required for all control file types except for + ** Manifest. It is not required for manifest only for historical + ** compatibility reasons. + */ + case 'Z': { + int rc; + Blob hash; + if( blob_token(&line, &a1)==0 ) goto manifest_syntax_error; + if( blob_token(&line, &a2)!=0 ) goto manifest_syntax_error; + if( blob_size(&a1)!=32 ) goto manifest_syntax_error; + if( !validate16(blob_buffer(&a1), 32) ) goto manifest_syntax_error; + md5sum_finish(&hash); + rc = blob_compare(&hash, &a1); + blob_reset(&hash); + if( rc!=0 ) goto manifest_syntax_error; + seenZ = 1; + break; } - }else if( z[0]=='Z' ){ - int rc; - Blob hash; - if( blob_token(&line, &a1)==0 ) goto manifest_syntax_error; - if( blob_token(&line, &a2)!=0 ) goto manifest_syntax_error; - if( blob_size(&a1)!=32 ) goto manifest_syntax_error; - if( !validate16(blob_buffer(&a1), 32) ) goto manifest_syntax_error; - md5sum_finish(&hash); - rc = blob_compare(&hash, &a1); - blob_reset(&hash); - if( rc!=0 ) goto manifest_syntax_error; - }else{ - goto manifest_syntax_error; + default: { + goto manifest_syntax_error; + } } } if( !seenHeader ) goto manifest_syntax_error; + + if( p->nFile>0 ){ + if( p->nCChild>0 ) goto manifest_syntax_error; + if( p->rDate==0.0 ) goto manifest_syntax_error; + if( p->nField>0 ) goto manifest_syntax_error; + if( p->zTicketUuid ) goto manifest_syntax_error; + if( p->nAttach>0 ) goto manifest_syntax_error; + if( p->zWiki ) goto manifest_syntax_error; + if( p->zWikiTitle ) goto manifest_syntax_error; + if( p->zTicketUuid ) goto manifest_syntax_error; + p->type = CFTYPE_MANIFEST; + }else if( p->nCChild>0 ){ + if( p->rDate>0.0 ) goto manifest_syntax_error; + if( p->zComment!=0 ) goto manifest_syntax_error; + if( p->zUser!=0 ) goto manifest_syntax_error; + if( p->nTag>0 ) goto manifest_syntax_error; + if( p->nParent>0 ) goto manifest_syntax_error; + if( p->zRepoCksum!=0 ) goto manifest_syntax_error; + if( p->nField>0 ) goto manifest_syntax_error; + if( p->zTicketUuid ) goto manifest_syntax_error; + if( p->nAttach>0 ) goto manifest_syntax_error; + if( p->zWiki ) goto manifest_syntax_error; + if( p->zWikiTitle ) goto manifest_syntax_error; + if( !seenZ ) goto manifest_syntax_error; + p->type = CFTYPE_CLUSTER; + }else if( p->nField>0 ){ + if( p->rDate==0.0 ) goto manifest_syntax_error; + if( p->zRepoCksum!=0 ) goto manifest_syntax_error; + if( p->zWiki ) goto manifest_syntax_error; + if( p->zWikiTitle ) goto manifest_syntax_error; + if( p->nCChild>0 ) goto manifest_syntax_error; + if( p->nTag>0 ) goto manifest_syntax_error; + if( p->zTicketUuid==0 ) goto manifest_syntax_error; + if( p->zUser==0 ) goto manifest_syntax_error; + if( !seenZ ) goto manifest_syntax_error; + p->type = CFTYPE_TICKET; + }else if( p->zWiki!=0 ){ + if( p->rDate==0.0 ) goto manifest_syntax_error; + if( p->zRepoCksum!=0 ) goto manifest_syntax_error; + if( p->nCChild>0 ) goto manifest_syntax_error; + if( p->nTag>0 ) goto manifest_syntax_error; + if( p->zTicketUuid!=0 ) goto manifest_syntax_error; + if( p->zWikiTitle==0 ) goto manifest_syntax_error; + if( !seenZ ) goto manifest_syntax_error; + p->type = CFTYPE_WIKI; + }else if( p->nTag>0 ){ + if( p->rDate<=0.0 ) goto manifest_syntax_error; + if( p->zRepoCksum!=0 ) goto manifest_syntax_error; + if( p->nParent>0 ) goto manifest_syntax_error; + if( p->nAttach>0 ) goto manifest_syntax_error; + if( p->nField>0 ) goto manifest_syntax_error; + if( p->zWiki ) goto manifest_syntax_error; + if( p->zWikiTitle ) goto manifest_syntax_error; + if( p->zTicketUuid ) goto manifest_syntax_error; + if( !seenZ ) goto manifest_syntax_error; + p->type = CFTYPE_CONTROL; + }else{ + goto manifest_syntax_error; + } + md5sum_init(); return 1; manifest_syntax_error: + /*fprintf(stderr, "Manifest error on line %i\n", lineNo);fflush(stderr);*/ md5sum_init(); manifest_clear(p); return 0; } @@ -322,42 +759,126 @@ */ int manifest_crosslink(int rid, Blob *pContent){ int i; Manifest m; Stmt q; + int parentid = 0; if( manifest_parse(&m, pContent)==0 ){ return 0; } db_begin_transaction(); - if( !db_exists("SELECT 1 FROM mlink WHERE mid=%d", rid) ){ - for(i=0; i<m.nParent; i++){ - int pid = uuid_to_rid(m.azParent[i], 1); - db_multi_exec("INSERT OR IGNORE INTO plink(pid, cid, isprim, mtime)" - "VALUES(%d, %d, %d, %.17g)", pid, rid, i==0, m.rDate); - if( i==0 ){ - add_mlink(pid, 0, rid, &m); + if( m.type==CFTYPE_MANIFEST ){ + if( !db_exists("SELECT 1 FROM mlink WHERE mid=%d", rid) ){ + for(i=0; i<m.nParent; i++){ + int pid = uuid_to_rid(m.azParent[i], 1); + db_multi_exec("INSERT OR IGNORE INTO plink(pid, cid, isprim, mtime)" + "VALUES(%d, %d, %d, %.17g)", pid, rid, i==0, m.rDate); + if( i==0 ){ + add_mlink(pid, 0, rid, &m); + parentid = pid; + } + } + db_prepare(&q, "SELECT cid FROM plink WHERE pid=%d AND isprim", rid); + while( db_step(&q)==SQLITE_ROW ){ + int cid = db_column_int(&q, 0); + add_mlink(rid, &m, cid, 0); + } + db_finalize(&q); + db_multi_exec( + "INSERT INTO event(type,mtime,objid,user,comment," + " bgcolor,brbgcolor,euser,ecomment)" + "VALUES('ci',%.17g,%d,%Q,%Q," + " (SELECT value FROM tagxref WHERE tagid=%d AND rid=%d AND tagtype=1)," + "(SELECT value FROM tagxref WHERE tagid=%d AND rid=%d AND tagtype!=1)," + " (SELECT value FROM tagxref WHERE tagid=%d AND rid=%d)," + " (SELECT value FROM tagxref WHERE tagid=%d AND rid=%d));", + m.rDate, rid, m.zUser, m.zComment, + TAG_BGCOLOR, rid, + TAG_BGCOLOR, rid, + TAG_USER, rid, + TAG_COMMENT, rid + ); + } + } + if( m.type==CFTYPE_CLUSTER ){ + for(i=0; i<m.nCChild; i++){ + int mid; + mid = uuid_to_rid(m.azCChild[i], 1); + if( mid>0 ){ + db_multi_exec("DELETE FROM unclustered WHERE rid=%d", mid); + } + } + } + if( m.type==CFTYPE_CONTROL || m.type==CFTYPE_MANIFEST ){ + for(i=0; i<m.nTag; i++){ + int tid; + int type; + tid = uuid_to_rid(m.aTag[i].zUuid, 1); + switch( m.aTag[i].zName[0] ){ + case '+': type = 1; break; + case '*': type = 2; break; + case '-': type = 0; break; + default: + fossil_fatal("unknown tag type in manifest: %s", m.aTag); + return 0; } + tag_insert(&m.aTag[i].zName[1], type, m.aTag[i].zValue, + rid, m.rDate, tid); } - db_prepare(&q, "SELECT cid FROM plink WHERE pid=%d AND isprim", rid); - while( db_step(&q)==SQLITE_ROW ){ - int cid = db_column_int(&q, 0); - add_mlink(rid, &m, cid, 0); + if( parentid ){ + tag_propagate_all(parentid); } - db_finalize(&q); - db_multi_exec( - "INSERT INTO event(type,mtime,objid,user,comment)" - "VALUES('ci',%.17g,%d,%Q,%Q)", - m.rDate, rid, m.zUser, m.zComment - ); } - for(i=0; i<m.nCChild; i++){ - int rid; - rid = uuid_to_rid(m.azCChild[i], 1); - if( rid>0 ){ - db_multi_exec("DELETE FROM unclustered WHERE rid=%d", rid); + if( m.type==CFTYPE_WIKI ){ + char *zTag = mprintf("wiki-%s", m.zWikiTitle); + int tagid = tag_findid(zTag, 1); + int prior; + char *zComment; + tag_insert(zTag, 1, 0, rid, m.rDate, rid); + free(zTag); + prior = db_int(0, + "SELECT rid FROM tagxref" + " WHERE tagid=%d AND mtime<%.17g" + " ORDER BY mtime DESC", + tagid, m.rDate + ); + if( prior ){ + content_deltify(prior, rid, 0); } + zComment = mprintf("Changes to wiki page [%h]", m.zWikiTitle); + db_multi_exec( + "INSERT INTO event(type,mtime,objid,user,comment," + " bgcolor,brbgcolor,euser,ecomment)" + "VALUES('w',%.17g,%d,%Q,%Q," + " (SELECT value FROM tagxref WHERE tagid=%d AND rid=%d AND tagtype=1)," + "(SELECT value FROM tagxref WHERE tagid=%d AND rid=%d AND tagtype!=1)," + " (SELECT value FROM tagxref WHERE tagid=%d AND rid=%d)," + " (SELECT value FROM tagxref WHERE tagid=%d AND rid=%d));", + m.rDate, rid, m.zUser, zComment, + TAG_BGCOLOR, rid, + TAG_BGCOLOR, rid, + TAG_USER, rid, + TAG_COMMENT, rid + ); + free(zComment); + } + if( m.type==CFTYPE_TICKET ){ + char *zTag; + char *zComment; + + ticket_insert(&m, 1, 1); + zTag = mprintf("tkt-%s", m.zTicketUuid); + tag_insert(zTag, 1, 0, rid, m.rDate, rid); + free(zTag); + zComment = mprintf("Changes to ticket [%.10s]", m.zTicketUuid); + db_multi_exec( + "INSERT INTO event(type,mtime,objid,user,comment)" + "VALUES('t',%.17g,%d,%Q,%Q)", + m.rDate, rid, m.zUser, zComment + ); + free(zComment); } db_end_transaction(0); manifest_clear(&m); return 1; }
Modified src/merge.c from [246b01382f] to [5979683d08].
@@ -44,11 +44,13 @@ void merge_cmd(void){ int vid; /* Current version */ int mid; /* Version we are merging against */ int pid; /* The pivot version - most recent common ancestor */ Stmt q; + int detailFlag; + detailFlag = find_option("detail",0,0)!=0; if( g.argc!=3 ){ usage("VERSION"); } db_must_be_within_tree(); vid = db_lget_int("checkout", 0); @@ -215,32 +217,45 @@ /* ** Do a three-way merge on files that have changes pid->mid and pid->vid */ db_prepare(&q, - "SELECT ridm, idv, ridp FROM fv" + "SELECT ridm, idv, ridp, ridv FROM fv" " WHERE idp>0 AND idv>0 AND idm>0" " AND ridm!=ridp AND (ridv!=ridp OR chnged)" ); while( db_step(&q)==SQLITE_ROW ){ int ridm = db_column_int(&q, 0); int idv = db_column_int(&q, 1); int ridp = db_column_int(&q, 2); + int ridv = db_column_int(&q, 3); + int rc; char *zName = db_text(0, "SELECT pathname FROM vfile WHERE id=%d", idv); char *zFullPath; Blob m, p, v, r; /* Do a 3-way merge of idp->idm into idp->idv. The results go into idv. */ - printf("MERGE %s\n", zName); + if( detailFlag ){ + printf("MERGE %s (pivot=%d v1=%d v2=%d)\n", zName, ridp, ridm, ridv); + }else{ + printf("MERGE %s\n", zName); + } undo_save(zName); zFullPath = mprintf("%s/%s", g.zLocalRoot, zName); - free(zName); content_get(ridp, &p); content_get(ridm, &m); blob_zero(&v); blob_read_from_file(&v, zFullPath); - blob_merge(&p, &m, &v, &r); - blob_write_to_file(&r, zFullPath); + rc = blob_merge(&p, &m, &v, &r); + if( rc>=0 ){ + blob_write_to_file(&r, zFullPath); + if( rc>0 ){ + printf("***** %d merge conflicts in %s\n", rc, zName); + } + }else{ + printf("***** Cannot merge binary file %s\n", zName); + } + free(zName); blob_reset(&p); blob_reset(&m); blob_reset(&v); blob_reset(&r); db_multi_exec("INSERT OR IGNORE INTO vmerge(id,merge) VALUES(%d,%d)",
Modified src/merge3.c from [5d18e08162] to [e01dd37d11].
@@ -25,593 +25,187 @@ */ #include "config.h" #include "merge3.h" #if 0 -# define DEBUG1(X) X +#define DEBUG(X) X #else -# define DEBUG1(X) -#endif -#if 0 -#define DEBUG2(X) X -/* -** For debugging: -** Print 16 characters of text from zBuf -*/ -static const char *print16(const char *z){ - int i; - static char zBuf[20]; - for(i=0; i<16; i++){ - if( z[i]>=0x20 && z[i]<=0x7e ){ - zBuf[i] = z[i]; - }else{ - zBuf[i] = '.'; - } - } - zBuf[i] = 0; - return zBuf; -} -#else -# define DEBUG2(X) +#define DEBUG(X) #endif /* -** Must be a 32-bit integer +** Opcodes */ -typedef unsigned int u32; - -/* -** Must be a 16-bit value -*/ -typedef unsigned short int u16; +#define CPY 0 +#define DEL 1 +#define INS 2 +#define END 3 +#define UNK 4 /* -** The width of a hash window in bytes. The algorithm only works if this -** is a power of 2. -*/ -#define NHASH 16 - -/* -** The current state of the rolling hash. +** Compare a single line of text from pV1 and pV2. If the lines +** are the same, return true. Return false if they are different. ** -** z[] holds the values that have been hashed. z[] is a circular buffer. -** z[i] is the first entry and z[(i+NHASH-1)%NHASH] is the last entry of -** the window. -** -** Hash.a is the sum of all elements of hash.z[]. Hash.b is a weighted -** sum. Hash.b is z[i]*NHASH + z[i+1]*(NHASH-1) + ... + z[i+NHASH-1]*1. -** (Each index for z[] should be module NHASH, of course. The %NHASH operator -** is omitted in the prior expression for brevity.) +** The cursor on both pV1 and pV2 is unchanged. */ -typedef struct hash hash; -struct hash { - u16 a, b; /* Hash values */ - u16 i; /* Start of the hash window */ - char z[NHASH]; /* The values that have been hashed */ -}; - -/* -** Initialize the rolling hash using the first NHASH characters of z[] -*/ -static void hash_init(hash *pHash, const char *z){ - u16 a, b, i; - a = b = 0; - for(i=0; i<NHASH; i++){ - a += z[i]; - b += (NHASH-i)*z[i]; - pHash->z[i] = z[i]; - } - pHash->a = a & 0xffff; - pHash->b = b & 0xffff; - pHash->i = 0; +static int sameLine(Blob *pV1, Blob *pV2){ + char *z1, *z2; + int i; + + z1 = &blob_buffer(pV1)[blob_tell(pV1)]; + z2 = &blob_buffer(pV2)[blob_tell(pV2)]; + for(i=0; z1[i]!='\n' && z1[i]==z2[i]; i++){} + return z2[i]=='\n' || (z2[i]=='\r' && z2[i+1]=='\n') + || (z1[i]=='\r' && z2[i]=='\n' && z1[i+1]=='\n'); } /* -** Advance the rolling hash by a single character "c" -*/ -static void hash_next(hash *pHash, int c){ - u16 old = pHash->z[pHash->i]; - pHash->z[pHash->i] = c; - pHash->i = (pHash->i+1)&(NHASH-1); - pHash->a = pHash->a - old + c; - pHash->b = pHash->b - NHASH*old + pHash->a; -} - -/* -** Return a 32-bit hash value +** Do a three-way merge. Initialize pOut to contain the result. +** +** The merge is an edit against pV2. Both pV1 and pV2 have a +** common origin at pPivot. Apply the changes of pPivot ==> pV1 +** to pV2. +** +** The return is 0 upon complete success. If any input file is binary, +** -1 is returned and pOut is unmodified. If there are merge +** conflicts, the merge proceeds as best as it can and the number +** of conflicts is returns */ -static u32 hash_32bit(hash *pHash){ - return (pHash->a & 0xffff) | (((u32)(pHash->b & 0xffff))<<16); -} +int blob_merge(Blob *pPivot, Blob *pV1, Blob *pV2, Blob *pOut){ + int *aC1; /* Changes from pPivot to pV1 */ + int *aC2; /* Changes from pPivot to pV2 */ + int i1, i2; + int op1, op2; + int limit1, limit2; + int inConflict = 0; + int nConflict = 0; + static const char zBegin[] = ">>>>>>>> BEGIN MERGE CONFLICT <<<<<<<<\n"; + static const char zEnd[] = ">>>>>>>>> END MERGE CONFLICT <<<<<<<<<\n"; + + aC1 = text_diff(pPivot, pV1, 0, 0); + aC2 = text_diff(pPivot, pV2, 0, 0); + + if( aC2==0 || aC2==0 ){ + free(aC1); + free(aC2); + return -1; + } + blob_zero(pOut); + blob_rewind(pV1); + blob_rewind(pV2); + blob_rewind(pPivot); + + for(i1=0; aC1[i1] || aC1[i1+1] || aC1[i1+2]; i1+=3){} + limit1 = i1; + for(i2=0; aC2[i2] || aC2[i2+1] || aC2[i2+2]; i2+=3){} + limit2 = i2; -/* -** Maximum number of landmarks to set in the source file. -*/ -#define MX_LANDMARK (1024*128) + DEBUG( + for(i1=0; i1<limit1; i1+=3){ + printf("c1: %4d %4d %4d\n", aC1[i1], aC1[i1+1], aC1[i1+2]); + } + for(i2=0; i2<limit2; i2+=3){ + printf("c2: %4d %4d %4d\n", aC2[i2], aC2[i2+1], aC2[i2+2]); + } + ) -/* -** A mapping structure is used to record which parts of two -** files contain the same text. There are zero or more mapping -** entries in a mapping. Each entry maps a segment of text in -** the source file into a segment of the output file. -** -** fromFirst...fromLast -> toFirst...toLast -** -** Extra text might be inserted in the output file after a -** mapping. The nExtra parameter records the number of bytes -** of extra text to insert. -*/ -typedef struct Mapping Mapping; -struct Mapping { - int nMap; - int nUsed; - struct Mapping_entry { - int fromFirst, fromLast; - int toFirst, toLast; - int nExtra; - } *aMap; -}; + op1 = op2 = UNK; + i1 = i2 = 0; + while( i1<limit1 && aC1[i1]==0 ){ i1++; } + while( i2<limit2 && aC2[i2]==0 ){ i2++; } -/* -** Free malloced memory associated with a mapping. -*/ -static void MappingClear(Mapping *p){ - free(p->aMap); - memset(p, 0, sizeof(*p)); -} - -/* -** Add an entry to a mapping structure. The mapping is: -** -** a...b -> c...d -** -** The nExtra parameter is initially zero. It will be changed -** later if necessary. -*/ -static void MappingInsert(Mapping *p, int a, int b, int c, int d){ - struct Mapping_entry *pEntry; - int i; - for(i=0, pEntry=p->aMap; i<p->nUsed; i++, pEntry++){ - if( pEntry->fromFirst==a && pEntry->fromLast==b && pEntry->toFirst==c ){ - DEBUG2( printf("DUPLICATE: %6d..%-6d %6d..%d\n", a, b, c, d); ) - return; + while(1){ + if( op1==UNK ){ + if( i1>=limit1 ){ + op1 = END; + DEBUG( printf("get op1=END\n"); ) + }else{ + op1 = i1 % 3; + aC1[i1]--; + DEBUG( printf("get op1=%d from %d (%d->%d)\n", + op1,i1,aC1[i1]+1,aC1[i1]); ) + while( i1<limit1 && aC1[i1]==0 ){ i1++; } + } + } + if( op2==UNK ){ + if( i2>=limit2 ){ + op2 = END; + DEBUG( printf("get op2=END\n"); ) + }else{ + op2 = i2 % 3; + aC2[i2]--; + DEBUG( printf("get op2=%d from %d (%d->%d)\n", + op2,i2,aC2[i2]+1,aC2[i2]); ) + while( i2<limit2 && aC2[i2]==0 ){ i2++; } + } + } + DEBUG( printf("op1=%d op2=%d\n", op1, op2); ) + if( op1==END ){ + if( op2==INS ){ + blob_copy_lines(pOut, pV2, 1); + op2 = UNK; + }else{ + break; + } + }else if( op2==END ){ + if( op1==INS ){ + blob_copy_lines(pOut, pV1, 1); + op1 = UNK; + }else{ + break; + } + }else if( op1==INS && op2==INS ){ + if( !inConflict && sameLine(pV1, pV2) ){ + blob_copy_lines(pOut, pV2, 1); + blob_copy_lines(0, pV1, 0); + op1 = UNK; + op2 = UNK; + }else{ + if( !inConflict ){ + inConflict = 1; + nConflict++; + blob_appendf(pOut, zBegin); + } + blob_copy_lines(pOut, pV1, 1); + op1 = UNK; + } + }else if( op1==INS ){ + blob_copy_lines(pOut, pV1, 1); + op1 = UNK; + }else if( op2==INS ){ + blob_copy_lines(pOut, pV2, 1); + op2 = UNK; + }else{ + if( inConflict ){ + inConflict = 0; + blob_appendf(pOut, zEnd); + } + if( op1==DEL || op2==DEL ){ + blob_copy_lines(0, pPivot, 1); + if( op2==CPY ){ + blob_copy_lines(0, pV2, 1); + } + if( op1==CPY ){ + blob_copy_lines(0, pV1, 1); + } + }else{ + assert( op1==CPY && op2==CPY ); + blob_copy_lines(pOut, pPivot, 1); + blob_copy_lines(0, pV1, 1); + blob_copy_lines(0, pV2, 1); + } + op1 = UNK; + op2 = UNK; } } - if( p->nUsed>=p->nMap ){ - p->nMap = p->nMap * 2 + 10; - p->aMap = realloc(p->aMap, p->nMap*sizeof(p->aMap[0]) ); - if( p->aMap==0 ) exit(1); - } - pEntry = &p->aMap[p->nUsed]; - pEntry->fromFirst = a; - pEntry->fromLast = b; - pEntry->toFirst = c; - pEntry->toLast = d; - pEntry->nExtra = 0; - p->nUsed++; -} - -DEBUG1( -/* -** For debugging purposes: -** Print the content of a mapping. -*/ -static void MappingPrint(Mapping *pMap){ - int i; - struct Mapping_entry *p; - for(i=0, p=pMap->aMap; i<pMap->nUsed; i++, p++){ - printf("%6d..%-6d %6d..%-6d %d\n", - p->fromFirst, p->fromLast, - p->toFirst, p->toLast, p->nExtra); - } -} -) - -/* -** Remove deleted entries from a mapping. Deleted enties have -** an fromFirst of less than 0. -*/ -static void MappingPurgeDeletedEntries(Mapping *p){ - int i, j; - for(i=j=0; i<p->nUsed; i++){ - if( p->aMap[i].fromFirst<0 ) continue; - if( j<i ){ - p->aMap[j] = p->aMap[i]; - } - j++; - } - p->nUsed = j; -} - -/* -** Comparisons functions used for sorting elements of a Mapping -*/ -static int intAbs(int x){ return x<0 ? -x : x; } -static int compareSize(const void *a, const void *b){ - const struct Mapping_entry *A = (const struct Mapping_entry*)a; - const struct Mapping_entry *B = (const struct Mapping_entry*)b; - int rc; - rc = (B->fromLast - B->fromFirst) - (A->fromLast - A->fromFirst); - if( rc==0 ){ - rc = intAbs(A->toFirst - A->fromFirst) - - intAbs(B->toFirst - B->fromFirst); - } - return rc; -} -static int compareFrom(const void *a, const void *b){ - const struct Mapping_entry *A = (const struct Mapping_entry*)a; - const struct Mapping_entry *B = (const struct Mapping_entry*)b; - return A->fromFirst - B->fromFirst; -} -static int compareTo(const void *a, const void *b){ - const struct Mapping_entry *A = (const struct Mapping_entry*)a; - const struct Mapping_entry *B = (const struct Mapping_entry*)b; - return A->toFirst - B->toFirst; -} - -/* -** Routines for sorting the entries of a mapping. SortSize sorts -** the entries in order of decreasing size (largest first.) -** SortFrom and SortTo sort the entries in order of increasing -** fromFirst and toFirst. -*/ -static void MappingSortSize(Mapping *p){ - qsort(p->aMap, p->nUsed, sizeof(p->aMap[0]), compareSize); -} -static void MappingSortFrom(Mapping *p){ - qsort(p->aMap, p->nUsed, sizeof(p->aMap[0]), compareFrom); -} -static void MappingSortTo(Mapping *p){ - qsort(p->aMap, p->nUsed, sizeof(p->aMap[0]), compareTo); -} - -/* -** Initialize pMap to contain a set of similarities between two files. -*/ -static void MappingInit( - const char *zSrc, /* The source or pattern file */ - int lenSrc, /* Length of the source file */ - const char *zOut, /* The target file */ - int lenOut, /* Length of the target file */ - Mapping *pMap /* Write the map of similaries here */ -){ - int i, j, base, prefix; - hash h; - int *collide; - int origLenOut = lenOut; - struct Mapping_entry *aMap; - int landmark[MX_LANDMARK]; - - /* - ** Initialize the map - */ - memset(pMap, 0, sizeof(*pMap)); - - /* - ** Find common prefix and suffix - */ - if( lenSrc<=NHASH || lenOut<=NHASH ){ - MappingInsert(pMap, 0, 0, 0, 0); - goto add_nextra; - } - for(i=0; i<lenSrc && i<lenOut && zSrc[i]==zOut[i]; i++){} - if( i>=NHASH ){ - MappingInsert(pMap, 0, i-1, 0, i-1); - lenSrc -= i; - zSrc += i; - lenOut -= i; - zOut += i; - if( lenSrc<=0 || lenOut<=0 ) goto add_nextra; - prefix = i; - }else{ - prefix = 0; - } - for(i=1; i<=lenSrc && i<=lenOut && zSrc[lenSrc-i]==zOut[lenOut-i]; i++){} - if( i>NHASH ){ - MappingInsert(pMap, prefix+lenSrc-i+1, prefix+lenSrc-1, - prefix+lenOut-i+1, prefix+lenOut-1); - lenSrc -= i; - lenOut -= i; + if( inConflict ){ + blob_appendf(pOut, zEnd); } - /* If the source file is very small, it means that we have no - ** chance of ever finding any matches. We can leave early. - */ - if( lenSrc<=NHASH ) goto add_nextra; - - /* Compute the hash table used to locate matching sections in the - ** source file. - */ - collide = malloc( lenSrc*sizeof(int)/NHASH ); - if( collide==0 ) return; - memset(landmark, -1, sizeof(landmark)); - memset(collide, -1, lenSrc*sizeof(int)/NHASH ); - for(i=0; i<lenSrc-NHASH; i+=NHASH){ - int hv; - hash_init(&h, &zSrc[i]); - hv = hash_32bit(&h) & (MX_LANDMARK-1); - collide[i/NHASH] = landmark[hv]; - landmark[hv] = i/NHASH; - } - - /* Begin scanning the target file and generating mappings. In this - ** step, we generate as many mapping entries is we can. Many of these - ** entries might overlap. The overlapping entries are removed by - ** the loop the follows. - */ - base = 0; /* We have already checked everything before zOut[base] */ - while( base<lenOut-NHASH ){ - int iSrc, iBlock, nextBase, nextBaseI; - hash_init(&h, &zOut[base]); - i = 0; /* Trying to match a landmark against zOut[base+i] */ - nextBaseI = NHASH; - nextBase = base; - while(1){ - int hv; - - hv = hash_32bit(&h) & (MX_LANDMARK-1); - DEBUG2( printf("LOOKING: %d+%d+%d=%d [%s]\n", - prefix,base,i,prefix+base+i, print16(&zOut[base+i])); ) - iBlock = landmark[hv]; - while( iBlock>=0 ){ - /* - ** The hash window has identified a potential match against - ** landmark block iBlock. But we need to investigate further. - ** - ** Look for a region in zOut that matches zSrc. Anchor the search - ** at zSrc[iSrc] and zOut[base+i]. - ** - ** Set cnt equal to the length of the match and set ofst so that - ** zSrc[ofst] is the first element of the match. - */ - int cnt, ofstSrc; - int j, k, x, y; - - /* Beginning at iSrc, match forwards as far as we can. j counts - ** the number of characters that match */ - iSrc = iBlock*NHASH; - for(j=0, x=iSrc, y=base+i; x<lenSrc && y<lenOut; j++, x++, y++){ - if( zSrc[x]!=zOut[y] ) break; - } - j--; - - /* Beginning at iSrc-1, match backwards as far as we can. k counts - ** the number of characters that match */ - for(k=1; k<iSrc && k<=base+i; k++){ - if( zSrc[iSrc-k]!=zOut[base+i-k] ) break; - } - k--; - - /* Compute the offset and size of the matching region zSrc */ - ofstSrc = iSrc-k; - cnt = j+k+1; - DEBUG2( printf("MATCH %d bytes at SRC[%d..%d]: [%s]\n", - cnt, ofstSrc, ofstSrc+cnt-1, print16(&zSrc[ofstSrc])); ) - if( cnt>NHASH ){ - int ofstOut = base+i-k; - DEBUG2( printf("COPY %6d..%-6d %6d..%d\n", - prefix+ofstSrc, prefix+ofstSrc+cnt-1, - prefix+ofstOut, prefix+ofstOut+cnt-1); ) - MappingInsert(pMap, - prefix+ofstSrc, prefix+ofstSrc+cnt-1, - prefix+ofstOut, prefix+ofstOut+cnt-1); - if( nextBase < ofstOut+cnt-1 ){ - nextBase = ofstOut+cnt-1; - nextBaseI = i+NHASH; - } - } - - /* Check the next matching block */ - iBlock = collide[iBlock]; - } - - /* If we found a match, then jump out to the outer loop and begin - ** a new cycle. - */ - if( nextBase>base && i>=nextBaseI ){ - base = nextBase; - break; - } - - /* Advance the hash by one character. Keep looking for a match */ - if( base+i+NHASH>=lenOut ){ - base = lenOut; - break; - } - hash_next(&h, zOut[base+i+NHASH]); - i++; - } - } - free(collide); - DEBUG1( - printf("after creation:\n"); - MappingPrint(pMap); - ) - - /* In this step, we will remove overlapping entries from the mapping. - ** - ** We use a greedy algorithm. Select the largest mapping first and - ** remove all overlapping mappings. Then take the next largest - ** mapping and remove others that overlap with it. Keep going until - ** all mappings have been processed. - */ - MappingSortSize(pMap); - for(i=0; i<pMap->nUsed; i++){ - int sortNeeded = 0; - int purgeNeeded = 0; - struct Mapping_entry *pA; - pA = &pMap->aMap[i]; - for(j=i+1; j<pMap->nUsed; j++){ - int diff; - struct Mapping_entry *pB; - pB = &pMap->aMap[j]; - if( pB->fromLast<pA->fromFirst || pB->fromFirst>pA->fromLast ){ - /* No overlap. Do nothing */ - }else if( pB->fromFirst>=pA->fromFirst && pB->fromLast<=pA->fromLast ){ - /* B is contained entirely within A. Drop B */ - pB->fromFirst = -1; - purgeNeeded = 1; - continue; - }else if( pB->fromFirst<pA->fromFirst ){ - /* The tail B overlaps the head of A */ - assert( pB->fromLast>=pA->fromFirst && pB->fromLast<=pA->fromLast ); - diff = pB->fromLast + 1 - pA->fromFirst; - pB->fromLast -= diff; - pB->toLast -= diff; - sortNeeded = 1; - }else{ - /* The head of B overlaps the tail of A */ - assert( pB->fromFirst<=pA->fromLast && pB->fromLast>pA->fromLast ); - diff = pA->fromLast + 1 - pB->fromFirst; - pB->fromFirst += diff; - pB->toFirst += diff; - sortNeeded = 1; - } - if( pB->toLast<pA->toFirst || pB->toFirst>pA->toLast ){ - /* No overlap. Do nothing */ - }else if( pB->toFirst>=pA->toFirst && pB->toLast<=pA->toLast ){ - /* B is contained entirely within A. Drop B */ - pB->fromFirst = -1; - purgeNeeded = 1; - }else if( pB->toFirst<pA->toFirst ){ - /* The tail of B overlaps the head of A */ - assert( pB->toLast>=pA->toFirst && pB->toLast<=pA->toLast ); - diff = pB->toLast + 1 - pA->toFirst; - pB->fromLast -= diff; - pB->toLast -= diff; - sortNeeded = 1; - }else{ - /* The head of B overlaps the tail of A */ - assert( pB->toFirst<=pA->toLast && pB->toLast>pA->toLast ); - diff = pA->toLast + 1 - pB->toFirst; - pB->fromFirst += diff; - pB->toFirst += diff; - sortNeeded = 1; - } - } - if( purgeNeeded ){ - MappingPurgeDeletedEntries(pMap); - } - if( sortNeeded && i<pMap->nUsed-2 ){ - MappingSortSize(pMap); - } - } - - /* Final step: Arrange the mapping entires so that they are in the - ** order of the output file. Then fill in the nExtra values. - */ -add_nextra: - MappingSortTo(pMap); - aMap = pMap->aMap; - for(i=0; i<pMap->nUsed-1; i++){ - aMap[i].nExtra = aMap[i+1].toFirst - aMap[i].toLast - 1; - } - if( pMap->nUsed>0 && origLenOut > aMap[i].toLast+1 ){ - aMap[i].nExtra = origLenOut - aMap[i].toLast - 1; - } -} - -/* -** Translate an index into a file using a mapping. -** -** The mapping "p" shows how blocks in the input file map into blocks -** of the output file. The index iFrom is an index into the input file. -** This routine returns the index into the output file of the corresponding -** character. -** -** If pInserted!=0 and iFrom points to the last character before a -** insert in the output file, then the return value is adjusted forward -** so that it points to the end of the insertion and the number of -** bytes inserted is written into *pInserted. If pInserted==0 then -** iFrom always maps directly in the corresponding output file -** index regardless of whether or not it points to the last character -** before an insertion. -*/ -static int MappingTranslate(Mapping *p, int iFrom, int *pInserted){ - int i; - for(i=0; i<p->nUsed; i++){ - if( iFrom>p->aMap[i].fromLast ) continue; - if( iFrom<=p->aMap[i].fromFirst ){ - return p->aMap[i].toFirst; - } - if( pInserted && iFrom==p->aMap[i].fromLast ){ - int n = p->aMap[i].nExtra; - *pInserted = n; - return p->aMap[i].toLast + n; - }else{ - return p->aMap[i].toFirst + iFrom - p->aMap[i].fromFirst; - } - } - i--; - return p->aMap[i].toLast + p->aMap[i].nExtra; -} - -/* -** Do a three-way merge. Initialize pOut to contain the result. -*/ -void blob_merge(Blob *pPivot, Blob *pV1, Blob *pV2, Blob *pOut){ - Mapping map1, map2; - int i; - const char *zV1, *zV2; - blob_zero(pOut); - DEBUG1( printf("map1:\n"); ) - MappingInit( - blob_buffer(pPivot), blob_size(pPivot), - blob_buffer(pV1), blob_size(pV1), - &map1); - MappingSortFrom(&map1); - DEBUG1( - printf("map1-final:\n"); - MappingPrint(&map1); - printf("map2:\n"); - ) - MappingInit( - blob_buffer(pPivot), blob_size(pPivot), - blob_buffer(pV2), blob_size(pV2), - &map2); - DEBUG1( - printf("map2-final:\n"); - MappingPrint(&map2); - ) - zV1 = blob_buffer(pV1); - zV2 = blob_buffer(pV2); - if( map2.nUsed==0 ) return; - if( map1.aMap[0].toFirst>0 ){ - blob_append(pOut, zV1, map1.aMap[0].toFirst); - DEBUG1( printf("INSERT %d bytes from V1[0..%d]\n", - map1.aMap[0].toFirst, map1.aMap[0].toFirst-1); ) - } - if( map2.aMap[0].toFirst>0 ){ - blob_append(pOut, zV2, map2.aMap[0].toFirst); - DEBUG1( printf("INSERT %d bytes from V2[0..%d]\n", - map2.aMap[0].toFirst, map2.aMap[0].toFirst-1); ) - } - for(i=0; i<map2.nUsed; i++){ - int iFirst, iLast, nInsert; - struct Mapping_entry *p = &map2.aMap[i]; - iFirst = MappingTranslate(&map1, p->fromFirst, 0); - iLast = MappingTranslate(&map1, p->fromLast, &nInsert); - blob_append(pOut, &zV1[iFirst], iLast - iFirst + 1); - DEBUG1( - printf("COPY %d bytes from V1[%d..%d]\n", iLast-iFirst+1, iFirst, iLast); - ) - if( p->nExtra>0 ){ - if( p->nExtra==nInsert - && memcmp(&zV2[p->toLast+1], &zV1[iLast-nInsert+1], nInsert)==0 ){ - /* Omit a duplicate insert */ - DEBUG1( printf("OMIT duplicate insert\n"); ) - }else{ - blob_append(pOut, &zV2[p->toLast+1], p->nExtra); - DEBUG1( - printf("INSERT %d bytes from V2[%d..%d]\n", - p->nExtra, p->toLast+1, p->toLast+p->nExtra); - ) - } - } - } - MappingClear(&map1); - MappingClear(&map2); + free(aC1); + free(aC2); + return nConflict; } /* ** COMMAND: test-3-way-merge ** @@ -643,35 +237,6 @@ } blob_reset(&pivot); blob_reset(&v1); blob_reset(&v2); blob_reset(&merged); -} - - -/* -** COMMAND: test-mapping -*/ -void mapping_test(void){ - int i; - const char *z; - Blob a, b; - Mapping map; - if( g.argc!=4 ){ - usage("FILE1 FILE2"); - } - blob_read_from_file(&a, g.argv[2]); - blob_read_from_file(&b, g.argv[3]); - memset(&map, 0, sizeof(map)); - MappingInit(blob_buffer(&a), blob_size(&a), - blob_buffer(&b), blob_size(&b), - &map); - z = blob_buffer(&a); - for(i=0; i<map.nUsed; i++){ - printf("======= %6d..%-6d %6d..%-6d %d\n", - map.aMap[i].fromFirst, map.aMap[i].fromLast, - map.aMap[i].toFirst, map.aMap[i].toLast, - map.aMap[i].nExtra); - printf("%.*s\n", map.aMap[i].fromLast - map.aMap[i].fromFirst + 1, - &z[map.aMap[i].fromFirst]); - } }
Modified src/name.c from [c08d513136] to [8d07e9c5fd].
@@ -34,19 +34,46 @@ /* ** This routine takes a user-entered UUID which might be in mixed ** case and might only be a prefix of the full UUID and converts it ** into the full-length UUID in canonical form. ** +** If the input is not a UUID or a UUID prefix, then try to resolve +** the name as a tag. +** ** Return the number of errors. */ int name_to_uuid(Blob *pName, int iErrPriority){ int rc; int sz; sz = blob_size(pName); if( sz>UUID_SIZE || sz<4 || !validate16(blob_buffer(pName), sz) ){ - fossil_error(iErrPriority, "not a valid object name: %b", pName); - return 1; + Stmt q; + Blob uuid; + + db_prepare(&q, + "SELECT (SELECT uuid FROM blob WHERE rid=objid)" + " FROM tagxref JOIN event ON rid=objid" + " WHERE tagid=(SELECT tagid FROM tag WHERE tagname=%B)" + " AND tagtype>0" + " AND value IS NULL" + " ORDER BY event.mtime DESC", + pName + ); + blob_zero(&uuid); + if( db_step(&q)==SQLITE_ROW ){ + db_column_blob(&q, 0, &uuid); + } + db_finalize(&q); + if( blob_size(&uuid)==0 ){ + fossil_error(iErrPriority, "not a valid object name: %b", pName); + blob_reset(&uuid); + return 1; + }else{ + blob_reset(pName); + *pName = uuid; + return 0; + } } blob_materialize(pName); canonical16(blob_buffer(pName), sz); if( sz==UUID_SIZE ){ rc = db_int(1, "SELECT 0 FROM blob WHERE uuid=%B", pName); @@ -72,10 +99,12 @@ rc = 1; }else{ rc = 0; } } + }else{ + rc = 0; } return rc; } /* @@ -120,11 +149,11 @@ return rid; } } blob_init(&name, zName, -1); if( name_to_uuid(&name, 1) ){ - fossil_panic("%s", g.zErrMsg); + fossil_fatal("%s", g.zErrMsg); } rid = db_int(0, "SELECT rid FROM blob WHERE uuid=%B", &name); blob_reset(&name); return rid; }
Modified src/pivot.c from [2953f62a20] to [55723054d5].
@@ -82,11 +82,11 @@ ** the secondaries. Return its rid. Return 0 if no common ancestor ** can be found. */ int pivot_find(void){ Stmt q1, q2, u1, i1; - int rid; + int rid = 0; /* aqueue must contain at least one primary and one other. Otherwise ** we abort early */ if( db_int(0, "SELECT count(distinct src) FROM aqueue")<2 ){
Modified src/printf.c from [48f1118d8e] to [af38cba6b0].
@@ -49,10 +49,13 @@ #define etPOINTER 15 /* The %p conversion */ #define etHTMLIZE 16 /* Make text safe for HTML */ #define etHTTPIZE 17 /* Make text safe for HTTP. "/" encoded as %2f */ #define etURLIZE 18 /* Make text safe for HTTP. "/" not encoded */ #define etFOSSILIZE 19 /* The fossil header encoding format. */ +#define etPATH 20 /* Path type */ +#define etWIKISTR 21 /* Wiki text rendered from a char* */ +#define etWIKIBLOB 22 /* Wiki text rendered from a Blob* */ /* ** An "etByte" is an 8-bit unsigned value. */ @@ -92,10 +95,12 @@ { 'z', 0, 6, etDYNSTRING, 0, 0 }, { 'q', 0, 4, etSQLESCAPE, 0, 0 }, { 'Q', 0, 4, etSQLESCAPE2, 0, 0 }, { 'b', 0, 2, etBLOB, 0, 0 }, { 'B', 0, 2, etBLOBSQL, 0, 0 }, + { 'w', 0, 2, etWIKISTR, 0, 0 }, + { 'W', 0, 2, etWIKIBLOB, 0, 0 }, { 'h', 0, 4, etHTMLIZE, 0, 0 }, { 't', 0, 4, etHTTPIZE, 0, 0 }, /* "/" -> "%2F" */ { 'T', 0, 4, etURLIZE, 0, 0 }, /* "/" unchanged */ { 'F', 0, 4, etFOSSILIZE, 0, 0 }, { 'c', 0, 0, etCHARX, 0, 0 }, @@ -109,10 +114,11 @@ { 'G', 0, 1, etGENERIC, 14, 0 }, { 'i', 10, 1, etRADIX, 0, 0 }, { 'n', 0, 0, etSIZE, 0, 0 }, { '%', 0, 0, etPERCENT, 0, 0 }, { 'p', 16, 0, etPOINTER, 0, 1 }, + { '/', 0, 0, etPATH, 0, 0 }, }; #define etNINFO (sizeof(fmtinfo)/sizeof(fmtinfo[0])) /* ** "*val" is a double such that 0.1 <= *val < 10.0 @@ -169,12 +175,11 @@ ** Note that the order in which automatic variables are declared below ** seems to make a big difference in determining how fast this beast ** will run. */ int vxprintf( - void (*func)(void*,const char*,int), /* Consumer of text */ - void *arg, /* First argument to the consumer */ + Blob *pBlob, /* Append output to this blob */ const char *fmt, /* Format string */ va_list ap /* arguments */ ){ int c; /* Next character in the format string */ char *bufpt; /* Pointer to the conversion buffer */ @@ -208,26 +213,25 @@ etByte flag_dp; /* True if decimal point should be shown */ etByte flag_rtz; /* True if trailing zeros should be removed */ etByte flag_exp; /* True to force display of the exponent */ int nsd; /* Number of significant digits returned */ - func(arg,"",0); count = length = 0; bufpt = 0; for(; (c=(*fmt))!=0; ++fmt){ if( c!='%' ){ int amt; bufpt = (char *)fmt; amt = 1; while( (c=(*++fmt))!='%' && c!=0 ) amt++; - (*func)(arg,bufpt,amt); + blob_append(pBlob,bufpt,amt); count += amt; if( c==0 ) break; } if( (c=(*++fmt))==0 ){ errorflag = 1; - (*func)(arg,"%",1); + blob_append(pBlob,"%",1); count++; break; } /* Find out what flags are present */ flag_leftjustify = flag_plussign = flag_blanksign = @@ -541,10 +545,26 @@ }else{ length =1; } bufpt = buf; break; + case etPATH: { + int i; + char *e = va_arg(ap,char*); + if( e==0 ){e="";} + length = strlen(e); + zExtra = bufpt = malloc(length+1); + for( i=0; i<length; i++ ){ + if( e[i]=='\\' ){ + bufpt[i]='/'; + }else{ + bufpt[i]=e[i]; + } + } + bufpt[length]='\0'; + break; + } case etSTRING: case etDYNSTRING: bufpt = va_arg(ap,char*); if( bufpt==0 ){ bufpt = ""; @@ -641,16 +661,31 @@ zExtra = bufpt = fossilize(zMem, -1); length = strlen(bufpt); if( precision>=0 && precision<length ) length = precision; break; } + case etWIKISTR: { + char *zWiki = va_arg(ap, char*); + Blob wiki; + blob_init(&wiki, zWiki, -1); + wiki_convert(&wiki, pBlob, WIKI_INLINE); + blob_reset(&wiki); + length = width = 0; + break; + } + case etWIKIBLOB: { + Blob *pWiki = va_arg(ap, Blob*); + wiki_convert(pWiki, pBlob, WIKI_INLINE); + length = width = 0; + break; + } case etERROR: buf[0] = '%'; buf[1] = c; errorflag = 0; idx = 1+(c!=0); - (*func)(arg,"%",idx); + blob_append(pBlob,"%",idx); count += idx; if( c==0 ) fmt--; break; }/* End switch over the format type */ /* @@ -662,30 +697,30 @@ register int nspace; nspace = width-length; if( nspace>0 ){ count += nspace; while( nspace>=etSPACESIZE ){ - (*func)(arg,spaces,etSPACESIZE); + blob_append(pBlob,spaces,etSPACESIZE); nspace -= etSPACESIZE; } - if( nspace>0 ) (*func)(arg,spaces,nspace); + if( nspace>0 ) blob_append(pBlob,spaces,nspace); } } if( length>0 ){ - (*func)(arg,bufpt,length); + blob_append(pBlob,bufpt,length); count += length; } if( flag_leftjustify ){ register int nspace; nspace = width-length; if( nspace>0 ){ count += nspace; while( nspace>=etSPACESIZE ){ - (*func)(arg,spaces,etSPACESIZE); + blob_append(pBlob,spaces,etSPACESIZE); nspace -= etSPACESIZE; } - if( nspace>0 ) (*func)(arg,spaces,nspace); + if( nspace>0 ) blob_append(pBlob,spaces,nspace); } } if( zExtra ){ free(zExtra); }
Modified src/rebuild.c from [45c4994360] to [5e55de3bcd].
@@ -26,52 +26,100 @@ #include "config.h" #include "rebuild.h" #include <assert.h> /* +** Schema changes +*/ +static const char zSchemaUpdates[] = +@ -- Index on the delta table +@ -- +@ CREATE INDEX IF NOT EXISTS delta_i1 ON delta(srcid); +@ +@ -- Artifacts that should not be processed are identified in the +@ -- "shun" table. Artifacts that are control-file forgeries or +@ -- spam can be shunned in order to prevent them from contaminating +@ -- the repository. +@ -- +@ CREATE TABLE IF NOT EXISTS shun(uuid UNIQUE); +@ +@ -- An entry in this table describes a database query that generates a +@ -- table of tickets. +@ -- +@ CREATE TABLE IF NOT EXISTS reportfmt( +@ rn integer primary key, -- Report number +@ owner text, -- Owner of this report format (not used) +@ title text, -- Title of this report +@ cols text, -- A color-key specification +@ sqlcode text -- An SQL SELECT statement for this report +@ ); +; + +/* ** Core function to rebuild the infomration in the derived tables of a ** fossil repository from the blobs. This function is shared between ** 'rebuild_database' ('rebuild') and 'reconstruct_cmd' ** ('reconstruct'), both of which have to regenerate this information ** from scratch. +** +** If the randomize parameter is true, then the BLOBs are deliberately +** extracted in a random order. This feature is used to test the +** ability of fossil to accept records in any order and still +** construct a sane repository. */ - -int rebuild_db(void){ +int rebuild_db(int randomize, int ttyOutput){ Stmt s; int errCnt = 0; char *zTable; + int cnt = 0; - db_multi_exec( - "CREATE INDEX IF NOT EXISTS delta_i1 ON delta(srcid);" - ); + db_multi_exec(zSchemaUpdates); for(;;){ zTable = db_text(0, "SELECT name FROM sqlite_master" " WHERE type='table'" - " AND name NOT IN ('blob','delta','rcvfrom','user','config')"); + " AND name NOT IN ('blob','delta','rcvfrom','user','config','shun')"); if( zTable==0 ) break; db_multi_exec("DROP TABLE %Q", zTable); free(zTable); } db_multi_exec(zRepositorySchema2); + ticket_create_table(0); db_multi_exec("INSERT INTO unclustered SELECT rid FROM blob"); db_multi_exec( + "DELETE FROM unclustered" + " WHERE rid IN (SELECT rid FROM shun JOIN blob USING(uuid))" + ); + db_multi_exec( "DELETE FROM config WHERE name IN ('remote-code', 'remote-maxid')" ); - db_prepare(&s, "SELECT rid, size FROM blob"); + db_prepare(&s, + "SELECT rid, size FROM blob %s" + " WHERE NOT EXISTS(SELECT 1 FROM shun WHERE uuid=blob.uuid)", + randomize ? "ORDER BY random()" : "" + ); while( db_step(&s)==SQLITE_ROW ){ int rid = db_column_int(&s, 0); int size = db_column_int(&s, 1); if( size>=0 ){ Blob content; + if( ttyOutput ){ + cnt++; + printf("%d...\r", cnt); + fflush(stdout); + } content_get(rid, &content); manifest_crosslink(rid, &content); blob_reset(&content); }else{ db_multi_exec("INSERT OR IGNORE INTO phantom VALUES(%d)", rid); } + } + db_finalize(&s); + if( ttyOutput ){ + printf("\n"); } return errCnt; } /* @@ -83,22 +131,24 @@ ** records. Run this command after updating the fossil ** executable in a way that changes the database schema. */ void rebuild_database(void){ int forceFlag; + int randomizeFlag; int errCnt; forceFlag = find_option("force","f",0)!=0; + randomizeFlag = find_option("randomize", 0, 0)!=0; if( g.argc!=3 ){ usage("REPOSITORY-FILENAME"); } db_open_repository(g.argv[2]); db_begin_transaction(); - errCnt = rebuild_db(); + errCnt = rebuild_db(randomizeFlag, 1); if( errCnt && !forceFlag ){ printf("%d errors. Rolling back changes. Use --force to force a commit.\n", errCnt); db_end_transaction(1); }else{ db_end_transaction(0); } }
Added src/report.c version [15271012d7]
@@ -1,1 +1,992 @@ +/* +** Copyright (c) 2007 D. Richard Hipp +** +** This program is free software; you can redistribute it and/or +** modify it under the terms of the GNU General Public +** License as published by the Free Software Foundation; either +** version 2 of the License, or (at your option) any later version. +** +** This program is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +** General Public License for more details. +** +** You should have received a copy of the GNU General Public +** License along with this library; if not, write to the +** Free Software Foundation, Inc., 59 Temple Place - Suite 330, +** Boston, MA 02111-1307, USA. +** +** Author contact information: +** drh@hwaci.com +** http://www.hwaci.com/drh/ +** +******************************************************************************* +** +** Code to generate the bug report listings +*/ +#include "config.h" +#include "report.h" +#include <assert.h> + +/* Forward references to static routines */ +static void report_format_hints(void); + +/* +** WEBPAGE: /reportlist +*/ +void view_list(void){ + Stmt q; + + login_check_credentials(); + if( !g.okRdTkt ){ login_needed(); return; } + style_header("Available Report Formats"); + db_prepare(&q, "SELECT rn, title, owner FROM reportfmt ORDER BY title"); + @ <p>Choose a report format from the following list:</p> + @ <ol> + while( db_step(&q)==SQLITE_ROW ){ + int rn = db_column_int(&q, 0); + const char *zTitle = db_column_text(&q, 1); + const char *zOwner = db_column_text(&q, 2); + @ <li><a href="rptview?rn=%d(rn)" + @ rel="nofollow">%h(zTitle)</a> + if( g.okWrite && zOwner && zOwner[0] ){ + @ (by <i>%h(zOwner)</i>) + } + if( g.okWrTkt ){ + @ [<a href="rptedit?rn=%d(rn)&copy=1" rel="nofollow">copy</a>] + } + if( g.okAdmin || (g.okWrTkt && zOwner && strcmp(g.zLogin,zOwner)==0) ){ + @ [<a href="rptedit?rn=%d(rn)" rel="nofollow">edit</a>] + } + @ [<a href="rptsql?rn=%d(rn)" rel="nofollow">sql</a>] + @ </li> + } + if( g.okWrTkt ){ + @ <li><a href="rptnew">Create a new report format</a></li> + } + @ </ol> + common_footer(); +} + +/* +** Remove whitespace from both ends of a string. +*/ +char *trim_string(const char *zOrig){ + int i; + while( isspace(*zOrig) ){ zOrig++; } + i = strlen(zOrig); + while( i>0 && isspace(zOrig[i-1]) ){ i--; } + return mprintf("%.*s", i, zOrig); +} + +/* +** Extract a numeric (integer) value from a string. +*/ +char *extract_integer(const char *zOrig){ + if( zOrig == NULL || zOrig[0] == 0 ) return ""; + while( *zOrig && !isdigit(*zOrig) ){ zOrig++; } + if( *zOrig ){ + /* we have a digit. atoi() will get as much of the number as it + ** can. We'll run it through mprintf() to get a string. Not + ** an efficient way to do it, but effective. + */ + return mprintf("%d", atoi(zOrig)); + } + return ""; +} + +/* +** Remove blank lines from the beginning of a string and +** all whitespace from the end. Removes whitespace preceeding a NL, +** which also converts any CRNL sequence into a single NL. +*/ +char *remove_blank_lines(const char *zOrig){ + int i, j, n; + char *z; + for(i=j=0; isspace(zOrig[i]); i++){ if( zOrig[i]=='\n' ) j = i+1; } + n = strlen(&zOrig[j]); + while( n>0 && isspace(zOrig[j+n-1]) ){ n--; } + z = mprintf("%.*s", n, &zOrig[j]); + for(i=j=0; z[i]; i++){ + if( z[i+1]=='\n' && z[i]!='\n' && isspace(z[i]) ){ + z[j] = z[i]; + while(isspace(z[j]) && z[j] != '\n' ){ j--; } + j++; + continue; + } + + z[j++] = z[i]; + } + z[j] = 0; + return z; +} + + +/*********************************************************************/ + +/* +** This is the SQLite authorizer callback used to make sure that the +** SQL statements entered by users do not try to do anything untoward. +** If anything suspicious is tried, set *(char**)pError to an error +** message obtained from malloc. +*/ +static int report_query_authorizer( + void *pError, + int code, + const char *zArg1, + const char *zArg2, + const char *zArg3, + const char *zArg4 +){ + char *zError = *(char**)pError; + if( zError ){ + /* We've already seen an error. No need to continue. */ + return SQLITE_OK; + } + switch( code ){ + case SQLITE_SELECT: + case SQLITE_FUNCTION: { + break; + } + case SQLITE_READ: { + static const char *azAllowed[] = { + "ticket", + "blob", + "filename", + "mlink", + "plink", + "event", + "tag", + "tagxref", + } + int i; + for(i=0; i<sizeof(azAllowed)/sizeof(azAllowed[0]); i++){ + if( strcasecmp(zArg1, azAllowed[i])==0 ) break; + } + if( i>=sizeof(azAllowed)/sizeof(azAllowed[0]) ){ + zError = mprintf("cannot access table %s", zArg1); + } + break; + } + default: { + zError = mprintf("only SELECT statements are allowed"); + break; + } + } + return SQLITE_OK; +} + + +/* +** Check the given SQL to see if is a valid query that does not +** attempt to do anything dangerous. Return 0 on success and a +** pointer to an error message string (obtained from malloc) if +** there is a problem. +*/ +char *verify_sql_statement(char *zSql){ + int i; + char *zErr1 = 0; + char *zErr2 = 0; + char *zTail; + + /* First make sure the SQL is a single query command by verifying that + ** the first token is "SELECT" and that there are no unquoted semicolons. + */ + for(i=0; isspace(zSql[i]); i++){} + if( strncasecmp(&zSql[i],"select",6)!=0 ){ + return mprintf("The SQL must be a SELECT statement"); + } + for(i=0; zSql[i]; i++){ + if( zSql[i]==';' ){ + int bad; + int c = zSql[i+1]; + zSql[i+1] = 0; + bad = sqlite3_complete(zSql); + zSql[i+1] = c; + if( bad ){ + /* A complete statement basically means that an unquoted semi-colon + ** was found. We don't actually check what's after that. + */ + return mprintf("Semi-colon detected! " + "Only a single SQL statement is allowed"); + } + } + } + + /* Compile the statement and check for illegal accesses or syntax errors. */ + sqlite3_set_authorizer(g.db, report_query_authorizer, (void*)&zErr); + rc = sqlite3_prepare(g.db, zSql, -1, &pStmt, &zTail); + if( rc!=SQLITE_OK ){ + free(zErr); + zErr = mprintf("Syntax error: %s", sqlite3_errmsg(g.db)); + } + if( pStmt ){ + sqlite3_finalize(pStmt); + } + sqlite3_set_authorizer(g.db, 0, 0); + return zErr; +} + +/* +** WEBPAGE: /rptsql +*/ +void view_see_sql(void){ + int rn, rc; + char *zTitle; + char *zSQL; + char *zOwner; + char *zClrKey; + Stmt q; + + login_check_credentials(); + if( !g.okQuery ){ + login_needed(); + return; + } + rn = atoi(PD("rn","0")); + db_prepare(&q, "SELECT title, sqlcode, owner, cols " + "FROM reportfmt WHERE rn=%d",rn); + style_header("SQL For Report Format Number %d", rn); + if( db_step(&q)!=SQLITE_ROW ){ + @ <p>Unknown report number: %d(rn)</p> + style_footer(); + return; + } + zTitle = db_column_text(&q, 0); + zSQL = db_column_text(&q, 1); + zOwner = db_column_text(&q, 2); + zClrKey = db_column_text(&q, 3); + @ <table cellpadding=0 cellspacing=0 border=0> + @ <tr><td valign="top" align="right">Title:</td><td width=15></td> + @ <td colspan=3>%h(zTitle)</td></tr> + @ <tr><td valign="top" align="right">Owner:</td><td></td> + @ <td colspan=3>%h(zOwner)</td></tr> + @ <tr><td valign="top" align="right">SQL:</td><td></td> + @ <td valign="top"><pre> + @ %h(zSQL) + @ </pre></td> + @ <td width=15></td><td valign="top"> + output_color_key(zClrKey, 0, "border=0 cellspacing=0 cellpadding=3"); + @ </td> + @ </tr></table> + report_format_hints(); + style_footer(); +} + +/* +** WEBPAGE: /rptnew +** WEBPAGE: /rptedit +*/ +void view_edit(void){ + int rn; + const char *zTitle; + const char *z; + const char *zOwner; + char *zClrKey; + char *zSQL; + char *zErr = 0; + + login_check_credentials(); + if( !g.okQuery ){ + login_needed(); + return; + } + view_add_functions(0); + rn = atoi(PD("rn","0")); + zTitle = P("t"); + zOwner = PD("w",g.zLogin); + z = P("s"); + zSQL = z ? trim_string(z) : 0; + zClrKey = trim_string(PD("k","")); + if( rn>0 && P("del2") ){ + db_multi_exec("DELETE FROM reportfmt WHERE rn=%d", rn); + cgi_redirect("reportlist"); + return; + }else if( rn>0 && P("del1") ){ + zTitle = db_text(0, "SELECT title FROM reportfmt " + "WHERE rn=%d", rn); + if( zTitle==0 ) cgi_redirect("reportlist"); + + style_header("Are You Sure?"); + @ <form action="rptedit" method="POST"> + @ <p>You are about to delete all traces of the report + @ <strong>%h(zTitle)</strong> from + @ the database. This is an irreversible operation. All records + @ related to this report will be removed and cannot be recovered.</p> + @ + @ <input type="hidden" name="rn" value="%d(rn)"> + @ <input type="submit" name="del2" value="Delete The Report"> + @ <input type="submit" name="can" value="Cancel"> + @ </form> + style_footer(); + return; + }else if( P("can") ){ + /* user cancelled */ + cgi_redirect("reportlist"); + return; + } + if( zTitle && zSQL ){ + if( zSQL[0]==0 ){ + zErr = "Please supply an SQL query statement"; + }else if( (zTitle = trim_string(zTitle))[0]==0 ){ + zErr = "Please supply a title"; + }else{ + zErr = verify_sql_statement(zSQL); + } + if( zErr==0 ){ + if( rn>0 ){ + db_multi_exec("UPDATE reportfmt SET title=%Q, sqlcode=%Q," + " owner=%Q, cols=%Q WHERE rn=%d", + zTitle, zSQL, zOwner, zClrKey, rn); + }else{ + db_multi_exec("INSERT INTO reportfmt(title,sqlcode,owner,cols) " + "VALUES(%Q,%Q,%Q,%Q)", + zTitle, zSQL, zOwner, zClrKey); + rn = db_last_insert_rowid(); + } + cgi_redirect(mprintf("rptview?rn=%d", rn)); + return; + } + }else if( rn==0 ){ + zTitle = ""; + zSQL = + @ SELECT + @ CASE WHEN status IN ('new','active') THEN '#f2dcdc' + @ WHEN status='review' THEN '#e8e8bd' + @ WHEN status='fixed' THEN '#cfe8bd' + @ WHEN status='tested' THEN '#bde5d6' + @ WHEN status='defer' THEN '#cacae5' + @ ELSE '#c8c8c8' END AS 'bgcolor', + @ tn AS '#', + @ type AS 'Type', + @ status AS 'Status', + @ sdate(origtime) AS 'Created', + @ owner AS 'By', + @ subsystem AS 'Subsys', + @ sdate(changetime) AS 'Changed', + @ assignedto AS 'Assigned', + @ severity AS 'Svr', + @ priority AS 'Pri', + @ title AS 'Title' + @ FROM ticket + ; + zClrKey = + @ #ffffff Key: + @ #f2dcdc Active + @ #e8e8e8 Review + @ #cfe8bd Fixed + @ #bde5d6 Tested + @ #cacae5 Deferred + @ #c8c8c8 Closed + ; + }else{ + db_prepare(&q, "SELECT title, sqlcode, owner, cols " + "FROM reportfmt WHERE rn=%d",rn); + if( db_step(&q)==SQLITE_ROW ){ + zTitle = db_column_malloc(&q, 0); + zSQL = db_column_malloc(&q, 1); + zOwner = db_column_malloc(&q, 2); + zClrKey = db_column_malloc(&q, 3); + } + if( P("copy") ){ + rn = 0; + zTitle = mprintf("Copy Of %s", zTitle); + zOwner = g.zLogin; + } + } + if( zOwner==0 ) zOwner = g.zLogin; + style_submenu_element("Cancel", "Cancel", "reportlist"); + if( rn>0 ){ + style_submenu_element("Delete", "Delete", "rptedit?rn=%d&del1=1", rn); + } + style_header(rn>0 ? "Edit Report Format":"Create New Report Format"); + if( zErr ){ + @ <blockquote><font color="#ff0000"><b>%h(zErr)</b></font></blockquote> + } + @ <form action="rptedit" method="POST"> + @ <input type="hidden" name="rn" value="%d(rn)"> + @ <p>Report Title:<br> + @ <input type="text" name="t" value="%h(zTitle)" size="60"></p> + @ <p>Enter a complete SQL query statement against the "TICKET" table:<br> + @ <textarea name="s" rows="20" cols="80">%h(zSQL)</textarea> + @ </p> + if( g.okAdmin ){ + @ <p>Report owner: + @ <input type="text" name="w" size="20" value="%h(zOwner)"> + @ </p> + } else { + @ <input type="hidden" name="w" value="%h(zOwner)"> + } + @ <p>Enter an optional color key in the following box. (If blank, no + @ color key is displayed.) Each line contains the text for a single + @ entry in the key. The first token of each line is the background + @ color for that line.<br> + @ <textarea name="k" rows="8" cols="50">%h(zClrKey)</textarea> + @ </p> + if( !g.okAdmin && strcmp(zOwner,g.zLogin)!=0 ){ + @ <p>This report format is owned by %h(zOwner). You are not allowed + @ to change it.</p> + @ </form> + report_format_hints(); + style_footer(); + return; + } + @ <input type="submit" value="Apply Changes"> + if( rn>0 ){ + @ <input type="submit" value="Delete This Report" name="del1"> + } + @ </form> + report_format_hints(); + style_footer(); +} + +/* +** Output a bunch of text that provides information about report +** formats +*/ +static void report_format_hints(void){ + char *zSchema; + zSchema = db_text(0,"SELECT sql FROM sqlite_master WHERE name='ticket'"); + @ <hr><h3>TICKET Schema</h3> + @ <blockquote><pre> + @ %h(zSchema) + @ </pre></blockquote> + @ <h3>Notes</h3> + @ <ul> + @ <li><p>The SQL must consist of a single SELECT statement</p></li> + @ + @ <li><p>If a column of the result set is named "#" then that column + @ is assumed to hold a ticket number. A hyperlink will be created from + @ that column to a detailed view of the ticket.</p></li> + @ + @ <li><p>If a column of the result set is named "bgcolor" then the content + @ of that column determines the background color of the row.</p></li> + @ + @ <li><p>The <b>user()</b> SQL function returns a string + @ which is the login of the current user.</p></li> + @ + @ <li><p>The first column whose name begins with underscore ("_") and all + @ subsequent columns are shown on their own rows in the table. This might + @ be useful for displaying the description of tickets. + @ </p></li> + @ + @ <li><p>The <b>aux()</b> SQL function takes a parameter name as an argument + @ and returns the value that the user enters in the resulting HTML form. A + @ second optional parameter provides a default value for the field.</p></li> + @ + @ <li><p>The <b>option()</b> SQL function takes a parameter name + @ and a quoted SELECT statement as parameters. The query results are + @ presented as an HTML dropdown menu and the function returns + @ the currently selected value. Results may be a single value column or + @ two <b>value,description</b> columns. The first row is the default.</p></li> + @ + @ <li><p>The <b>cgi()</b> SQL function takes a parameter name as an argument + @ and returns the value of a corresponding CGI query value. If the CGI + @ parameter doesn't exist, an optional second argument will be returned + @ instead.</p></li> + @ + @ <li><p>If a column is wrapped by the <b>wiki()</b> SQL function, it will + @ be rendered as wiki formatted content.</p></li> + @ + @ <li><p>If a column is wrapped by the <b>tkt()</b> SQL function, it will + @ be shown as a ticket id with a link to the appropriate page</p></li> + @ + @ <li><p>If a column is wrapped by the <b>chng()</b> SQL function, it will + @ be shown as a baseline id with a link to the appropriate page.</p></li> + @ + @ <li><p>The <b>search()</b> SQL function takes a keyword pattern and + @ a search text. The function returns an integer score which is + @ higher depending on how well the search went.</p></li> + @ + @ <li><p>The query can join other tables in the database besides TICKET. + @ </p></li> + @ </ul> + @ + @ <h3>Examples</h3> + @ <p>In this example, the first column in the result set is named + @ "bgcolor". The value of this column is not displayed. Instead, it + @ selects the background color of each row based on the TICKET.STATUS + @ field of the database. The color key at the right shows the various + @ color codes.</p> + @ <table align="right" style="margin: 0 5px;" border=1 cellspacing=0 width=125> + @ <tr bgcolor="#f2dcdc"><td align="center">new or active</td></tr> + @ <tr bgcolor="#e8e8bd"><td align="center">review</td></tr> + @ <tr bgcolor="#cfe8bd"><td align="center">fixed</td></tr> + @ <tr bgcolor="#bde5d6"><td align="center">tested</td></tr> + @ <tr bgcolor="#cacae5"><td align="center">defer</td></tr> + @ <tr bgcolor="#c8c8c8"><td align="center">closed</td></tr> + @ </table> + @ <blockquote><pre> + @ SELECT + @ CASE WHEN status IN ('new','active') THEN '#f2dcdc' + @ WHEN status='review' THEN '#e8e8bd' + @ WHEN status='fixed' THEN '#cfe8bd' + @ WHEN status='tested' THEN '#bde5d6' + @ WHEN status='defer' THEN '#cacae5' + @ ELSE '#c8c8c8' END as 'bgcolor', + @ tn AS '#', + @ type AS 'Type', + @ status AS 'Status', + @ sdate(origtime) AS 'Created', + @ owner AS 'By', + @ subsystem AS 'Subsys', + @ sdate(changetime) AS 'Changed', + @ assignedto AS 'Assigned', + @ severity AS 'Svr', + @ priority AS 'Pri', + @ title AS 'Title' + @ FROM ticket + @ </pre></blockquote> + @ <p>To base the background color on the TICKET.PRIORITY or + @ TICKET.SEVERITY fields, substitute the following code for the + @ first column of the query:</p> + @ <table align="right" style="margin: 0 5px;" border=1 cellspacing=0 width=125> + @ <tr bgcolor="#f2dcdc"><td align="center">1</td></tr> + @ <tr bgcolor="#e8e8bd"><td align="center">2</td></tr> + @ <tr bgcolor="#cfe8bd"><td align="center">3</td></tr> + @ <tr bgcolor="#cacae5"><td align="center">4</td></tr> + @ <tr bgcolor="#c8c8c8"><td align="center">5</td></tr> + @ </table> + @ <blockquote><pre> + @ SELECT + @ CASE priority WHEN 1 THEN '#f2dcdc' + @ WHEN 2 THEN '#e8e8bd' + @ WHEN 3 THEN '#cfe8bd' + @ WHEN 4 THEN '#cacae5' + @ ELSE '#c8c8c8' END as 'bgcolor', + @ ... + @ FROM ticket + @ </pre></blockquote> +#if 0 + @ <p>You can, of course, substitute different colors if you choose. + @ Here is a palette of suggested background colors:</p> + @ <blockquote> + @ <table border=1 cellspacing=0 width=300> + @ <tr><td align="center" bgcolor="#ffbdbd">#ffbdbd</td> + @ <td align="center" bgcolor="#f2dcdc">#f2dcdc</td></tr> + @ <tr><td align="center" bgcolor="#ffffbd">#ffffbd</td> + @ <td align="center" bgcolor="#e8e8bd">#e8e8bd</td></tr> + @ <tr><td align="center" bgcolor="#c0ebc0">#c0ebc0</td> + @ <td align="center" bgcolor="#cfe8bd">#cfe8bd</td></tr> + @ <tr><td align="center" bgcolor="#c0c0f4">#c0c0f4</td> + @ <td align="center" bgcolor="#d6d6e8">#d6d6e8</td></tr> + @ <tr><td align="center" bgcolor="#d0b1ff">#d0b1ff</td> + @ <td align="center" bgcolor="#d2c0db">#d2c0db</td></tr> + @ <tr><td align="center" bgcolor="#bbbbbb">#bbbbbb</td> + @ <td align="center" bgcolor="#d0d0d0">#d0d0d0</td></tr> + @ </table> + @ </blockquote> +#endif + @ <p>To see the TICKET.DESCRIPTION and TICKET.REMARKS fields, include + @ them as the last two columns of the result set and given them names + @ that begin with an underscore. Like this:</p> + @ <blockquote><pre> + @ SELECT + @ tn AS '#', + @ type AS 'Type', + @ status AS 'Status', + @ sdate(origtime) AS 'Created', + @ owner AS 'By', + @ subsystem AS 'Subsys', + @ sdate(changetime) AS 'Changed', + @ assignedto AS 'Assigned', + @ severity AS 'Svr', + @ priority AS 'Pri', + @ title AS 'Title', + @ description AS '_Description', -- When the column name begins with '_' + @ remarks AS '_Remarks' -- the data is shown on a separate row. + @ FROM ticket + @ </pre></blockquote> + @ + @ <p>Or, to see part of the description on the same row, use the + @ <b>wiki()</b> function with some string manipulation. Using the + @ <b>tkt()</b> function on the ticket number will also generate a linked + @ field, but without the extra <i>edit</i> column: + @ </p> + @ <blockquote><pre> + @ SELECT + @ tkt(tn) AS '', + @ title AS 'Title', + @ wiki(substr(description,0,80)) AS 'Description' + @ FROM ticket + @ </pre></blockquote> + @ +} + +/*********************************************************************/ +static void output_report_field(const char *zData,int rn){ + const char *zWkey = wiki_key(); + const char *zTkey = tkt_key(); + const char *zCkey = chng_key(); + + if( !strncmp(zData,zWkey,strlen(zWkey)) ){ + output_formatted(&zData[strlen(zWkey)],0); + }else if( !strncmp(zData,zTkey,strlen(zTkey)) ){ + output_ticket(atoi(&zData[strlen(zTkey)]),rn); + }else if( !strncmp(zData,zCkey,strlen(zCkey)) ){ + output_chng(atoi(&zData[strlen(zCkey)])); + }else{ + @ %h(zData) + } +} + +static void column_header(int rn,const char *zCol, int nCol, int nSorted, + const char *zDirection, const char *zExtra +){ + int set = (nCol==nSorted); + int desc = !strcmp(zDirection,"DESC"); + + /* + ** Clicking same column header 3 times in a row resets any sorting. + ** Note that we link to rptview, which means embedded reports will get + ** sent to the actual report view page as soon as a user tries to do + ** any sorting. I don't see that as a Bad Thing. + */ + if(set && desc){ + @ <th bgcolor="%s(BG1)" class="bkgnd1"> + @ <a href="rptview?rn=%d(rn)%s(zExtra)">%h(zCol)</a></th> + }else{ + if(set){ + @ <th bgcolor="%s(BG1)" class="bkgnd1"><a + }else{ + @ <th><a + } + @ href="rptview?rn=%d(rn)&order_by=%d(nCol)&\ + @ order_dir=%s(desc?"ASC":"DESC")\ + @ %s(zExtra)">%h(zCol)</a></th> + } +} + +/*********************************************************************/ +struct GenerateHTML { + int rn; + int nCount; +}; + +/* +** The callback function for db_query +*/ +static int generate_html( + void* pUser, /* Pointer to output state */ + int nArg, /* Number of columns in this result row */ + char **azArg, /* Text of data in all columns */ + char **azName /* Names of the columns */ +){ + struct GenerateHTML* pState = (struct GenerateHTML*)pUser; + int i; + int tn; /* Ticket number. (value of column named '#') */ + int rn; /* Report number */ + int ncol; /* Number of columns in the table */ + int multirow; /* True if multiple table rows per line of data */ + int newrowidx; /* Index of first column that goes on a separate row */ + int iBg = -1; /* Index of column that determines background color */ + char *zBg = 0; /* Use this background color */ + char zPage[30]; /* Text version of the ticket number */ + + /* Get the report number + */ + rn = pState->rn; + + /* Figure out the number of columns, the column that determines background + ** color, and whether or not this row of data is represented by multiple + ** rows in the table. + */ + ncol = 0; + multirow = 0; + newrowidx = -1; + for(i=0; i<nArg; i++){ + if( azName[i][0]=='b' && strcmp(azName[i],"bgcolor")==0 ){ + zBg = azArg ? azArg[i] : 0; + iBg = i; + continue; + } + if( g.okWrite && azName[i][0]=='#' ){ + ncol++; + } + if( !multirow ){ + if( azName[i][0]=='_' ){ + multirow = 1; + newrowidx = i; + }else{ + ncol++; + } + } + } + + /* The first time this routine is called, output a table header + */ + if( pState->nCount==0 ){ + char zExtra[2000]; + int nField = atoi(PD("order_by","0")); + const char* zDir = PD("order_dir",""); + zDir = !strcmp("ASC",zDir) ? "ASC" : "DESC"; + zExtra[0] = 0; + + if( g.nAux ){ + @ <tr> + @ <td colspan=%d(ncol)><form action="rptview" method="GET"> + @ <input type="hidden" name="rn" value="%d(rn)"> + for(i=0; i<g.nAux; i++){ + const char *zN = g.azAuxName[i]; + const char *zP = g.azAuxParam[i]; + if( g.azAuxVal[i] && g.azAuxVal[i][0] ){ + appendf(zExtra,0,sizeof(zExtra), + "&%t=%t",g.azAuxParam[i],g.azAuxVal[i]); + } + if( g.azAuxOpt[i] ){ + @ %h(zN): + if( g.anAuxCols[i]==1 ) { + cgi_v_optionmenu( 0, zP, g.azAuxVal[i], g.azAuxOpt[i] ); + }else if( g.anAuxCols[i]==2 ){ + cgi_v_optionmenu2( 0, zP, g.azAuxVal[i], g.azAuxOpt[i] ); + } + }else{ + @ %h(zN): <input type="text" name="%h(zP)" value="%h(g.azAuxVal[i])"> + } + } + @ <input type="submit" value="Go"> + @ </form></td></tr> + } + @ <tr> + tn = -1; + for(i=0; i<nArg; i++){ + char *zName = azName[i]; + if( i==iBg ) continue; + if( newrowidx>=0 && i>=newrowidx ){ + if( g.okWrite && tn>=0 ){ + @ <th> </th> + tn = -1; + } + if( zName[0]=='_' ) zName++; + @ </tr><tr><th colspan=%d(ncol)>%h(zName)</th> + }else{ + if( zName[0]=='#' ){ + tn = i; + } + /* + ** This handles any sorting related stuff. Note that we don't + ** bother trying to sort on the "wiki format" columns. I don't + ** think it makes much sense, visually. + */ + column_header(rn,azName[i],i+1,nField,zDir,zExtra); + } + } + if( g.okWrite && tn>=0 ){ + @ <th> </th> + } + @ </tr> + } + if( azArg==0 ){ + @ <tr><td colspan="%d(ncol)"> + @ <i>No records match the report criteria</i> + @ </td></tr> + return 0; + } + ++pState->nCount; + + /* Output the separator above each entry in a table which has multiple lines + ** per database entry. + */ + if( newrowidx>=0 ){ + @ <tr><td colspan=%d(ncol)><font size=1> </font></td></tr> + } + + /* Output the data for this entry from the database + */ + if( zBg==0 ) zBg = "white"; + @ <tr bgcolor="%h(zBg)"> + tn = 0; + zPage[0] = 0; + for(i=0; i<nArg; i++){ + char *zData; + if( i==iBg ) continue; + zData = azArg[i]; + if( zData==0 ) zData = ""; + if( newrowidx>=0 && i>=newrowidx ){ + if( tn>0 && g.okWrite ){ + @ <td valign="top"><a href="tktedit?tn=%d(tn),%d(rn)">edit</a></td> + tn = 0; + } + if( zData[0] ){ + @ </tr><tr bgcolor="%h(zBg)"><td colspan=%d(ncol)> + output_formatted(zData, zPage[0] ? zPage : 0); + } + }else if( azName[i][0]=='#' ){ + tn = atoi(zData); + if( tn>0 ) bprintf(zPage, sizeof(zPage), "%d", tn); + @ <td valign="top"><a href="tktview?tn=%d(tn),%d(rn)">%h(zData)</a></td> + }else if( zData[0]==0 ){ + @ <td valign="top"> </td> + }else{ + @ <td valign="top"> + output_report_field(zData,rn); + @ </td> + } + } + if( tn>0 && g.okWrite ){ + @ <td valign="top"><a href="tktedit?tn=%d(tn),%d(rn)">edit</a></td> + } + @ </tr> + return 0; +} + +/* +** Output the text given in the argument. Convert tabs and newlines into +** spaces. +*/ +static void output_no_tabs(const char *z){ + while( z && z[0] ){ + int i, j; + for(i=0; z[i] && (!isspace(z[i]) || z[i]==' '); i++){} + if( i>0 ){ + cgi_printf("%.*s", i, z); + } + for(j=i; isspace(z[j]); j++){} + if( j>i ){ + cgi_printf("%*s", j-i, ""); + } + z += j; + } +} + +/* +** Output a row as a tab-separated line of text. +*/ +static int output_tab_separated( + void *pUser, /* Pointer to row-count integer */ + int nArg, /* Number of columns in this result row */ + char **azArg, /* Text of data in all columns */ + char **azName /* Names of the columns */ +){ + int *pCount = (int*)pUser; + int i; + + if( *pCount==0 ){ + for(i=0; i<nArg; i++){ + output_no_tabs(azName[i]); + cgi_printf("%c", i<nArg-1 ? '\t' : '\n'); + } + } + ++*pCount; + for(i=0; i<nArg; i++){ + output_no_tabs(azArg[i]); + cgi_printf("%c", i<nArg-1 ? '\t' : '\n'); + } + return 0; +} + +/* +** Generate HTML that describes a color key. +*/ +void output_color_key(const char *zClrKey, int horiz, char *zTabArgs){ + int i, j, k; + char *zSafeKey, *zToFree; + while( isspace(*zClrKey) ) zClrKey++; + if( zClrKey[0]==0 ) return; + @ <table %s(zTabArgs)> + if( horiz ){ + @ <tr> + } + zToFree = zSafeKey = mprintf("%h", zClrKey); + while( zSafeKey[0] ){ + while( isspace(*zSafeKey) ) zSafeKey++; + for(i=0; zSafeKey[i] && !isspace(zSafeKey[i]); i++){} + for(j=i; isspace(zSafeKey[j]); j++){} + for(k=j; zSafeKey[k] && zSafeKey[k]!='\n' && zSafeKey[k]!='\r'; k++){} + if( !horiz ){ + cgi_printf("<tr bgcolor=\"%.*s\"><td>%.*s</td></tr>\n", + i, zSafeKey, k-j, &zSafeKey[j]); + }else{ + cgi_printf("<td bgcolor=\"%.*s\">%.*s</td>\n", + i, zSafeKey, k-j, &zSafeKey[j]); + } + zSafeKey += k; + } + free(zToFree); + if( horiz ){ + @ </tr> + } + @ </table> +} + + +/* +** WEBPAGE: /rptview +** +** Generate a report. The rn query parameter is the report number +** corresponding to REPORTFMT.RN. If the tablist query parameter exists, +** then the output consists of lines of tab-separated fields instead of +** an HTML table. +*/ +void rptview_page(void){ + int count = 0; + int rn; + char *zSql; + char *zTitle; + char *zOwner; + char *zClrKey; + int tabs; + Stmt q; + + login_check_credentials(); + if( !g.okRead ){ login_needed(); return; } + rn = atoi(PD("rn","0")); + if( rn==0 ){ + cgi_redirect("reportlist"); + return; + } + tabs = P("tablist")!=0; + view_add_functions(tabs); + db_prepare(&q, + "SELECT title, sqlcode, owner, cols FROM reportfmt WHERE rn=%d", rn); + if( db_step(&q)!=SQLITE_ROW ){ + cgi_redirect("reportlist"); + return; + } + zTitle = db_column_malloc(&q, 0); + zSql = db_column_malloc(&q, 1); + zOwner = db_column_malloc(&q, 2); + zClrKey = db_column_malloc(&q, 3); + db_finalize(&q); + + if( P("order_by") ){ + /* + ** If the user wants to do a column sort, wrap the query into a sub + ** query and then sort the results. This is a whole lot easier than + ** trying to insert an ORDER BY into the query itself, especially + ** if the query is already ordered. + */ + int nField = atoi(P("order_by")); + if( nField > 0 ){ + const char* zDir = PD("order_dir",""); + zDir = !strcmp("ASC",zDir) ? "ASC" : "DESC"; + zSql = mprintf("SELECT * FROM (%s) ORDER BY %d %s", zSql, nField, zDir); + } + } + + count = 0; + if( !tabs ){ + struct GenerateHTML sState; + db_execute("PRAGMA empty_result_callbacks=ON"); + style_submenu_element("Raw", "Raw", + "rptview?tablist=1&%s", P("QUERY_STRING","")); + if( g.okAdmin + || (g.okQuery && g.zLogin && zOwner && strcmp(g.zLogin,zOwner)==0) ){ + style_submentu_element("Edit", "Edit", "rptedit?rn=%d", rn); + } + style_submenu_element("SQL", "SQL", "rptsql?rn=%d",rn); + style_header(zTitle); + output_color_key(zClrKey, 1, + "border=0 cellpadding=3 cellspacing=0 class=\"report\""); + @ <table border=1 cellpadding=2 cellspacing=0 class="report"> + sState.rn = rn; + sState.nCount = 0; + sqlite3_exec(g.db, zSql, generate_html, &sState, 0); + @ </table> + style_footer(); + }else{ + sqlite3_exec(g.db, zSql, output_tab_separated, &count, 0); + cgi_set_content_type("text/plain"); + } +}
Added src/rss.c version [05e7ced61b]
@@ -1,1 +1,126 @@ +/* +** Copyright (c) 2007 D. Richard Hipp +** +** This program is free software; you can redistribute it and/or +** modify it under the terms of the GNU General Public +** License version 2 as published by the Free Software Foundation. +** +** This program is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +** General Public License for more details. +** +** You should have received a copy of the GNU General Public +** License along with this library; if not, write to the +** Free Software Foundation, Inc., 59 Temple Place - Suite 330, +** Boston, MA 02111-1307, USA. +** +** Author contact information: +** drh@hwaci.com +** http://www.hwaci.com/drh/ +** +******************************************************************************* +** +** This file contains code used to create a RSS feed for the CGI interface. +*/ +#include "config.h" +#include "rss.h" +#include <assert.h> +#include <time.h> + +time_t rss_datetime_to_time_t(const char *dt){ + struct tm the_tm; + + the_tm.tm_year = atoi(dt)-1900; + the_tm.tm_mon = atoi(&dt[5])-1; + the_tm.tm_mday = atoi(&dt[8]); + the_tm.tm_hour = atoi(&dt[11]); + the_tm.tm_min = atoi(&dt[14]); + the_tm.tm_sec = atoi(&dt[17]); + + return mktime(&the_tm); +} + +/* +** WEBPAGE: timeline.rss +*/ + +void page_timeline_rss(void){ + Stmt q; + int nLine=0; + char *zPubDate, *zProjectName, *zProjectDescr, *zFreeProjectName=0; + const char zSQL[] = + @ SELECT + @ blob.rid, + @ uuid, + @ datetime(event.mtime), + @ coalesce(ecomment,comment), + @ coalesce(euser,user), + @ (SELECT count(*) FROM plink WHERE pid=blob.rid AND isprim), + @ (SELECT count(*) FROM plink WHERE cid=blob.rid) + @ FROM event, blob + @ WHERE blob.rid=event.objid + @ ORDER BY event.mtime DESC + ; + + cgi_set_content_type("application/rss+xml"); + + zProjectName = db_get("project-name", 0); + if( zProjectName==0 ){ + zFreeProjectName = zProjectName = mprintf("Fossil source repository for: %s", + g.zBaseURL); + } + zProjectDescr = db_get("project-description", 0); + if( zProjectDescr==0 ){ + zProjectDescr = zProjectName; + } + + zPubDate = cgi_rfc822_datestamp(time(NULL)); + + @ <?xml version="1.0"?> + @ <rss version="2.0"> + @ <channel> + @ <title>%s(zProjectName)</title> + @ <link>%s(g.zBaseURL)</link> + @ <description>%s(zProjectDescr)</description> + @ <pubDate>%s(zPubDate)</pubDate> + @ <generator>Fossil version %s(MANIFEST_VERSION) %s(MANIFEST_DATE)</generator> + db_prepare(&q, zSQL); + while( db_step(&q)==SQLITE_ROW && nLine<=20 ){ + const char *zId = db_column_text(&q, 1); + const char *zDate = db_column_text(&q, 2); + const char *zCom = db_column_text(&q, 3); + const char *zAuthor = db_column_text(&q, 4); + char *zPrefix = ""; + int nChild = db_column_int(&q, 5); + int nParent = db_column_int(&q, 6); + + zDate = cgi_rfc822_datestamp(rss_datetime_to_time_t(zDate)); + + if( nParent>1 && nChild>1 ){ + zPrefix = "*MERGE/FORK* "; + }else if( nParent>1 ){ + zPrefix = "*MERGE* "; + }else if( nChild>1 ){ + zPrefix = "*FORK* "; + } + + @ <item> + @ <title>%s(zPrefix)%s(zCom)</title> + @ <link>%s(g.zBaseURL)/vinfo/%s(zId)</link> + @ <description>%s(zPrefix)%s(zCom)</description> + @ <pubDate>%s(zDate)</pubDate> + @ <author>%s(zAuthor)</author> + @ <guid>%s(g.zBaseURL)/vinfo/%s(zId)</guid> + @ </item> + nLine++; + } + + db_finalize(&q); + @ </channel> + @ </rss> + if( zFreeProjectName != 0 ){ + free( zFreeProjectName ); + } +}
Modified src/schema.c from [23e27b4093] to [384e115ad0].
@@ -115,11 +115,30 @@ @ CREATE TABLE config( @ name TEXT PRIMARY KEY NOT NULL, -- Primary name of the entry @ value CLOB, -- Content of the named parameter @ CHECK( typeof(name)='text' AND length(name)>=1 ) @ ); +@ +@ -- Artifacts that should not be processed are identified in the +@ -- "shun" table. Artifacts that are control-file forgeries or +@ -- spam can be shunned in order to prevent them from contaminating +@ -- the repository. +@ -- +@ CREATE TABLE shun(uuid UNIQUE); +@ +@ -- An entry in this table describes a database query that generates a +@ -- table of tickets. +@ -- +@ CREATE TABLE reportfmt( +@ rn integer primary key, -- Report number +@ owner text, -- Owner of this report format (not used) +@ title text, -- Title of this report +@ cols text, -- A color-key specification +@ sqlcode text -- An SQL SELECT statement for this report +@ ); ; + const char zRepositorySchema2[] = @ -- Filenames @ -- @ CREATE TABLE filename( @ fnid INTEGER PRIMARY KEY, -- Filename ID @@ -126,10 +145,13 @@ @ name TEXT UNIQUE -- Name of file page @ ); @ @ -- Linkages between manifests, files created by that manifest, and @ -- the names of those files. +@ -- +@ -- pid==0 if the file is added by check-in mid. +@ -- fid==0 if the file is removed by check-in mid. @ -- @ CREATE TABLE mlink( @ mid INTEGER REFERENCES blob, -- Manifest ID where change occurs @ pid INTEGER REFERENCES blob, -- File ID in parent manifest @ fid INTEGER REFERENCES blob, -- Changed file ID in this manifest @@ -152,19 +174,22 @@ @ CREATE INDEX plink_i2 ON plink(cid); @ @ -- Events used to generate a timeline @ -- @ CREATE TABLE event( -@ type TEXT, -@ mtime DATETIME, -@ objid INTEGER, -@ uid INTEGER REFERENCES user, -@ user TEXT, -@ comment TEXT +@ type TEXT, -- Type of event +@ mtime DATETIME, -- Date and time when the event occurs +@ objid INTEGER PRIMARY KEY, -- Associated record ID +@ uid INTEGER REFERENCES user, -- User who caused the event +@ bgcolor TEXT, -- Color set by 'bgcolor' property +@ brbgcolor TEXT, -- Color set by 'br-bgcolor' property +@ euser TEXT, -- User set by 'user' property +@ user TEXT, -- Name of the user +@ ecomment TEXT, -- Comment set by 'comment' property +@ comment TEXT -- Comment describing the event @ ); @ CREATE INDEX event_i1 ON event(mtime); -@ CREATE INDEX event_i2 ON event(objid); @ @ -- A record of phantoms. A phantom is a record for which we know the @ -- UUID but we do not (yet) know the file content. @ -- @ CREATE TABLE phantom( @@ -190,30 +215,52 @@ @ -- @ CREATE TABLE unsent( @ rid INTEGER PRIMARY KEY -- Record ID of the phantom @ ); @ -@ -- Aggregated ticket information +@ -- Each baseline or manifest can have one or more tags. A tag +@ -- is defined by a row in the next table. +@ -- +@ -- Wiki pages are tagged with "wiki-NAME" where NAME is the name of +@ -- the wiki page. Tickets changes are tagged with "ticket-UUID" where +@ -- UUID is the indentifier of the ticket. @ -- -@ CREATE TABLE tkt( -@ tktid INTEGER PRIMARY KEY, -- Internal ticket ID -@ fnid INTEGER REFERENCES filename, -- Name of the ticket file -@ rid INTEGER REFERENCES blob, -- version of ticket file scanned -@ title TEXT, -- title of the ticket -@ remarks TEXT -- text of the ticket +@ CREATE TABLE tag( +@ tagid INTEGER PRIMARY KEY, -- Numeric tag ID +@ tagname TEXT UNIQUE -- Tag name. @ ); -@ CREATE TABLE tkttag( -@ tagid INTEGER PRIMARY KEY, -- Numeric tag ID -@ name TEXT UNIQUE -- Human-readable name of tag +@ INSERT INTO tag VALUES(1, 'bgcolor'); -- TAG_BGCOLOR +@ INSERT INTO tag VALUES(2, 'comment'); -- TAG_COMMENT +@ INSERT INTO tag VALUES(3, 'user'); -- TAG_USER +@ INSERT INTO tag VALUES(4, 'hidden'); -- TAG_HIDDEN +@ +@ -- Assignments of tags to baselines. Note that we allow tags to +@ -- have values assigned to them. So we are not really dealing with +@ -- tags here. These are really properties. But we are going to +@ -- keep calling them tags because in many cases the value is ignored. +@ -- +@ CREATE TABLE tagxref( +@ tagid INTEGER REFERENCES tag, -- The tag that added or removed +@ tagtype INTEGER, -- 0:cancel 1:single 2:branch +@ srcid INTEGER REFERENCES blob, -- Origin of the tag. 0 for propagated tags +@ value TEXT, -- Value of the tag. Might be NULL. +@ mtime TIMESTAMP, -- Time of addition or removal +@ rid INTEGER REFERENCE blob, -- Baseline that tag added/removed from +@ UNIQUE(rid, tagid) @ ); -@ CREATE TABLE tktmap( -@ tktid INTEGER REFERENCES tkt, -- This ticket -@ tagid INTEGER REFERENCES tkttag, -- ....holds this tag -@ UNIQUE(tktid, tagid) -@ ); -@ CREATE INDEX tktmap_i2 ON tktmap(tagid); +@ CREATE INDEX tagxref_i1 ON tagxref(tagid, mtime); ; + +/* +** Predefined tagid values +*/ +#if INTERFACE +# define TAG_BGCOLOR 1 +# define TAG_COMMENT 2 +# define TAG_USER 3 +# define TAG_HIDDEN 4 +#endif /* ** The schema for the locate FOSSIL database file found at the root ** of very check-out. This database contains the complete state of ** the checkout.
Modified src/setup.c from [0c2a6e74d5] to [89b2ca9e01].
@@ -33,23 +33,22 @@ ** Output a single entry for a menu generated using an HTML table. ** If zLink is not NULL or an empty string, then it is the page that ** the menu entry will hyperlink to. If zLink is NULL or "", then ** the menu entry has no hyperlink - it is disabled. */ -static void menu_entry( +void setup_menu_entry( const char *zTitle, const char *zLink, const char *zDesc ){ - @ <dt> + @ <tr><td valign="top" align="right"> if( zLink && zLink[0] ){ @ <a href="%s(zLink)">%h(zTitle)</a> }else{ @ %h(zTitle) } - @ </dt> - @ <dd>%h(zDesc)</dd> + @ </td><td valign="top">%h(zDesc)</td></tr> } /* ** WEBPAGE: /setup */ @@ -58,18 +57,28 @@ if( !g.okSetup ){ login_needed(); } style_header("Setup"); - @ <dl id="setup"> - menu_entry("Users", "setup_ulist", + @ <table border="0" cellspacing="20"> + setup_menu_entry("Users", "setup_ulist", "Grant privileges to individual users."); - menu_entry("Access", "setup_access", + setup_menu_entry("Access", "setup_access", "Control access settings."); - menu_entry("Configuration", "setup_config", + setup_menu_entry("Configuration", "setup_config", "Configure the WWW components of the repository"); - @ </dl> + setup_menu_entry("Timeline", "setup_timeline", + "Timeline display preferences"); + setup_menu_entry("Tickets", "setup_ticket", + "Configure the trouble-ticketing system for this repository"); + setup_menu_entry("CSS", "setup_editcss", + "Edit the Cascading Style Sheet used by all pages of this repository"); + setup_menu_entry("Header", "setup_header", + "Edit HTML text inserted at the top of every page"); + setup_menu_entry("Footer", "setup_footer", + "Edit HTML text inserted at the bottom of every page"); + @ </table> style_footer(); } /* @@ -79,11 +88,10 @@ ** screen for that user. */ void setup_ulist(void){ Stmt s; - style_footer(); login_check_credentials(); if( !g.okSetup ){ login_needed(); return; } @@ -123,10 +131,11 @@ @ <li><p>The permission flags are as follows:</p> @ <ol type="a"> @ <li value="1"><b>Admin</b>: Create and delete users</li> @ <li value="3"><b>Append-Tkt</b>: Append to tickets</li> @ <li value="4"><b>Delete</b>: Delete wiki and tickets</li> + @ <li value="5"><b>Email</b>: View EMail addresses on tickets</li> @ <li value="6"><b>New-Wiki</b>: Create new wiki pages</li> @ <li value="7"><b>Clone</b>: Clone the repository</li> @ <li value="8"><b>History</b>: View detail repository history</li> @ <li value="9"><b>Check-In</b>: Commit new versions in the repository</li> @ <li value="10"><b>Read-Wiki</b>: View wiki pages</li> @@ -157,12 +166,12 @@ /* ** WEBPAGE: /setup_uedit */ void user_edit(void){ const char *zId, *zLogin, *zInfo, *zCap; - char *oaa, *oas, *oar, *oaw, *oan, *oai, *oaj, *oao, *oap ; - char *oak, *oad, *oaq, *oac, *oaf, *oam, *oah, *oag; + char *oaa, *oas, *oar, *oaw, *oan, *oai, *oaj, *oao, *oap; + char *oak, *oad, *oaq, *oac, *oaf, *oam, *oah, *oag, *oae; int doWrite; int uid; int higherUser = 0; /* True if user being edited is SETUP and the */ /* user doing the editing is ADMIN. Disallow editing */ @@ -197,10 +206,11 @@ const char *zLogin; char zCap[30]; int i = 0; int aa = P("aa")!=0; int ad = P("ad")!=0; + int ae = P("ae")!=0; int ai = P("ai")!=0; int aj = P("aj")!=0; int ak = P("ak")!=0; int an = P("an")!=0; int ao = P("ao")!=0; @@ -215,10 +225,11 @@ int ah = P("ah")!=0; int ag = P("ag")!=0; if( aa ){ zCap[i++] = 'a'; } if( ac ){ zCap[i++] = 'c'; } if( ad ){ zCap[i++] = 'd'; } + if( ae ){ zCap[i++] = 'e'; } if( af ){ zCap[i++] = 'f'; } if( ah ){ zCap[i++] = 'h'; } if( ag ){ zCap[i++] = 'g'; } if( ai ){ zCap[i++] = 'i'; } if( aj ){ zCap[i++] = 'j'; } @@ -261,19 +272,20 @@ /* Load the existing information about the user, if any */ zLogin = ""; zInfo = ""; zCap = ""; - oaa = oac = oad = oaf = oag = oah = oai = oaj = oak = oam = + oaa = oac = oad = oae = oaf = oag = oah = oai = oaj = oak = oam = oan = oao = oap = oaq = oar = oas = oaw = ""; if( uid ){ zLogin = db_text("", "SELECT login FROM user WHERE uid=%d", uid); zInfo = db_text("", "SELECT info FROM user WHERE uid=%d", uid); zCap = db_text("", "SELECT cap FROM user WHERE uid=%d", uid); if( strchr(zCap, 'a') ) oaa = " checked"; if( strchr(zCap, 'c') ) oac = " checked"; if( strchr(zCap, 'd') ) oad = " checked"; + if( strchr(zCap, 'e') ) oae = " checked"; if( strchr(zCap, 'f') ) oaf = " checked"; if( strchr(zCap, 'g') ) oag = " checked"; if( strchr(zCap, 'h') ) oah = " checked"; if( strchr(zCap, 'i') ) oai = " checked"; if( strchr(zCap, 'j') ) oaj = " checked"; @@ -321,10 +333,11 @@ if( g.okSetup ){ @ <input type="checkbox" name="as"%s(oas)>Setup</input><br> } @ <input type="checkbox" name="aa"%s(oaa)>Admin</input><br> @ <input type="checkbox" name="ad"%s(oad)>Delete</input><br> + @ <input type="checkbox" name="ae"%s(oad)>Email</input><br> @ <input type="checkbox" name="ap"%s(oap)>Password</input><br> @ <input type="checkbox" name="aq"%s(oaq)>Query</input><br> @ <input type="checkbox" name="ai"%s(oai)>Check-In</input><br> @ <input type="checkbox" name="ao"%s(oao)>Check-Out</input><br> @ <input type="checkbox" name="ah"%s(oah)>History</input><br> @@ -361,11 +374,13 @@ } @ @ <li><p> @ The <b>Delete</b> privilege give the user the ability to erase @ wiki, tickets, and atttachments that have been added by anonymous - @ users. This capability is intended for deletion of spam. + @ users. This capability is intended for deletion of spam. The + @ delete capability is only in effect for 24 hours after the item + @ is first posted. The Setup user can delete anything at any time. @ </p></li> @ @ <li><p> @ The <b>Query</b> privilege allows the user to create or edit @ report formats by specifying appropriate SQL. Users can run @@ -430,11 +445,11 @@ zQ = "off"; } if( zQ ){ int iQ = strcmp(zQ,"on")==0 || atoi(zQ); if( iQ!=iVal ){ - db_set(zVar, iQ ? "1" : "0"); + db_set(zVar, iQ ? "1" : "0", 0); iVal = iQ; } } if( iVal ){ @ <input type="checkbox" name="%s(zQParm)" checked>%s(zLabel)</input> @@ -449,22 +464,44 @@ static void entry_attribute( const char *zLabel, /* The text label on the entry box */ int width, /* Width of the entry box */ const char *zVar, /* The corresponding row in the VAR table */ const char *zQParm, /* The query parameter */ - const char *zDflt /* Default value if VAR table entry does not exist */ + char *zDflt /* Default value if VAR table entry does not exist */ ){ const char *zVal = db_get(zVar, zDflt); const char *zQ = P(zQParm); if( zQ && strcmp(zQ,zVal)!=0 ){ - db_set(zVar, zQ); + db_set(zVar, zQ, 0); zVal = zQ; } @ <input type="text" name="%s(zQParm)" value="%h(zVal)" size="%d(width)"> @ %s(zLabel) } +/* +** Generate a text box for an attribute. +*/ +static void textarea_attribute( + const char *zLabel, /* The text label on the textarea */ + int rows, /* Rows in the textarea */ + int cols, /* Columns in the textarea */ + const char *zVar, /* The corresponding row in the VAR table */ + const char *zQP, /* The query parameter */ + const char *zDflt /* Default value if VAR table entry does not exist */ +){ + const char *z = db_get(zVar, (char*)zDflt); + const char *zQ = P(zQP); + if( zQ && strcmp(zQ,z)!=0 ){ + db_set(zVar, zQ, 0); + z = zQ; + } + if( rows>0 && cols>0 ){ + @ <textarea name="%s(zQP)" rows="%d(rows)" cols="%d(cols)">%h(z)</textarea> + @ %s(zLabel) + } +} /* ** WEBPAGE: setup_access */ @@ -478,11 +515,11 @@ db_begin_transaction(); @ <form action="%s(g.zBaseURL)/setup_access" method="POST"> @ <hr> onoff_attribute("Require password for local access", - "authenticate-localhost", "localauth", 1); + "localauth", "localauth", 1); @ <p>When enabled, the password sign-in is required for @ web access coming from 127.0.0.1. When disabled, web access @ from 127.0.0.1 is allows without any login - the user id is selected @ from the ~/.fossil database. Password login is always required @ for incoming web connections on internet addresses other than @@ -493,12 +530,40 @@ @ <p>The number of hours for which a login is valid. This must be a @ positive number. The default is 8760 hours which is approximately equal @ to a year.</p> @ <hr> - onoff_attribute("Allow anonymous signup", "anon-signup", "asu", 0); - @ <p>Allow users to create their own accounts</p> + @ <p><input type="submit" name="submit" value="Apply Changes"></p> + @ </form> + db_end_transaction(0); + style_footer(); +} + +/* +** WEBPAGE: setup_timeline +*/ +void setup_timeline(void){ + login_check_credentials(); + if( !g.okSetup ){ + login_needed(); + } + + style_header("Timeline Display Preferences"); + db_begin_transaction(); + @ <form action="%s(g.zBaseURL)/setup_timeline" method="POST"> + + @ <hr> + onoff_attribute("Block markup in timeline", + "timeline-block-markup", "tbm", 0); + @ <p>In timeline displays, check-in comments can be displayed with or + @ without block markup (paragraphs, tables, etc.)</p> + + @ <hr> + entry_attribute("Max timeline comment length", 6, + "timeline-max-comment", "tmc", "0"); + @ <p>The maximum length of a comment to be displayed in a timeline. + @ "0" there is no length limit.</p> @ <hr> @ <p><input type="submit" name="submit" value="Apply Changes"></p> @ </form> db_end_transaction(0); @@ -515,32 +580,159 @@ } style_header("WWW Configuration"); db_begin_transaction(); @ <form action="%s(g.zBaseURL)/setup_config" method="POST"> - - @ <hr> - entry_attribute("Home page", 60, "homepage", "hp", ""); - @ <p>The name of a wiki file that is the homepage for the website. - @ The home page is the page that is displayed by the "Home" link - @ at the top of this screen. Omit the path and the ".wiki" - @ suffix. </p> - - entry_attribute("Ticket subdirectory", 60, "ticket-subdir", "tsd", ""); - @ <p>A subdirectory in the file hierarchy that contains all trouble - @ tickets. Leave this blank to disable ticketing. Tickets text - @ files within this subdirectory containing a particular format - @ (documented separately) and with the ".tkt" suffix.</p> - - entry_attribute("Wiki subdirectory", 60, "wiki-subdir", "wsd", ""); - @ <p>A subdirectory in the file hierarchy that contains wiki pages. - @ Leave this blank to disable wiki. Wiki pages are - @ files within this subdirectory whose name is he wiki page title - @ and with the suffix ".wiki".</p> - - - @ <hr> + @ <hr /> + entry_attribute("Project Name", 60, "project-name", "pn", ""); + @ <p>Give your project a name so visitors know what this site is about. + @ The project name will also be used as the RSS feed title.</p> + @ <hr /> + textarea_attribute("Project Description", 5, 60, + "project-description", "pd", ""); + @ <p>Describe your project. This will be used in page headers for search + @ engines as well as a short RSS description.</p> + @ <hr /> @ <p><input type="submit" name="submit" value="Apply Changes"></p> @ </form> db_end_transaction(0); style_footer(); +} + +/* +** WEBPAGE: setup_editcss +*/ +void setup_editcss(void){ + login_check_credentials(); + if( !g.okSetup ){ + login_needed(); + } + style_header("Edit CSS"); + @ <form action="%s(g.zBaseURL)/setup_editcss" method="POST"> + @ Edit the CSS:<br /> + textarea_attribute("", 40, 80, "css", "css", zDefaultCSS); + @ <br /> + @ <input type="submit" name="submit" value="Apply Changes"> + @ </form> + @ <hr> + @ Here is the default CSS: + @ <blockquote><pre> + @ %h(zDefaultCSS) + @ </pre></blockquote> + style_footer(); +} + +/* +** WEBPAGE: setup_header +*/ +void setup_header(void){ + login_check_credentials(); + if( !g.okSetup ){ + login_needed(); + } + db_begin_transaction(); + if( P("clear")!=0 ){ + db_multi_exec("DELETE FROM config WHERE name='header'"); + cgi_replace_parameter("header", zDefaultHeader); + }else{ + textarea_attribute(0, 0, 0, "header", "header", zDefaultHeader); + } + style_header("Edit Page Header"); + @ <form action="%s(g.zBaseURL)/setup_header" method="POST"> + @ <p>Edit HTML text with embedded subscript that will be used to + @ generate the beginning of every page through start of the main + @ menu.</p> + textarea_attribute("", 40, 80, "header", "header", zDefaultHeader); + @ <br /> + @ <input type="submit" name="submit" value="Apply Changes"> + @ <input type="submit" name="clear" value="Revert To Default"> + @ </form> + @ <hr> + @ Here is the default page header: + @ <blockquote><pre> + @ %h(zDefaultHeader) + @ </pre></blockquote> + db_end_transaction(0); +} + +/* +** WEBPAGE: setup_footer +*/ +void setup_footer(void){ + login_check_credentials(); + if( !g.okSetup ){ + login_needed(); + } + db_begin_transaction(); + if( P("clear")!=0 ){ + db_multi_exec("DELETE FROM config WHERE name='footer'"); + cgi_replace_parameter("footer", zDefaultFooter); + }else{ + textarea_attribute(0, 0, 0, "footer", "footer", zDefaultFooter); + } + style_header("Edit Page Footer"); + @ <form action="%s(g.zBaseURL)/setup_footer" method="POST"> + @ <p>Edit HTML text with embedded subscript that will be used to + @ generate the end of every page.</p> + textarea_attribute("", 20, 80, "footer", "footer", zDefaultFooter); + @ <br /> + @ <input type="submit" name="submit" value="Apply Changes"> + @ <input type="submit" name="clear" value="Revert To Default"> + @ </form> + @ <hr> + @ Here is the default page footer: + @ <blockquote><pre> + @ %h(zDefaultFooter) + @ </pre></blockquote> + db_end_transaction(0); +} + +/* +** WEBPAGE: setup_ticket +*/ +void setup_ticket(void){ + const char *zConfig; + int isSubmit; + + login_check_credentials(); + if( !g.okSetup ){ + login_needed(); + } + isSubmit = P("submit")!=0; + db_begin_transaction(); + zConfig = P("cfg"); + if( zConfig==0 ){ + zConfig = db_text((char*)zDefaultTicketConfig, + "SELECT value FROM config WHERE name='ticket-configuration'"); + } + style_header("Edit Ticket Configuration"); + if( P("clear")!=0 ){ + db_multi_exec("DELETE FROM config WHERE name='ticket-configuration'"); + zConfig = zDefaultTicketConfig; + }else if( isSubmit ){ + char *zErr = ticket_config_check(zConfig); + if( zErr==0 ){ + db_multi_exec( + "REPLACE INTO config(name,value) VALUES('ticket-configuration'," + "%Q)", zConfig + ); + }else{ + @ <p><font color="red"><b> + @ SCRIPT ERROR: %h(zErr) + @ </b></font></p> + } + } + @ <form action="%s(g.zBaseURL)/setup_ticket" method="POST"> + @ <p>Edit the "subscript" script that defines the ticketing + @ system setup for this server.</p> + @ <textarea name="cfg" rows="40" cols="80">%h(zConfig)</textarea> + @ <br /> + @ <input type="submit" name="submit" value="Apply Changes"> + @ <input type="submit" name="clear" value="Revert To Default"> + @ </form> + @ <hr> + @ Here is the default page header: + @ <blockquote><pre> + @ %h(zDefaultTicketConfig) + @ </pre></blockquote> + db_end_transaction(0); }
Modified src/sha1.c from [2a394ff16c] to [7f2336da5a].
@@ -1,20 +1,20 @@ /* ** This implementation of SHA1 is adapted from the example implementation ** contained in RFC-3174. */ #include <stdint.h> +#include <sys/types.h> #include "config.h" #include "sha1.h" /* * If you do not have the ISO standard stdint.h header file, then you * must typdef the following: * name meaning * uint32_t unsigned 32 bit integer * uint8_t unsigned 8 bit integer (i.e., unsigned char) - * int_least16_t integer of >= 16 bits * */ #define SHA1HashSize 20 #define shaSuccess 0 #define shaInputTooLong 1 @@ -29,12 +29,11 @@ uint32_t Intermediate_Hash[SHA1HashSize/4]; /* Message Digest */ uint32_t Length_Low; /* Message length in bits */ uint32_t Length_High; /* Message length in bits */ - /* Index into message block array */ - int_least16_t Message_Block_Index; + int Message_Block_Index; /* Index into message block array */ uint8_t Message_Block[64]; /* 512-bit message blocks */ int Computed; /* Is the digest computed? */ int Corrupted; /* Is the message digest corrupted? */ };
Modified src/sqlite3.c from [78b5167351] to [81b02daa4d].
@@ -1,8 +1,8 @@ /****************************************************************************** ** This file is an amalgamation of many separate C source files from SQLite -** version 3.5.0. By combining all the individual C code files into this +** version 3.5.2. By combining all the individual C code files into this ** single large file, the entire code can be compiled as a one translation ** unit. This allows many compilers to do optimizations that would not be ** possible if the files were compiled separately. Performance improvements ** of 5% are more are commonly seen when SQLite is compiled as a single ** translation unit. @@ -9,25 +9,346 @@ ** ** This file is all you need to compile SQLite. To use SQLite in other ** programs, you need this file and the "sqlite3.h" header file that defines ** the programming interface to the SQLite library. (If you do not have ** the "sqlite3.h" header file at hand, you will find a copy in the first -** 3539 lines past this header comment.) Additional code files may be +** 3530 lines past this header comment.) Additional code files may be ** needed if you want a wrapper to interface SQLite with your choice of ** programming language. The code for the "sqlite3" command-line shell ** is also in a separate file. This file contains only code for the core ** SQLite library. ** -** This amalgamation was generated on 2007-09-14 14:58:10 UTC. +** This amalgamation was generated on 2007-11-25 16:04:31 UTC. */ #define SQLITE_AMALGAMATION 1 #ifndef SQLITE_PRIVATE # define SQLITE_PRIVATE static #endif #ifndef SQLITE_API # define SQLITE_API #endif +/************** Begin file sqliteInt.h ***************************************/ +/* +** 2001 September 15 +** +** 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. +** +************************************************************************* +** Internal interface definitions for SQLite. +** +** @(#) $Id: sqliteInt.h,v 1.618 2007/11/12 09:50:26 danielk1977 Exp $ +*/ +#ifndef _SQLITEINT_H_ +#define _SQLITEINT_H_ + +/* +** These #defines should enable >2GB file support on Posix if the +** underlying operating system supports it. If the OS lacks +** large file support, or if the OS is windows, these should be no-ops. +** +** Ticket #2739: The _LARGEFILE_SOURCE macro must appear before any +** system #includes. Hence, this block of code must be the very first +** code in all source files. +** +** Large file support can be disabled using the -DSQLITE_DISABLE_LFS switch +** on the compiler command line. This is necessary if you are compiling +** on a recent machine (ex: RedHat 7.2) but you want your code to work +** on an older machine (ex: RedHat 6.0). If you compile on RedHat 7.2 +** without this option, LFS is enable. But LFS does not exist in the kernel +** in RedHat 6.0, so the code won't work. Hence, for maximum binary +** portability you should omit LFS. +** +** Similar is true for MacOS. LFS is only supported on MacOS 9 and later. +*/ +#ifndef SQLITE_DISABLE_LFS +# define _LARGE_FILE 1 +# ifndef _FILE_OFFSET_BITS +# define _FILE_OFFSET_BITS 64 +# endif +# define _LARGEFILE_SOURCE 1 +#endif + + +/************** Include sqliteLimit.h in the middle of sqliteInt.h ***********/ +/************** Begin file sqliteLimit.h *************************************/ +/* +** 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 defines various limits of what SQLite can process. +** +** @(#) $Id: sqliteLimit.h,v 1.3 2007/11/05 14:30:23 drh Exp $ +*/ + +/* +** The maximum length of a TEXT or BLOB in bytes. This also +** limits the size of a row in a table or index. +** +** The hard limit is the ability of a 32-bit signed integer +** to count the size: 2^31-1 or 2147483647. +*/ +#ifndef SQLITE_MAX_LENGTH +# define SQLITE_MAX_LENGTH 1000000000 +#endif + +/* +** This is the maximum number of +** +** * Columns in a table +** * Columns in an index +** * Columns in a view +** * Terms in the SET clause of an UPDATE statement +** * Terms in the result set of a SELECT statement +** * Terms in the GROUP BY or ORDER BY clauses of a SELECT statement. +** * Terms in the VALUES clause of an INSERT statement +** +** The hard upper limit here is 32676. Most database people will +** tell you that in a well-normalized database, you usually should +** not have more than a dozen or so columns in any table. And if +** that is the case, there is no point in having more than a few +** dozen values in any of the other situations described above. +*/ +#ifndef SQLITE_MAX_COLUMN +# define SQLITE_MAX_COLUMN 2000 +#endif + +/* +** The maximum length of a single SQL statement in bytes. +** The hard limit here is the same as SQLITE_MAX_LENGTH. +*/ +#ifndef SQLITE_MAX_SQL_LENGTH +# define SQLITE_MAX_SQL_LENGTH 1000000 +#endif + +/* +** The maximum depth of an expression tree. This is limited to +** some extent by SQLITE_MAX_SQL_LENGTH. But sometime you might +** want to place more severe limits on the complexity of an +** expression. A value of 0 (the default) means do not enforce +** any limitation on expression tree depth. +*/ +#ifndef SQLITE_MAX_EXPR_DEPTH +# define SQLITE_MAX_EXPR_DEPTH 1000 +#endif + +/* +** The maximum number of terms in a compound SELECT statement. +** The code generator for compound SELECT statements does one +** level of recursion for each term. A stack overflow can result +** if the number of terms is too large. In practice, most SQL +** never has more than 3 or 4 terms. Use a value of 0 to disable +** any limit on the number of terms in a compount SELECT. +*/ +#ifndef SQLITE_MAX_COMPOUND_SELECT +# define SQLITE_MAX_COMPOUND_SELECT 500 +#endif + +/* +** The maximum number of opcodes in a VDBE program. +** Not currently enforced. +*/ +#ifndef SQLITE_MAX_VDBE_OP +# define SQLITE_MAX_VDBE_OP 25000 +#endif + +/* +** The maximum number of arguments to an SQL function. +*/ +#ifndef SQLITE_MAX_FUNCTION_ARG +# define SQLITE_MAX_FUNCTION_ARG 100 +#endif + +/* +** The maximum number of in-memory pages to use for the main database +** table and for temporary tables. The SQLITE_DEFAULT_CACHE_SIZE +*/ +#ifndef SQLITE_DEFAULT_CACHE_SIZE +# define SQLITE_DEFAULT_CACHE_SIZE 2000 +#endif +#ifndef SQLITE_DEFAULT_TEMP_CACHE_SIZE +# define SQLITE_DEFAULT_TEMP_CACHE_SIZE 500 +#endif + +/* +** The maximum number of attached databases. This must be at least 2 +** in order to support the main database file (0) and the file used to +** hold temporary tables (1). And it must be less than 32 because +** we use a bitmask of databases with a u32 in places (for example +** the Parse.cookieMask field). +*/ +#ifndef SQLITE_MAX_ATTACHED +# define SQLITE_MAX_ATTACHED 10 +#endif + + +/* +** The maximum value of a ?nnn wildcard that the parser will accept. +*/ +#ifndef SQLITE_MAX_VARIABLE_NUMBER +# define SQLITE_MAX_VARIABLE_NUMBER 999 +#endif + +/* Maximum page size. The upper bound on this value is 32768. This a limit +** imposed by the necessity of storing the value in a 2-byte unsigned integer +** and the fact that the page size must be a power of 2. +*/ +#ifndef SQLITE_MAX_PAGE_SIZE +# define SQLITE_MAX_PAGE_SIZE 32768 +#endif + + +/* +** The default size of a database page. +*/ +#ifndef SQLITE_DEFAULT_PAGE_SIZE +# define SQLITE_DEFAULT_PAGE_SIZE 1024 +#endif +#if SQLITE_DEFAULT_PAGE_SIZE>SQLITE_MAX_PAGE_SIZE +# undef SQLITE_DEFAULT_PAGE_SIZE +# define SQLITE_DEFAULT_PAGE_SIZE SQLITE_MAX_PAGE_SIZE +#endif + +/* +** Ordinarily, if no value is explicitly provided, SQLite creates databases +** with page size SQLITE_DEFAULT_PAGE_SIZE. However, based on certain +** device characteristics (sector-size and atomic write() support), +** SQLite may choose a larger value. This constant is the maximum value +** SQLite will choose on it's own. +*/ +#ifndef SQLITE_MAX_DEFAULT_PAGE_SIZE +# define SQLITE_MAX_DEFAULT_PAGE_SIZE 8192 +#endif +#if SQLITE_MAX_DEFAULT_PAGE_SIZE>SQLITE_MAX_PAGE_SIZE +# undef SQLITE_MAX_DEFAULT_PAGE_SIZE +# define SQLITE_MAX_DEFAULT_PAGE_SIZE SQLITE_MAX_PAGE_SIZE +#endif + + +/* +** Maximum number of pages in one database file. +** +** This is really just the default value for the max_page_count pragma. +** This value can be lowered (or raised) at run-time using that the +** max_page_count macro. +*/ +#ifndef SQLITE_MAX_PAGE_COUNT +# define SQLITE_MAX_PAGE_COUNT 1073741823 +#endif + +/* +** Maximum length (in bytes) of the pattern in a LIKE or GLOB +** operator. +*/ +#ifndef SQLITE_MAX_LIKE_PATTERN_LENGTH +# define SQLITE_MAX_LIKE_PATTERN_LENGTH 50000 +#endif + +/************** End of sqliteLimit.h *****************************************/ +/************** Continuing where we left off in sqliteInt.h ******************/ + +/* +** For testing purposes, the various size limit constants are really +** variables that we can modify in the testfixture. +*/ +#ifdef SQLITE_TEST + #undef SQLITE_MAX_LENGTH + #undef SQLITE_MAX_COLUMN + #undef SQLITE_MAX_SQL_LENGTH + #undef SQLITE_MAX_EXPR_DEPTH + #undef SQLITE_MAX_COMPOUND_SELECT + #undef SQLITE_MAX_VDBE_OP + #undef SQLITE_MAX_FUNCTION_ARG + #undef SQLITE_MAX_VARIABLE_NUMBER + #undef SQLITE_MAX_PAGE_SIZE + #undef SQLITE_MAX_PAGE_COUNT + #undef SQLITE_MAX_LIKE_PATTERN_LENGTH + + #define SQLITE_MAX_LENGTH sqlite3MAX_LENGTH + #define SQLITE_MAX_COLUMN sqlite3MAX_COLUMN + #define SQLITE_MAX_SQL_LENGTH sqlite3MAX_SQL_LENGTH + #define SQLITE_MAX_EXPR_DEPTH sqlite3MAX_EXPR_DEPTH + #define SQLITE_MAX_COMPOUND_SELECT sqlite3MAX_COMPOUND_SELECT + #define SQLITE_MAX_VDBE_OP sqlite3MAX_VDBE_OP + #define SQLITE_MAX_FUNCTION_ARG sqlite3MAX_FUNCTION_ARG + #define SQLITE_MAX_VARIABLE_NUMBER sqlite3MAX_VARIABLE_NUMBER + #define SQLITE_MAX_PAGE_SIZE sqlite3MAX_PAGE_SIZE + #define SQLITE_MAX_PAGE_COUNT sqlite3MAX_PAGE_COUNT + #define SQLITE_MAX_LIKE_PATTERN_LENGTH sqlite3MAX_LIKE_PATTERN_LENGTH + + extern int sqlite3MAX_LENGTH; + extern int sqlite3MAX_COLUMN; + extern int sqlite3MAX_SQL_LENGTH; + extern int sqlite3MAX_EXPR_DEPTH; + extern int sqlite3MAX_COMPOUND_SELECT; + extern int sqlite3MAX_VDBE_OP; + extern int sqlite3MAX_FUNCTION_ARG; + extern int sqlite3MAX_VARIABLE_NUMBER; + extern int sqlite3MAX_PAGE_SIZE; + extern int sqlite3MAX_PAGE_COUNT; + extern int sqlite3MAX_LIKE_PATTERN_LENGTH; +#endif + + +/* +** The SQLITE_THREADSAFE macro must be defined as either 0 or 1. +** Older versions of SQLite used an optional THREADSAFE macro. +** We support that for legacy +*/ +#if !defined(SQLITE_THREADSAFE) +#if defined(THREADSAFE) +# define SQLITE_THREADSAFE THREADSAFE +#else +# define SQLITE_THREADSAFE 1 +#endif +#endif + +/* +** We need to define _XOPEN_SOURCE as follows in order to enable +** recursive mutexes on most unix systems. But Mac OS X is different. +** The _XOPEN_SOURCE define causes problems for Mac OS X we are told, +** so it is omitted there. See ticket #2673. +** +** Later we learn that _XOPEN_SOURCE is poorly or incorrectly +** implemented on some systems. So we avoid defining it at all +** if it is already defined or if it is unneeded because we are +** not doing a threadsafe build. Ticket #2681. +** +** See also ticket #2741. +*/ +#if !defined(_XOPEN_SOURCE) && !defined(__MACOS__) && SQLITE_THREADSAFE +# define _XOPEN_SOURCE 500 /* Needed to enable pthread recursive mutexes */ +#endif + +#if defined(SQLITE_TCL) || defined(TCLSH) +# include <tcl.h> +#endif + +/* +** Many people are failing to set -DNDEBUG=1 when compiling SQLite. +** Setting NDEBUG makes the code smaller and run faster. So the following +** lines are added to automatically set NDEBUG unless the -DSQLITE_DEBUG=1 +** option is set. Thus NDEBUG becomes an opt-in rather than an opt-out +** feature. +*/ +#if !defined(NDEBUG) && !defined(SQLITE_DEBUG) +# define NDEBUG 1 +#endif + +/************** Include sqlite3.h in the middle of sqliteInt.h ***************/ /************** Begin file sqlite3.h *****************************************/ /* ** 2001 September 15 ** ** The author disclaims copyright to this source code. In place of @@ -57,11 +378,11 @@ ** The name of this file under configuration management is "sqlite.h.in". ** The makefile makes some minor changes to this file (such as inserting ** the version number) and changes its name to "sqlite3.h" as ** part of the build process. ** -** @(#) $Id: sqlite.h.in,v 1.259 2007/09/04 22:31:37 drh Exp $ +** @(#) $Id: sqlite.h.in,v 1.271 2007/11/21 15:24:01 drh Exp $ */ #ifndef _SQLITE3_H_ #define _SQLITE3_H_ #include <stdarg.h> /* Needed for the definition of va_list */ @@ -116,12 +437,12 @@ ** version 3.1.1 or greater at compile time, programs may use the test ** (SQLITE_VERSION_NUMBER>=3001001). ** ** See also: [sqlite3_libversion()] and [sqlite3_libversion_number()]. */ -#define SQLITE_VERSION "3.5.0" -#define SQLITE_VERSION_NUMBER 3005000 +#define SQLITE_VERSION "3.5.2" +#define SQLITE_VERSION_NUMBER 3005002 /* ** CAPI3REF: Run-Time Library Version Numbers ** ** These routines return values equivalent to the header constants @@ -322,11 +643,11 @@ #define SQLITE_CANTOPEN 14 /* Unable to open the database file */ #define SQLITE_PROTOCOL 15 /* NOT USED. Database lock protocol error */ #define SQLITE_EMPTY 16 /* Database is empty */ #define SQLITE_SCHEMA 17 /* The database schema changed */ #define SQLITE_TOOBIG 18 /* String or BLOB exceeds size limit */ -#define SQLITE_CONSTRAINT 19 /* Abort due to contraint violation */ +#define SQLITE_CONSTRAINT 19 /* Abort due to constraint violation */ #define SQLITE_MISMATCH 20 /* Data type mismatch */ #define SQLITE_MISUSE 21 /* Library used incorrectly */ #define SQLITE_NOLFS 22 /* Uses OS features not supported on host */ #define SQLITE_AUTH 23 /* Authorization denied */ #define SQLITE_FORMAT 24 /* Auxiliary database format error */ @@ -372,10 +693,11 @@ #define SQLITE_IOERR_FSTAT (SQLITE_IOERR | (7<<8)) #define SQLITE_IOERR_UNLOCK (SQLITE_IOERR | (8<<8)) #define SQLITE_IOERR_RDLOCK (SQLITE_IOERR | (9<<8)) #define SQLITE_IOERR_DELETE (SQLITE_IOERR | (10<<8)) #define SQLITE_IOERR_BLOCKED (SQLITE_IOERR | (11<<8)) +#define SQLITE_IOERR_NOMEM (SQLITE_IOERR | (12<<8)) /* ** CAPI3REF: Flags For File Open Operations ** ** Combination of the following bit values are used as the @@ -689,11 +1011,16 @@ ** if a file is readable and writable, or [SQLITE_ACCESS_READ] ** to test to see if a file is at least readable. The file can be a ** directory. ** ** SQLite will always allocate at least mxPathname+1 byte for -** the output buffers for xGetTempName and xFullPathname. +** the output buffers for xGetTempname and xFullPathname. The exact +** size of the output buffer is also passed as a parameter to both +** methods. If the output buffer is not large enough, SQLITE_CANTOPEN +** should be returned. As this is handled as a fatal error by SQLite, +** vfs implementations should endevour to prevent this by setting +** mxPathname to a sufficiently large value. ** ** The xRandomness(), xSleep(), and xCurrentTime() interfaces ** are not strictly a part of the filesystem, but they are ** included in the VFS structure for completeness. ** The xRandomness() function attempts to return nBytes bytes @@ -714,12 +1041,12 @@ void *pAppData; /* Pointer to application-specific data */ int (*xOpen)(sqlite3_vfs*, const char *zName, sqlite3_file*, int flags, int *pOutFlags); int (*xDelete)(sqlite3_vfs*, const char *zName, int syncDir); int (*xAccess)(sqlite3_vfs*, const char *zName, int flags); - int (*xGetTempName)(sqlite3_vfs*, char *zOut); - int (*xFullPathname)(sqlite3_vfs*, const char *zName, char *zOut); + int (*xGetTempname)(sqlite3_vfs*, int nOut, char *zOut); + int (*xFullPathname)(sqlite3_vfs*, const char *zName, int nOut, char *zOut); void *(*xDlOpen)(sqlite3_vfs*, const char *zFilename); void (*xDlError)(sqlite3_vfs*, int nByte, char *zErrMsg); void *(*xDlSym)(sqlite3_vfs*,void*, const char *zSymbol); void (*xDlClose)(sqlite3_vfs*, void*); int (*xRandomness)(sqlite3_vfs*, int nByte, char *zOut); @@ -769,20 +1096,30 @@ ** called the "rowid". The rowid is always available as an undeclared ** column named ROWID, OID, or _ROWID_. If the table has a column of ** type INTEGER PRIMARY KEY then that column is another an alias for the ** rowid. ** -** This routine returns the rowid of the most recent INSERT into -** the database from the database connection given in the first -** argument. If no inserts have ever occurred on this database +** This routine returns the rowid of the most recent successful INSERT into +** the database from the database connection given in the first +** argument. If no successful inserts have ever occurred on this database ** connection, zero is returned. ** ** If an INSERT occurs within a trigger, then the rowid of the ** inserted row is returned by this routine as long as the trigger ** is running. But once the trigger terminates, the value returned ** by this routine reverts to the last value inserted before the ** trigger fired. +** +** An INSERT that fails due to a constraint violation is not a +** successful insert and does not change the value returned by this +** routine. Thus INSERT OR FAIL, INSERT OR IGNORE, INSERT OR ROLLBACK, +** and INSERT OR ABORT make no changes to the return value of this +** routine when their insertion fails. When INSERT OR REPLACE +** encounters a constraint violation, it does not fail. The +** INSERT continues to completion after deleting rows that caused +** the constraint problem so INSERT OR REPLACE will always change +** the return value of this interface. ** ** If another thread does a new insert on the same database connection ** while this routine is running and thus changes the last insert rowid, ** then the return value of this routine is undefined. */ @@ -1142,33 +1479,27 @@ /* ** CAPI3REF: Memory Allocation Subsystem ** ** The SQLite core uses these three routines for all of its own ** internal memory allocation needs. (See the exception below.) +** ** The default implementation ** of the memory allocation subsystem uses the malloc(), realloc() ** and free() provided by the standard C library. However, if ** SQLite is compiled with the following C preprocessor macro ** -** <blockquote> SQLITE_OMIT_MEMORY_ALLOCATION </blockquote> -** -** then no implementation is provided for these routines by -** SQLite. The application that links against SQLite is -** expected to provide its own implementation. If the application -** does provide its own implementation for these routines, then -** it must also provide an implementations for -** [sqlite3_memory_alarm()], [sqlite3_memory_used()], and -** [sqlite3_memory_highwater()]. The alternative implementations -** for these last three routines need not actually work, but -** stub functions at least are needed to statisfy the linker. -** SQLite never calls [sqlite3_memory_highwater()] itself, but -** the symbol is included in a table as part of the -** [sqlite3_load_extension()] interface. The -** [sqlite3_memory_alarm()] and [sqlite3_memory_used()] interfaces -** are called by [sqlite3_soft_heap_limit()] and working implementations -** of both routines must be provided if [sqlite3_soft_heap_limit()] -** is to operate correctly. +** <blockquote> SQLITE_MEMORY_SIZE=<i>NNN</i> </blockquote> +** +** where <i>NNN</i> is an integer, then SQLite create a static +** array of at least <i>NNN</i> bytes in size and use that array +** for all of its dynamic memory allocation needs. +** +** In SQLite version 3.5.0 and 3.5.1, it was possible to define +** the SQLITE_OMIT_MEMORY_ALLOCATION which would cause the built-in +** implementation of these routines to be omitted. That capability +** is no longer provided. Only built-in memory allocators can be +** used. ** ** <b>Exception:</b> The windows OS interface layer calls ** the system malloc() and free() directly when converting ** filenames between the UTF-8 encoding used by SQLite ** and whatever filename encoding is used by the particular windows @@ -1192,57 +1523,16 @@ ** currently outstanding (malloced but not freed). The second ** returns the largest instantaneous amount of outstanding ** memory. The highwater mark is reset if the argument is ** true. ** -** The implementation of these routines in the SQLite core -** is omitted if the application is compiled with the -** SQLITE_OMIT_MEMORY_ALLOCATION macro defined. In that case, -** the application that links SQLite must provide its own -** alternative implementation. See the documentation on -** [sqlite3_malloc()] for additional information. +** The value returned may or may not include allocation +** overhead, depending on which built-in memory allocator +** implementation is used. */ SQLITE_API sqlite3_int64 sqlite3_memory_used(void); SQLITE_API sqlite3_int64 sqlite3_memory_highwater(int resetFlag); - -/* -** CAPI3REF: Memory Allocation Alarms -** -** The [sqlite3_memory_alarm] routine is used to register -** a callback on memory allocation events. -** -** This routine registers or clears a callbacks that fires when -** the amount of memory allocated exceeds iThreshold. Only -** a single callback can be registered at a time. Each call -** to [sqlite3_memory_alarm()] overwrites the previous callback. -** The callback is disabled by setting xCallback to a NULL -** pointer. -** -** The parameters to the callback are the pArg value, the -** amount of memory currently in use, and the size of the -** allocation that provoked the callback. The callback will -** presumably invoke [sqlite3_free()] to free up memory space. -** The callback may invoke [sqlite3_malloc()] or [sqlite3_realloc()] -** but if it does, no additional callbacks will be invoked by -** the recursive calls. -** -** The [sqlite3_soft_heap_limit()] interface works by registering -** a memory alarm at the soft heap limit and invoking -** [sqlite3_release_memory()] in the alarm callback. Application -** programs should not attempt to use the [sqlite3_memory_alarm()] -** interface because doing so will interfere with the -** [sqlite3_soft_heap_limit()] module. This interface is exposed -** only so that applications can provide their own -** alternative implementation when the SQLite core is -** compiled with SQLITE_OMIT_MEMORY_ALLOCATION. -*/ -SQLITE_API int sqlite3_memory_alarm( - void(*xCallback)(void *pArg, sqlite3_int64 used, int N), - void *pArg, - sqlite3_int64 iThreshold -); - /* ** CAPI3REF: Compile-Time Authorization Callbacks *** ** This routine registers a authorizer callback with the SQLite library. @@ -1504,11 +1794,11 @@ ** for the most recent failed sqlite3_* API call associated ** with [sqlite3] handle 'db'. If a prior API call failed but the ** most recent API call succeeded, the return value from sqlite3_errcode() ** is undefined. ** -** The sqlite3_errmsg() and sqlite3_errmsg16() return English-langauge +** The sqlite3_errmsg() and sqlite3_errmsg16() return English-language ** text that describes the error, as either UTF8 or UTF16 respectively. ** Memory to hold the error message string is managed internally. The ** string may be overwritten or deallocated by subsequent calls to SQLite ** interface functions. ** @@ -1651,10 +1941,27 @@ const void *zSql, /* SQL statement, UTF-16 encoded */ int nByte, /* Maximum length of zSql in bytes. */ sqlite3_stmt **ppStmt, /* OUT: Statement handle */ const void **pzTail /* OUT: Pointer to unused portion of zSql */ ); + +/* +** Retrieve the original SQL statement associated with a compiled statement +** in UTF-8 encoding. +** +** If the compiled SQL statement passed as an argument was compiled using +** either sqlite3_prepare_v2 or sqlite3_prepare16_v2, then this function +** returns a pointer to a nul-terminated string containing a copy of +** the original SQL statement. The pointer is valid until the statement +** is deleted using sqlite3_finalize(). +** +** If the statement was compiled using either of the legacy interfaces +** sqlite3_prepare() or sqlite3_prepare16(), this function returns NULL. +** +****** EXPERIMENTAL - subject to change without notice ************** +*/ +SQLITE_API const char *sqlite3_sql(sqlite3_stmt *pStmt); /* ** CAPI3REF: Dynamically Typed Value Object ** ** SQLite uses dynamic typing for the values it stores. Values can @@ -2335,10 +2642,11 @@ SQLITE_API int sqlite3_aggregate_count(sqlite3_context*); SQLITE_API int sqlite3_expired(sqlite3_stmt*); SQLITE_API int sqlite3_transfer_bindings(sqlite3_stmt*, sqlite3_stmt*); SQLITE_API int sqlite3_global_recover(void); SQLITE_API void sqlite3_thread_cleanup(void); +SQLITE_API int sqlite3_memory_alarm(void(*)(void*,sqlite3_int64,int),void*,sqlite3_int64); /* ** CAPI3REF: Obtaining SQL Function Parameter Values ** ** The C-language implementation of SQL functions and aggregates uses @@ -2539,14 +2847,17 @@ ** The name of the new collation sequence is specified as a UTF-8 string ** for sqlite3_create_collation() and sqlite3_create_collation_v2() ** and a UTF-16 string for sqlite3_create_collation16(). In all cases ** the name is passed as the second function argument. ** -** The third argument must be one of the constants [SQLITE_UTF8], +** The third argument may be one of the constants [SQLITE_UTF8], ** [SQLITE_UTF16LE] or [SQLITE_UTF16BE], indicating that the user-supplied ** routine expects to be passed pointers to strings encoded using UTF-8, -** UTF-16 little-endian or UTF-16 big-endian respectively. +** UTF-16 little-endian or UTF-16 big-endian respectively. The +** third argument might also be [SQLITE_UTF16_ALIGNED] to indicate that +** the routine expects pointers to 16-bit word aligned strings +** of UTF16 in the native byte order of the host computer. ** ** A pointer to the user supplied routine must be passed as the fifth ** argument. If it is NULL, this is the same as deleting the collation ** sequence (so that SQLite cannot call it anymore). Each time the user ** supplied function is invoked, it is passed a copy of the void* passed as @@ -2695,10 +3006,17 @@ ** Test to see whether or not the database connection is in autocommit ** mode. Return TRUE if it is and FALSE if not. Autocommit mode is on ** by default. Autocommit is disabled by a BEGIN statement and reenabled ** by the next COMMIT or ROLLBACK. ** +** If certain kinds of errors occur on a statement within a multi-statement +** transactions (errors including [SQLITE_FULL], [SQLITE_IOERR], +** [SQLITE_NOMEM], [SQLITE_BUSY], and [SQLITE_INTERRUPT]) then the +** transaction might be rolled back automatically. The only way to +** find out if SQLite automatically rolled back the transaction after +** an error is to use this function. +** ** If another thread changes the autocommit status of the database ** connection while this routine is running, then the return value ** is undefined. */ SQLITE_API int sqlite3_get_autocommit(sqlite3*); @@ -2830,16 +3148,10 @@ ** SQLite makes a best effort to honor the soft heap limit. But if it ** is unable to reduce memory usage below the soft limit, execution will ** continue without error or notification. This is why the limit is ** called a "soft" limit. It is advisory only. ** -** The soft heap limit is implemented using the [sqlite3_memory_alarm()] -** interface. Only a single memory alarm is available in the default -** implementation. This means that if the application also uses the -** memory alarm interface it will interfere with the operation of the -** soft heap limit and undefined behavior will result. -** ** Prior to SQLite version 3.5.0, this routine only constrained the memory ** allocated by a single thread - the same thread in which this routine ** runs. Beginning with SQLite version 3.5.0, the soft heap limit is ** applied to all threads. The value specified for the soft heap limit ** is an upper bound on the total memory allocation for all threads. In @@ -2919,11 +3231,11 @@ const char *zColumnName, /* Column name */ char const **pzDataType, /* OUTPUT: Declared data type */ char const **pzCollSeq, /* OUTPUT: Collation sequence name */ int *pNotNull, /* OUTPUT: True if NOT NULL constraint exists */ int *pPrimaryKey, /* OUTPUT: True if column part of PK */ - int *pAutoinc /* OUTPUT: True if colums is auto-increment */ + int *pAutoinc /* OUTPUT: True if column is auto-increment */ ); /* ** CAPI3REF: Load An Extension ** @@ -2976,11 +3288,11 @@ ** times with the same extension is harmless. ** ** This routine stores a pointer to the extension in an array ** that is obtained from malloc(). If you run a memory leak ** checker on your program and it reports a leak because of this -** array, then invoke [sqlite3_automatic_extension_reset()] prior +** array, then invoke [sqlite3_reset_auto_extension()] prior ** to shutdown to free the memory. ** ** Automatic extensions apply across all threads. ** ** This interface is experimental and is subject to change or @@ -3076,11 +3388,11 @@ ** aConstraint[].iColumn. aConstraint[].usable is TRUE if the ** expr on the right-hand side can be evaluated (and thus the constraint ** is usable) and false if it cannot. ** ** The optimizer automatically inverts terms of the form "expr OP column" -** and makes other simplificatinos to the WHERE clause in an attempt to +** and makes other simplifications to the WHERE clause in an attempt to ** get as many WHERE clause terms into the form shown above as possible. ** The aConstraint[] array only reports WHERE clause terms in the correct ** form that refer to the particular virtual table being queried. ** ** Information about the ORDER BY clause is stored in aOrderBy[]. @@ -3105,28 +3417,28 @@ ** a cost of N. A binary search of a table of N entries should have a ** cost of approximately log(N). */ struct sqlite3_index_info { /* Inputs */ - const int nConstraint; /* Number of entries in aConstraint */ - const struct sqlite3_index_constraint { + int nConstraint; /* Number of entries in aConstraint */ + struct sqlite3_index_constraint { int iColumn; /* Column on left-hand side of constraint */ unsigned char op; /* Constraint operator */ unsigned char usable; /* True if this constraint is usable */ int iTermOffset; /* Used internally - xBestIndex should ignore */ - } *const aConstraint; /* Table of WHERE clause constraints */ - const int nOrderBy; /* Number of terms in the ORDER BY clause */ - const struct sqlite3_index_orderby { + } *aConstraint; /* Table of WHERE clause constraints */ + int nOrderBy; /* Number of terms in the ORDER BY clause */ + struct sqlite3_index_orderby { int iColumn; /* Column number */ unsigned char desc; /* True for DESC. False for ASC. */ - } *const aOrderBy; /* The ORDER BY clause */ + } *aOrderBy; /* The ORDER BY clause */ /* Outputs */ struct sqlite3_index_constraint_usage { int argvIndex; /* if >0, constraint is part of argv to xFilter */ unsigned char omit; /* Do not code a test for this constraint */ - } *const aConstraintUsage; + } *aConstraintUsage; int idxNum; /* Number used to identify the index */ char *idxStr; /* String, possibly obtained from sqlite3_malloc */ int needToFreeIdxStr; /* Free idxStr using sqlite3_free() if true */ int orderByConsumed; /* True if output is already ordered */ double estimatedCost; /* Estimated cost of using this index */ @@ -3165,11 +3477,11 @@ ); /* ** Every module implementation uses a subclass of the following structure ** to describe a particular instance of the module. Each subclass will -** be taylored to the specific needs of the module implementation. The +** be tailored to the specific needs of the module implementation. The ** purpose of this superclass is to define certain fields that are common ** to all module implementations. ** ** Virtual tables methods can set an error message by assigning a ** string obtained from sqlite3_mprintf() to zErrMsg. The method should @@ -3231,11 +3543,11 @@ ** The interface to the virtual-table mechanism defined above (back up ** to a comment remarkably similar to this one) is currently considered ** to be experimental. The interface might change in incompatible ways. ** If this is a problem for you, do not use the interface at this time. ** -** When the virtual-table mechanism stablizes, we will declare the +** When the virtual-table mechanism stabilizes, we will declare the ** interface fixed, support it indefinitely, and remove this comment. ** ****** EXPERIMENTAL - subject to change without notice ************** */ @@ -3566,347 +3878,11 @@ } /* End of the 'extern "C"' block */ #endif #endif /************** End of sqlite3.h *********************************************/ -/************** Begin file date.c ********************************************/ -/* -** 2003 October 31 -** -** 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 contains the C functions that implement date and time -** functions for SQLite. -** -** There is only one exported symbol in this file - the function -** sqlite3RegisterDateTimeFunctions() found at the bottom of the file. -** All other code has file scope. -** -** $Id: date.c,v 1.73 2007/09/12 17:01:45 danielk1977 Exp $ -** -** SQLite processes all times and dates as Julian Day numbers. The -** dates and times are stored as the number of days since noon -** in Greenwich on November 24, 4714 B.C. according to the Gregorian -** calendar system. -** -** 1970-01-01 00:00:00 is JD 2440587.5 -** 2000-01-01 00:00:00 is JD 2451544.5 -** -** This implemention requires years to be expressed as a 4-digit number -** which means that only dates between 0000-01-01 and 9999-12-31 can -** be represented, even though julian day numbers allow a much wider -** range of dates. -** -** The Gregorian calendar system is used for all dates and times, -** even those that predate the Gregorian calendar. Historians usually -** use the Julian calendar for dates prior to 1582-10-15 and for some -** dates afterwards, depending on locale. Beware of this difference. -** -** The conversion algorithms are implemented based on descriptions -** in the following text: -** -** Jean Meeus -** Astronomical Algorithms, 2nd Edition, 1998 -** ISBM 0-943396-61-1 -** Willmann-Bell, Inc -** Richmond, Virginia (USA) -*/ -/************** Include sqliteInt.h in the middle of date.c ******************/ -/************** Begin file sqliteInt.h ***************************************/ -/* -** 2001 September 15 -** -** 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. -** -************************************************************************* -** Internal interface definitions for SQLite. -** -** @(#) $Id: sqliteInt.h,v 1.608 2007/09/03 15:19:35 drh Exp $ -*/ -#ifndef _SQLITEINT_H_ -#define _SQLITEINT_H_ -/************** Include sqliteLimit.h in the middle of sqliteInt.h ***********/ -/************** Begin file sqliteLimit.h *************************************/ -/* -** 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 defines various limits of what SQLite can process. -** -** @(#) $Id: sqliteLimit.h,v 1.2 2007/08/24 11:52:29 danielk1977 Exp $ -*/ - -/* -** The maximum length of a TEXT or BLOB in bytes. This also -** limits the size of a row in a table or index. -** -** The hard limit is the ability of a 32-bit signed integer -** to count the size: 2^31-1 or 2147483647. -*/ -#ifndef SQLITE_MAX_LENGTH -# define SQLITE_MAX_LENGTH 1000000000 -#endif - -/* -** This is the maximum number of -** -** * Columns in a table -** * Columns in an index -** * Columns in a view -** * Terms in the SET clause of an UPDATE statement -** * Terms in the result set of a SELECT statement -** * Terms in the GROUP BY or ORDER BY clauses of a SELECT statement. -** * Terms in the VALUES clause of an INSERT statement -** -** The hard upper limit here is 32676. Most database people will -** tell you that in a well-normalized database, you usually should -** not have more than a dozen or so columns in any table. And if -** that is the case, there is no point in having more than a few -** dozen values in any of the other situations described above. -*/ -#ifndef SQLITE_MAX_COLUMN -# define SQLITE_MAX_COLUMN 2000 -#endif - -/* -** The maximum length of a single SQL statement in bytes. -** The hard limit here is the same as SQLITE_MAX_LENGTH. -*/ -#ifndef SQLITE_MAX_SQL_LENGTH -# define SQLITE_MAX_SQL_LENGTH 1000000 -#endif - -/* -** The maximum depth of an expression tree. This is limited to -** some extent by SQLITE_MAX_SQL_LENGTH. But sometime you might -** want to place more severe limits on the complexity of an -** expression. A value of 0 (the default) means do not enforce -** any limitation on expression tree depth. -*/ -#ifndef SQLITE_MAX_EXPR_DEPTH -# define SQLITE_MAX_EXPR_DEPTH 1000 -#endif - -/* -** The maximum number of terms in a compound SELECT statement. -** The code generator for compound SELECT statements does one -** level of recursion for each term. A stack overflow can result -** if the number of terms is too large. In practice, most SQL -** never has more than 3 or 4 terms. Use a value of 0 to disable -** any limit on the number of terms in a compount SELECT. -*/ -#ifndef SQLITE_MAX_COMPOUND_SELECT -# define SQLITE_MAX_COMPOUND_SELECT 500 -#endif - -/* -** The maximum number of opcodes in a VDBE program. -** Not currently enforced. -*/ -#ifndef SQLITE_MAX_VDBE_OP -# define SQLITE_MAX_VDBE_OP 25000 -#endif - -/* -** The maximum number of arguments to an SQL function. -*/ -#ifndef SQLITE_MAX_FUNCTION_ARG -# define SQLITE_MAX_FUNCTION_ARG 100 -#endif - -/* -** The maximum number of in-memory pages to use for the main database -** table and for temporary tables. The SQLITE_DEFAULT_CACHE_SIZE -*/ -#ifndef SQLITE_DEFAULT_CACHE_SIZE -# define SQLITE_DEFAULT_CACHE_SIZE 2000 -#endif -#ifndef SQLITE_DEFAULT_TEMP_CACHE_SIZE -# define SQLITE_DEFAULT_TEMP_CACHE_SIZE 500 -#endif - -/* -** The maximum number of attached databases. This must be at least 2 -** in order to support the main database file (0) and the file used to -** hold temporary tables (1). And it must be less than 32 because -** we use a bitmask of databases with a u32 in places (for example -** the Parse.cookieMask field). -*/ -#ifndef SQLITE_MAX_ATTACHED -# define SQLITE_MAX_ATTACHED 10 -#endif - - -/* -** The maximum value of a ?nnn wildcard that the parser will accept. -*/ -#ifndef SQLITE_MAX_VARIABLE_NUMBER -# define SQLITE_MAX_VARIABLE_NUMBER 999 -#endif - -/* -** The default size of a database page. -*/ -#ifndef SQLITE_DEFAULT_PAGE_SIZE -# define SQLITE_DEFAULT_PAGE_SIZE 1024 -#endif - -/* -** Ordinarily, if no value is explicitly provided, SQLite creates databases -** with page size SQLITE_DEFAULT_PAGE_SIZE. However, based on certain -** device characteristics (sector-size and atomic write() support), -** SQLite may choose a larger value. This constant is the maximum value -** SQLite will choose on it's own. -*/ -#ifndef SQLITE_MAX_DEFAULT_PAGE_SIZE -# define SQLITE_MAX_DEFAULT_PAGE_SIZE 8192 -#endif - -/* Maximum page size. The upper bound on this value is 32768. This a limit -** imposed by the necessity of storing the value in a 2-byte unsigned integer -** and the fact that the page size must be a power of 2. -*/ -#ifndef SQLITE_MAX_PAGE_SIZE -# define SQLITE_MAX_PAGE_SIZE 32768 -#endif - -/* -** Maximum number of pages in one database file. -** -** This is really just the default value for the max_page_count pragma. -** This value can be lowered (or raised) at run-time using that the -** max_page_count macro. -*/ -#ifndef SQLITE_MAX_PAGE_COUNT -# define SQLITE_MAX_PAGE_COUNT 1073741823 -#endif - -/* -** Maximum length (in bytes) of the pattern in a LIKE or GLOB -** operator. -*/ -#ifndef SQLITE_MAX_LIKE_PATTERN_LENGTH -# define SQLITE_MAX_LIKE_PATTERN_LENGTH 50000 -#endif - -/************** End of sqliteLimit.h *****************************************/ -/************** Continuing where we left off in sqliteInt.h ******************/ - -/* -** For testing purposes, the various size limit constants are really -** variables that we can modify in the testfixture. -*/ -#ifdef SQLITE_TEST - #undef SQLITE_MAX_LENGTH - #undef SQLITE_MAX_COLUMN - #undef SQLITE_MAX_SQL_LENGTH - #undef SQLITE_MAX_EXPR_DEPTH - #undef SQLITE_MAX_COMPOUND_SELECT - #undef SQLITE_MAX_VDBE_OP - #undef SQLITE_MAX_FUNCTION_ARG - #undef SQLITE_MAX_VARIABLE_NUMBER - #undef SQLITE_MAX_PAGE_SIZE - #undef SQLITE_MAX_PAGE_COUNT - #undef SQLITE_MAX_LIKE_PATTERN_LENGTH - - #define SQLITE_MAX_LENGTH sqlite3MAX_LENGTH - #define SQLITE_MAX_COLUMN sqlite3MAX_COLUMN - #define SQLITE_MAX_SQL_LENGTH sqlite3MAX_SQL_LENGTH - #define SQLITE_MAX_EXPR_DEPTH sqlite3MAX_EXPR_DEPTH - #define SQLITE_MAX_COMPOUND_SELECT sqlite3MAX_COMPOUND_SELECT - #define SQLITE_MAX_VDBE_OP sqlite3MAX_VDBE_OP - #define SQLITE_MAX_FUNCTION_ARG sqlite3MAX_FUNCTION_ARG - #define SQLITE_MAX_VARIABLE_NUMBER sqlite3MAX_VARIABLE_NUMBER - #define SQLITE_MAX_PAGE_SIZE sqlite3MAX_PAGE_SIZE - #define SQLITE_MAX_PAGE_COUNT sqlite3MAX_PAGE_COUNT - #define SQLITE_MAX_LIKE_PATTERN_LENGTH sqlite3MAX_LIKE_PATTERN_LENGTH - - extern int sqlite3MAX_LENGTH; - extern int sqlite3MAX_COLUMN; - extern int sqlite3MAX_SQL_LENGTH; - extern int sqlite3MAX_EXPR_DEPTH; - extern int sqlite3MAX_COMPOUND_SELECT; - extern int sqlite3MAX_VDBE_OP; - extern int sqlite3MAX_FUNCTION_ARG; - extern int sqlite3MAX_VARIABLE_NUMBER; - extern int sqlite3MAX_PAGE_SIZE; - extern int sqlite3MAX_PAGE_COUNT; - extern int sqlite3MAX_LIKE_PATTERN_LENGTH; -#endif - -#define _XOPEN_SOURCE 500 /* Needed to enable pthread recursive mutexes */ - -#if defined(SQLITE_TCL) || defined(TCLSH) -# include <tcl.h> -#endif - -/* -** Many people are failing to set -DNDEBUG=1 when compiling SQLite. -** Setting NDEBUG makes the code smaller and run faster. So the following -** lines are added to automatically set NDEBUG unless the -DSQLITE_DEBUG=1 -** option is set. Thus NDEBUG becomes an opt-in rather than an opt-out -** feature. -*/ -#if !defined(NDEBUG) && !defined(SQLITE_DEBUG) -# define NDEBUG 1 -#endif - -/* -** The SQLITE_THREADSAFE macro must be defined as either 0 or 1. -** Older versions of SQLite used an optional THREADSAFE macro. -** We support that for legacy -*/ -#if !defined(SQLITE_THREADSAFE) -#if defined(THREADSAFE) -# define SQLITE_THREADSAFE THREADSAFE -#else -# define SQLITE_THREADSAFE 1 -#endif -#endif - -/* -** These #defines should enable >2GB file support on Posix if the -** underlying operating system supports it. If the OS lacks -** large file support, or if the OS is windows, these should be no-ops. -** -** Large file support can be disabled using the -DSQLITE_DISABLE_LFS switch -** on the compiler command line. This is necessary if you are compiling -** on a recent machine (ex: RedHat 7.2) but you want your code to work -** on an older machine (ex: RedHat 6.0). If you compile on RedHat 7.2 -** without this option, LFS is enable. But LFS does not exist in the kernel -** in RedHat 6.0, so the code won't work. Hence, for maximum binary -** portability you should omit LFS. -** -** Similar is true for MacOS. LFS is only supported on MacOS 9 and later. -*/ -#ifndef SQLITE_DISABLE_LFS -# define _LARGE_FILE 1 -# ifndef _FILE_OFFSET_BITS -# define _FILE_OFFSET_BITS 64 -# endif -# define _LARGEFILE_SOURCE 1 -#endif - +/************** Continuing where we left off in sqliteInt.h ******************/ /************** Include hash.h in the middle of sqliteInt.h ******************/ /************** Begin file hash.h ********************************************/ /* ** 2001 September 22 ** @@ -4563,11 +4539,11 @@ ** ** This header defines the interface to the virtual database engine ** or VDBE. The VDBE implements an abstract machine that runs a ** simple program to access and modify the underlying database. ** -** $Id: vdbe.h,v 1.113 2007/08/30 01:19:59 drh Exp $ +** $Id: vdbe.h,v 1.115 2007/11/14 06:48:48 danielk1977 Exp $ */ #ifndef _SQLITE_VDBE_H_ #define _SQLITE_VDBE_H_ /* @@ -4619,10 +4595,12 @@ #define P3_VDBEFUNC (-7) /* P3 is a pointer to a VdbeFunc structure */ #define P3_MEM (-8) /* P3 is a pointer to a Mem* structure */ #define P3_TRANSIENT (-9) /* P3 is a pointer to a transient string */ #define P3_VTAB (-10) /* P3 is a pointer to an sqlite3_vtab structure */ #define P3_MPRINTF (-11) /* P3 is a string obtained from sqlite3_mprintf() */ +#define P3_REAL (-12) /* P3 is a 64-bit floating point value */ +#define P3_INT64 (-13) /* P3 is a 64-bit signed integer */ /* When adding a P3 argument using P3_KEYINFO, a copy of the KeyInfo structure ** is made. That copy is freed when the Vdbe is finalized. But if the ** argument is P3_KEYINFO_HANDOFF, the passed in pointer is used. It still ** gets freed when the Vdbe is finalized so it still should be obtained @@ -4656,167 +4634,167 @@ */ /************** Include opcodes.h in the middle of vdbe.h ********************/ /************** Begin file opcodes.h *****************************************/ /* Automatically generated. Do not edit */ /* See the mkopcodeh.awk script for details */ -#define OP_MemLoad 1 -#define OP_VNext 2 -#define OP_HexBlob 126 /* same as TK_BLOB */ -#define OP_Column 3 -#define OP_SetCookie 4 -#define OP_IfMemPos 5 -#define OP_Real 125 /* same as TK_FLOAT */ -#define OP_Sequence 6 -#define OP_MoveGt 7 -#define OP_Ge 72 /* same as TK_GE */ -#define OP_RowKey 8 -#define OP_Eq 68 /* same as TK_EQ */ -#define OP_OpenWrite 9 -#define OP_NotNull 66 /* same as TK_NOTNULL */ -#define OP_If 10 +#define OP_ReadCookie 1 +#define OP_AutoCommit 2 +#define OP_Found 3 +#define OP_NullRow 4 +#define OP_Lt 71 /* same as TK_LT */ +#define OP_MoveLe 5 +#define OP_Variable 6 +#define OP_Pull 7 +#define OP_RealAffinity 8 +#define OP_Sort 9 +#define OP_IfNot 10 +#define OP_Gosub 11 +#define OP_Add 78 /* same as TK_PLUS */ +#define OP_NotFound 12 +#define OP_IsNull 65 /* same as TK_ISNULL */ +#define OP_MoveLt 13 +#define OP_Rowid 14 +#define OP_CreateIndex 15 +#define OP_Push 17 +#define OP_Explain 18 +#define OP_Statement 19 +#define OP_Callback 20 +#define OP_MemLoad 21 +#define OP_DropIndex 22 +#define OP_Null 23 #define OP_ToInt 141 /* same as TK_TO_INT */ -#define OP_String8 88 /* same as TK_STRING */ -#define OP_Pop 11 -#define OP_VRowid 12 -#define OP_CollSeq 13 -#define OP_OpenRead 14 -#define OP_Expire 15 -#define OP_AutoCommit 17 -#define OP_Gt 69 /* same as TK_GT */ -#define OP_IntegrityCk 18 -#define OP_Sort 19 -#define OP_Function 20 -#define OP_And 61 /* same as TK_AND */ -#define OP_Subtract 79 /* same as TK_MINUS */ -#define OP_Noop 21 -#define OP_Return 22 -#define OP_Remainder 82 /* same as TK_REM */ -#define OP_NewRowid 23 +#define OP_Int64 24 +#define OP_LoadAnalysis 25 +#define OP_IdxInsert 26 +#define OP_VUpdate 27 +#define OP_Next 28 +#define OP_SetNumColumns 29 +#define OP_ToNumeric 140 /* same as TK_TO_NUMERIC*/ +#define OP_Ge 72 /* same as TK_GE */ +#define OP_BitNot 87 /* same as TK_BITNOT */ +#define OP_MemInt 30 +#define OP_Dup 31 +#define OP_Rewind 32 #define OP_Multiply 80 /* same as TK_STAR */ -#define OP_IfMemNeg 24 -#define OP_Variable 25 -#define OP_String 26 -#define OP_RealAffinity 27 -#define OP_VRename 28 -#define OP_ParseSchema 29 -#define OP_VOpen 30 -#define OP_Close 31 -#define OP_CreateIndex 32 -#define OP_IsUnique 33 -#define OP_NotFound 34 -#define OP_Int64 35 -#define OP_MustBeInt 36 -#define OP_Halt 37 -#define OP_Rowid 38 -#define OP_IdxLT 39 -#define OP_AddImm 40 -#define OP_Statement 41 -#define OP_RowData 42 -#define OP_MemMax 43 -#define OP_Push 44 -#define OP_Or 60 /* same as TK_OR */ -#define OP_NotExists 45 -#define OP_MemIncr 46 -#define OP_Gosub 47 -#define OP_Divide 81 /* same as TK_SLASH */ -#define OP_Integer 48 -#define OP_ToNumeric 140 /* same as TK_TO_NUMERIC*/ -#define OP_MemInt 49 -#define OP_Prev 50 -#define OP_Concat 83 /* same as TK_CONCAT */ +#define OP_ToReal 142 /* same as TK_TO_REAL */ +#define OP_Gt 69 /* same as TK_GT */ +#define OP_Last 33 +#define OP_MustBeInt 34 +#define OP_Ne 67 /* same as TK_NE */ +#define OP_MoveGe 35 +#define OP_IncrVacuum 36 +#define OP_String 37 +#define OP_VFilter 38 +#define OP_ForceInt 39 +#define OP_Close 40 +#define OP_AggFinal 41 +#define OP_AbsValue 42 +#define OP_RowData 43 +#define OP_IdxRowid 44 +#define OP_BitOr 75 /* same as TK_BITOR */ +#define OP_NotNull 66 /* same as TK_NOTNULL */ +#define OP_MoveGt 45 +#define OP_Not 16 /* same as TK_NOT */ +#define OP_OpenPseudo 46 +#define OP_Halt 47 +#define OP_MemMove 48 +#define OP_NewRowid 49 +#define OP_Real 125 /* same as TK_FLOAT */ +#define OP_IdxLT 50 +#define OP_Distinct 51 +#define OP_MemMax 52 +#define OP_Function 53 +#define OP_IntegrityCk 54 +#define OP_Remainder 82 /* same as TK_REM */ +#define OP_HexBlob 126 /* same as TK_BLOB */ +#define OP_ShiftLeft 76 /* same as TK_LSHIFT */ +#define OP_FifoWrite 55 #define OP_BitAnd 74 /* same as TK_BITAND */ -#define OP_VColumn 51 -#define OP_CreateTable 52 -#define OP_Last 53 -#define OP_IsNull 65 /* same as TK_ISNULL */ -#define OP_IncrVacuum 54 -#define OP_IdxRowid 55 -#define OP_MakeIdxRec 56 -#define OP_ShiftRight 77 /* same as TK_RSHIFT */ -#define OP_ResetCount 57 -#define OP_FifoWrite 58 -#define OP_Callback 59 -#define OP_ContextPush 62 -#define OP_DropTrigger 63 -#define OP_DropIndex 64 -#define OP_IdxGE 73 -#define OP_IdxDelete 84 -#define OP_Vacuum 86 -#define OP_MoveLe 89 -#define OP_IfNot 90 -#define OP_DropTable 91 -#define OP_MakeRecord 92 +#define OP_Or 60 /* same as TK_OR */ +#define OP_NotExists 56 +#define OP_VDestroy 57 +#define OP_MemStore 58 +#define OP_IdxDelete 59 +#define OP_Vacuum 62 +#define OP_If 63 +#define OP_Destroy 64 +#define OP_AggStep 73 +#define OP_Clear 84 +#define OP_Insert 86 +#define OP_VBegin 89 +#define OP_IdxGE 90 +#define OP_OpenEphemeral 91 +#define OP_Divide 81 /* same as TK_SLASH */ +#define OP_String8 88 /* same as TK_STRING */ +#define OP_IfMemZero 92 +#define OP_Concat 83 /* same as TK_CONCAT */ +#define OP_VRowid 93 +#define OP_MakeRecord 94 +#define OP_SetCookie 95 +#define OP_Prev 96 +#define OP_ContextPush 97 +#define OP_DropTrigger 98 +#define OP_IdxGT 99 +#define OP_MemNull 100 +#define OP_IfMemNeg 101 +#define OP_And 61 /* same as TK_AND */ +#define OP_VColumn 102 +#define OP_Return 103 +#define OP_OpenWrite 104 +#define OP_Integer 105 +#define OP_Transaction 106 +#define OP_CollSeq 107 +#define OP_VRename 108 #define OP_ToBlob 139 /* same as TK_TO_BLOB */ -#define OP_Delete 93 -#define OP_AggFinal 94 -#define OP_ShiftLeft 76 /* same as TK_LSHIFT */ -#define OP_Dup 95 -#define OP_Goto 96 -#define OP_TableLock 97 -#define OP_FifoRead 98 -#define OP_Clear 99 -#define OP_IdxGT 100 -#define OP_MoveLt 101 -#define OP_Le 70 /* same as TK_LE */ -#define OP_VerifyCookie 102 -#define OP_AggStep 103 -#define OP_Pull 104 +#define OP_Sequence 109 +#define OP_ContextPop 110 +#define OP_ShiftRight 77 /* same as TK_RSHIFT */ +#define OP_VCreate 111 +#define OP_CreateTable 112 +#define OP_AddImm 113 #define OP_ToText 138 /* same as TK_TO_TEXT */ -#define OP_Not 16 /* same as TK_NOT */ -#define OP_ToReal 142 /* same as TK_TO_REAL */ -#define OP_SetNumColumns 105 -#define OP_AbsValue 106 -#define OP_Transaction 107 -#define OP_VFilter 108 -#define OP_Negative 85 /* same as TK_UMINUS */ -#define OP_Ne 67 /* same as TK_NE */ -#define OP_VDestroy 109 -#define OP_ContextPop 110 -#define OP_BitOr 75 /* same as TK_BITOR */ -#define OP_Next 111 -#define OP_IdxInsert 112 -#define OP_Distinct 113 -#define OP_Lt 71 /* same as TK_LT */ -#define OP_Insert 114 -#define OP_Destroy 115 -#define OP_ReadCookie 116 -#define OP_ForceInt 117 -#define OP_LoadAnalysis 118 -#define OP_Explain 119 -#define OP_IfMemZero 120 -#define OP_OpenPseudo 121 -#define OP_OpenEphemeral 122 -#define OP_Null 123 +#define OP_DropTable 114 +#define OP_IsUnique 115 +#define OP_VOpen 116 +#define OP_Noop 117 +#define OP_RowKey 118 +#define OP_Expire 119 +#define OP_FifoRead 120 +#define OP_Delete 121 +#define OP_IfMemPos 122 +#define OP_Subtract 79 /* same as TK_MINUS */ +#define OP_MemIncr 123 #define OP_Blob 124 -#define OP_Add 78 /* same as TK_PLUS */ -#define OP_MemStore 127 -#define OP_Rewind 128 -#define OP_MoveGe 129 -#define OP_VBegin 130 -#define OP_VUpdate 131 -#define OP_BitNot 87 /* same as TK_BITNOT */ -#define OP_VCreate 132 -#define OP_MemMove 133 -#define OP_MemNull 134 -#define OP_Found 135 -#define OP_NullRow 136 +#define OP_MakeIdxRec 127 +#define OP_Goto 128 +#define OP_Negative 85 /* same as TK_UMINUS */ +#define OP_ParseSchema 129 +#define OP_Eq 68 /* same as TK_EQ */ +#define OP_VNext 130 +#define OP_Pop 131 +#define OP_Le 70 /* same as TK_LE */ +#define OP_TableLock 132 +#define OP_VerifyCookie 133 +#define OP_Column 134 +#define OP_OpenRead 135 +#define OP_ResetCount 136 /* The following opcode values are never used */ #define OP_NotUsed_137 137 /* Opcodes that are guaranteed to never push a value onto the stack ** contain a 1 their corresponding position of the following mask ** set. See the opcodeNoPush() function in vdbeaux.c */ -#define NOPUSH_MASK_0 0xeeb4 -#define NOPUSH_MASK_1 0xf96b -#define NOPUSH_MASK_2 0xfbb6 -#define NOPUSH_MASK_3 0xfe64 -#define NOPUSH_MASK_4 0xffff -#define NOPUSH_MASK_5 0x6ef7 -#define NOPUSH_MASK_6 0xfbfb -#define NOPUSH_MASK_7 0x8767 -#define NOPUSH_MASK_8 0x7d9f +#define NOPUSH_MASK_0 0x3fbc +#define NOPUSH_MASK_1 0x3e5b +#define NOPUSH_MASK_2 0xe3df +#define NOPUSH_MASK_3 0xff9c +#define NOPUSH_MASK_4 0xfffe +#define NOPUSH_MASK_5 0x9ef7 +#define NOPUSH_MASK_6 0xddaf +#define NOPUSH_MASK_7 0x0ebe +#define NOPUSH_MASK_8 0x7dbf #define NOPUSH_MASK_9 0x0000 /************** End of opcodes.h *********************************************/ /************** Continuing where we left off in vdbe.h ***********************/ @@ -4849,11 +4827,10 @@ SQLITE_PRIVATE void sqlite3VdbeSetNumCols(Vdbe*,int); SQLITE_PRIVATE int sqlite3VdbeSetColName(Vdbe*, int, int, const char *, int); SQLITE_PRIVATE void sqlite3VdbeCountChanges(Vdbe*); SQLITE_PRIVATE sqlite3 *sqlite3VdbeDb(Vdbe*); SQLITE_PRIVATE void sqlite3VdbeSetSql(Vdbe*, const char *z, int n); -SQLITE_PRIVATE const char *sqlite3VdbeGetSql(Vdbe*); SQLITE_PRIVATE void sqlite3VdbeSwap(Vdbe*,Vdbe*); #ifndef NDEBUG SQLITE_PRIVATE void sqlite3VdbeComment(Vdbe*, const char*, ...); # define VdbeComment(X) sqlite3VdbeComment X @@ -5136,10 +5113,11 @@ # define INCL_DOSFILEMGR # define INCL_DOSERRORS # define INCL_DOSMISC # define INCL_DOSPROCESS # define INCL_DOSMODULEMGR +# define INCL_DOSSEMAPHORES # include <os2.h> # define SQLITE_TEMPNAME_SIZE (CCHMAXPATHCOMP) #else # define SQLITE_TEMPNAME_SIZE 200 #endif @@ -5304,12 +5282,12 @@ ** Functions for accessing sqlite3_vfs methods */ SQLITE_PRIVATE int sqlite3OsOpen(sqlite3_vfs *, const char *, sqlite3_file*, int, int *); SQLITE_PRIVATE int sqlite3OsDelete(sqlite3_vfs *, const char *, int); SQLITE_PRIVATE int sqlite3OsAccess(sqlite3_vfs *, const char *, int); -SQLITE_PRIVATE int sqlite3OsGetTempName(sqlite3_vfs *, char *); -SQLITE_PRIVATE int sqlite3OsFullPathname(sqlite3_vfs *, const char *, char *); +SQLITE_PRIVATE int sqlite3OsGetTempname(sqlite3_vfs *, int, char *); +SQLITE_PRIVATE int sqlite3OsFullPathname(sqlite3_vfs *, const char *, int, char *); SQLITE_PRIVATE void *sqlite3OsDlOpen(sqlite3_vfs *, const char *); SQLITE_PRIVATE void sqlite3OsDlError(sqlite3_vfs *, int, char *); SQLITE_PRIVATE void *sqlite3OsDlSym(sqlite3_vfs *, void *, const char *); SQLITE_PRIVATE void sqlite3OsDlClose(sqlite3_vfs *, void *); SQLITE_PRIVATE int sqlite3OsRandomness(sqlite3_vfs *, int, char *); @@ -5825,11 +5803,11 @@ Module *pMod; /* Pointer to the implementation of the module */ sqlite3_vtab *pVtab; /* Pointer to the module instance */ int nModuleArg; /* Number of arguments to the module */ char **azModuleArg; /* Text of all module args. [0] is module name */ #endif - Schema *pSchema; + Schema *pSchema; /* Schema that contains this table */ }; /* ** Test to see whether or not a table is a virtual table. This is ** done as a macro so that it will be optimized out when virtual @@ -5883,11 +5861,11 @@ u8 deleteConf; /* How to resolve conflicts that occur on DELETE */ u8 insertConf; /* How to resolve conflicts that occur on INSERT */ }; /* -** SQLite supports many different ways to resolve a contraint +** SQLite supports many different ways to resolve a constraint ** error. ROLLBACK processing means that a constraint violation ** causes the operation in process to fail and for the current transaction ** to be rolled back. ABORT processing means the operation in process ** fails and any prior changes from that one operation are backed out, ** but the transaction is not rolled back. FAIL processing means that @@ -6104,11 +6082,11 @@ int iAgg; /* Which entry in pAggInfo->aCol[] or ->aFunc[] */ int iRightJoinTable; /* If EP_FromJoin, the right table of the join */ Select *pSelect; /* When the expression is a sub-select. Also the ** right side of "<expr> IN (<select>)" */ Table *pTab; /* Table for OP_Column expressions. */ - Schema *pSchema; +/* Schema *pSchema; */ #if defined(SQLITE_TEST) || SQLITE_MAX_EXPR_DEPTH>0 int nHeight; /* Height of the tree headed by this node */ #endif }; @@ -6715,11 +6693,11 @@ SQLITE_PRIVATE void sqlite3AddNotNull(Parse*, int); SQLITE_PRIVATE void sqlite3AddPrimaryKey(Parse*, ExprList*, int, int, int); SQLITE_PRIVATE void sqlite3AddCheckConstraint(Parse*, Expr*); SQLITE_PRIVATE void sqlite3AddColumnType(Parse*,Token*); SQLITE_PRIVATE void sqlite3AddDefaultValue(Parse*,Expr*); -SQLITE_PRIVATE void sqlite3AddCollateType(Parse*, const char*, int); +SQLITE_PRIVATE void sqlite3AddCollateType(Parse*, Token*); SQLITE_PRIVATE void sqlite3EndTable(Parse*,Token*,Token*,Select*); SQLITE_PRIVATE void sqlite3CreateView(Parse*,Token*,Token*,Token*,Select*,int,int); #if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_VIRTUALTABLE) @@ -6835,16 +6813,16 @@ SQLITE_PRIVATE int sqlite3JoinType(Parse*, Token*, Token*, Token*); SQLITE_PRIVATE void sqlite3CreateForeignKey(Parse*, ExprList*, Token*, ExprList*, int); SQLITE_PRIVATE void sqlite3DeferForeignKey(Parse*, int); #ifndef SQLITE_OMIT_AUTHORIZATION -SQLITE_PRIVATE void sqlite3AuthRead(Parse*,Expr*,SrcList*); +SQLITE_PRIVATE void sqlite3AuthRead(Parse*,Expr*,Schema*,SrcList*); SQLITE_PRIVATE int sqlite3AuthCheck(Parse*,int, const char*, const char*, const char*); SQLITE_PRIVATE void sqlite3AuthContextPush(Parse*, AuthContext*, const char*); SQLITE_PRIVATE void sqlite3AuthContextPop(AuthContext*); #else -# define sqlite3AuthRead(a,b,c) +# define sqlite3AuthRead(a,b,c,d) # define sqlite3AuthCheck(a,b,c,d,e) SQLITE_OK # define sqlite3AuthContextPush(a,b,c) # define sqlite3AuthContextPop(a) ((void)(a)) #endif SQLITE_PRIVATE void sqlite3Attach(Parse*, Expr*, Expr*, Expr*); @@ -6858,11 +6836,11 @@ SQLITE_PRIVATE int sqlite3FixExprList(DbFixer*, ExprList*); SQLITE_PRIVATE int sqlite3FixTriggerStep(DbFixer*, TriggerStep*); SQLITE_PRIVATE int sqlite3AtoF(const char *z, double*); SQLITE_API char *sqlite3_snprintf(int,char*,const char*,...); SQLITE_PRIVATE int sqlite3GetInt32(const char *, int*); -SQLITE_PRIVATE int sqlite3FitsIn64Bits(const char *); +SQLITE_PRIVATE int sqlite3FitsIn64Bits(const char *, int); SQLITE_PRIVATE int sqlite3Utf16ByteLen(const void *pData, int nChar); SQLITE_PRIVATE int sqlite3Utf8CharLen(const char *pData, int nByte); SQLITE_PRIVATE int sqlite3Utf8Read(const u8*, const u8*, const u8**); SQLITE_PRIVATE int sqlite3PutVarint(unsigned char *, u64); SQLITE_PRIVATE int sqlite3GetVarint(const unsigned char *, u64 *); @@ -6966,14 +6944,18 @@ */ #ifdef SQLITE_MEMDEBUG SQLITE_PRIVATE void sqlite3MallocDisallow(void); SQLITE_PRIVATE void sqlite3MallocAllow(void); SQLITE_PRIVATE void sqlite3MallocBenignFailure(int); +SQLITE_PRIVATE void sqlite3MallocEnterBenignBlock(int isBenign); +SQLITE_PRIVATE void sqlite3MallocLeaveBenignBlock(); #else # define sqlite3MallocDisallow() # define sqlite3MallocAllow() # define sqlite3MallocBenignFailure(x) +# define sqlite3MallocEnterBenignBlock(x); +# define sqlite3MallocLeaveBenignBlock(); #endif #ifdef SQLITE_OMIT_VIRTUALTABLE # define sqlite3VtabClear(X) @@ -7043,11 +7025,58 @@ SQLITE_EXTERN void (*sqlite3_io_trace)(const char*,...); #endif /************** End of sqliteInt.h *******************************************/ -/************** Continuing where we left off in date.c ***********************/ +/************** Begin file date.c ********************************************/ +/* +** 2003 October 31 +** +** 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 contains the C functions that implement date and time +** functions for SQLite. +** +** There is only one exported symbol in this file - the function +** sqlite3RegisterDateTimeFunctions() found at the bottom of the file. +** All other code has file scope. +** +** $Id: date.c,v 1.73 2007/09/12 17:01:45 danielk1977 Exp $ +** +** SQLite processes all times and dates as Julian Day numbers. The +** dates and times are stored as the number of days since noon +** in Greenwich on November 24, 4714 B.C. according to the Gregorian +** calendar system. +** +** 1970-01-01 00:00:00 is JD 2440587.5 +** 2000-01-01 00:00:00 is JD 2451544.5 +** +** This implemention requires years to be expressed as a 4-digit number +** which means that only dates between 0000-01-01 and 9999-12-31 can +** be represented, even though julian day numbers allow a much wider +** range of dates. +** +** The Gregorian calendar system is used for all dates and times, +** even those that predate the Gregorian calendar. Historians usually +** use the Julian calendar for dates prior to 1582-10-15 and for some +** dates afterwards, depending on locale. Beware of this difference. +** +** The conversion algorithms are implemented based on descriptions +** in the following text: +** +** Jean Meeus +** Astronomical Algorithms, 2nd Edition, 1998 +** ISBM 0-943396-61-1 +** Willmann-Bell, Inc +** Richmond, Virginia (USA) +*/ #include <ctype.h> #include <time.h> #ifndef SQLITE_OMIT_DATETIME_FUNCS @@ -8061,10 +8090,37 @@ */ #define _SQLITE_OS_C_ 1 #undef _SQLITE_OS_C_ /* +** The default SQLite sqlite3_vfs implementations do not allocate +** memory (actually, os_unix.c allocates a small amount of memory +** from within OsOpen()), but some third-party implementations may. +** So we test the effects of a malloc() failing and the sqlite3OsXXX() +** function returning SQLITE_IOERR_NOMEM using the DO_OS_MALLOC_TEST macro. +** +** The following functions are instrumented for malloc() failure +** testing: +** +** sqlite3OsOpen() +** sqlite3OsRead() +** sqlite3OsWrite() +** sqlite3OsSync() +** sqlite3OsLock() +** +*/ +#ifdef SQLITE_TEST + #define DO_OS_MALLOC_TEST if (1) { \ + void *pTstAlloc = sqlite3_malloc(10); \ + if (!pTstAlloc) return SQLITE_IOERR_NOMEM; \ + sqlite3_free(pTstAlloc); \ + } +#else + #define DO_OS_MALLOC_TEST +#endif + +/* ** The following routines are convenience wrappers around methods ** of the sqlite3_file object. This is mostly just syntactic sugar. All ** of this would be completely automatic if SQLite were coded using ** C++ instead of plain old C. */ @@ -8075,25 +8131,29 @@ pId->pMethods = 0; } return rc; } SQLITE_PRIVATE int sqlite3OsRead(sqlite3_file *id, void *pBuf, int amt, i64 offset){ + DO_OS_MALLOC_TEST; return id->pMethods->xRead(id, pBuf, amt, offset); } SQLITE_PRIVATE int sqlite3OsWrite(sqlite3_file *id, const void *pBuf, int amt, i64 offset){ + DO_OS_MALLOC_TEST; return id->pMethods->xWrite(id, pBuf, amt, offset); } SQLITE_PRIVATE int sqlite3OsTruncate(sqlite3_file *id, i64 size){ return id->pMethods->xTruncate(id, size); } SQLITE_PRIVATE int sqlite3OsSync(sqlite3_file *id, int flags){ + DO_OS_MALLOC_TEST; return id->pMethods->xSync(id, flags); } SQLITE_PRIVATE int sqlite3OsFileSize(sqlite3_file *id, i64 *pSize){ return id->pMethods->xFileSize(id, pSize); } SQLITE_PRIVATE int sqlite3OsLock(sqlite3_file *id, int lockType){ + DO_OS_MALLOC_TEST; return id->pMethods->xLock(id, lockType); } SQLITE_PRIVATE int sqlite3OsUnlock(sqlite3_file *id, int lockType){ return id->pMethods->xUnlock(id, lockType); } @@ -8142,23 +8202,29 @@ const char *zPath, sqlite3_file *pFile, int flags, int *pFlagsOut ){ + DO_OS_MALLOC_TEST; return pVfs->xOpen(pVfs, zPath, pFile, flags, pFlagsOut); } SQLITE_PRIVATE int sqlite3OsDelete(sqlite3_vfs *pVfs, const char *zPath, int dirSync){ return pVfs->xDelete(pVfs, zPath, dirSync); } SQLITE_PRIVATE int sqlite3OsAccess(sqlite3_vfs *pVfs, const char *zPath, int flags){ return pVfs->xAccess(pVfs, zPath, flags); } -SQLITE_PRIVATE int sqlite3OsGetTempName(sqlite3_vfs *pVfs, char *zBufOut){ - return pVfs->xGetTempName(pVfs, zBufOut); -} -SQLITE_PRIVATE int sqlite3OsFullPathname(sqlite3_vfs *pVfs, const char *zPath, char *zPathOut){ - return pVfs->xFullPathname(pVfs, zPath, zPathOut); +SQLITE_PRIVATE int sqlite3OsGetTempname(sqlite3_vfs *pVfs, int nBufOut, char *zBufOut){ + return pVfs->xGetTempname(pVfs, nBufOut, zBufOut); +} +SQLITE_PRIVATE int sqlite3OsFullPathname( + sqlite3_vfs *pVfs, + const char *zPath, + int nPathOut, + char *zPathOut +){ + return pVfs->xFullPathname(pVfs, zPath, nPathOut, zPathOut); } SQLITE_PRIVATE void *sqlite3OsDlOpen(sqlite3_vfs *pVfs, const char *zPath){ return pVfs->xDlOpen(pVfs, zPath); } SQLITE_PRIVATE void sqlite3OsDlError(sqlite3_vfs *pVfs, int nByte, char *zBufOut){ @@ -8220,11 +8286,11 @@ ** Locate a VFS by name. If no name is given, simply return the ** first VFS on the list. */ SQLITE_API sqlite3_vfs *sqlite3_vfs_find(const char *zVfs){ sqlite3_mutex *mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER); - sqlite3_vfs *pVfs; + sqlite3_vfs *pVfs = 0; static int isInit = 0; sqlite3_mutex_enter(mutex); if( !isInit ){ vfsList = sqlite3OsDefaultVfs(); isInit = 1; @@ -8240,13 +8306,15 @@ /* ** Unlink a VFS from the linked list */ static void vfsUnlink(sqlite3_vfs *pVfs){ assert( sqlite3_mutex_held(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER)) ); - if( vfsList==pVfs ){ + if( pVfs==0 ){ + /* No-op */ + }else if( vfsList==pVfs ){ vfsList = pVfs->pNext; - }else{ + }else if( vfsList ){ sqlite3_vfs *p = vfsList; while( p->pNext && p->pNext!=pVfs ){ p = p->pNext; } if( p->pNext==pVfs ){ @@ -8282,11 +8350,10 @@ */ SQLITE_API int sqlite3_vfs_unregister(sqlite3_vfs *pVfs){ sqlite3_mutex *mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER); sqlite3_mutex_enter(mutex); vfsUnlink(pVfs); - assert(vfsList); sqlite3_mutex_leave(mutex); return SQLITE_OK; } /************** End of os.c **************************************************/ @@ -8303,19 +8370,19 @@ ** ************************************************************************* ** This file contains the C functions that implement a memory ** allocation subsystem for use by SQLite. ** -** $Id: mem1.c,v 1.10 2007/09/02 17:50:35 drh Exp $ +** $Id: mem1.c,v 1.13 2007/11/05 17:54:17 drh Exp $ */ /* ** This version of the memory allocator is the default. It is ** used when no other memory allocator is specified using compile-time ** macros. */ -#if !defined(SQLITE_MEMDEBUG) && !defined(SQLITE_OMIT_MEMORY_ALLOCATION) +#if !defined(SQLITE_MEMDEBUG) && !defined(SQLITE_MEMORY_SIZE) /* ** We will eventually construct multiple memory allocation subsystems ** suitable for use in various contexts: ** @@ -8502,10 +8569,12 @@ sqlite3MemsysAlarm(nBytes-nOld); } p = realloc(p, nBytes+8); if( p==0 ){ sqlite3MemsysAlarm(nBytes); + p = pPrior; + p--; p = realloc(p, nBytes+8); } if( p ){ p[0] = nBytes; p++; @@ -8534,19 +8603,19 @@ ** ************************************************************************* ** This file contains the C functions that implement a memory ** allocation subsystem for use by SQLite. ** -** $Id: mem2.c,v 1.13 2007/09/01 09:02:54 danielk1977 Exp $ +** $Id: mem2.c,v 1.17 2007/11/05 17:54:17 drh Exp $ */ /* ** This version of the memory allocator is used only if the ** SQLITE_MEMDEBUG macro is defined and SQLITE_OMIT_MEMORY_ALLOCATION ** is not defined. */ -#if defined(SQLITE_MEMDEBUG) && !defined(SQLITE_OMIT_MEMORY_ALLOCATION) +#if defined(SQLITE_MEMDEBUG) && !defined(SQLITE_MEMORY_SIZE) /* ** We will eventually construct multiple memory allocation subsystems ** suitable for use in various contexts: ** @@ -8605,10 +8674,15 @@ */ #define FOREGUARD 0x80F5E153 #define REARGUARD 0xE4676B53 /* +** Number of malloc size increments to track. +*/ +#define NCSIZE 1000 + +/* ** All of the static variables used by this module are collected ** into a single structure named "mem". This is to keep the ** static variables organized and to reduce namespace pollution ** when this module is combined with other in the amalgamation. */ @@ -8661,17 +8735,25 @@ int iFail; /* Decrement and fail malloc when this is 1 */ int iReset; /* When malloc fails set iiFail to this value */ int iFailCnt; /* Number of failures */ int iBenignFailCnt; /* Number of benign failures */ int iNextIsBenign; /* True if the next call to malloc may fail benignly */ + int iIsBenign; /* All malloc calls may fail benignly */ /* ** sqlite3MallocDisallow() increments the following counter. ** sqlite3MallocAllow() decrements it. */ int disallow; /* Do not allow memory allocation */ + /* + ** Gather statistics on the sizes of memory allocations. + ** sizeCnt[i] is the number of allocation attempts of i*8 + ** bytes. i==NCSIZE is the number of allocation attempts for + ** sizes more than NCSIZE*8 bytes. + */ + int sizeCnt[NCSIZE]; } mem; /* @@ -8791,10 +8873,15 @@ assert( mem.disallow==0 ); if( mem.alarmCallback!=0 && mem.nowUsed+nByte>=mem.alarmThreshold ){ sqlite3MemsysAlarm(nByte); } nByte = (nByte+3)&~3; + if( nByte/8>NCSIZE-1 ){ + mem.sizeCnt[NCSIZE-1]++; + }else{ + mem.sizeCnt[nByte/8]++; + } totalSize = nByte + sizeof(*pHdr) + sizeof(int) + mem.nBacktrace*sizeof(void*) + mem.nTitle; if( mem.iFail>0 ){ if( mem.iFail==1 ){ p = 0; @@ -8801,11 +8888,11 @@ mem.iFail = mem.iReset; if( mem.iFailCnt==0 ){ sqlite3MemsysFailed(); /* A place to set a breakpoint */ } mem.iFailCnt++; - if( mem.iNextIsBenign ){ + if( mem.iNextIsBenign || mem.iIsBenign ){ mem.iBenignFailCnt++; } }else{ p = malloc(totalSize); mem.iFail--; @@ -8959,10 +9046,11 @@ */ SQLITE_API void sqlite3_memdebug_dump(const char *zFilename){ FILE *out; struct MemBlockHdr *pHdr; void **pBt; + int i; out = fopen(zFilename, "w"); if( out==0 ){ fprintf(stderr, "** Unable to output memory debug output log: %s **\n", zFilename); return; @@ -8977,10 +9065,19 @@ pBt = (void**)pHdr; pBt -= pHdr->nBacktraceSlots; backtrace_symbols_fd(pBt, pHdr->nBacktrace, fileno(out)); fprintf(out, "\n"); } + } + fprintf(out, "COUNTS:\n"); + for(i=0; i<NCSIZE-1; i++){ + if( mem.sizeCnt[i] ){ + fprintf(out, " %3d: %d\n", i*8+8, mem.sizeCnt[i]); + } + } + if( mem.sizeCnt[NCSIZE-1] ){ + fprintf(out, " >%3d: %d\n", NCSIZE*8, mem.sizeCnt[NCSIZE-1]); } fclose(out); } /* @@ -9014,14 +9111,36 @@ SQLITE_API int sqlite3_memdebug_pending(){ return (mem.iFail-1); } +/* +** The following three functions are used to indicate to the test +** infrastructure which malloc() calls may fail benignly without +** affecting functionality. This can happen when resizing hash tables +** (failing to resize a hash-table is a performance hit, but not an +** error) or sometimes during a rollback operation. +** +** If the argument is true, sqlite3MallocBenignFailure() indicates that the +** next call to allocate memory may fail benignly. +** +** If sqlite3MallocEnterBenignBlock() is called with a non-zero argument, +** then all memory allocations requested before the next call to +** sqlite3MallocLeaveBenignBlock() may fail benignly. +*/ SQLITE_PRIVATE void sqlite3MallocBenignFailure(int isBenign){ if( isBenign ){ mem.iNextIsBenign = 1; } +} +SQLITE_PRIVATE void sqlite3MallocEnterBenignBlock(int isBenign){ + if( isBenign ){ + mem.iIsBenign = 1; + } +} +SQLITE_PRIVATE void sqlite3MallocLeaveBenignBlock(){ + mem.iIsBenign = 0; } /* ** The following two routines are used to assert that no memory ** allocations occur between one call and the next. The use of @@ -9043,10 +9162,631 @@ } #endif /* SQLITE_MEMDEBUG && !SQLITE_OMIT_MEMORY_ALLOCATION */ /************** End of mem2.c ************************************************/ +/************** Begin file mem3.c ********************************************/ +/* +** 2007 October 14 +** +** 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 contains the C functions that implement a memory +** allocation subsystem for use by SQLite. +** +** This version of the memory allocation subsystem omits all +** use of malloc(). All dynamically allocatable memory is +** contained in a static array, mem.aPool[]. The size of this +** fixed memory pool is SQLITE_MEMORY_SIZE bytes. +** +** This version of the memory allocation subsystem is used if +** and only if SQLITE_MEMORY_SIZE is defined. +** +** $Id: mem3.c,v 1.6 2007/11/07 15:13:25 drh Exp $ +*/ + +/* +** This version of the memory allocator is used only when +** SQLITE_MEMORY_SIZE is defined. +*/ +#if defined(SQLITE_MEMORY_SIZE) + +/* +** Maximum size (in Mem3Blocks) of a "small" chunk. +*/ +#define MX_SMALL 10 + + +/* +** Number of freelist hash slots +*/ +#define N_HASH 61 + +/* +** A memory allocation (also called a "chunk") consists of two or +** more blocks where each block is 8 bytes. The first 8 bytes are +** a header that is not returned to the user. +** +** A chunk is two or more blocks that is either checked out or +** free. The first block has format u.hdr. u.hdr.size is the +** size of the allocation in blocks if the allocation is free. +** If the allocation is checked out, u.hdr.size is the negative +** of the size. Similarly, u.hdr.prevSize is the size of the +** immediately previous allocation. +** +** We often identify a chunk by its index in mem.aPool[]. When +** this is done, the chunk index refers to the second block of +** the chunk. In this way, the first chunk has an index of 1. +** A chunk index of 0 means "no such chunk" and is the equivalent +** of a NULL pointer. +** +** The second block of free chunks is of the form u.list. The +** two fields form a double-linked list of chunks of related sizes. +** Pointers to the head of the list are stored in mem.aiSmall[] +** for smaller chunks and mem.aiHash[] for larger chunks. +** +** The second block of a chunk is user data if the chunk is checked +** out. +*/ +typedef struct Mem3Block Mem3Block; +struct Mem3Block { + union { + struct { + int prevSize; /* Size of previous chunk in Mem3Block elements */ + int size; /* Size of current chunk in Mem3Block elements */ + } hdr; + struct { + int next; /* Index in mem.aPool[] of next free chunk */ + int prev; /* Index in mem.aPool[] of previous free chunk */ + } list; + } u; +}; + +/* +** All of the static variables used by this module are collected +** into a single structure named "mem". This is to keep the +** static variables organized and to reduce namespace pollution +** when this module is combined with other in the amalgamation. +*/ +static struct { + /* + ** True if we are evaluating an out-of-memory callback. + */ + int alarmBusy; + + /* + ** Mutex to control access to the memory allocation subsystem. + */ + sqlite3_mutex *mutex; + + /* + ** The minimum amount of free space that we have seen. + */ + int mnMaster; + + /* + ** iMaster is the index of the master chunk. Most new allocations + ** occur off of this chunk. szMaster is the size (in Mem3Blocks) + ** of the current master. iMaster is 0 if there is not master chunk. + ** The master chunk is not in either the aiHash[] or aiSmall[]. + */ + int iMaster; + int szMaster; + + /* + ** Array of lists of free blocks according to the block size + ** for smaller chunks, or a hash on the block size for larger + ** chunks. + */ + int aiSmall[MX_SMALL-1]; /* For sizes 2 through MX_SMALL, inclusive */ + int aiHash[N_HASH]; /* For sizes MX_SMALL+1 and larger */ + + /* + ** Memory available for allocation + */ + Mem3Block aPool[SQLITE_MEMORY_SIZE/sizeof(Mem3Block)+2]; +} mem; + +/* +** Unlink the chunk at mem.aPool[i] from list it is currently +** on. *pRoot is the list that i is a member of. +*/ +static void memsys3UnlinkFromList(int i, int *pRoot){ + int next = mem.aPool[i].u.list.next; + int prev = mem.aPool[i].u.list.prev; + assert( sqlite3_mutex_held(mem.mutex) ); + if( prev==0 ){ + *pRoot = next; + }else{ + mem.aPool[prev].u.list.next = next; + } + if( next ){ + mem.aPool[next].u.list.prev = prev; + } + mem.aPool[i].u.list.next = 0; + mem.aPool[i].u.list.prev = 0; +} + +/* +** Unlink the chunk at index i from +** whatever list is currently a member of. +*/ +static void memsys3Unlink(int i){ + int size, hash; + assert( sqlite3_mutex_held(mem.mutex) ); + size = mem.aPool[i-1].u.hdr.size; + assert( size==mem.aPool[i+size-1].u.hdr.prevSize ); + assert( size>=2 ); + if( size <= MX_SMALL ){ + memsys3UnlinkFromList(i, &mem.aiSmall[size-2]); + }else{ + hash = size % N_HASH; + memsys3UnlinkFromList(i, &mem.aiHash[hash]); + } +} + +/* +** Link the chunk at mem.aPool[i] so that is on the list rooted +** at *pRoot. +*/ +static void memsys3LinkIntoList(int i, int *pRoot){ + assert( sqlite3_mutex_held(mem.mutex) ); + mem.aPool[i].u.list.next = *pRoot; + mem.aPool[i].u.list.prev = 0; + if( *pRoot ){ + mem.aPool[*pRoot].u.list.prev = i; + } + *pRoot = i; +} + +/* +** Link the chunk at index i into either the appropriate +** small chunk list, or into the large chunk hash table. +*/ +static void memsys3Link(int i){ + int size, hash; + assert( sqlite3_mutex_held(mem.mutex) ); + size = mem.aPool[i-1].u.hdr.size; + assert( size==mem.aPool[i+size-1].u.hdr.prevSize ); + assert( size>=2 ); + if( size <= MX_SMALL ){ + memsys3LinkIntoList(i, &mem.aiSmall[size-2]); + }else{ + hash = size % N_HASH; + memsys3LinkIntoList(i, &mem.aiHash[hash]); + } +} + +/* +** Enter the mutex mem.mutex. Allocate it if it is not already allocated. +** +** Also: Initialize the memory allocation subsystem the first time +** this routine is called. +*/ +static void memsys3Enter(void){ + if( mem.mutex==0 ){ + mem.mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MEM); + mem.aPool[0].u.hdr.size = SQLITE_MEMORY_SIZE/8; + mem.aPool[SQLITE_MEMORY_SIZE/8].u.hdr.prevSize = SQLITE_MEMORY_SIZE/8; + mem.iMaster = 1; + mem.szMaster = SQLITE_MEMORY_SIZE/8; + mem.mnMaster = mem.szMaster; + } + sqlite3_mutex_enter(mem.mutex); +} + +/* +** Return the amount of memory currently checked out. +*/ +SQLITE_API sqlite3_int64 sqlite3_memory_used(void){ + sqlite3_int64 n; + memsys3Enter(); + n = SQLITE_MEMORY_SIZE - mem.szMaster*8; + sqlite3_mutex_leave(mem.mutex); + return n; +} + +/* +** Return the maximum amount of memory that has ever been +** checked out since either the beginning of this process +** or since the most recent reset. +*/ +SQLITE_API sqlite3_int64 sqlite3_memory_highwater(int resetFlag){ + sqlite3_int64 n; + memsys3Enter(); + n = SQLITE_MEMORY_SIZE - mem.mnMaster*8; + if( resetFlag ){ + mem.mnMaster = mem.szMaster; + } + sqlite3_mutex_leave(mem.mutex); + return n; +} + +/* +** Change the alarm callback. +** +** This is a no-op for the static memory allocator. The purpose +** of the memory alarm is to support sqlite3_soft_heap_limit(). +** But with this memory allocator, the soft_heap_limit is really +** a hard limit that is fixed at SQLITE_MEMORY_SIZE. +*/ +SQLITE_API int sqlite3_memory_alarm( + void(*xCallback)(void *pArg, sqlite3_int64 used,int N), + void *pArg, + sqlite3_int64 iThreshold +){ + return SQLITE_OK; +} + +/* +** Called when we are unable to satisfy an allocation of nBytes. +*/ +static void memsys3OutOfMemory(int nByte){ + if( !mem.alarmBusy ){ + mem.alarmBusy = 1; + assert( sqlite3_mutex_held(mem.mutex) ); + sqlite3_mutex_leave(mem.mutex); + sqlite3_release_memory(nByte); + sqlite3_mutex_enter(mem.mutex); + mem.alarmBusy = 0; + } +} + +/* +** Return the size of an outstanding allocation, in bytes. The +** size returned omits the 8-byte header overhead. This only +** works for chunks that are currently checked out. +*/ +static int memsys3Size(void *p){ + Mem3Block *pBlock = (Mem3Block*)p; + assert( pBlock[-1].u.hdr.size<0 ); + return (-1-pBlock[-1].u.hdr.size)*8; +} + +/* +** Chunk i is a free chunk that has been unlinked. Adjust its +** size parameters for check-out and return a pointer to the +** user portion of the chunk. +*/ +static void *memsys3Checkout(int i, int nBlock){ + assert( sqlite3_mutex_held(mem.mutex) ); + assert( mem.aPool[i-1].u.hdr.size==nBlock ); + assert( mem.aPool[i+nBlock-1].u.hdr.prevSize==nBlock ); + mem.aPool[i-1].u.hdr.size = -nBlock; + mem.aPool[i+nBlock-1].u.hdr.prevSize = -nBlock; + return &mem.aPool[i]; +} + +/* +** Carve a piece off of the end of the mem.iMaster free chunk. +** Return a pointer to the new allocation. Or, if the master chunk +** is not large enough, return 0. +*/ +static void *memsys3FromMaster(int nBlock){ + assert( sqlite3_mutex_held(mem.mutex) ); + assert( mem.szMaster>=nBlock ); + if( nBlock>=mem.szMaster-1 ){ + /* Use the entire master */ + void *p = memsys3Checkout(mem.iMaster, mem.szMaster); + mem.iMaster = 0; + mem.szMaster = 0; + mem.mnMaster = 0; + return p; + }else{ + /* Split the master block. Return the tail. */ + int newi; + newi = mem.iMaster + mem.szMaster - nBlock; + assert( newi > mem.iMaster+1 ); + mem.aPool[mem.iMaster+mem.szMaster-1].u.hdr.prevSize = -nBlock; + mem.aPool[newi-1].u.hdr.size = -nBlock; + mem.szMaster -= nBlock; + mem.aPool[newi-1].u.hdr.prevSize = mem.szMaster; + mem.aPool[mem.iMaster-1].u.hdr.size = mem.szMaster; + if( mem.szMaster < mem.mnMaster ){ + mem.mnMaster = mem.szMaster; + } + return (void*)&mem.aPool[newi]; + } +} + +/* +** *pRoot is the head of a list of free chunks of the same size +** or same size hash. In other words, *pRoot is an entry in either +** mem.aiSmall[] or mem.aiHash[]. +** +** This routine examines all entries on the given list and tries +** to coalesce each entries with adjacent free chunks. +** +** If it sees a chunk that is larger than mem.iMaster, it replaces +** the current mem.iMaster with the new larger chunk. In order for +** this mem.iMaster replacement to work, the master chunk must be +** linked into the hash tables. That is not the normal state of +** affairs, of course. The calling routine must link the master +** chunk before invoking this routine, then must unlink the (possibly +** changed) master chunk once this routine has finished. +*/ +static void memsys3Merge(int *pRoot){ + int iNext, prev, size, i; + + assert( sqlite3_mutex_held(mem.mutex) ); + for(i=*pRoot; i>0; i=iNext){ + iNext = mem.aPool[i].u.list.next; + size = mem.aPool[i-1].u.hdr.size; + assert( size>0 ); + if( mem.aPool[i-1].u.hdr.prevSize>0 ){ + memsys3UnlinkFromList(i, pRoot); + prev = i - mem.aPool[i-1].u.hdr.prevSize; + assert( prev>=0 ); + if( prev==iNext ){ + iNext = mem.aPool[prev].u.list.next; + } + memsys3Unlink(prev); + size = i + size - prev; + mem.aPool[prev-1].u.hdr.size = size; + mem.aPool[prev+size-1].u.hdr.prevSize = size; + memsys3Link(prev); + i = prev; + } + if( size>mem.szMaster ){ + mem.iMaster = i; + mem.szMaster = size; + } + } +} + +/* +** Return a block of memory of at least nBytes in size. +** Return NULL if unable. +*/ +static void *memsys3Malloc(int nByte){ + int i; + int nBlock; + int toFree; + + assert( sqlite3_mutex_held(mem.mutex) ); + assert( sizeof(Mem3Block)==8 ); + if( nByte<=0 ){ + nBlock = 2; + }else{ + nBlock = (nByte + 15)/8; + } + assert( nBlock >= 2 ); + + /* STEP 1: + ** Look for an entry of the correct size in either the small + ** chunk table or in the large chunk hash table. This is + ** successful most of the time (about 9 times out of 10). + */ + if( nBlock <= MX_SMALL ){ + i = mem.aiSmall[nBlock-2]; + if( i>0 ){ + memsys3UnlinkFromList(i, &mem.aiSmall[nBlock-2]); + return memsys3Checkout(i, nBlock); + } + }else{ + int hash = nBlock % N_HASH; + for(i=mem.aiHash[hash]; i>0; i=mem.aPool[i].u.list.next){ + if( mem.aPool[i-1].u.hdr.size==nBlock ){ + memsys3UnlinkFromList(i, &mem.aiHash[hash]); + return memsys3Checkout(i, nBlock); + } + } + } + + /* STEP 2: + ** Try to satisfy the allocation by carving a piece off of the end + ** of the master chunk. This step usually works if step 1 fails. + */ + if( mem.szMaster>=nBlock ){ + return memsys3FromMaster(nBlock); + } + + + /* STEP 3: + ** Loop through the entire memory pool. Coalesce adjacent free + ** chunks. Recompute the master chunk as the largest free chunk. + ** Then try again to satisfy the allocation by carving a piece off + ** of the end of the master chunk. This step happens very + ** rarely (we hope!) + */ + for(toFree=nBlock*16; toFree<SQLITE_MEMORY_SIZE*2; toFree *= 2){ + memsys3OutOfMemory(toFree); + if( mem.iMaster ){ + memsys3Link(mem.iMaster); + mem.iMaster = 0; + mem.szMaster = 0; + } + for(i=0; i<N_HASH; i++){ + memsys3Merge(&mem.aiHash[i]); + } + for(i=0; i<MX_SMALL-1; i++){ + memsys3Merge(&mem.aiSmall[i]); + } + if( mem.szMaster ){ + memsys3Unlink(mem.iMaster); + if( mem.szMaster>=nBlock ){ + return memsys3FromMaster(nBlock); + } + } + } + + /* If none of the above worked, then we fail. */ + return 0; +} + +/* +** Free an outstanding memory allocation. +*/ +void memsys3Free(void *pOld){ + Mem3Block *p = (Mem3Block*)pOld; + int i; + int size; + assert( sqlite3_mutex_held(mem.mutex) ); + assert( p>mem.aPool && p<&mem.aPool[SQLITE_MEMORY_SIZE/8] ); + i = p - mem.aPool; + size = -mem.aPool[i-1].u.hdr.size; + assert( size>=2 ); + assert( mem.aPool[i+size-1].u.hdr.prevSize==-size ); + mem.aPool[i-1].u.hdr.size = size; + mem.aPool[i+size-1].u.hdr.prevSize = size; + memsys3Link(i); + + /* Try to expand the master using the newly freed chunk */ + if( mem.iMaster ){ + while( mem.aPool[mem.iMaster-1].u.hdr.prevSize>0 ){ + size = mem.aPool[mem.iMaster-1].u.hdr.prevSize; + mem.iMaster -= size; + mem.szMaster += size; + memsys3Unlink(mem.iMaster); + mem.aPool[mem.iMaster-1].u.hdr.size = mem.szMaster; + mem.aPool[mem.iMaster+mem.szMaster-1].u.hdr.prevSize = mem.szMaster; + } + while( mem.aPool[mem.iMaster+mem.szMaster-1].u.hdr.size>0 ){ + memsys3Unlink(mem.iMaster+mem.szMaster); + mem.szMaster += mem.aPool[mem.iMaster+mem.szMaster-1].u.hdr.size; + mem.aPool[mem.iMaster-1].u.hdr.size = mem.szMaster; + mem.aPool[mem.iMaster+mem.szMaster-1].u.hdr.prevSize = mem.szMaster; + } + } +} + +/* +** Allocate nBytes of memory +*/ +SQLITE_API void *sqlite3_malloc(int nBytes){ + sqlite3_int64 *p = 0; + if( nBytes>0 ){ + memsys3Enter(); + p = memsys3Malloc(nBytes); + sqlite3_mutex_leave(mem.mutex); + } + return (void*)p; +} + +/* +** Free memory. +*/ +SQLITE_API void sqlite3_free(void *pPrior){ + if( pPrior==0 ){ + return; + } + assert( mem.mutex!=0 ); + sqlite3_mutex_enter(mem.mutex); + memsys3Free(pPrior); + sqlite3_mutex_leave(mem.mutex); +} + +/* +** Change the size of an existing memory allocation +*/ +SQLITE_API void *sqlite3_realloc(void *pPrior, int nBytes){ + int nOld; + void *p; + if( pPrior==0 ){ + return sqlite3_malloc(nBytes); + } + if( nBytes<=0 ){ + sqlite3_free(pPrior); + return 0; + } + assert( mem.mutex!=0 ); + nOld = memsys3Size(pPrior); + if( nBytes<=nOld && nBytes>=nOld-128 ){ + return pPrior; + } + sqlite3_mutex_enter(mem.mutex); + p = memsys3Malloc(nBytes); + if( p ){ + if( nOld<nBytes ){ + memcpy(p, pPrior, nOld); + }else{ + memcpy(p, pPrior, nBytes); + } + memsys3Free(pPrior); + } + sqlite3_mutex_leave(mem.mutex); + return p; +} + +/* +** Open the file indicated and write a log of all unfreed memory +** allocations into that log. +*/ +SQLITE_API void sqlite3_memdebug_dump(const char *zFilename){ +#ifdef SQLITE_DEBUG + FILE *out; + int i, j, size; + if( zFilename==0 || zFilename[0]==0 ){ + out = stdout; + }else{ + out = fopen(zFilename, "w"); + if( out==0 ){ + fprintf(stderr, "** Unable to output memory debug output log: %s **\n", + zFilename); + return; + } + } + memsys3Enter(); + fprintf(out, "CHUNKS:\n"); + for(i=1; i<=SQLITE_MEMORY_SIZE/8; i+=size){ + size = mem.aPool[i-1].u.hdr.size; + if( size>=-1 && size<=1 ){ + fprintf(out, "%p size error\n", &mem.aPool[i]); + assert( 0 ); + break; + } + if( mem.aPool[i+(size<0?-size:size)-1].u.hdr.prevSize!=size ){ + fprintf(out, "%p tail size does not match\n", &mem.aPool[i]); + assert( 0 ); + break; + } + if( size<0 ){ + size = -size; + fprintf(out, "%p %6d bytes checked out\n", &mem.aPool[i], size*8-8); + }else{ + fprintf(out, "%p %6d bytes free%s\n", &mem.aPool[i], size*8-8, + i==mem.iMaster ? " **master**" : ""); + } + } + for(i=0; i<MX_SMALL-1; i++){ + if( mem.aiSmall[i]==0 ) continue; + fprintf(out, "small(%2d):", i); + for(j = mem.aiSmall[i]; j>0; j=mem.aPool[j].u.list.next){ + fprintf(out, " %p(%d)", &mem.aPool[j], mem.aPool[j-1].u.hdr.size*8-8); + } + fprintf(out, "\n"); + } + for(i=0; i<N_HASH; i++){ + if( mem.aiHash[i]==0 ) continue; + fprintf(out, "hash(%2d):", i); + for(j = mem.aiHash[i]; j>0; j=mem.aPool[j].u.list.next){ + fprintf(out, " %p(%d)", &mem.aPool[j], mem.aPool[j-1].u.hdr.size*8-8); + } + fprintf(out, "\n"); + } + fprintf(out, "master=%d\n", mem.iMaster); + fprintf(out, "nowUsed=%d\n", SQLITE_MEMORY_SIZE - mem.szMaster*8); + fprintf(out, "mxUsed=%d\n", SQLITE_MEMORY_SIZE - mem.mnMaster*8); + sqlite3_mutex_leave(mem.mutex); + if( out==stdout ){ + fflush(stdout); + }else{ + fclose(out); + } +#endif +} + + +#endif /* !SQLITE_MEMORY_SIZE */ + +/************** End of mem3.c ************************************************/ /************** Begin file mutex.c *******************************************/ /* ** 2007 August 14 ** ** The author disclaims copyright to this source code. In place of @@ -9185,70 +9925,139 @@ ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains the C functions that implement mutexes for OS/2 ** -** $Id: mutex_os2.c,v 1.1 2007/08/28 16:34:43 drh Exp $ -*/ - +** $Id: mutex_os2.c,v 1.3 2007/10/02 19:56:04 pweilbacher Exp $ +*/ /* ** The code in this file is only used if SQLITE_MUTEX_OS2 is defined. ** See the mutex.h file for details. */ #ifdef SQLITE_MUTEX_OS2 -/**** FIX ME: -***** This is currently a no-op implementation suitable for use -***** in single-threaded applications only. Somebody please replace -***** this with a real mutex implementation for OS/2. -****/ +/********************** OS/2 Mutex Implementation ********************** +** +** This implementation of mutexes is built using the OS/2 API. +*/ /* ** The mutex object +** Each recursive mutex is an instance of the following structure. */ struct sqlite3_mutex { - int id; /* The mutex type */ - int cnt; /* Number of entries without a matching leave */ + PSZ mutexName; /* Mutex name controlling the lock */ + HMTX mutex; /* Mutex controlling the lock */ + int id; /* Mutex type */ + int nRef; /* Number of references */ + TID owner; /* Thread holding this mutex */ }; /* ** The sqlite3_mutex_alloc() routine allocates a new ** mutex and returns a pointer to it. If it returns NULL ** that means that a mutex could not be allocated. -*/ -SQLITE_API sqlite3_mutex *sqlite3_mutex_alloc(int id){ - static sqlite3_mutex aStatic[4]; - sqlite3_mutex *pNew = 0; - switch( id ){ +** SQLite will unwind its stack and return an error. The argument +** to sqlite3_mutex_alloc() is one of these integer constants: +** +** <ul> +** <li> SQLITE_MUTEX_FAST 0 +** <li> SQLITE_MUTEX_RECURSIVE 1 +** <li> SQLITE_MUTEX_STATIC_MASTER 2 +** <li> SQLITE_MUTEX_STATIC_MEM 3 +** <li> SQLITE_MUTEX_STATIC_PRNG 4 +** </ul> +** +** The first two constants cause sqlite3_mutex_alloc() to create +** a new mutex. The new mutex is recursive when SQLITE_MUTEX_RECURSIVE +** is used but not necessarily so when SQLITE_MUTEX_FAST is used. +** The mutex implementation does not need to make a distinction +** between SQLITE_MUTEX_RECURSIVE and SQLITE_MUTEX_FAST if it does +** not want to. But SQLite will only request a recursive mutex in +** cases where it really needs one. If a faster non-recursive mutex +** implementation is available on the host platform, the mutex subsystem +** might return such a mutex in response to SQLITE_MUTEX_FAST. +** +** The other allowed parameters to sqlite3_mutex_alloc() each return +** a pointer to a static preexisting mutex. Three static mutexes are +** used by the current version of SQLite. Future versions of SQLite +** may add additional static mutexes. Static mutexes are for internal +** use by SQLite only. Applications that use SQLite mutexes should +** use only the dynamic mutexes returned by SQLITE_MUTEX_FAST or +** SQLITE_MUTEX_RECURSIVE. +** +** Note that if one of the dynamic mutex parameters (SQLITE_MUTEX_FAST +** or SQLITE_MUTEX_RECURSIVE) is used then sqlite3_mutex_alloc() +** returns a different mutex on every call. But for the static +** mutex types, the same mutex is returned on every call that has +** the same type number. +*/ +SQLITE_API sqlite3_mutex *sqlite3_mutex_alloc(int iType){ + PSZ mutex_name = "\\SEM32\\SQLITE\\MUTEX"; + int mutex_name_len = strlen(mutex_name) + 1; /* name length + null byte */ + sqlite3_mutex *p; + + switch( iType ){ case SQLITE_MUTEX_FAST: case SQLITE_MUTEX_RECURSIVE: { - pNew = sqlite3_malloc(sizeof(*pNew)); - if( pNew ){ - pNew->id = id; - pNew->cnt = 0; - } - break; - } - default: { - assert( id-2 >= 0 ); - assert( id-2 < sizeof(aStatic)/sizeof(aStatic[0]) ); - pNew = &aStatic[id-2]; - pNew->id = id; - break; - } - } - return pNew; -} + p = sqlite3MallocZero( sizeof(*p) ); + if( p ){ + p->mutexName = (PSZ)malloc(mutex_name_len); + sqlite3_snprintf(mutex_name_len, p->mutexName, "%s", mutex_name); + p->id = iType; + DosCreateMutexSem(p->mutexName, &p->mutex, 0, FALSE); + DosOpenMutexSem(p->mutexName, &p->mutex); + } + break; + } + default: { + static sqlite3_mutex staticMutexes[5]; + static int isInit = 0; + while( !isInit ) { + static long lock = 0; + DosEnterCritSec(); + lock++; + if( lock == 1 ) { + DosExitCritSec(); + int i; + for(i = 0; i < sizeof(staticMutexes)/sizeof(staticMutexes[0]); i++) { + staticMutexes[i].mutexName = (PSZ)malloc(mutex_name_len + 1); + sqlite3_snprintf(mutex_name_len + 1, /* one more for the number */ + staticMutexes[i].mutexName, "%s%1d", mutex_name, i); + DosCreateMutexSem(staticMutexes[i].mutexName, + &staticMutexes[i].mutex, 0, FALSE); + DosOpenMutexSem(staticMutexes[i].mutexName, + &staticMutexes[i].mutex); + } + isInit = 1; + } else { + DosExitCritSec(); + DosSleep(1); + } + } + assert( iType-2 >= 0 ); + assert( iType-2 < sizeof(staticMutexes)/sizeof(staticMutexes[0]) ); + p = &staticMutexes[iType-2]; + p->id = iType; + break; + } + } + return p; +} + /* ** This routine deallocates a previously allocated mutex. +** SQLite is careful to deallocate every mutex that it allocates. */ SQLITE_API void sqlite3_mutex_free(sqlite3_mutex *p){ assert( p ); - assert( p->cnt==0 ); + assert( p->nRef==0 ); assert( p->id==SQLITE_MUTEX_FAST || p->id==SQLITE_MUTEX_RECURSIVE ); + DosCloseMutexSem(p->mutex); + free(p->mutexName); sqlite3_free(p); } /* ** The sqlite3_mutex_enter() and sqlite3_mutex_try() routines attempt @@ -9260,43 +10069,86 @@ ** mutex must be exited an equal number of times before another thread ** can enter. If the same thread tries to enter any other kind of mutex ** more than once, the behavior is undefined. */ SQLITE_API void sqlite3_mutex_enter(sqlite3_mutex *p){ + TID tid; + PID holder1; + ULONG holder2; assert( p ); assert( p->id==SQLITE_MUTEX_RECURSIVE || sqlite3_mutex_notheld(p) ); - p->cnt++; + DosRequestMutexSem(p->mutex, SEM_INDEFINITE_WAIT); + DosQueryMutexSem(p->mutex, &holder1, &tid, &holder2); + p->owner = tid; + p->nRef++; } SQLITE_API int sqlite3_mutex_try(sqlite3_mutex *p){ + int rc; + TID tid; + PID holder1; + ULONG holder2; assert( p ); assert( p->id==SQLITE_MUTEX_RECURSIVE || sqlite3_mutex_notheld(p) ); - p->cnt++; - return SQLITE_OK; + if( DosRequestMutexSem(p->mutex, SEM_IMMEDIATE_RETURN) == NO_ERROR) { + DosQueryMutexSem(p->mutex, &holder1, &tid, &holder2); + p->owner = tid; + p->nRef++; + rc = SQLITE_OK; + } else { + rc = SQLITE_BUSY; + } + + return rc; } /* ** The sqlite3_mutex_leave() routine exits a mutex that was ** previously entered by the same thread. The behavior ** is undefined if the mutex is not currently entered or ** is not currently allocated. SQLite will never do either. */ SQLITE_API void sqlite3_mutex_leave(sqlite3_mutex *p){ - assert( p ); - assert( sqlite3_mutex_held(p) ); - p->cnt--; - assert( p->id==SQLITE_MUTEX_RECURSIVE || sqlite3_mutex_notheld(p) ); + TID tid; + PID holder1; + ULONG holder2; + assert( p->nRef>0 ); + DosQueryMutexSem(p->mutex, &holder1, &tid, &holder2); + assert( p->owner==tid ); + p->nRef--; + assert( p->nRef==0 || p->id==SQLITE_MUTEX_RECURSIVE ); + DosReleaseMutexSem(p->mutex); } /* ** The sqlite3_mutex_held() and sqlite3_mutex_notheld() routine are ** intended for use inside assert() statements. */ SQLITE_API int sqlite3_mutex_held(sqlite3_mutex *p){ - return p==0 || p->cnt>0; + TID tid; + PID pid; + ULONG ulCount; + PTIB ptib; + if( p!=0 ) { + DosQueryMutexSem(p->mutex, &pid, &tid, &ulCount); + } else { + DosGetInfoBlocks(&ptib, NULL); + tid = ptib->tib_ptib2->tib2_ultid; + } + return p==0 || (p->nRef!=0 && p->owner==tid); } SQLITE_API int sqlite3_mutex_notheld(sqlite3_mutex *p){ - return p==0 || p->cnt==0; + TID tid; + PID pid; + ULONG ulCount; + PTIB ptib; + if( p!= 0 ) { + DosQueryMutexSem(p->mutex, &pid, &tid, &ulCount); + } else { + DosGetInfoBlocks(&ptib, NULL); + tid = ptib->tib_ptib2->tib2_ultid; + } + return p==0 || p->nRef==0 || p->owner!=tid; } #endif /* SQLITE_MUTEX_OS2 */ /************** End of mutex_os2.c *******************************************/ /************** Begin file mutex_unix.c **************************************/ @@ -9536,11 +10388,11 @@ ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains the C functions that implement mutexes for win32 ** -** $Id: mutex_w32.c,v 1.4 2007/09/05 14:30:42 drh Exp $ +** $Id: mutex_w32.c,v 1.5 2007/10/05 15:08:01 drh Exp $ */ /* ** The code in this file is only used if we are compiling multithreaded ** on a win32 system. @@ -9692,20 +10544,31 @@ EnterCriticalSection(&p->mutex); p->owner = GetCurrentThreadId(); p->nRef++; } SQLITE_API int sqlite3_mutex_try(sqlite3_mutex *p){ - int rc; + int rc = SQLITE_BUSY; assert( p ); assert( p->id==SQLITE_MUTEX_RECURSIVE || sqlite3_mutex_notheld(p) ); + /* + ** The sqlite3_mutex_try() routine is very rarely used, and when it + ** is used it is merely an optimization. So it is OK for it to always + ** fail. + ** + ** The TryEnterCriticalSection() interface is only available on WinNT. + ** And some windows compilers complain if you try to use it without + ** first doing some #defines that prevent SQLite from building on Win98. + ** For that reason, we will omit this optimization for now. See + ** ticket #2685. + */ +#if 0 if( mutexIsNT() && TryEnterCriticalSection(&p->mutex) ){ p->owner = GetCurrentThreadId(); p->nRef++; rc = SQLITE_OK; - }else{ - rc = SQLITE_BUSY; - } + } +#endif return rc; } /* ** The sqlite3_mutex_leave() routine exits a mutex that was @@ -9747,11 +10610,11 @@ ** ************************************************************************* ** Memory allocation functions used throughout sqlite. ** ** -** $Id: malloc.c,v 1.13 2007/08/29 14:06:23 danielk1977 Exp $ +** $Id: malloc.c,v 1.14 2007/10/20 16:36:31 drh Exp $ */ /* ** This routine runs when the memory allocator sees that the ** total memory allocation is about to exceed the soft heap @@ -9970,11 +10833,10 @@ rc = SQLITE_NOMEM; } return rc & (db ? db->errMask : 0xff); } - /************** End of malloc.c **********************************************/ /************** Begin file printf.c ******************************************/ /* ** The "printf" code that follows dates from the 1980's. It is in ** the public domain. The original comments are included here for @@ -10025,11 +10887,10 @@ ** faster than the library printf for SUN OS 4.1. ** ** + All functions are fully reentrant. ** */ -#include <math.h> /* ** Conversion types fall into various categories as defined by the ** following enumeration. */ @@ -11001,11 +11862,11 @@ ** ************************************************************************* ** This file contains routines used to translate between UTF-8, ** UTF-16, UTF-16BE, and UTF-16LE. ** -** $Id: utf.c,v 1.58 2007/09/12 17:01:45 danielk1977 Exp $ +** $Id: utf.c,v 1.59 2007/10/03 08:46:45 danielk1977 Exp $ ** ** Notes on UTF-8: ** ** Byte-0 Byte-1 Byte-2 Byte-3 Value ** 0xxxxxxx 00000000 00000000 0xxxxxxx @@ -11865,10 +12726,14 @@ Mem m; memset(&m, 0, sizeof(m)); m.db = db; sqlite3VdbeMemSetStr(&m, z, nByte, SQLITE_UTF16NATIVE, SQLITE_STATIC); sqlite3VdbeChangeEncoding(&m, SQLITE_UTF8); + if( db->mallocFailed ){ + sqlite3VdbeMemRelease(&m); + m.z = 0; + } assert( (m.flags & MEM_Term)!=0 || db->mallocFailed ); assert( (m.flags & MEM_Str)!=0 || db->mallocFailed ); return (m.flags & MEM_Dyn)!=0 ? m.z : sqlite3DbStrDup(db, m.z); } @@ -11976,11 +12841,11 @@ ** Utility functions used throughout sqlite. ** ** This file contains functions for allocating memory, comparing ** strings, and stuff like that. ** -** $Id: util.c,v 1.212 2007/09/01 10:01:13 danielk1977 Exp $ +** $Id: util.c,v 1.213 2007/10/23 15:39:45 drh Exp $ */ /* ** Set the most recent error code and error string for the sqlite @@ -12335,19 +13200,20 @@ ** This routine returns FALSE for the string -9223372036854775808 even that ** that number will, in theory fit in a 64-bit integer. Positive ** 9223373036854775808 will not fit in 64 bits. So it seems safer to return ** false. */ -SQLITE_PRIVATE int sqlite3FitsIn64Bits(const char *zNum){ +SQLITE_PRIVATE int sqlite3FitsIn64Bits(const char *zNum, int negFlag){ int i, c; int neg = 0; if( *zNum=='-' ){ neg = 1; zNum++; }else if( *zNum=='+' ){ zNum++; } + if( negFlag ) neg = 1-neg; while( *zNum=='0' ){ zNum++; /* Skip leading zeros. Ticket #2454 */ } for(i=0; (c=zNum[i])>='0' && c<='9'; i++){} if( i<19 ){ @@ -13090,83 +13956,83 @@ /* Automatically generated. Do not edit */ /* See the mkopcodec.awk script for details. */ #if !defined(SQLITE_OMIT_EXPLAIN) || !defined(NDEBUG) || defined(VDBE_PROFILE) || defined(SQLITE_DEBUG) SQLITE_PRIVATE const char *sqlite3OpcodeName(int i){ static const char *const azName[] = { "?", - /* 1 */ "MemLoad", - /* 2 */ "VNext", - /* 3 */ "Column", - /* 4 */ "SetCookie", - /* 5 */ "IfMemPos", - /* 6 */ "Sequence", - /* 7 */ "MoveGt", - /* 8 */ "RowKey", - /* 9 */ "OpenWrite", - /* 10 */ "If", - /* 11 */ "Pop", - /* 12 */ "VRowid", - /* 13 */ "CollSeq", - /* 14 */ "OpenRead", - /* 15 */ "Expire", + /* 1 */ "ReadCookie", + /* 2 */ "AutoCommit", + /* 3 */ "Found", + /* 4 */ "NullRow", + /* 5 */ "MoveLe", + /* 6 */ "Variable", + /* 7 */ "Pull", + /* 8 */ "RealAffinity", + /* 9 */ "Sort", + /* 10 */ "IfNot", + /* 11 */ "Gosub", + /* 12 */ "NotFound", + /* 13 */ "MoveLt", + /* 14 */ "Rowid", + /* 15 */ "CreateIndex", /* 16 */ "Not", - /* 17 */ "AutoCommit", - /* 18 */ "IntegrityCk", - /* 19 */ "Sort", - /* 20 */ "Function", - /* 21 */ "Noop", - /* 22 */ "Return", - /* 23 */ "NewRowid", - /* 24 */ "IfMemNeg", - /* 25 */ "Variable", - /* 26 */ "String", - /* 27 */ "RealAffinity", - /* 28 */ "VRename", - /* 29 */ "ParseSchema", - /* 30 */ "VOpen", - /* 31 */ "Close", - /* 32 */ "CreateIndex", - /* 33 */ "IsUnique", - /* 34 */ "NotFound", - /* 35 */ "Int64", - /* 36 */ "MustBeInt", - /* 37 */ "Halt", - /* 38 */ "Rowid", - /* 39 */ "IdxLT", - /* 40 */ "AddImm", - /* 41 */ "Statement", - /* 42 */ "RowData", - /* 43 */ "MemMax", - /* 44 */ "Push", - /* 45 */ "NotExists", - /* 46 */ "MemIncr", - /* 47 */ "Gosub", - /* 48 */ "Integer", - /* 49 */ "MemInt", - /* 50 */ "Prev", - /* 51 */ "VColumn", - /* 52 */ "CreateTable", - /* 53 */ "Last", - /* 54 */ "IncrVacuum", - /* 55 */ "IdxRowid", - /* 56 */ "MakeIdxRec", - /* 57 */ "ResetCount", - /* 58 */ "FifoWrite", - /* 59 */ "Callback", + /* 17 */ "Push", + /* 18 */ "Explain", + /* 19 */ "Statement", + /* 20 */ "Callback", + /* 21 */ "MemLoad", + /* 22 */ "DropIndex", + /* 23 */ "Null", + /* 24 */ "Int64", + /* 25 */ "LoadAnalysis", + /* 26 */ "IdxInsert", + /* 27 */ "VUpdate", + /* 28 */ "Next", + /* 29 */ "SetNumColumns", + /* 30 */ "MemInt", + /* 31 */ "Dup", + /* 32 */ "Rewind", + /* 33 */ "Last", + /* 34 */ "MustBeInt", + /* 35 */ "MoveGe", + /* 36 */ "IncrVacuum", + /* 37 */ "String", + /* 38 */ "VFilter", + /* 39 */ "ForceInt", + /* 40 */ "Close", + /* 41 */ "AggFinal", + /* 42 */ "AbsValue", + /* 43 */ "RowData", + /* 44 */ "IdxRowid", + /* 45 */ "MoveGt", + /* 46 */ "OpenPseudo", + /* 47 */ "Halt", + /* 48 */ "MemMove", + /* 49 */ "NewRowid", + /* 50 */ "IdxLT", + /* 51 */ "Distinct", + /* 52 */ "MemMax", + /* 53 */ "Function", + /* 54 */ "IntegrityCk", + /* 55 */ "FifoWrite", + /* 56 */ "NotExists", + /* 57 */ "VDestroy", + /* 58 */ "MemStore", + /* 59 */ "IdxDelete", /* 60 */ "Or", /* 61 */ "And", - /* 62 */ "ContextPush", - /* 63 */ "DropTrigger", - /* 64 */ "DropIndex", + /* 62 */ "Vacuum", + /* 63 */ "If", + /* 64 */ "Destroy", /* 65 */ "IsNull", /* 66 */ "NotNull", /* 67 */ "Ne", /* 68 */ "Eq", /* 69 */ "Gt", /* 70 */ "Le", /* 71 */ "Lt", /* 72 */ "Ge", - /* 73 */ "IdxGE", + /* 73 */ "AggStep", /* 74 */ "BitAnd", /* 75 */ "BitOr", /* 76 */ "ShiftLeft", /* 77 */ "ShiftRight", /* 78 */ "Add", @@ -13173,63 +14039,63 @@ /* 79 */ "Subtract", /* 80 */ "Multiply", /* 81 */ "Divide", /* 82 */ "Remainder", /* 83 */ "Concat", - /* 84 */ "IdxDelete", + /* 84 */ "Clear", /* 85 */ "Negative", - /* 86 */ "Vacuum", + /* 86 */ "Insert", /* 87 */ "BitNot", /* 88 */ "String8", - /* 89 */ "MoveLe", - /* 90 */ "IfNot", - /* 91 */ "DropTable", - /* 92 */ "MakeRecord", - /* 93 */ "Delete", - /* 94 */ "AggFinal", - /* 95 */ "Dup", - /* 96 */ "Goto", - /* 97 */ "TableLock", - /* 98 */ "FifoRead", - /* 99 */ "Clear", - /* 100 */ "IdxGT", - /* 101 */ "MoveLt", - /* 102 */ "VerifyCookie", - /* 103 */ "AggStep", - /* 104 */ "Pull", - /* 105 */ "SetNumColumns", - /* 106 */ "AbsValue", - /* 107 */ "Transaction", - /* 108 */ "VFilter", - /* 109 */ "VDestroy", + /* 89 */ "VBegin", + /* 90 */ "IdxGE", + /* 91 */ "OpenEphemeral", + /* 92 */ "IfMemZero", + /* 93 */ "VRowid", + /* 94 */ "MakeRecord", + /* 95 */ "SetCookie", + /* 96 */ "Prev", + /* 97 */ "ContextPush", + /* 98 */ "DropTrigger", + /* 99 */ "IdxGT", + /* 100 */ "MemNull", + /* 101 */ "IfMemNeg", + /* 102 */ "VColumn", + /* 103 */ "Return", + /* 104 */ "OpenWrite", + /* 105 */ "Integer", + /* 106 */ "Transaction", + /* 107 */ "CollSeq", + /* 108 */ "VRename", + /* 109 */ "Sequence", /* 110 */ "ContextPop", - /* 111 */ "Next", - /* 112 */ "IdxInsert", - /* 113 */ "Distinct", - /* 114 */ "Insert", - /* 115 */ "Destroy", - /* 116 */ "ReadCookie", - /* 117 */ "ForceInt", - /* 118 */ "LoadAnalysis", - /* 119 */ "Explain", - /* 120 */ "IfMemZero", - /* 121 */ "OpenPseudo", - /* 122 */ "OpenEphemeral", - /* 123 */ "Null", + /* 111 */ "VCreate", + /* 112 */ "CreateTable", + /* 113 */ "AddImm", + /* 114 */ "DropTable", + /* 115 */ "IsUnique", + /* 116 */ "VOpen", + /* 117 */ "Noop", + /* 118 */ "RowKey", + /* 119 */ "Expire", + /* 120 */ "FifoRead", + /* 121 */ "Delete", + /* 122 */ "IfMemPos", + /* 123 */ "MemIncr", /* 124 */ "Blob", /* 125 */ "Real", /* 126 */ "HexBlob", - /* 127 */ "MemStore", - /* 128 */ "Rewind", - /* 129 */ "MoveGe", - /* 130 */ "VBegin", - /* 131 */ "VUpdate", - /* 132 */ "VCreate", - /* 133 */ "MemMove", - /* 134 */ "MemNull", - /* 135 */ "Found", - /* 136 */ "NullRow", + /* 127 */ "MakeIdxRec", + /* 128 */ "Goto", + /* 129 */ "ParseSchema", + /* 130 */ "VNext", + /* 131 */ "Pop", + /* 132 */ "TableLock", + /* 133 */ "VerifyCookie", + /* 134 */ "Column", + /* 135 */ "OpenRead", + /* 136 */ "ResetCount", /* 137 */ "NotUsed_137", /* 138 */ "ToText", /* 139 */ "ToBlob", /* 140 */ "ToNumeric", /* 141 */ "ToInt", @@ -13258,13 +14124,39 @@ #if OS_OS2 /* +** A Note About Memory Allocation: +** +** This driver uses malloc()/free() directly rather than going through +** the SQLite-wrappers sqlite3_malloc()/sqlite3_free(). Those wrappers +** are designed for use on embedded systems where memory is scarce and +** malloc failures happen frequently. OS/2 does not typically run on +** embedded systems, and when it does the developers normally have bigger +** problems to worry about than running out of memory. So there is not +** a compelling need to use the wrappers. +** +** But there is a good reason to not use the wrappers. If we use the +** wrappers then we will get simulated malloc() failures within this +** driver. And that causes all kinds of problems for our tests. We +** could enhance SQLite to deal with simulated malloc failures within +** the OS driver, but the code to deal with those failure would not +** be exercised on Linux (which does not need to malloc() in the driver) +** and so we would have difficulty writing coverage tests for that +** code. Better to leave the code out, we think. +** +** The point of this discussion is as follows: When creating a new +** OS layer for an embedded system, if you use this file as an example, +** avoid the use of malloc()/free(). Those routines work ok on OS/2 +** desktops but not so well in embedded systems. +*/ + +/* ** Macros used to determine whether or not to use threads. */ -#if defined(THREADSAFE) && THREADSAFE +#if defined(SQLITE_THREADSAFE) && SQLITE_THREADSAFE # define SQLITE_OS2_THREADS 1 #endif /* ** Include code that is common to all os_*.c files @@ -13401,253 +14293,44 @@ /************** End of os_common.h *******************************************/ /************** Continuing where we left off in os_os2.c *********************/ /* -** The os2File structure is subclass of OsFile specific for the OS/2 +** The os2File structure is subclass of sqlite3_file specific for the OS/2 ** protability layer. */ typedef struct os2File os2File; struct os2File { - IoMethod const *pMethod; /* Always the first entry */ + const sqlite3_io_methods *pMethod; /* Always the first entry */ HFILE h; /* Handle for accessing the file */ int delOnClose; /* True if file is to be deleted on close */ char* pathToDel; /* Name of file to delete on close */ unsigned char locktype; /* Type of lock currently held on this file */ }; -/* -** Do not include any of the File I/O interface procedures if the -** SQLITE_OMIT_DISKIO macro is defined (indicating that there database -** will be in-memory only) -*/ -#ifndef SQLITE_OMIT_DISKIO - -/* -** Delete the named file -*/ -SQLITE_PRIVATE int sqlite3Os2Delete( const char *zFilename ){ +/***************************************************************************** +** The next group of routines implement the I/O methods specified +** by the sqlite3_io_methods object. +******************************************************************************/ + +/* +** Close a file. +*/ +int os2Close( sqlite3_file *id ){ APIRET rc = NO_ERROR; - - rc = DosDelete( (PSZ)zFilename ); - OSTRACE2( "DELETE \"%s\"\n", zFilename ); - return rc == NO_ERROR ? SQLITE_OK : SQLITE_IOERR; -} - -/* -** Return TRUE if the named file exists. -*/ -SQLITE_PRIVATE int sqlite3Os2FileExists( const char *zFilename ){ - FILESTATUS3 fsts3ConfigInfo; - memset(&fsts3ConfigInfo, 0, sizeof(fsts3ConfigInfo)); - return DosQueryPathInfo( (PSZ)zFilename, FIL_STANDARD, - &fsts3ConfigInfo, sizeof(FILESTATUS3) ) == NO_ERROR; -} - -/* Forward declaration */ -int allocateOs2File( os2File *pInit, OsFile **pld ); - -/* -** Attempt to open a file for both reading and writing. If that -** fails, try opening it read-only. If the file does not exist, -** try to create it. -** -** On success, a handle for the open file is written to *id -** and *pReadonly is set to 0 if the file was opened for reading and -** writing or 1 if the file was opened read-only. The function returns -** SQLITE_OK. -** -** On failure, the function returns SQLITE_CANTOPEN and leaves -** *id and *pReadonly unchanged. -*/ -SQLITE_PRIVATE int sqlite3Os2OpenReadWrite( - const char *zFilename, - OsFile **pld, - int *pReadonly -){ - os2File f; - HFILE hf; - ULONG ulAction; - APIRET rc = NO_ERROR; - - assert( *pld == 0 ); - rc = DosOpen( (PSZ)zFilename, &hf, &ulAction, 0L, - FILE_ARCHIVED | FILE_NORMAL, - OPEN_ACTION_CREATE_IF_NEW | OPEN_ACTION_OPEN_IF_EXISTS, - OPEN_FLAGS_FAIL_ON_ERROR | OPEN_FLAGS_RANDOM | - OPEN_SHARE_DENYNONE | OPEN_ACCESS_READWRITE, (PEAOP2)NULL ); - if( rc != NO_ERROR ){ - rc = DosOpen( (PSZ)zFilename, &hf, &ulAction, 0L, - FILE_ARCHIVED | FILE_NORMAL, - OPEN_ACTION_CREATE_IF_NEW | OPEN_ACTION_OPEN_IF_EXISTS, - OPEN_FLAGS_FAIL_ON_ERROR | OPEN_FLAGS_RANDOM | - OPEN_SHARE_DENYWRITE | OPEN_ACCESS_READONLY, (PEAOP2)NULL ); - if( rc != NO_ERROR ){ - return SQLITE_CANTOPEN; - } - *pReadonly = 1; - } - else{ - *pReadonly = 0; - } - f.h = hf; - f.locktype = NO_LOCK; - f.delOnClose = 0; - f.pathToDel = NULL; - OpenCounter(+1); - OSTRACE3( "OPEN R/W %d \"%s\"\n", hf, zFilename ); - return allocateOs2File( &f, pld ); -} - - -/* -** Attempt to open a new file for exclusive access by this process. -** The file will be opened for both reading and writing. To avoid -** a potential security problem, we do not allow the file to have -** previously existed. Nor do we allow the file to be a symbolic -** link. -** -** If delFlag is true, then make arrangements to automatically delete -** the file when it is closed. -** -** On success, write the file handle into *id and return SQLITE_OK. -** -** On failure, return SQLITE_CANTOPEN. -*/ -SQLITE_PRIVATE int sqlite3Os2OpenExclusive( const char *zFilename, OsFile **pld, int delFlag ){ - os2File f; - HFILE hf; - ULONG ulAction; - APIRET rc = NO_ERROR; - - assert( *pld == 0 ); - rc = DosOpen( (PSZ)zFilename, &hf, &ulAction, 0L, FILE_NORMAL, - OPEN_ACTION_CREATE_IF_NEW | OPEN_ACTION_REPLACE_IF_EXISTS, - OPEN_FLAGS_FAIL_ON_ERROR | OPEN_FLAGS_RANDOM | - OPEN_SHARE_DENYREADWRITE | OPEN_ACCESS_READWRITE, (PEAOP2)NULL ); - if( rc != NO_ERROR ){ - return SQLITE_CANTOPEN; - } - - f.h = hf; - f.locktype = NO_LOCK; - f.delOnClose = delFlag ? 1 : 0; - f.pathToDel = delFlag ? sqlite3OsFullPathname( zFilename ) : NULL; - OpenCounter( +1 ); - if( delFlag ) DosForceDelete( (PSZ)sqlite3OsFullPathname( zFilename ) ); - OSTRACE3( "OPEN EX %d \"%s\"\n", hf, sqlite3OsFullPathname ( zFilename ) ); - return allocateOs2File( &f, pld ); -} - -/* -** Attempt to open a new file for read-only access. -** -** On success, write the file handle into *id and return SQLITE_OK. -** -** On failure, return SQLITE_CANTOPEN. -*/ -SQLITE_PRIVATE int sqlite3Os2OpenReadOnly( const char *zFilename, OsFile **pld ){ - os2File f; - HFILE hf; - ULONG ulAction; - APIRET rc = NO_ERROR; - - assert( *pld == 0 ); - rc = DosOpen( (PSZ)zFilename, &hf, &ulAction, 0L, - FILE_NORMAL, OPEN_ACTION_OPEN_IF_EXISTS, - OPEN_FLAGS_FAIL_ON_ERROR | OPEN_FLAGS_RANDOM | - OPEN_SHARE_DENYWRITE | OPEN_ACCESS_READONLY, (PEAOP2)NULL ); - if( rc != NO_ERROR ){ - return SQLITE_CANTOPEN; - } - f.h = hf; - f.locktype = NO_LOCK; - f.delOnClose = 0; - f.pathToDel = NULL; - OpenCounter( +1 ); - OSTRACE3( "OPEN RO %d \"%s\"\n", hf, zFilename ); - return allocateOs2File( &f, pld ); -} - -/* -** Attempt to open a file descriptor for the directory that contains a -** file. This file descriptor can be used to fsync() the directory -** in order to make sure the creation of a new file is actually written -** to disk. -** -** This routine is only meaningful for Unix. It is a no-op under -** OS/2 since OS/2 does not support hard links. -** -** On success, a handle for a previously open file is at *id is -** updated with the new directory file descriptor and SQLITE_OK is -** returned. -** -** On failure, the function returns SQLITE_CANTOPEN and leaves -** *id unchanged. -*/ -int os2OpenDirectory( - OsFile *id, - const char *zDirname -){ - return SQLITE_OK; -} - -/* -** Create a temporary file name in zBuf. zBuf must be big enough to -** hold at least SQLITE_TEMPNAME_SIZE characters. -*/ -SQLITE_PRIVATE int sqlite3Os2TempFileName( char *zBuf ){ - static const unsigned char zChars[] = - "abcdefghijklmnopqrstuvwxyz" - "ABCDEFGHIJKLMNOPQRSTUVWXYZ" - "0123456789"; - int i, j; - PSZ zTempPath = 0; - if( DosScanEnv( (PSZ)"TEMP", &zTempPath ) ){ - if( DosScanEnv( (PSZ)"TMP", &zTempPath ) ){ - if( DosScanEnv( (PSZ)"TMPDIR", &zTempPath ) ){ - ULONG ulDriveNum = 0, ulDriveMap = 0; - DosQueryCurrentDisk( &ulDriveNum, &ulDriveMap ); - sprintf( (char*)zTempPath, "%c:", (char)( 'A' + ulDriveNum - 1 ) ); - } - } - } - /* strip off a trailing slashes or backslashes, otherwise we would get * - * multiple (back)slashes which causes DosOpen() to fail */ - j = strlen(zTempPath); - while( j > 0 && zTempPath[j-1] == '\\' || zTempPath[j-1] == '/' ){ - j--; - } - zTempPath[j] = '\0'; - for(;;){ - sprintf( zBuf, "%s\\"TEMP_FILE_PREFIX, zTempPath ); - j = strlen( zBuf ); - sqlite3Randomness( 15, &zBuf[j] ); - for( i = 0; i < 15; i++, j++ ){ - zBuf[j] = (char)zChars[ ((unsigned char)zBuf[j])%(sizeof(zChars)-1) ]; - } - zBuf[j] = 0; - if( !sqlite3OsFileExists( zBuf ) ) break; - } - OSTRACE2( "TEMP FILENAME: %s\n", zBuf ); - return SQLITE_OK; -} - -/* -** Close a file. -*/ -int os2Close( OsFile **pld ){ os2File *pFile; - APIRET rc = NO_ERROR; - if( pld && (pFile = (os2File*)*pld) != 0 ){ + if( id && (pFile = (os2File*)id) != 0 ){ OSTRACE2( "CLOSE %d\n", pFile->h ); rc = DosClose( pFile->h ); pFile->locktype = NO_LOCK; if( pFile->delOnClose != 0 ){ - rc = DosForceDelete( (PSZ)pFile->pathToDel ); - } - *pld = 0; + rc = DosForceDelete( (PSZ)pFile->pathToDel ); + } + if( pFile->pathToDel ){ + free( pFile->pathToDel ); + } + id = 0; OpenCounter( -1 ); } return rc == NO_ERROR ? SQLITE_OK : SQLITE_IOERR; } @@ -13655,20 +14338,30 @@ /* ** Read data from a file into a buffer. Return SQLITE_OK if all ** bytes were read successfully and SQLITE_IOERR if anything goes ** wrong. */ -int os2Read( OsFile *id, void *pBuf, int amt ){ +int os2Read( + sqlite3_file *id, /* File to read from */ + void *pBuf, /* Write content into this buffer */ + int amt, /* Number of bytes to read */ + sqlite3_int64 offset /* Begin reading at this offset */ +){ + ULONG fileLocation = 0L; ULONG got; + os2File *pFile = (os2File*)id; assert( id!=0 ); - SimulateIOError( return SQLITE_IOERR ); - OSTRACE3( "READ %d lock=%d\n", ((os2File*)id)->h, ((os2File*)id)->locktype ); - DosRead( ((os2File*)id)->h, pBuf, amt, &got ); - if (got == (ULONG)amt) - return SQLITE_OK; - else if (got == 0) + SimulateIOError( return SQLITE_IOERR_READ ); + OSTRACE3( "READ %d lock=%d\n", pFile->h, pFile->locktype ); + if( DosSetFilePtr(pFile->h, offset, FILE_BEGIN, &fileLocation) != NO_ERROR ){ + return SQLITE_IOERR; + } + if( DosRead( pFile->h, pBuf, amt, &got ) != NO_ERROR ){ return SQLITE_IOERR_READ; + } + if( got == (ULONG)amt ) + return SQLITE_OK; else { memset(&((char*)pBuf)[got], 0, amt-got); return SQLITE_IOERR_SHORT_READ; } } @@ -13675,140 +14368,133 @@ /* ** Write data from a buffer into a file. Return SQLITE_OK on success ** or some other error code on failure. */ -int os2Write( OsFile *id, const void *pBuf, int amt ){ +int os2Write( + sqlite3_file *id, /* File to write into */ + const void *pBuf, /* The bytes to be written */ + int amt, /* Number of bytes to write */ + sqlite3_int64 offset /* Offset into the file to begin writing at */ +){ + ULONG fileLocation = 0L; APIRET rc = NO_ERROR; ULONG wrote; + os2File *pFile = (os2File*)id; assert( id!=0 ); - SimulateIOError( return SQLITE_IOERR ); + SimulateIOError( return SQLITE_IOERR_WRITE ); SimulateDiskfullError( return SQLITE_FULL ); - OSTRACE3( "WRITE %d lock=%d\n", ((os2File*)id)->h, ((os2File*)id)->locktype ); + OSTRACE3( "WRITE %d lock=%d\n", pFile->h, pFile->locktype ); + if( DosSetFilePtr(pFile->h, offset, FILE_BEGIN, &fileLocation) != NO_ERROR ){ + return SQLITE_IOERR; + } + assert( amt>0 ); while( amt > 0 && - (rc = DosWrite( ((os2File*)id)->h, (PVOID)pBuf, amt, &wrote )) && wrote > 0 ){ - amt -= wrote; - pBuf = &((char*)pBuf)[wrote]; + (rc = DosWrite( pFile->h, (PVOID)pBuf, amt, &wrote )) && + wrote > 0 + ){ + amt -= wrote; + pBuf = &((char*)pBuf)[wrote]; } return ( rc != NO_ERROR || amt > (int)wrote ) ? SQLITE_FULL : SQLITE_OK; } /* -** Move the read/write pointer in a file. -*/ -int os2Seek( OsFile *id, i64 offset ){ +** Truncate an open file to a specified size +*/ +int os2Truncate( sqlite3_file *id, i64 nByte ){ APIRET rc = NO_ERROR; - ULONG filePointer = 0L; - assert( id!=0 ); - rc = DosSetFilePtr( ((os2File*)id)->h, offset, FILE_BEGIN, &filePointer ); - OSTRACE3( "SEEK %d %lld\n", ((os2File*)id)->h, offset ); + ULONG filePosition = 0L; + os2File *pFile = (os2File*)id; + OSTRACE3( "TRUNCATE %d %lld\n", pFile->h, nByte ); + SimulateIOError( return SQLITE_IOERR_TRUNCATE ); + rc = DosSetFilePtr( pFile->h, nByte, FILE_BEGIN, &filePosition ); + if( rc != NO_ERROR ){ + return SQLITE_IOERR; + } + rc = DosSetFilePtr( pFile->h, 0L, FILE_END, &filePosition ); return rc == NO_ERROR ? SQLITE_OK : SQLITE_IOERR; } + +#ifdef SQLITE_TEST +/* +** Count the number of fullsyncs and normal syncs. This is used to test +** that syncs and fullsyncs are occuring at the right times. +*/ +SQLITE_API int sqlite3_sync_count = 0; +SQLITE_API int sqlite3_fullsync_count = 0; +#endif /* ** Make sure all writes to a particular file are committed to disk. */ -int os2Sync( OsFile *id, int dataOnly ){ - assert( id!=0 ); - OSTRACE3( "SYNC %d lock=%d\n", ((os2File*)id)->h, ((os2File*)id)->locktype ); - return DosResetBuffer( ((os2File*)id)->h ) == NO_ERROR ? SQLITE_OK : SQLITE_IOERR; -} - -/* -** Sync the directory zDirname. This is a no-op on operating systems other -** than UNIX. -*/ -SQLITE_PRIVATE int sqlite3Os2SyncDirectory( const char *zDirname ){ - SimulateIOError( return SQLITE_IOERR ); - return SQLITE_OK; -} - -/* -** Truncate an open file to a specified size -*/ -int os2Truncate( OsFile *id, i64 nByte ){ - APIRET rc = NO_ERROR; - ULONG upperBits = nByte>>32; - assert( id!=0 ); - OSTRACE3( "TRUNCATE %d %lld\n", ((os2File*)id)->h, nByte ); - SimulateIOError( return SQLITE_IOERR ); - rc = DosSetFilePtr( ((os2File*)id)->h, nByte, FILE_BEGIN, &upperBits ); - if( rc != NO_ERROR ){ - return SQLITE_IOERR; - } - rc = DosSetFilePtr( ((os2File*)id)->h, 0L, FILE_END, &upperBits ); - return rc == NO_ERROR ? SQLITE_OK : SQLITE_IOERR; +int os2Sync( sqlite3_file *id, int flags ){ + os2File *pFile = (os2File*)id; + OSTRACE3( "SYNC %d lock=%d\n", pFile->h, pFile->locktype ); +#ifdef SQLITE_TEST + if( flags & SQLITE_SYNC_FULL){ + sqlite3_fullsync_count++; + } + sqlite3_sync_count++; +#endif + return DosResetBuffer( pFile->h ) == NO_ERROR ? SQLITE_OK : SQLITE_IOERR; } /* ** Determine the current size of a file in bytes */ -int os2FileSize( OsFile *id, i64 *pSize ){ +int os2FileSize( sqlite3_file *id, sqlite3_int64 *pSize ){ APIRET rc = NO_ERROR; FILESTATUS3 fsts3FileInfo; memset(&fsts3FileInfo, 0, sizeof(fsts3FileInfo)); assert( id!=0 ); SimulateIOError( return SQLITE_IOERR ); rc = DosQueryFileInfo( ((os2File*)id)->h, FIL_STANDARD, &fsts3FileInfo, sizeof(FILESTATUS3) ); if( rc == NO_ERROR ){ *pSize = fsts3FileInfo.cbFile; return SQLITE_OK; - } - else{ + }else{ return SQLITE_IOERR; } } /* ** Acquire a reader lock. */ -static int getReadLock( os2File *id ){ +static int getReadLock( os2File *pFile ){ FILELOCK LockArea, UnlockArea; + APIRET res; memset(&LockArea, 0, sizeof(LockArea)); memset(&UnlockArea, 0, sizeof(UnlockArea)); LockArea.lOffset = SHARED_FIRST; LockArea.lRange = SHARED_SIZE; UnlockArea.lOffset = 0L; UnlockArea.lRange = 0L; - return DosSetFileLocks( id->h, &UnlockArea, &LockArea, 2000L, 1L ); + res = DosSetFileLocks( pFile->h, &UnlockArea, &LockArea, 2000L, 1L ); + OSTRACE3( "GETREADLOCK %d res=%d\n", pFile->h, res ); + return res; } /* ** Undo a readlock */ static int unlockReadLock( os2File *id ){ FILELOCK LockArea, UnlockArea; + APIRET res; memset(&LockArea, 0, sizeof(LockArea)); memset(&UnlockArea, 0, sizeof(UnlockArea)); LockArea.lOffset = 0L; LockArea.lRange = 0L; UnlockArea.lOffset = SHARED_FIRST; UnlockArea.lRange = SHARED_SIZE; - return DosSetFileLocks( id->h, &UnlockArea, &LockArea, 2000L, 1L ); -} - -#ifndef SQLITE_OMIT_PAGER_PRAGMAS -/* -** Check that a given pathname is a directory and is writable -** -*/ -SQLITE_PRIVATE int sqlite3Os2IsDirWritable( char *zDirname ){ - FILESTATUS3 fsts3ConfigInfo; - APIRET rc = NO_ERROR; - memset(&fsts3ConfigInfo, 0, sizeof(fsts3ConfigInfo)); - if( zDirname==0 ) return 0; - if( strlen(zDirname)>CCHMAXPATH ) return 0; - rc = DosQueryPathInfo( (PSZ)zDirname, FIL_STANDARD, &fsts3ConfigInfo, sizeof(FILESTATUS3) ); - if( rc != NO_ERROR ) return 0; - if( (fsts3ConfigInfo.attrFile & FILE_DIRECTORY) != FILE_DIRECTORY ) return 0; - - return 1; -} -#endif /* SQLITE_OMIT_PAGER_PRAGMAS */ + res = DosSetFileLocks( id->h, &UnlockArea, &LockArea, 2000L, 1L ); + OSTRACE3( "UNLOCK-READLOCK file handle=%d res=%d?\n", id->h, res ); + return res; +} /* ** Lock the file with the lock specified by parameter locktype - one ** of the following: ** @@ -13832,14 +14518,14 @@ ** This routine will only increase a lock. The os2Unlock() routine ** erases all locks at once and returns us immediately to locking level 0. ** It is not possible to lower the locking level one step at a time. You ** must go straight to locking level 0. */ -int os2Lock( OsFile *id, int locktype ){ - APIRET rc = SQLITE_OK; /* Return code from subroutines */ +int os2Lock( sqlite3_file *id, int locktype ){ + int rc = SQLITE_OK; /* Return code from subroutines */ APIRET res = NO_ERROR; /* Result of an OS/2 lock call */ - int newLocktype; /* Set id->locktype to this value before exiting */ + int newLocktype; /* Set pFile->locktype to this value before exiting */ int gotPendingLock = 0;/* True if we acquired a PENDING lock this time */ FILELOCK LockArea, UnlockArea; os2File *pFile = (os2File*)id; memset(&LockArea, 0, sizeof(LockArea)); @@ -13846,14 +14532,15 @@ memset(&UnlockArea, 0, sizeof(UnlockArea)); assert( pFile!=0 ); OSTRACE4( "LOCK %d %d was %d\n", pFile->h, locktype, pFile->locktype ); /* If there is already a lock of this type or more restrictive on the - ** OsFile, do nothing. Don't use the end_lock: exit path, as + ** os2File, do nothing. Don't use the end_lock: exit path, as ** sqlite3OsEnterMutex() hasn't been called yet. */ if( pFile->locktype>=locktype ){ + OSTRACE3( "LOCK %d %d ok (already held)\n", pFile->h, locktype ); return SQLITE_OK; } /* Make sure the locking sequence is correct */ @@ -13865,63 +14552,71 @@ ** a SHARED lock. If we are acquiring a SHARED lock, the acquisition of ** the PENDING_LOCK byte is temporary. */ newLocktype = pFile->locktype; if( pFile->locktype==NO_LOCK - || (locktype==EXCLUSIVE_LOCK && pFile->locktype==RESERVED_LOCK) + || (locktype==EXCLUSIVE_LOCK && pFile->locktype==RESERVED_LOCK) ){ int cnt = 3; LockArea.lOffset = PENDING_BYTE; LockArea.lRange = 1L; UnlockArea.lOffset = 0L; UnlockArea.lRange = 0L; - while( cnt-->0 && (res = DosSetFileLocks( pFile->h, &UnlockArea, &LockArea, 2000L, 1L) )!=NO_ERROR ){ + while( cnt-->0 && ( res = DosSetFileLocks( pFile->h, &UnlockArea, &LockArea, 2000L, 1L) ) + != NO_ERROR + ){ /* Try 3 times to get the pending lock. The pending lock might be ** held by another reader process who will release it momentarily. */ - OSTRACE2( "could not get a PENDING lock. cnt=%d\n", cnt ); + OSTRACE2( "LOCK could not get a PENDING lock. cnt=%d\n", cnt ); DosSleep(1); } - gotPendingLock = res; + if( res == NO_ERROR){ + gotPendingLock = 1; + OSTRACE3( "LOCK %d pending lock boolean set. res=%d\n", pFile->h, res ); + } } /* Acquire a shared lock */ - if( locktype==SHARED_LOCK && res ){ + if( locktype==SHARED_LOCK && res == NO_ERROR ){ assert( pFile->locktype==NO_LOCK ); res = getReadLock(pFile); if( res == NO_ERROR ){ newLocktype = SHARED_LOCK; } + OSTRACE3( "LOCK %d acquire shared lock. res=%d\n", pFile->h, res ); } /* Acquire a RESERVED lock */ - if( locktype==RESERVED_LOCK && res ){ + if( locktype==RESERVED_LOCK && res == NO_ERROR ){ assert( pFile->locktype==SHARED_LOCK ); LockArea.lOffset = RESERVED_BYTE; LockArea.lRange = 1L; UnlockArea.lOffset = 0L; UnlockArea.lRange = 0L; res = DosSetFileLocks( pFile->h, &UnlockArea, &LockArea, 2000L, 1L ); if( res == NO_ERROR ){ newLocktype = RESERVED_LOCK; } + OSTRACE3( "LOCK %d acquire reserved lock. res=%d\n", pFile->h, res ); } /* Acquire a PENDING lock */ - if( locktype==EXCLUSIVE_LOCK && res ){ + if( locktype==EXCLUSIVE_LOCK && res == NO_ERROR ){ newLocktype = PENDING_LOCK; gotPendingLock = 0; + OSTRACE2( "LOCK %d acquire pending lock. pending lock boolean unset.\n", pFile->h ); } /* Acquire an EXCLUSIVE lock */ - if( locktype==EXCLUSIVE_LOCK && res ){ + if( locktype==EXCLUSIVE_LOCK && res == NO_ERROR ){ assert( pFile->locktype>=SHARED_LOCK ); res = unlockReadLock(pFile); OSTRACE2( "unreadlock = %d\n", res ); LockArea.lOffset = SHARED_FIRST; LockArea.lRange = SHARED_SIZE; @@ -13929,45 +14624,50 @@ UnlockArea.lRange = 0L; res = DosSetFileLocks( pFile->h, &UnlockArea, &LockArea, 2000L, 1L ); if( res == NO_ERROR ){ newLocktype = EXCLUSIVE_LOCK; }else{ - OSTRACE2( "error-code = %d\n", res ); - } + OSTRACE2( "OS/2 error-code = %d\n", res ); + getReadLock(pFile); + } + OSTRACE3( "LOCK %d acquire exclusive lock. res=%d\n", pFile->h, res ); } /* If we are holding a PENDING lock that ought to be released, then ** release it now. */ if( gotPendingLock && locktype==SHARED_LOCK ){ + int r; LockArea.lOffset = 0L; LockArea.lRange = 0L; UnlockArea.lOffset = PENDING_BYTE; UnlockArea.lRange = 1L; - DosSetFileLocks( pFile->h, &UnlockArea, &LockArea, 2000L, 1L ); + r = DosSetFileLocks( pFile->h, &UnlockArea, &LockArea, 2000L, 1L ); + OSTRACE3( "LOCK %d unlocking pending/is shared. r=%d\n", pFile->h, r ); } /* Update the state of the lock has held in the file descriptor then ** return the appropriate result code. */ if( res == NO_ERROR ){ rc = SQLITE_OK; }else{ OSTRACE4( "LOCK FAILED %d trying for %d but got %d\n", pFile->h, - locktype, newLocktype ); + locktype, newLocktype ); rc = SQLITE_BUSY; } pFile->locktype = newLocktype; + OSTRACE3( "LOCK %d now %d\n", pFile->h, pFile->locktype ); return rc; } /* ** This routine checks if there is a RESERVED lock held on the specified ** file by this or any other process. If such a lock is held, return ** non-zero, otherwise zero. */ -int os2CheckReservedLock( OsFile *id ){ +int os2CheckReservedLock( sqlite3_file *id ){ APIRET rc = NO_ERROR; os2File *pFile = (os2File*)id; assert( pFile!=0 ); if( pFile->locktype>=RESERVED_LOCK ){ rc = 1; @@ -13980,16 +14680,19 @@ LockArea.lOffset = RESERVED_BYTE; LockArea.lRange = 1L; UnlockArea.lOffset = 0L; UnlockArea.lRange = 0L; rc = DosSetFileLocks( pFile->h, &UnlockArea, &LockArea, 2000L, 1L ); + OSTRACE3( "TEST WR-LOCK %d lock reserved byte rc=%d\n", pFile->h, rc ); if( rc == NO_ERROR ){ + int r; LockArea.lOffset = 0L; LockArea.lRange = 0L; UnlockArea.lOffset = RESERVED_BYTE; UnlockArea.lRange = 1L; - rc = DosSetFileLocks( pFile->h, &UnlockArea, &LockArea, 2000L, 1L ); + r = DosSetFileLocks( pFile->h, &UnlockArea, &LockArea, 2000L, 1L ); + OSTRACE3( "TEST WR-LOCK %d unlock reserved byte r=%d\n", pFile->h, r ); } OSTRACE3( "TEST WR-LOCK %d %d (remote)\n", pFile->h, rc ); } return rc; } @@ -14003,14 +14706,15 @@ ** ** It is not possible for this routine to fail if the second argument ** is NO_LOCK. If the second argument is SHARED_LOCK then this routine ** might return SQLITE_IOERR; */ -int os2Unlock( OsFile *id, int locktype ){ +int os2Unlock( sqlite3_file *id, int locktype ){ int type; - APIRET rc = SQLITE_OK; os2File *pFile = (os2File*)id; + APIRET rc = SQLITE_OK; + APIRET res = NO_ERROR; FILELOCK LockArea, UnlockArea; memset(&LockArea, 0, sizeof(LockArea)); memset(&UnlockArea, 0, sizeof(UnlockArea)); assert( pFile!=0 ); @@ -14020,91 +14724,56 @@ if( type>=EXCLUSIVE_LOCK ){ LockArea.lOffset = 0L; LockArea.lRange = 0L; UnlockArea.lOffset = SHARED_FIRST; UnlockArea.lRange = SHARED_SIZE; - DosSetFileLocks( pFile->h, &UnlockArea, &LockArea, 2000L, 1L ); + res = DosSetFileLocks( pFile->h, &UnlockArea, &LockArea, 2000L, 1L ); + OSTRACE3( "UNLOCK %d exclusive lock res=%d\n", pFile->h, res ); if( locktype==SHARED_LOCK && getReadLock(pFile) != NO_ERROR ){ /* This should never happen. We should always be able to ** reacquire the read lock */ - rc = SQLITE_IOERR; + OSTRACE3( "UNLOCK %d to %d getReadLock() failed\n", pFile->h, locktype ); + rc = SQLITE_IOERR_UNLOCK; } } if( type>=RESERVED_LOCK ){ LockArea.lOffset = 0L; LockArea.lRange = 0L; UnlockArea.lOffset = RESERVED_BYTE; UnlockArea.lRange = 1L; - DosSetFileLocks( pFile->h, &UnlockArea, &LockArea, 2000L, 1L ); + res = DosSetFileLocks( pFile->h, &UnlockArea, &LockArea, 2000L, 1L ); + OSTRACE3( "UNLOCK %d reserved res=%d\n", pFile->h, res ); } if( locktype==NO_LOCK && type>=SHARED_LOCK ){ - unlockReadLock(pFile); + res = unlockReadLock(pFile); + OSTRACE5( "UNLOCK %d is %d want %d res=%d\n", pFile->h, type, locktype, res ); } if( type>=PENDING_LOCK ){ LockArea.lOffset = 0L; LockArea.lRange = 0L; UnlockArea.lOffset = PENDING_BYTE; UnlockArea.lRange = 1L; - DosSetFileLocks( pFile->h, &UnlockArea, &LockArea, 2000L, 1L ); + res = DosSetFileLocks( pFile->h, &UnlockArea, &LockArea, 2000L, 1L ); + OSTRACE3( "UNLOCK %d pending res=%d\n", pFile->h, res ); } pFile->locktype = locktype; - return rc; -} - -/* -** Turn a relative pathname into a full pathname. Return a pointer -** to the full pathname stored in space obtained from sqliteMalloc(). -** The calling function is responsible for freeing this space once it -** is no longer needed. -*/ -SQLITE_PRIVATE char *sqlite3Os2FullPathname( const char *zRelative ){ - char *zFull = 0; - if( strchr(zRelative, ':') ){ - sqlite3SetString( &zFull, zRelative, (char*)0 ); - }else{ - ULONG ulDriveNum = 0; - ULONG ulDriveMap = 0; - ULONG cbzBufLen = SQLITE_TEMPNAME_SIZE; - char zDrive[2]; - char *zBuff; - - zBuff = sqliteMalloc( cbzBufLen ); - if( zBuff != 0 ){ - DosQueryCurrentDisk( &ulDriveNum, &ulDriveMap ); - if( DosQueryCurrentDir( ulDriveNum, (PBYTE)zBuff, &cbzBufLen ) == NO_ERROR ){ - sprintf( zDrive, "%c", (char)('A' + ulDriveNum - 1) ); - sqlite3SetString( &zFull, zDrive, ":\\", zBuff, - "\\", zRelative, (char*)0 ); - } - sqliteFree( zBuff ); - } - } - return zFull; -} - -/* -** The fullSync option is meaningless on os2, or correct me if I'm wrong. This is a no-op. -** From os_unix.c: Change the value of the fullsync flag in the given file descriptor. -** From os_unix.c: ((unixFile*)id)->fullSync = v; -*/ -static void os2SetFullSync( OsFile *id, int v ){ - return; -} - -/* -** Return the underlying file handle for an OsFile -*/ -static int os2FileHandle( OsFile *id ){ - return (int)((os2File*)id)->h; -} - -/* -** Return an integer that indices the type of lock currently held -** by this handle. (Used for testing and analysis only.) -*/ -static int os2LockState( OsFile *id ){ - return ((os2File*)id)->locktype; + OSTRACE3( "UNLOCK %d now %d\n", pFile->h, pFile->locktype ); + return rc; +} + +/* +** Control and query of the open file handle. +*/ +static int os2FileControl(sqlite3_file *id, int op, void *pArg){ + switch( op ){ + case SQLITE_FCNTL_LOCKSTATE: { + *(int*)pArg = ((os2File*)id)->locktype; + OSTRACE3( "FCNTL_LOCKSTATE %d lock=%d\n", ((os2File*)id)->h, ((os2File*)id)->locktype ); + return SQLITE_OK; + } + } + return SQLITE_ERROR; } /* ** Return the sector size in bytes of the underlying block device for ** the specified file. This is almost always 512 bytes, but may be @@ -14113,183 +14782,392 @@ ** SQLite code assumes this function cannot fail. It also assumes that ** if two files are created in the same file-system directory (i.e. ** a database and it's journal file) that the sector size will be the ** same for both. */ -static int os2SectorSize(OsFile *id){ +static int os2SectorSize(sqlite3_file *id){ return SQLITE_DEFAULT_SECTOR_SIZE; } /* -** This vector defines all the methods that can operate on an OsFile -** for os2. -*/ -static const IoMethod sqlite3Os2IoMethod = { - os2Close, - os2OpenDirectory, +** Return a vector of device characteristics. +*/ +static int os2DeviceCharacteristics(sqlite3_file *id){ + return 0; +} + +/* +** This vector defines all the methods that can operate on an +** sqlite3_file for os2. +*/ +static const sqlite3_io_methods os2IoMethod = { + 1, /* iVersion */ + os2Close, os2Read, os2Write, - os2Seek, os2Truncate, os2Sync, - os2SetFullSync, - os2FileHandle, os2FileSize, os2Lock, os2Unlock, - os2LockState, os2CheckReservedLock, + os2FileControl, os2SectorSize, -}; - -/* -** Allocate memory for an OsFile. Initialize the new OsFile -** to the value given in pInit and return a pointer to the new -** OsFile. If we run out of memory, close the file and return NULL. -*/ -int allocateOs2File( os2File *pInit, OsFile **pld ){ - os2File *pNew; - pNew = sqliteMalloc( sizeof(*pNew) ); - if( pNew==0 ){ - DosClose( pInit->h ); - *pld = 0; - return SQLITE_NOMEM; - }else{ - *pNew = *pInit; - pNew->pMethod = &sqlite3Os2IoMethod; - pNew->locktype = NO_LOCK; - *pld = (OsFile*)pNew; - OpenCounter(+1); - return SQLITE_OK; - } -} - -#endif /* SQLITE_OMIT_DISKIO */ + os2DeviceCharacteristics +}; + /*************************************************************************** -** Everything above deals with file I/O. Everything that follows deals -** with other miscellanous aspects of the operating system interface +** Here ends the I/O methods that form the sqlite3_io_methods object. +** +** The next block of code implements the VFS methods. ****************************************************************************/ +/* +** Open a file. +*/ +static int os2Open( + sqlite3_vfs *pVfs, /* Not used */ + const char *zName, /* Name of the file */ + sqlite3_file *id, /* Write the SQLite file handle here */ + int flags, /* Open mode flags */ + int *pOutFlags /* Status return flags */ +){ + HFILE h; + ULONG ulFileAttribute = 0; + ULONG ulOpenFlags = 0; + ULONG ulOpenMode = 0; + os2File *pFile = (os2File*)id; + APIRET rc = NO_ERROR; + ULONG ulAction; + + memset(pFile, 0, sizeof(*pFile)); + + OSTRACE2( "OPEN want %d\n", flags ); + + //ulOpenMode = flags & SQLITE_OPEN_READWRITE ? OPEN_ACCESS_READWRITE : OPEN_ACCESS_READONLY; + if( flags & SQLITE_OPEN_READWRITE ){ + ulOpenMode |= OPEN_ACCESS_READWRITE; + OSTRACE1( "OPEN read/write\n" ); + }else{ + ulOpenMode |= OPEN_ACCESS_READONLY; + OSTRACE1( "OPEN read only\n" ); + } + + //ulOpenFlags = flags & SQLITE_OPEN_CREATE ? OPEN_ACTION_CREATE_IF_NEW : OPEN_ACTION_FAIL_IF_NEW; + if( flags & SQLITE_OPEN_CREATE ){ + ulOpenFlags |= OPEN_ACTION_OPEN_IF_EXISTS | OPEN_ACTION_CREATE_IF_NEW; + OSTRACE1( "OPEN open new/create\n" ); + }else{ + ulOpenFlags |= OPEN_ACTION_OPEN_IF_EXISTS | OPEN_ACTION_FAIL_IF_NEW; + OSTRACE1( "OPEN open existing\n" ); + } + + //ulOpenMode |= flags & SQLITE_OPEN_MAIN_DB ? OPEN_SHARE_DENYNONE : OPEN_SHARE_DENYWRITE; + if( flags & SQLITE_OPEN_MAIN_DB ){ + ulOpenMode |= OPEN_SHARE_DENYNONE; + OSTRACE1( "OPEN share read/write\n" ); + }else{ + ulOpenMode |= OPEN_SHARE_DENYWRITE; + OSTRACE1( "OPEN share read only\n" ); + } + + if( flags & (SQLITE_OPEN_TEMP_DB | SQLITE_OPEN_TEMP_JOURNAL + | SQLITE_OPEN_SUBJOURNAL) ){ + //ulFileAttribute = FILE_HIDDEN; //for debugging, we want to make sure it is deleted + ulFileAttribute = FILE_NORMAL; + pFile->delOnClose = 1; + pFile->pathToDel = (char*)malloc(sizeof(char) * pVfs->mxPathname); + sqlite3OsFullPathname(pVfs, zName, pVfs->mxPathname, pFile->pathToDel); + OSTRACE1( "OPEN hidden/delete on close file attributes\n" ); + }else{ + ulFileAttribute = FILE_ARCHIVED | FILE_NORMAL; + pFile->delOnClose = 0; + pFile->pathToDel = NULL; + OSTRACE1( "OPEN normal file attribute\n" ); + } + + //ulOpenMode |= flags & (SQLITE_OPEN_MAIN_DB | SQLITE_OPEN_TEMP_DB) ? + // OPEN_FLAGS_RANDOM : OPEN_FLAGS_SEQUENTIAL; + if( flags & (SQLITE_OPEN_MAIN_DB | SQLITE_OPEN_TEMP_DB) ){ + ulOpenMode |= OPEN_FLAGS_RANDOM; + OSTRACE1( "OPEN random access\n" ); + }else{ + ulOpenMode |= OPEN_FLAGS_SEQUENTIAL; + OSTRACE1( "OPEN sequential access\n" ); + } + ulOpenMode |= OPEN_FLAGS_FAIL_ON_ERROR; + + rc = DosOpen( (PSZ)zName, + &h, + &ulAction, + 0L, + ulFileAttribute, + ulOpenFlags, + ulOpenMode, + (PEAOP2)NULL ); + if( rc != NO_ERROR ){ + OSTRACE7( "OPEN Invalid handle rc=%d: zName=%s, ulAction=%#lx, ulAttr=%#lx, ulFlags=%#lx, ulMode=%#lx\n", + rc, zName, ulAction, ulFileAttribute, ulOpenFlags, ulOpenMode ); + if( flags & SQLITE_OPEN_READWRITE ){ + OSTRACE2( "OPEN %d Invalid handle\n", ((flags | SQLITE_OPEN_READONLY) & ~SQLITE_OPEN_READWRITE) ); + return os2Open( 0, zName, id, + ((flags | SQLITE_OPEN_READONLY) & ~SQLITE_OPEN_READWRITE), + pOutFlags ); + }else{ + return SQLITE_CANTOPEN; + } + } + + if( pOutFlags ){ + *pOutFlags = flags & SQLITE_OPEN_READWRITE ? SQLITE_OPEN_READWRITE : SQLITE_OPEN_READONLY; + } + + pFile->pMethod = &os2IoMethod; + pFile->h = h; + OpenCounter(+1); + OSTRACE3( "OPEN %d pOutFlags=%d\n", pFile->h, pOutFlags ); + return SQLITE_OK; +} + +/* +** Delete the named file. +*/ +int os2Delete( + sqlite3_vfs *pVfs, /* Not used on os2 */ + const char *zFilename, /* Name of file to delete */ + int syncDir /* Not used on os2 */ +){ + APIRET rc = NO_ERROR; + SimulateIOError(return SQLITE_IOERR_DELETE); + rc = DosDelete( (PSZ)zFilename ); + OSTRACE2( "DELETE \"%s\"\n", zFilename ); + return rc == NO_ERROR ? SQLITE_OK : SQLITE_IOERR; +} + +/* +** Check the existance and status of a file. +*/ +static int os2Access( + sqlite3_vfs *pVfs, /* Not used on os2 */ + const char *zFilename, /* Name of file to check */ + int flags /* Type of test to make on this file */ +){ + FILESTATUS3 fsts3ConfigInfo; + APIRET rc = NO_ERROR; + + memset(&fsts3ConfigInfo, 0, sizeof(fsts3ConfigInfo)); + rc = DosQueryPathInfo( (PSZ)zFilename, FIL_STANDARD, + &fsts3ConfigInfo, sizeof(FILESTATUS3) ); + OSTRACE4( "ACCESS fsts3ConfigInfo.attrFile=%d flags=%d rc=%d\n", + fsts3ConfigInfo.attrFile, flags, rc ); + switch( flags ){ + case SQLITE_ACCESS_READ: + case SQLITE_ACCESS_EXISTS: + rc = (rc == NO_ERROR); + OSTRACE3( "ACCESS %s access of read and exists rc=%d\n", zFilename, rc ); + break; + case SQLITE_ACCESS_READWRITE: + rc = (fsts3ConfigInfo.attrFile & FILE_READONLY) == 0; + OSTRACE3( "ACCESS %s access of read/write rc=%d\n", zFilename, rc ); + break; + default: + assert( !"Invalid flags argument" ); + } + return rc; +} + + +/* +** Create a temporary file name in zBuf. zBuf must be big enough to +** hold at pVfs->mxPathname characters. +*/ +static int os2GetTempname( sqlite3_vfs *pVfs, int nBuf, char *zBuf ){ + static const unsigned char zChars[] = + "abcdefghijklmnopqrstuvwxyz" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "0123456789"; + int i, j; + PSZ zTempPath = ""; + if( DosScanEnv( (PSZ)"TEMP", &zTempPath ) ){ + if( DosScanEnv( (PSZ)"TMP", &zTempPath ) ){ + if( DosScanEnv( (PSZ)"TMPDIR", &zTempPath ) ){ + ULONG ulDriveNum = 0, ulDriveMap = 0; + DosQueryCurrentDisk( &ulDriveNum, &ulDriveMap ); + sprintf( (char*)zTempPath, "%c:", (char)( 'A' + ulDriveNum - 1 ) ); + } + } + } + /* strip off a trailing slashes or backslashes, otherwise we would get * + * multiple (back)slashes which causes DosOpen() to fail */ + j = strlen(zTempPath); + while( j > 0 && ( zTempPath[j-1] == '\\' || zTempPath[j-1] == '/' ) ){ + j--; + } + zTempPath[j] = '\0'; + assert( nBuf>=pVfs->mxPathname ); + sqlite3_snprintf( pVfs->mxPathname-30, zBuf, + "%s\\"SQLITE_TEMP_FILE_PREFIX, zTempPath ); + j = strlen( zBuf ); + sqlite3Randomness( 20, &zBuf[j] ); + for( i = 0; i < 20; i++, j++ ){ + zBuf[j] = (char)zChars[ ((unsigned char)zBuf[j])%(sizeof(zChars)-1) ]; + } + zBuf[j] = 0; + OSTRACE2( "TEMP FILENAME: %s\n", zBuf ); + return SQLITE_OK; +} + + +/* +** Turn a relative pathname into a full pathname. Write the full +** pathname into zFull[]. zFull[] will be at least pVfs->mxPathname +** bytes in size. +*/ +static int os2FullPathname( + sqlite3_vfs *pVfs, /* Pointer to vfs object */ + const char *zRelative, /* Possibly relative input path */ + int nFull, /* Size of output buffer in bytes */ + char *zFull /* Output buffer */ +){ + if( strchr(zRelative, ':') ){ + sqlite3SetString( &zFull, zRelative, (char*)0 ); + }else{ + ULONG ulDriveNum = 0; + ULONG ulDriveMap = 0; + ULONG cbzBufLen = SQLITE_TEMPNAME_SIZE; + char zDrive[2]; + char *zBuff = (char*)malloc( cbzBufLen ); + if( zBuff == 0 ){ + return SQLITE_NOMEM; + } + DosQueryCurrentDisk( &ulDriveNum, &ulDriveMap ); + if( DosQueryCurrentDir( ulDriveNum, (PBYTE)zBuff, &cbzBufLen ) == NO_ERROR ){ + sprintf( zDrive, "%c", (char)('A' + ulDriveNum - 1) ); + sqlite3SetString( &zFull, zDrive, ":\\", zBuff, + "\\", zRelative, (char*)0 ); + } + free( zBuff ); + } + return SQLITE_OK; +} + #ifndef SQLITE_OMIT_LOAD_EXTENSION /* ** Interfaces for opening a shared library, finding entry points ** within the shared library, and closing the shared library. */ -SQLITE_PRIVATE void *sqlite3Os2Dlopen(const char *zFilename){ +/* +** Interfaces for opening a shared library, finding entry points +** within the shared library, and closing the shared library. +*/ +static void *os2DlOpen(sqlite3_vfs *pVfs, const char *zFilename){ UCHAR loadErr[256]; HMODULE hmod; APIRET rc; rc = DosLoadModule((PSZ)loadErr, sizeof(loadErr), zFilename, &hmod); - if (rc != NO_ERROR) return 0; - return (void*)hmod; -} -SQLITE_PRIVATE void *sqlite3Os2Dlsym(void *pHandle, const char *zSymbol){ + return rc != NO_ERROR ? 0 : (void*)hmod; +} +/* +** A no-op since the error code is returned on the DosLoadModule call. +** os2Dlopen returns zero if DosLoadModule is not successful. +*/ +static void os2DlError(sqlite3_vfs *pVfs, int nBuf, char *zBufOut){ +/* no-op */ +} +void *os2DlSym(sqlite3_vfs *pVfs, void *pHandle, const char *zSymbol){ PFN pfn; APIRET rc; rc = DosQueryProcAddr((HMODULE)pHandle, 0L, zSymbol, &pfn); - if (rc != NO_ERROR) { + if( rc != NO_ERROR ){ /* if the symbol itself was not found, search again for the same * symbol with an extra underscore, that might be needed depending * on the calling convention */ char _zSymbol[256] = "_"; strncat(_zSymbol, zSymbol, 255); rc = DosQueryProcAddr((HMODULE)pHandle, 0L, _zSymbol, &pfn); } - if (rc != NO_ERROR) return 0; - return (void *)pfn; -} -SQLITE_PRIVATE int sqlite3Os2Dlclose(void *pHandle){ - return DosFreeModule((HMODULE)pHandle); -} -#endif /* SQLITE_OMIT_LOAD_EXTENSION */ - - -/* -** Get information to seed the random number generator. The seed -** is written into the buffer zBuf[256]. The calling function must -** supply a sufficiently large buffer. -*/ -SQLITE_PRIVATE int sqlite3Os2RandomSeed( char *zBuf ){ - /* We have to initialize zBuf to prevent valgrind from reporting - ** errors. The reports issued by valgrind are incorrect - we would - ** prefer that the randomness be increased by making use of the - ** uninitialized space in zBuf - but valgrind errors tend to worry - ** some users. Rather than argue, it seems easier just to initialize - ** the whole array and silence valgrind, even if that means less randomness - ** in the random seed. - ** - ** When testing, initializing zBuf[] to zero is all we do. That means - ** that we always use the same random number sequence. This makes the - ** tests repeatable. - */ - memset( zBuf, 0, 256 ); - DosGetDateTime( (PDATETIME)zBuf ); - return SQLITE_OK; + return rc != NO_ERROR ? 0 : (void*)pfn; +} +void os2DlClose(sqlite3_vfs *pVfs, void *pHandle){ + DosFreeModule((HMODULE)pHandle); +} +#else /* if SQLITE_OMIT_LOAD_EXTENSION is defined: */ + #define os2DlOpen 0 + #define os2DlError 0 + #define os2DlSym 0 + #define os2DlClose 0 +#endif + + +/* +** Write up to nBuf bytes of randomness into zBuf. +*/ +static int os2Randomness(sqlite3_vfs *pVfs, int nBuf, char *zBuf ){ + ULONG sizeofULong = sizeof(ULONG); + int n = 0; + if( sizeof(DATETIME) <= nBuf - n ){ + DATETIME x; + DosGetDateTime(&x); + memcpy(&zBuf[n], &x, sizeof(x)); + n += sizeof(x); + } + + if( sizeofULong <= nBuf - n ){ + PPIB ppib; + DosGetInfoBlocks(NULL, &ppib); + memcpy(&zBuf[n], &ppib->pib_ulpid, sizeofULong); + n += sizeofULong; + } + + if( sizeofULong <= nBuf - n ){ + PTIB ptib; + DosGetInfoBlocks(&ptib, NULL); + memcpy(&zBuf[n], &ptib->tib_ptib2->tib2_ultid, sizeofULong); + n += sizeofULong; + } + + /* if we still haven't filled the buffer yet the following will */ + /* grab everything once instead of making several calls for a single item */ + if( sizeofULong <= nBuf - n ){ + ULONG ulSysInfo[QSV_MAX]; + DosQuerySysInfo(1L, QSV_MAX, ulSysInfo, sizeofULong * QSV_MAX); + + memcpy(&zBuf[n], &ulSysInfo[QSV_MS_COUNT - 1], sizeofULong); + n += sizeofULong; + + if( sizeofULong <= nBuf - n ){ + memcpy(&zBuf[n], &ulSysInfo[QSV_TIMER_INTERVAL - 1], sizeofULong); + n += sizeofULong; + } + if( sizeofULong <= nBuf - n ){ + memcpy(&zBuf[n], &ulSysInfo[QSV_TIME_LOW - 1], sizeofULong); + n += sizeofULong; + } + if( sizeofULong <= nBuf - n ){ + memcpy(&zBuf[n], &ulSysInfo[QSV_TIME_HIGH - 1], sizeofULong); + n += sizeofULong; + } + if( sizeofULong <= nBuf - n ){ + memcpy(&zBuf[n], &ulSysInfo[QSV_TOTAVAILMEM - 1], sizeofULong); + n += sizeofULong; + } + } + + return n; } /* ** Sleep for a little while. Return the amount of time slept. -*/ -SQLITE_PRIVATE int sqlite3Os2Sleep( int ms ){ - DosSleep( ms ); - return ms; -} - -/* -** Static variables used for thread synchronization -*/ -static int inMutex = 0; -#ifdef SQLITE_OS2_THREADS -static ULONG mutexOwner; -#endif - -/* -** The following pair of routines implement mutual exclusion for -** multi-threaded processes. Only a single thread is allowed to -** executed code that is surrounded by EnterMutex() and LeaveMutex(). -** -** SQLite uses only a single Mutex. There is not much critical -** code and what little there is executes quickly and without blocking. -*/ -SQLITE_PRIVATE void sqlite3Os2EnterMutex(){ -#ifdef SQLITE_OS2_THREADS - PTIB ptib; - DosEnterCritSec(); - DosGetInfoBlocks( &ptib, NULL ); - mutexOwner = ptib->tib_ptib2->tib2_ultid; -#endif - assert( !inMutex ); - inMutex = 1; -} -SQLITE_PRIVATE void sqlite3Os2LeaveMutex(){ -#ifdef SQLITE_OS2_THREADS - PTIB ptib; -#endif - assert( inMutex ); - inMutex = 0; -#ifdef SQLITE_OS2_THREADS - DosGetInfoBlocks( &ptib, NULL ); - assert( mutexOwner == ptib->tib_ptib2->tib2_ultid ); - DosExitCritSec(); -#endif -} - -/* -** Return TRUE if the mutex is currently held. -** -** If the thisThreadOnly parameter is true, return true if and only if the -** calling thread holds the mutex. If the parameter is false, return -** true if any thread holds the mutex. -*/ -SQLITE_PRIVATE int sqlite3Os2InMutex( int thisThreadOnly ){ -#ifdef SQLITE_OS2_THREADS - PTIB ptib; - DosGetInfoBlocks( &ptib, NULL ); - return inMutex>0 && (thisThreadOnly==0 || mutexOwner==ptib->tib_ptib2->tib2_ultid); -#else - return inMutex>0; -#endif +** The argument is the number of microseconds we want to sleep. +** The return value is the number of microseconds of sleep actually +** requested from the underlying operating system, a number which +** might be greater than or equal to the argument, but not less +** than the argument. +*/ +static int os2Sleep( sqlite3_vfs *pVfs, int microsec ){ + DosSleep( (microsec/1000) ); + return microsec; } /* ** The following variable, if set to a non-zero value, becomes the result ** returned from sqlite3OsCurrentTime(). This is used for testing. @@ -14301,18 +15179,19 @@ /* ** Find the current time (in Universal Coordinated Time). Write the ** current time and date as a Julian Day number into *prNow and ** return 0. Return 1 if the time and date cannot be found. */ -SQLITE_PRIVATE int sqlite3Os2CurrentTime( double *prNow ){ +int os2CurrentTime( sqlite3_vfs *pVfs, double *prNow ){ double now; - USHORT second, minute, hour, + SHORT minute; /* needs to be able to cope with negative timezone offset */ + USHORT second, hour, day, month, year; DATETIME dt; DosGetDateTime( &dt ); second = (USHORT)dt.seconds; - minute = (USHORT)dt.minutes + dt.timezone; + minute = (SHORT)dt.minutes + dt.timezone; hour = (USHORT)dt.hours; day = (USHORT)dt.day; month = (USHORT)dt.month; year = (USHORT)dt.year; @@ -14336,74 +15215,41 @@ #endif return 0; } /* -** Remember the number of thread-specific-data blocks allocated. -** Use this to verify that we are not leaking thread-specific-data. -** Ticket #1601 -*/ -#ifdef SQLITE_TEST -SQLITE_API int sqlite3_tsd_count = 0; -# define TSD_COUNTER_INCR InterlockedIncrement( &sqlite3_tsd_count ) -# define TSD_COUNTER_DECR InterlockedDecrement( &sqlite3_tsd_count ) -#else -# define TSD_COUNTER_INCR /* no-op */ -# define TSD_COUNTER_DECR /* no-op */ -#endif - -/* -** If called with allocateFlag>1, then return a pointer to thread -** specific data for the current thread. Allocate and zero the -** thread-specific data if it does not already exist necessary. -** -** If called with allocateFlag==0, then check the current thread -** specific data. Return it if it exists. If it does not exist, -** then return NULL. -** -** If called with allocateFlag<0, check to see if the thread specific -** data is allocated and is all zero. If it is then deallocate it. -** Return a pointer to the thread specific data or NULL if it is -** unallocated or gets deallocated. -*/ -SQLITE_PRIVATE ThreadData *sqlite3Os2ThreadSpecificData( int allocateFlag ){ - static ThreadData **s_ppTsd = NULL; - static const ThreadData zeroData = {0, 0, 0}; - ThreadData *pTsd; - - if( !s_ppTsd ){ - sqlite3OsEnterMutex(); - if( !s_ppTsd ){ - PULONG pul; - APIRET rc = DosAllocThreadLocalMemory(1, &pul); - if( rc != NO_ERROR ){ - sqlite3OsLeaveMutex(); - return 0; - } - s_ppTsd = (ThreadData **)pul; - } - sqlite3OsLeaveMutex(); - } - pTsd = *s_ppTsd; - if( allocateFlag>0 ){ - if( !pTsd ){ - pTsd = sqlite3OsMalloc( sizeof(zeroData) ); - if( pTsd ){ - *pTsd = zeroData; - *s_ppTsd = pTsd; - TSD_COUNTER_INCR; - } - } - }else if( pTsd!=0 && allocateFlag<0 - && memcmp( pTsd, &zeroData, sizeof(ThreadData) )==0 ){ - sqlite3OsFree(pTsd); - *s_ppTsd = NULL; - TSD_COUNTER_DECR; - pTsd = 0; - } - return pTsd; -} +** Return a pointer to the sqlite3DefaultVfs structure. We use +** a function rather than give the structure global scope because +** some compilers (MSVC) do not allow forward declarations of +** initialized structures. +*/ +SQLITE_PRIVATE sqlite3_vfs *sqlite3OsDefaultVfs(void){ + static sqlite3_vfs os2Vfs = { + 1, /* iVersion */ + sizeof(os2File), /* szOsFile */ + CCHMAXPATH, /* mxPathname */ + 0, /* pNext */ + "os2", /* zName */ + 0, /* pAppData */ + + os2Open, /* xOpen */ + os2Delete, /* xDelete */ + os2Access, /* xAccess */ + os2GetTempname, /* xGetTempname */ + os2FullPathname, /* xFullPathname */ + os2DlOpen, /* xDlOpen */ + os2DlError, /* xDlError */ + os2DlSym, /* xDlSym */ + os2DlClose, /* xDlClose */ + os2Randomness, /* xRandomness */ + os2Sleep, /* xSleep */ + os2CurrentTime /* xCurrentTime */ + }; + + return &os2Vfs; +} + #endif /* OS_OS2 */ /************** End of os_os2.c **********************************************/ /************** Begin file os_unix.c *****************************************/ /* @@ -15306,10 +16152,16 @@ #endif /* ** Seek to the offset passed as the second argument, then read cnt ** bytes into pBuf. Return the number of bytes actually read. +** +** NB: If you define USE_PREAD or USE_PREAD64, then it might also +** be necessary to define _XOPEN_SOURCE to be 500. This varies from +** one system to another. Since SQLite does not define USE_PREAD +** any any form by default, we will not attempt to define _XOPEN_SOURCE. +** See tickets #2741 and #2681. */ static int seekAndRead(unixFile *id, sqlite3_int64 offset, void *pBuf, int cnt){ int got; i64 newOffset; TIMER_START; @@ -16796,10 +17648,11 @@ enterMutex(); rc = findLockInfo(h, &pNew->pLock, &pNew->pOpen); leaveMutex(); if( rc ){ + if( dirfd>=0 ) close(dirfd); close(h); return SQLITE_NOMEM; } OSTRACE3("OPEN %-3d %s\n", h, zFilename); @@ -16824,27 +17677,27 @@ ** If SQLITE_OK is returned, the caller is responsible for closing ** the file descriptor *pFd using close(). */ static int openDirectory(const char *zFilename, int *pFd){ int ii; - int fd; + int fd = -1; char zDirname[MAX_PATHNAME+1]; sqlite3_snprintf(MAX_PATHNAME, zDirname, "%s", zFilename); for(ii=strlen(zDirname); ii>=0 && zDirname[ii]!='/'; ii--); if( ii>0 ){ zDirname[ii] = '\0'; fd = open(zDirname, O_RDONLY|O_BINARY, 0); - if( fd>0 ){ + if( fd>=0 ){ #ifdef FD_CLOEXEC fcntl(fd, F_SETFD, fcntl(fd, F_GETFD, 0) | FD_CLOEXEC); #endif OSTRACE3("OPENDIR %-3d %s\n", fd, zDirname); } } *pFd = fd; - return (fd>0?SQLITE_OK:SQLITE_CANTOPEN); + return (fd>=0?SQLITE_OK:SQLITE_CANTOPEN); } /* ** Open the file zPath. ** @@ -16985,11 +17838,11 @@ ** SQLITE_ACCESS_READONLY: Return 1 if the file is readable. ** ** Otherwise return 0. */ static int unixAccess(sqlite3_vfs *pVfs, const char *zPath, int flags){ - int amode; + int amode = 0; switch( flags ){ case SQLITE_ACCESS_EXISTS: amode = F_OK; break; case SQLITE_ACCESS_READWRITE: @@ -17008,11 +17861,11 @@ /* ** Create a temporary file name in zBuf. zBuf must be allocated ** by the calling process and must be big enough to hold at least ** pVfs->mxPathname bytes. */ -static int unixGetTempName(sqlite3_vfs *pVfs, char *zBuf){ +static int unixGetTempname(sqlite3_vfs *pVfs, int nBuf, char *zBuf){ static const char *azDirs[] = { 0, "/var/tmp", "/usr/tmp", "/tmp", @@ -17041,10 +17894,11 @@ zDir = azDirs[i]; break; } do{ assert( pVfs->mxPathname==MAX_PATHNAME ); + assert( nBuf>=MAX_PATHNAME ); sqlite3_snprintf(MAX_PATHNAME-17, zBuf, "%s/"SQLITE_TEMP_FILE_PREFIX, zDir); j = strlen(zBuf); sqlite3Randomness(15, &zBuf[j]); for(i=0; i<15; i++, j++){ zBuf[j] = (char)zChars[ ((unsigned char)zBuf[j])%(sizeof(zChars)-1) ]; @@ -17062,11 +17916,16 @@ ** ** zOut points to a buffer of at least sqlite3_vfs.mxPathname bytes ** (in this case, MAX_PATHNAME bytes). The full-path is written to ** this buffer before returning. */ -static int unixFullPathname(sqlite3_vfs *pVfs, const char *zPath, char *zOut){ +static int unixFullPathname( + sqlite3_vfs *pVfs, /* Pointer to vfs object */ + const char *zPath, /* Possibly relative input path */ + int nOut, /* Size of output buffer in bytes */ + char *zOut /* Output buffer */ +){ /* It's odd to simulate an io-error here, but really this is just ** using the io-error infrastructure to test that SQLite handles this ** function failing. This function could fail if, for example, the ** current working directly has been unlinked. @@ -17260,11 +18119,11 @@ 0, /* pAppData */ unixOpen, /* xOpen */ unixDelete, /* xDelete */ unixAccess, /* xAccess */ - unixGetTempName, /* xGetTempName */ + unixGetTempname, /* xGetTempName */ unixFullPathname, /* xFullPathname */ unixDlOpen, /* xDlOpen */ unixDlError, /* xDlError */ unixDlSym, /* xDlSym */ unixDlClose, /* xDlClose */ @@ -17699,11 +18558,11 @@ struct tm *__cdecl localtime(const time_t *t) { static struct tm y; FILETIME uTm, lTm; SYSTEMTIME pTm; - i64 t64; + sqlite3_int64 t64; t64 = *t; t64 = (t64 + 11644473600)*10000000; uTm.dwLowDateTime = t64 & 0xFFFFFFFF; uTm.dwHighDateTime= t64 >> 32; FileTimeToLocalFileTime(&uTm,&lTm); @@ -17839,16 +18698,10 @@ } /* De-reference and close our copy of the shared memory handle */ UnmapViewOfFile(pFile->shared); CloseHandle(pFile->hShared); - - if( pFile->zDeleteOnClose ){ - DeleteFileW(pFile->zDeleteOnClose); - free(pFile->zDeleteOnClose); - pFile->zDeleteOnClose = 0; - } /* Done with the mutex */ winceMutexRelease(pFile->hMutex); CloseHandle(pFile->hMutex); pFile->hMutex = NULL; @@ -18022,10 +18875,14 @@ do{ rc = CloseHandle(pFile->h); }while( rc==0 && cnt++ < MX_CLOSE_ATTEMPT && (Sleep(100), 1) ); #if OS_WINCE winceDestroyLock(pFile); + if( pFile->zDeleteOnClose ){ + DeleteFileW(pFile->zDeleteOnClose); + free(pFile->zDeleteOnClose); + } #endif OpenCounter(-1); return rc ? SQLITE_OK : SQLITE_IOERR; } @@ -18109,11 +18966,11 @@ } /* ** Truncate an open file to a specified size */ -static int winTruncate(sqlite3_file *id, i64 nByte){ +static int winTruncate(sqlite3_file *id, sqlite3_int64 nByte){ LONG upperBits = (nByte>>32) & 0x7fffffff; LONG lowerBits = nByte & 0xffffffff; winFile *pFile = (winFile*)id; OSTRACE3("TRUNCATE %d %lld\n", pFile->h, nByte); SimulateIOError(return SQLITE_IOERR_TRUNCATE); @@ -18492,10 +19349,11 @@ HANDLE h; DWORD dwDesiredAccess; DWORD dwShareMode; DWORD dwCreationDisposition; DWORD dwFlagsAndAttributes = 0; + int isTemp; winFile *pFile = (winFile*)id; void *zConverted = convertUtf8Filename(zName); if( zConverted==0 ){ return SQLITE_NOMEM; } @@ -18515,21 +19373,25 @@ }else{ dwShareMode = 0; } if( flags & (SQLITE_OPEN_TEMP_DB | SQLITE_OPEN_TEMP_JOURNAL | SQLITE_OPEN_SUBJOURNAL) ){ +#if OS_WINCE + dwFlagsAndAttributes = FILE_ATTRIBUTE_HIDDEN; +#else dwFlagsAndAttributes = FILE_ATTRIBUTE_TEMPORARY | FILE_ATTRIBUTE_HIDDEN | FILE_FLAG_DELETE_ON_CLOSE; +#endif + isTemp = 1; }else{ dwFlagsAndAttributes = FILE_ATTRIBUTE_NORMAL; - } - if( flags & (SQLITE_OPEN_MAIN_DB | SQLITE_OPEN_TEMP_DB) ){ - dwFlagsAndAttributes |= FILE_FLAG_RANDOM_ACCESS; - }else{ - dwFlagsAndAttributes |= FILE_FLAG_SEQUENTIAL_SCAN; - } + isTemp = 0; + } + /* Reports from the internet are that performance is always + ** better if FILE_FLAG_RANDOM_ACCESS is used. Ticket #2699. */ + dwFlagsAndAttributes |= FILE_FLAG_RANDOM_ACCESS; if( isNT() ){ h = CreateFileW((WCHAR*)zConverted, dwDesiredAccess, dwShareMode, NULL, @@ -18571,17 +19433,17 @@ pFile->pMethod = &winIoMethod; pFile->h = h; #if OS_WINCE if( (flags & (SQLITE_OPEN_READWRITE|SQLITE_OPEN_MAIN_DB)) == (SQLITE_OPEN_READWRITE|SQLITE_OPEN_MAIN_DB) - && !winceCreateLock(zFilename, &f) + && !winceCreateLock(zName, pFile) ){ CloseHandle(h); free(zConverted); return SQLITE_CANTOPEN; } - if( dwFlagsAndAttributes & FILE_FLAG_DELETEONCLOSE ){ + if( isTemp ){ pFile->zDeleteOnClose = zConverted; }else #endif { free(zConverted); @@ -18594,17 +19456,17 @@ ** Delete the named file. ** ** Note that windows does not allow a file to be deleted if some other ** process has it open. Sometimes a virus scanner or indexing program ** will open a journal file shortly after it is created in order to do -** whatever it is it does. While this other process is holding the +** whatever does. While this other process is holding the ** file open, we will be unable to delete it. To work around this ** problem, we delay 100 milliseconds and try to delete again. Up ** to MX_DELETION_ATTEMPTs deletion attempts are run before giving ** up and returning an error. */ -#define MX_DELETION_ATTEMPTS 3 +#define MX_DELETION_ATTEMPTS 5 static int winDelete( sqlite3_vfs *pVfs, /* Not used on win32 */ const char *zFilename, /* Name of file to delete */ int syncDir /* Not used on win32 */ ){ @@ -18615,26 +19477,26 @@ return SQLITE_NOMEM; } SimulateIOError(return SQLITE_IOERR_DELETE); if( isNT() ){ do{ - rc = DeleteFileW(zConverted); - }while( rc==0 && GetFileAttributesW(zConverted)!=0xffffffff + DeleteFileW(zConverted); + }while( (rc = GetFileAttributesW(zConverted))!=0xffffffff && cnt++ < MX_DELETION_ATTEMPTS && (Sleep(100), 1) ); }else{ #if OS_WINCE return SQLITE_NOMEM; #else do{ - rc = DeleteFileA(zConverted); - }while( rc==0 && GetFileAttributesA(zConverted)!=0xffffffff + DeleteFileA(zConverted); + }while( (rc = GetFileAttributesA(zConverted))!=0xffffffff && cnt++ < MX_DELETION_ATTEMPTS && (Sleep(100), 1) ); #endif } free(zConverted); OSTRACE2("DELETE \"%s\"\n", zFilename); - return rc!=0 ? SQLITE_OK : SQLITE_IOERR; + return rc==0xffffffff ? SQLITE_OK : SQLITE_IOERR_DELETE; } /* ** Check the existance and status of a file. */ @@ -18676,11 +19538,11 @@ /* ** Create a temporary file name in zBuf. zBuf must be big enough to ** hold at pVfs->mxPathname characters. */ -static int winGetTempName(sqlite3_vfs *pVfs, char *zBuf){ +static int winGetTempname(sqlite3_vfs *pVfs, int nBuf, char *zBuf){ static char zChars[] = "abcdefghijklmnopqrstuvwxyz" "ABCDEFGHIJKLMNOPQRSTUVWXYZ" "0123456789"; int i, j; @@ -18728,13 +19590,14 @@ ** Turn a relative pathname into a full pathname. Write the full ** pathname into zOut[]. zOut[] will be at least pVfs->mxPathname ** bytes in size. */ static int winFullPathname( - sqlite3_vfs *pVfs, - const char *zRelative, - char *zFull + sqlite3_vfs *pVfs, /* Pointer to vfs object */ + const char *zRelative, /* Possibly relative input path */ + int nFull, /* Size of output buffer in bytes */ + char *zFull /* Output buffer */ ){ #if defined(__CYGWIN__) cygwin_conv_to_full_win32_path(zRelative, zFull); return SQLITE_OK; @@ -18741,10 +19604,11 @@ #endif #if OS_WINCE /* WinCE has no concept of a relative pathname, or so I am told. */ sqlite3_snprintf(pVfs->mxPathname, zFull, "%s", zRelative); + return SQLITE_OK; #endif #if !OS_WINCE && !defined(__CYGWIN__) int nByte; void *zConverted; @@ -18811,19 +19675,28 @@ } free(zConverted); return (void*)h; } static void winDlError(sqlite3_vfs *pVfs, int nBuf, char *zBufOut){ - FormatMessage( +#if OS_WINCE + int error = GetLastError(); + if( error>0x7FFFFFF ){ + sqlite3_snprintf(nBuf, zBufOut, "OsError 0x%x", error); + }else{ + sqlite3_snprintf(nBuf, zBufOut, "OsError %d", error); + } +#else + FormatMessageA( FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(), 0, zBufOut, nBuf-1, 0 ); +#endif } void *winDlSym(sqlite3_vfs *pVfs, void *pHandle, const char *zSymbol){ #if OS_WINCE /* The GetProcAddressA() routine is only available on wince. */ return GetProcAddressA((HANDLE)pHandle, zSymbol); @@ -18936,11 +19809,11 @@ 0, /* pAppData */ winOpen, /* xOpen */ winDelete, /* xDelete */ winAccess, /* xAccess */ - winGetTempName, /* xGetTempName */ + winGetTempname, /* xGetTempName */ winFullPathname, /* xFullPathname */ winDlOpen, /* xDlOpen */ winDlError, /* xDlError */ winDlSym, /* xDlSym */ winDlClose, /* xDlClose */ @@ -18974,11 +19847,11 @@ ** is separate from the database file. The pager also implements file ** locking to prevent two processes from writing the same database ** file simultaneously, or one process from reading the database while ** another is writing. ** -** @(#) $Id: pager.c,v 1.388 2007/09/10 06:12:04 danielk1977 Exp $ +** @(#) $Id: pager.c,v 1.394 2007/11/05 15:30:13 danielk1977 Exp $ */ #ifndef SQLITE_OMIT_DISKIO /* ** Macros for troubleshooting. Normally turned off @@ -19762,13 +20635,21 @@ ** code. The first argument is a pointer to the pager structure, the ** second the error-code about to be returned by a pager API function. ** The value returned is a copy of the second argument to this function. ** ** If the second argument is SQLITE_IOERR, SQLITE_CORRUPT, or SQLITE_FULL -** the error becomes persistent. All subsequent API calls on this Pager -** will immediately return the same error code. -*/ +** the error becomes persistent. Until the persisten error is cleared, +** subsequent API calls on this Pager will immediately return the same +** error code. +** +** A persistent error indicates that the contents of the pager-cache +** cannot be trusted. This state can be cleared by completely discarding +** the contents of the pager-cache. If a transaction was active when +** the persistent error occured, then the rollback journal may need +** to be replayed. +*/ +static void pager_unlock(Pager *pPager); static int pager_error(Pager *pPager, int rc){ int rc2 = rc & 0xff; assert( pPager->errCode==SQLITE_FULL || pPager->errCode==SQLITE_OK || @@ -19778,10 +20659,17 @@ rc2==SQLITE_FULL || rc2==SQLITE_IOERR || rc2==SQLITE_CORRUPT ){ pPager->errCode = rc; + if( pPager->state==PAGER_UNLOCK && pPager->nRef==0 ){ + /* If the pager is already unlocked, call pager_unlock() now to + ** clear the error state and ensure that the pager-cache is + ** completely empty. + */ + pager_unlock(pPager); + } } return rc; } /* @@ -20152,42 +21040,10 @@ } return p; } /* -** Unlock the database file. -*/ -static void pager_unlock(Pager *pPager){ - if( !pPager->exclusiveMode ){ - if( !MEMDB ){ - osUnlock(pPager->fd, NO_LOCK); - pPager->dbSize = -1; - IOTRACE(("UNLOCK %p\n", pPager)) - } - pPager->state = PAGER_UNLOCK; - pPager->changeCountDone = 0; - } -} - -/* -** Execute a rollback if a transaction is active and unlock the -** database file. This is a no-op if the pager has already entered -** the error-state. -*/ -static void pagerUnlockAndRollback(Pager *p){ - if( p->errCode ) return; - assert( p->state>=PAGER_RESERVED || p->journalOpen==0 ); - if( p->state>=PAGER_RESERVED ){ - sqlite3PagerRollback(p); - } - pager_unlock(p); - assert( p->errCode || !p->journalOpen || (p->exclusiveMode&&!p->journalOff) ); - assert( p->errCode || !p->stmtOpen || p->exclusiveMode ); -} - - -/* ** Clear the in-memory cache. This routine ** sets the state of the pager back to what it was when it was first ** opened. Any outstanding pages are invalidated and subsequent attempts ** to access those pages will likely result in a coredump. */ @@ -20197,23 +21053,90 @@ for(pPg=pPager->pAll; pPg; pPg=pNext){ IOTRACE(("PGFREE %p %d\n", pPager, pPg->pgno)); PAGER_INCR(sqlite3_pager_pgfree_count); pNext = pPg->pNextAll; lruListRemove(pPg); - sqlite3_free(pPg->pData); sqlite3_free(pPg); } assert(pPager->lru.pFirst==0); assert(pPager->lru.pFirstSynced==0); assert(pPager->lru.pLast==0); pPager->pStmt = 0; pPager->pAll = 0; + pPager->pDirty = 0; pPager->nHash = 0; sqlite3_free(pPager->aHash); pPager->nPage = 0; pPager->aHash = 0; pPager->nRef = 0; +} + +/* +** Unlock the database file. +** +** If the pager is currently in error state, discard the contents of +** the cache and reset the Pager structure internal state. If there is +** an open journal-file, then the next time a shared-lock is obtained +** on the pager file (by this or any other process), it will be +** treated as a hot-journal and rolled back. +*/ +static void pager_unlock(Pager *pPager){ + if( !pPager->exclusiveMode ){ + if( !MEMDB ){ + if( pPager->fd->pMethods ){ + osUnlock(pPager->fd, NO_LOCK); + } + pPager->dbSize = -1; + IOTRACE(("UNLOCK %p\n", pPager)) + + /* If Pager.errCode is set, the contents of the pager cache cannot be + ** trusted. Now that the pager file is unlocked, the contents of the + ** cache can be discarded and the error code safely cleared. + */ + if( pPager->errCode ){ + pPager->errCode = SQLITE_OK; + pager_reset(pPager); + if( pPager->stmtOpen ){ + sqlite3OsClose(pPager->stfd); + sqlite3_free(pPager->aInStmt); + pPager->aInStmt = 0; + } + if( pPager->journalOpen ){ + sqlite3OsClose(pPager->jfd); + pPager->journalOpen = 0; + sqlite3_free(pPager->aInJournal); + pPager->aInJournal = 0; + } + pPager->stmtOpen = 0; + pPager->stmtInUse = 0; + pPager->journalOff = 0; + pPager->journalStarted = 0; + pPager->stmtAutoopen = 0; + pPager->origDbSize = 0; + } + } + + if( !MEMDB || pPager->errCode==SQLITE_OK ){ + pPager->state = PAGER_UNLOCK; + pPager->changeCountDone = 0; + } + } +} + +/* +** Execute a rollback if a transaction is active and unlock the +** database file. If the pager has already entered the error state, +** do not attempt the rollback. +*/ +static void pagerUnlockAndRollback(Pager *p){ + assert( p->state>=PAGER_RESERVED || p->journalOpen==0 ); + if( p->errCode==SQLITE_OK && p->state>=PAGER_RESERVED ){ + sqlite3PagerRollback(p); + } + pager_unlock(p); + assert( p->errCode || !p->journalOpen || (p->exclusiveMode&&!p->journalOff) ); + assert( p->errCode || !p->stmtOpen || p->exclusiveMode ); } /* ** This routine ends a transaction. A transaction is ended by either ** a COMMIT or a ROLLBACK. @@ -20992,11 +21915,12 @@ /* The default return is a NULL pointer */ *ppPager = 0; /* Compute the full pathname */ - zPathname = sqlite3_malloc(pVfs->mxPathname+1); + nPathname = pVfs->mxPathname+1; + zPathname = sqlite3_malloc(nPathname); if( zPathname==0 ){ return SQLITE_NOMEM; } if( zFilename && zFilename[0] ){ #ifndef SQLITE_OMIT_MEMORYDB @@ -21004,14 +21928,14 @@ memDb = 1; zPathname[0] = 0; }else #endif { - rc = sqlite3OsFullPathname(pVfs, zFilename, zPathname); - } - }else{ - rc = sqlite3OsGetTempName(pVfs, zPathname); + rc = sqlite3OsFullPathname(pVfs, zFilename, nPathname, zPathname); + } + }else{ + rc = sqlite3OsGetTempname(pVfs, nPathname, zPathname); } if( rc!=SQLITE_OK ){ sqlite3_free(zPathname); return rc; } @@ -21319,11 +22243,13 @@ n = pPager->dbSize; } else { assert(pPager->fd->pMethods||pPager->tempFile); if( (pPager->fd->pMethods) && (rc = sqlite3OsFileSize(pPager->fd, &n))!=SQLITE_OK ){ + pPager->nRef++; pager_error(pPager, rc); + pPager->nRef--; return 0; } if( n>0 && n<pPager->pageSize ){ n = 1; }else{ @@ -21432,11 +22358,10 @@ *ppPg = pPg->pNextAll; IOTRACE(("PGFREE %p %d\n", pPager, pPg->pgno)); PAGER_INCR(sqlite3_pager_pgfree_count); unlinkPage(pPg); makeClean(pPg); - sqlite3_free(pPg->pData); sqlite3_free(pPg); pPager->nPage--; } } } @@ -22096,11 +23021,10 @@ + sizeof(u32) + pPager->nExtra + MEMDB*sizeof(PgHistory) ); IOTRACE(("PGFREE %p %d *\n", pPager, pPg->pgno)); PAGER_INCR(sqlite3_pager_pgfree_count); - sqlite3_free(pPg->pData); sqlite3_free(pPg); pPager->nPage--; }else{ /* An error occured whilst writing to the database file or ** journal in pager_recycle(). The error is not returned to the @@ -22167,12 +23091,34 @@ ** checks for a hot-journal file. If one is found, an emergency rollback ** is performed immediately. */ static int pagerSharedLock(Pager *pPager){ int rc = SQLITE_OK; - - if( pPager->state==PAGER_UNLOCK ){ + int isHot = 0; + + /* If this database is opened for exclusive access, has no outstanding + ** page references and is in an error-state, now is the chance to clear + ** the error. Discard the contents of the pager-cache and treat any + ** open journal file as a hot-journal. + */ + if( !MEMDB && pPager->exclusiveMode && pPager->nRef==0 && pPager->errCode ){ + if( pPager->journalOpen ){ + isHot = 1; + } + pager_reset(pPager); + pPager->errCode = SQLITE_OK; + } + + /* If the pager is still in an error state, do not proceed. The error + ** state will be cleared at some point in the future when all page + ** references are dropped and the cache can be discarded. + */ + if( pPager->errCode && pPager->errCode!=SQLITE_FULL ){ + return pPager->errCode; + } + + if( pPager->state==PAGER_UNLOCK || isHot ){ sqlite3_vfs *pVfs = pPager->pVfs; if( !MEMDB ){ assert( pPager->nRef==0 ); if( !pPager->noReadlock ){ rc = pager_wait_on_lock(pPager, SHARED_LOCK); @@ -22183,11 +23129,11 @@ } /* If a journal file exists, and there is no RESERVED lock on the ** database file, then it either needs to be played back or deleted. */ - if( hasHotJournal(pPager) ){ + if( hasHotJournal(pPager) || isHot ){ /* Get an EXCLUSIVE lock on the database file. At this point it is ** important that a RESERVED lock is not obtained on the way to the ** EXCLUSIVE lock. If it were, another process might open the ** database file, detect the RESERVED lock, and conclude that the ** database is safe to read while this process is still rolling it @@ -22195,16 +23141,18 @@ ** ** Because the intermediate RESERVED lock is not requested, the ** second process will get to this point in the code and fail to ** obtain it's own EXCLUSIVE lock on the database file. */ - rc = sqlite3OsLock(pPager->fd, EXCLUSIVE_LOCK); - if( rc!=SQLITE_OK ){ - pager_unlock(pPager); - return pager_error(pPager, rc); - } - pPager->state = PAGER_EXCLUSIVE; + if( pPager->state<EXCLUSIVE_LOCK ){ + rc = sqlite3OsLock(pPager->fd, EXCLUSIVE_LOCK); + if( rc!=SQLITE_OK ){ + pager_unlock(pPager); + return pager_error(pPager, rc); + } + pPager->state = PAGER_EXCLUSIVE; + } /* Open the journal for reading only. Return SQLITE_BUSY if ** we are unable to open the journal file. ** ** The journal file does not need to be locked itself. The @@ -22216,25 +23164,27 @@ ** exclusive-access mode the file descriptor will be kept open and ** possibly used for a transaction later on. On some systems, the ** OsTruncate() call used in exclusive-access mode also requires ** a read/write file handle. */ - rc = SQLITE_BUSY; - if( sqlite3OsAccess(pVfs, pPager->zJournal, SQLITE_ACCESS_EXISTS) ){ - int fout = 0; - int flags = SQLITE_OPEN_READWRITE|SQLITE_OPEN_MAIN_JOURNAL; - assert( !pPager->tempFile ); - rc = sqlite3OsOpen(pVfs, pPager->zJournal, pPager->jfd, flags, &fout); - assert( rc!=SQLITE_OK || pPager->jfd->pMethods ); - if( fout&SQLITE_OPEN_READONLY ){ - rc = SQLITE_BUSY; - sqlite3OsClose(pPager->jfd); + if( !isHot ){ + rc = SQLITE_BUSY; + if( sqlite3OsAccess(pVfs, pPager->zJournal, SQLITE_ACCESS_EXISTS) ){ + int fout = 0; + int f = SQLITE_OPEN_READWRITE|SQLITE_OPEN_MAIN_JOURNAL; + assert( !pPager->tempFile ); + rc = sqlite3OsOpen(pVfs, pPager->zJournal, pPager->jfd, f, &fout); + assert( rc!=SQLITE_OK || pPager->jfd->pMethods ); + if( fout&SQLITE_OPEN_READONLY ){ + rc = SQLITE_BUSY; + sqlite3OsClose(pPager->jfd); + } } } if( rc!=SQLITE_OK ){ pager_unlock(pPager); - return (rc==SQLITE_NOMEM?rc:SQLITE_BUSY); + return ((rc==SQLITE_NOMEM||rc==SQLITE_IOERR_NOMEM)?rc:SQLITE_BUSY); } pPager->journalOpen = 1; pPager->journalStarted = 0; pPager->journalOff = 0; pPager->setMaster = 0; @@ -22333,11 +23283,11 @@ ** allowed. */ static int pagerAllocatePage(Pager *pPager, PgHdr **ppPg){ int rc = SQLITE_OK; PgHdr *pPg; - void *pData; + int nByteHdr; /* Create a new PgHdr if any of the four conditions defined ** above are met: */ if( pPager->nPage<pPager->mxPage || pPager->lru.pFirst==0 @@ -22351,29 +23301,20 @@ rc = SQLITE_NOMEM; goto pager_allocate_out; } } pagerLeave(pPager); - pPg = sqlite3_malloc( sizeof(*pPg) + sizeof(u32) + pPager->nExtra - + MEMDB*sizeof(PgHistory) ); - if( pPg ){ - pData = sqlite3_malloc( pPager->pageSize ); - if( pData==0 ){ - sqlite3_free(pPg); - pPg = 0; - } - } + nByteHdr = sizeof(*pPg) + sizeof(u32) + pPager->nExtra + + MEMDB*sizeof(PgHistory); + pPg = sqlite3_malloc( nByteHdr + pPager->pageSize ); pagerEnter(pPager); if( pPg==0 ){ rc = SQLITE_NOMEM; goto pager_allocate_out; } - memset(pPg, 0, sizeof(*pPg)); - if( MEMDB ){ - memset(PGHDR_TO_HIST(pPg, pPager), 0, sizeof(PgHistory)); - } - pPg->pData = pData; + memset(pPg, 0, nByteHdr); + pPg->pData = (void*)(nByteHdr + (char*)pPg); pPg->pPager = pPager; pPg->pNextAll = pPager->pAll; pPager->pAll = pPg; pPager->nPage++; }else{ @@ -22465,13 +23406,10 @@ /* Make sure we have not hit any critical errors. */ assert( pPager!=0 ); *ppPage = 0; - if( pPager->errCode && pPager->errCode!=SQLITE_FULL ){ - return pPager->errCode; - } /* If this is the first page accessed, then get a SHARED lock ** on the database file. pagerSharedLock() is a no-op if ** a database lock is already held. */ @@ -22514,12 +23452,12 @@ if( pPager->nExtra>0 ){ memset(PGHDR_TO_EXTRA(pPg, pPager), 0, pPager->nExtra); } nMax = sqlite3PagerPagecount(pPager); if( pPager->errCode ){ - sqlite3PagerUnref(pPg); rc = pPager->errCode; + sqlite3PagerUnref(pPg); return rc; } /* Populate the page with data, either by reading from the database ** file, or by setting the entire page to zero. @@ -22620,10 +23558,11 @@ ** page is added to the LRU list. When all references to all pages ** are released, a rollback occurs and the lock on the database is ** removed. */ SQLITE_PRIVATE int sqlite3PagerUnref(DbPage *pPg){ + Pager *pPager = pPg->pPager; /* Decrement the reference count for this page */ assert( pPg->nRef>0 ); pagerEnter(pPg->pPager); @@ -22634,11 +23573,10 @@ /* When the number of references to a page reach 0, call the ** destructor and add the page to the freelist. */ if( pPg->nRef==0 ){ - Pager *pPager = pPg->pPager; lruListAdd(pPg); if( pPager->xDestructor ){ pPager->xDestructor(pPg, pPager->pageSize); } @@ -22650,11 +23588,11 @@ assert( pPager->nRef>=0 ); if( pPager->nRef==0 && (!pPager->exclusiveMode || pPager->journalOff>0) ){ pagerUnlockAndRollback(pPager); } } - pagerLeave(pPg->pPager); + pagerLeave(pPager); return SQLITE_OK; } /* ** Create a journal file for pPager. There should already be a RESERVED @@ -22718,11 +23656,11 @@ rc = writeJournalHdr(pPager); if( pPager->stmtAutoopen && rc==SQLITE_OK ){ rc = sqlite3PagerStmtBegin(pPager); } - if( rc!=SQLITE_OK && rc!=SQLITE_NOMEM ){ + if( rc!=SQLITE_OK && rc!=SQLITE_NOMEM && rc!=SQLITE_IOERR_NOMEM ){ rc = pager_end_transaction(pPager); if( rc==SQLITE_OK ){ rc = SQLITE_FULL; } } @@ -22939,13 +23877,14 @@ if( MEMDB ){ PgHistory *pHist = PGHDR_TO_HIST(pPg, pPager); PAGERTRACE3("JOURNAL %d page %d\n", PAGERID(pPager), pPg->pgno); assert( pHist->pOrig==0 ); pHist->pOrig = sqlite3_malloc( pPager->pageSize ); - if( pHist->pOrig ){ - memcpy(pHist->pOrig, PGHDR_TO_DATA(pPg), pPager->pageSize); - } + if( !pHist->pOrig ){ + return SQLITE_NOMEM; + } + memcpy(pHist->pOrig, PGHDR_TO_DATA(pPg), pPager->pageSize); }else{ u32 cksum; char *pData2; /* We should never write to the journal file the page that @@ -23283,11 +24222,14 @@ rc = sqlite3PagerGet(pPager, 1, &pPgHdr); if( rc!=SQLITE_OK ) return rc; if( !isDirect ){ rc = sqlite3PagerWrite(pPgHdr); - if( rc!=SQLITE_OK ) return rc; + if( rc!=SQLITE_OK ){ + sqlite3PagerUnref(pPgHdr); + return rc; + } } /* Increment the value just read and write it back to byte 24. */ change_counter = sqlite3Get4byte((u8*)pPager->dbFileVers); change_counter++; @@ -23363,17 +24305,18 @@ ** the in-memory representation of page 1 to include the updated ** change counter and then write page 1 directly to the database ** file. Because of the atomic-write property of the host file-system, ** this is safe. */ - rc = pager_incr_changecounter(pPager, 1); + if( rc==SQLITE_OK ){ + rc = pager_incr_changecounter(pPager, 1); + } }else{ rc = sqlite3JournalCreate(pPager->jfd); - if( rc!=SQLITE_OK ) goto sync_exit; - } - - if( !useAtomicWrite ) + } + + if( !useAtomicWrite && rc==SQLITE_OK ) #endif /* If a master journal file name has already been written to the ** journal file, then no sync is required. This happens when it is ** written, then the process fails to upgrade from a RESERVED to an @@ -23648,10 +24591,11 @@ pPager->stmtAutoopen = 1; return SQLITE_OK; } assert( pPager->journalOpen ); pagerLeave(pPager); + assert( pPager->aInStmt==0 ); pPager->aInStmt = sqlite3MallocZero( pPager->dbSize/8 + 1 ); pagerEnter(pPager); if( pPager->aInStmt==0 ){ /* sqlite3OsLock(pPager->fd, SHARED_LOCK); */ return SQLITE_NOMEM; @@ -24952,11 +25896,11 @@ ** 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. ** ************************************************************************* -** $Id: btree.c,v 1.426 2007/09/12 17:01:45 danielk1977 Exp $ +** $Id: btree.c,v 1.430 2007/11/05 15:30:13 danielk1977 Exp $ ** ** This file implements a external (disk-based) database using BTrees. ** See the header comment on "btreeInt.h" for additional information. ** Including a description of file format and an overview of operation. */ @@ -26100,21 +27044,22 @@ && isMemdb==0 && (pSqlite->flags & SQLITE_Vtab)==0 && zFilename && zFilename[0] ){ if( sqlite3SharedCacheEnabled ){ - char *zFullPathname = (char *)sqlite3_malloc(pVfs->mxPathname); + int nFullPathname = pVfs->mxPathname+1; + char *zFullPathname = (char *)sqlite3_malloc(nFullPathname); sqlite3_mutex *mutexShared; p->sharable = 1; if( pSqlite ){ pSqlite->flags |= SQLITE_SharedCache; } if( !zFullPathname ){ sqlite3_free(p); return SQLITE_NOMEM; } - sqlite3OsFullPathname(pVfs, zFilename, zFullPathname); + sqlite3OsFullPathname(pVfs, zFilename, nFullPathname, zFullPathname); mutexShared = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER); sqlite3_mutex_enter(mutexShared); for(pBt=sqlite3SharedCacheList; pBt; pBt=pBt->pNext){ assert( pBt->nRef>0 ); if( 0==strcmp(zFullPathname, sqlite3PagerFilename(pBt->pPager)) @@ -27109,14 +28054,13 @@ releasePage(pFreePg); }while( nFin!=0 && iFreePg>nFin ); assert( iFreePg<iLastPg ); rc = sqlite3PagerWrite(pLastPg->pDbPage); - if( rc!=SQLITE_OK ){ - return rc; - } - rc = relocatePage(pBt, pLastPg, eType, iPtrPage, iFreePg); + if( rc==SQLITE_OK ){ + rc = relocatePage(pBt, pLastPg, eType, iPtrPage, iFreePg); + } releasePage(pLastPg); if( rc!=SQLITE_OK ){ return rc; } } @@ -27526,17 +28470,15 @@ */ SQLITE_PRIVATE int sqlite3BtreeRollbackStmt(Btree *p){ int rc = SQLITE_OK; BtShared *pBt = p->pBt; sqlite3BtreeEnter(p); - sqlite3MallocDisallow(); if( pBt->inStmt && !pBt->readOnly ){ rc = sqlite3PagerStmtRollback(pBt->pPager); assert( countWriteCursors(pBt)==0 ); pBt->inStmt = 0; } - sqlite3MallocAllow(); sqlite3BtreeLeave(p); return rc; } /* @@ -27982,11 +28924,11 @@ unsigned char *aPayload; int rc = SQLITE_OK; u32 nKey; int iIdx = 0; MemPage *pPage = pCur->pPage; /* Btree page of current cursor entry */ - BtShared *pBt = pCur->pBt; /* Btree this cursor belongs to */ + BtShared *pBt; /* Btree this cursor belongs to */ assert( pPage ); assert( pCur->eState==CURSOR_VALID ); assert( pCur->idx>=0 && pCur->idx<pPage->nCell ); assert( offset>=0 ); @@ -28016,10 +28958,11 @@ amt -= a; }else{ offset -= pCur->info.nLocal; } + pBt = pCur->pBt; if( rc==SQLITE_OK && amt>0 ){ const int ovflSize = pBt->usableSize - 4; /* Bytes content per ovfl page */ Pgno nextPage; nextPage = get4byte(&aPayload[pCur->info.nLocal]); @@ -33024,12 +33967,12 @@ } /* ** Return the SQL associated with a prepared statement */ -SQLITE_PRIVATE const char *sqlite3VdbeGetSql(Vdbe *p){ - return p->zSql; +SQLITE_API const char *sqlite3_sql(sqlite3_stmt *pStmt){ + return ((Vdbe *)pStmt)->zSql; } /* ** Swap all content between two VDBE structures. */ @@ -33063,33 +34006,26 @@ } #endif /* ** Resize the Vdbe.aOp array so that it contains at least N -** elements. If the Vdbe is in VDBE_MAGIC_RUN state, then -** the Vdbe.aOp array will be sized to contain exactly N -** elements. Vdbe.nOpAlloc is set to reflect the new size of -** the array. +** elements. ** ** If an out-of-memory error occurs while resizing the array, ** Vdbe.aOp and Vdbe.nOpAlloc remain unchanged (this is so that ** any opcodes already allocated can be correctly deallocated ** along with the rest of the Vdbe). */ static void resizeOpArray(Vdbe *p, int N){ - int runMode = p->magic==VDBE_MAGIC_RUN; - if( runMode || p->nOpAlloc<N ){ - VdbeOp *pNew; - int nNew = N + 100*(!runMode); - int oldSize = p->nOpAlloc; - pNew = sqlite3DbRealloc(p->db, p->aOp, nNew*sizeof(Op)); - if( pNew ){ - p->nOpAlloc = nNew; - p->aOp = pNew; - if( nNew>oldSize ){ - memset(&p->aOp[oldSize], 0, (nNew-oldSize)*sizeof(Op)); - } + VdbeOp *pNew; + int oldSize = p->nOpAlloc; + pNew = sqlite3DbRealloc(p->db, p->aOp, N*sizeof(Op)); + if( pNew ){ + p->nOpAlloc = N; + p->aOp = pNew; + if( N>oldSize ){ + memset(&p->aOp[oldSize], 0, (N-oldSize)*sizeof(Op)); } } } /* @@ -33113,11 +34049,11 @@ VdbeOp *pOp; i = p->nOp; assert( p->magic==VDBE_MAGIC_INIT ); if( p->nOpAlloc<=i ){ - resizeOpArray(p, i+1); + resizeOpArray(p, p->nOpAlloc*2 + 100); if( p->db->mallocFailed ){ return 0; } } p->nOp++; @@ -33324,11 +34260,13 @@ ** address of the first operation added. */ SQLITE_PRIVATE int sqlite3VdbeAddOpList(Vdbe *p, int nOp, VdbeOpList const *aOp){ int addr; assert( p->magic==VDBE_MAGIC_INIT ); - resizeOpArray(p, p->nOp + nOp); + if( p->nOp + nOp > p->nOpAlloc ){ + resizeOpArray(p, p->nOp*2 + nOp); + } if( p->db->mallocFailed ){ return 0; } addr = p->nOp; if( nOp>0 ){ @@ -33401,17 +34339,16 @@ ** Delete a P3 value if necessary. */ static void freeP3(int p3type, void *p3){ if( p3 ){ switch( p3type ){ + case P3_REAL: + case P3_INT64: + case P3_MPRINTF: case P3_DYNAMIC: case P3_KEYINFO: case P3_KEYINFO_HANDOFF: { - sqlite3_free(p3); - break; - } - case P3_MPRINTF: { sqlite3_free(p3); break; } case P3_VDBEFUNC: { VdbeFunc *pVdbeFunc = (VdbeFunc *)p3; @@ -33597,10 +34534,20 @@ break; } case P3_FUNCDEF: { FuncDef *pDef = (FuncDef*)pOp->p3; sqlite3_snprintf(nTemp, zTemp, "%s(%d)", pDef->zName, pDef->nArg); + zP3 = zTemp; + break; + } + case P3_INT64: { + sqlite3_snprintf(nTemp, zTemp, "%lld", *(sqlite3_int64*)pOp->p3); + zP3 = zTemp; + break; + } + case P3_REAL: { + sqlite3_snprintf(nTemp, zTemp, "%.16g", *(double*)pOp->p3); zP3 = zTemp; break; } #ifndef SQLITE_OMIT_VIRTUALTABLE case P3_VTAB: { @@ -34283,11 +35230,11 @@ ** Remember that a rollback can delete tables complete and ** reorder rootpages. So it is not sufficient just to save ** the state of the cursor. We have to invalidate the cursor ** so that it is never used again. */ -void invalidateCursorsOnModifiedBtrees(sqlite3 *db){ +static void invalidateCursorsOnModifiedBtrees(sqlite3 *db){ int i; for(i=0; i<db->nDb; i++){ Btree *p = db->aDb[i].pBt; if( p && sqlite3BtreeIsInTrans(p) ){ sqlite3BtreeTripAllCursors(p, SQLITE_ABORT); @@ -34316,32 +35263,20 @@ /* This function contains the logic that determines if a statement or ** transaction will be committed or rolled back as a result of the ** execution of this virtual machine. ** - ** Special errors: - ** - ** If an SQLITE_NOMEM error has occured in a statement that writes to - ** the database, then either a statement or transaction must be rolled - ** back to ensure the tree-structures are in a consistent state. A - ** statement transaction is rolled back if one is open, otherwise the - ** entire transaction must be rolled back. - ** - ** If an SQLITE_IOERR error has occured in a statement that writes to - ** the database, then the entire transaction must be rolled back. The - ** I/O error may have caused garbage to be written to the journal - ** file. Were the transaction to continue and eventually be rolled - ** back that garbage might end up in the database file. - ** - ** In both of the above cases, the Vdbe.errorAction variable is - ** ignored. If the sqlite3.autoCommit flag is false and a transaction - ** is rolled back, it will be set to true. - ** - ** Other errors: - ** - ** No error: - ** + ** If any of the following errors occur: + ** + ** SQLITE_NOMEM + ** SQLITE_IOERR + ** SQLITE_FULL + ** SQLITE_INTERRUPT + ** + ** Then the internal cache might have been left in an inconsistent + ** state. We need to rollback the statement transaction, if there is + ** one, or the complete transaction if there is no statement transaction. */ if( p->db->mallocFailed ){ p->rc = SQLITE_NOMEM; } @@ -34356,14 +35291,14 @@ int mrc; /* Primary error code from p->rc */ /* Lock all btrees used by the statement */ sqlite3BtreeMutexArrayEnter(&p->aMutex); - /* Check for one of the special errors - SQLITE_NOMEM or SQLITE_IOERR */ + /* Check for one of the special errors */ mrc = p->rc & 0xff; - isSpecialError = ( - (mrc==SQLITE_NOMEM || mrc==SQLITE_IOERR || mrc==SQLITE_INTERRUPT)?1:0); + isSpecialError = mrc==SQLITE_NOMEM || mrc==SQLITE_IOERR + || mrc==SQLITE_INTERRUPT || mrc==SQLITE_FULL ; if( isSpecialError ){ /* This loop does static analysis of the query to see which of the ** following three categories it falls into: ** ** Read-only @@ -34374,29 +35309,17 @@ ** store the type of query as part of the compliation phase), but ** handling malloc() or IO failure is a fairly obscure edge case so ** this is probably easier. Todo: Might be an opportunity to reduce ** code size a very small amount though... */ - int isReadOnly = 1; + int notReadOnly = 0; int isStatement = 0; assert(p->aOp || p->nOp==0); for(i=0; i<p->nOp; i++){ switch( p->aOp[i].opcode ){ case OP_Transaction: - /* This is a bit strange. If we hit a malloc() or IO error and - ** the statement did not open a statement transaction, we will - ** rollback any active transaction and abort all other active - ** statements. Or, if this is an SQLITE_INTERRUPT error, we - ** will only rollback if the interrupted statement was a write. - ** - ** It could be argued that read-only statements should never - ** rollback anything. But careful analysis is required before - ** making this change - */ - if( p->aOp[i].p2 || mrc!=SQLITE_INTERRUPT ){ - isReadOnly = 0; - } + notReadOnly |= p->aOp[i].p2; break; case OP_Statement: isStatement = 1; break; } @@ -34404,15 +35327,15 @@ /* If the query was read-only, we need do no rollback at all. Otherwise, ** proceed with the special handling. */ - if( !isReadOnly ){ + if( notReadOnly || mrc!=SQLITE_INTERRUPT ){ if( p->rc==SQLITE_IOERR_BLOCKED && isStatement ){ xFunc = sqlite3BtreeRollbackStmt; p->rc = SQLITE_BUSY; - } else if( p->rc==SQLITE_NOMEM && isStatement ){ + } else if( (mrc==SQLITE_NOMEM || mrc==SQLITE_FULL) && isStatement ){ xFunc = sqlite3BtreeRollbackStmt; }else{ /* We are forced to roll back the active transaction. Before doing ** so, abort any other statements this handle currently has active. */ @@ -34570,10 +35493,12 @@ /* The expired flag was set on the VDBE before the first call ** to sqlite3_step(). For consistency (since sqlite3_step() was ** called), set the database error in this case as well. */ sqlite3Error(db, p->rc, 0); + sqlite3ValueSetStr(db->pErr, -1, p->zErrMsg, SQLITE_UTF8, sqlite3_free); + p->zErrMsg = 0; } /* Reclaim all memory used by the VDBE */ Cleanup(p); @@ -35487,17 +36412,19 @@ */ static int sqlite3Step(Vdbe *p){ sqlite3 *db; int rc; + assert(p); + if( p->magic!=VDBE_MAGIC_RUN ){ + return SQLITE_MISUSE; + } + /* Assert that malloc() has not failed */ db = p->db; assert( !db->mallocFailed ); - if( p==0 || p->magic!=VDBE_MAGIC_RUN ){ - return SQLITE_MISUSE; - } if( p->aborted ){ return SQLITE_ABORT; } if( p->pc<=0 && p->expired ){ if( p->rc==SQLITE_OK ){ @@ -35604,31 +36531,55 @@ ** sqlite3Step() to do most of the work. If a schema error occurs, ** call sqlite3Reprepare() and try again. */ #ifdef SQLITE_OMIT_PARSER SQLITE_API int sqlite3_step(sqlite3_stmt *pStmt){ - int rc; - Vdbe *v; - v = (Vdbe*)pStmt; - sqlite3_mutex_enter(v->db->mutex); - rc = sqlite3Step(v); - sqlite3_mutex_leave(v->db->mutex); + int rc = SQLITE_MISUSE; + if( pStmt ){ + Vdbe *v; + v = (Vdbe*)pStmt; + sqlite3_mutex_enter(v->db->mutex); + rc = sqlite3Step(v); + sqlite3_mutex_leave(v->db->mutex); + } return rc; } #else SQLITE_API int sqlite3_step(sqlite3_stmt *pStmt){ - int cnt = 0; - int rc; - Vdbe *v = (Vdbe*)pStmt; - sqlite3_mutex_enter(v->db->mutex); - while( (rc = sqlite3Step(v))==SQLITE_SCHEMA - && cnt++ < 5 - && sqlite3Reprepare(v) ){ - sqlite3_reset(pStmt); - v->expired = 0; - } - sqlite3_mutex_leave(v->db->mutex); + int rc = SQLITE_MISUSE; + if( pStmt ){ + int cnt = 0; + Vdbe *v = (Vdbe*)pStmt; + sqlite3 *db = v->db; + sqlite3_mutex_enter(db->mutex); + while( (rc = sqlite3Step(v))==SQLITE_SCHEMA + && cnt++ < 5 + && sqlite3Reprepare(v) ){ + sqlite3_reset(pStmt); + v->expired = 0; + } + if( rc==SQLITE_SCHEMA && v->zSql && db->pErr ){ + /* This case occurs after failing to recompile an sql statement. + ** The error message from the SQL compiler has already been loaded + ** into the database handle. This block copies the error message + ** from the database handle into the statement and sets the statement + ** program counter to 0 to ensure that when the statement is + ** finalized or reset the parser error message is available via + ** sqlite3_errmsg() and sqlite3_errcode(). + */ + const char *zErr = (const char *)sqlite3_value_text(db->pErr); + sqlite3_free(v->zErrMsg); + if( !db->mallocFailed ){ + v->zErrMsg = sqlite3DbStrDup(db, zErr); + } else { + v->zErrMsg = 0; + v->rc = SQLITE_NOMEM; + } + } + rc = sqlite3ApiExit(db, rc); + sqlite3_mutex_leave(db->mutex); + } return rc; } #endif /* @@ -35677,16 +36628,11 @@ pMem->z = 0; }else{ pMem->flags = MEM_Agg; pMem->xDel = sqlite3_free; pMem->u.pDef = p->pFunc; - if( nByte<=NBFS ){ - pMem->z = pMem->zShort; - memset(pMem->z, 0, nByte); - }else{ - pMem->z = sqlite3DbMallocZero(p->s.db, nByte); - } + pMem->z = sqlite3DbMallocZero(p->s.db, nByte); } } return (void*)pMem->z; } @@ -36344,11 +37290,11 @@ ** documentation, headers files, or other derived files. The formatting ** of the code in this file is, therefore, important. See other comments ** in this file for details. If in doubt, do not deviate from existing ** commenting and indentation practices when changing or adding code. ** -** $Id: vdbe.c,v 1.650 2007/09/03 15:19:36 drh Exp $ +** $Id: vdbe.c,v 1.654 2007/11/12 08:09:35 danielk1977 Exp $ */ /* ** The following global variable is incremented every time a cursor ** moves, either by the OP_MoveXX, OP_Next, or OP_Prev opcodes. The test @@ -37003,38 +37949,30 @@ break; } /* Opcode: Int64 * * P3 ** -** P3 is a string representation of an integer. Convert that integer -** to a 64-bit value and push it onto the stack. +** P3 is a pointer to a 64-bit integer value. +** Push that value onto the stack. */ case OP_Int64: { pTos++; assert( pOp->p3!=0 ); - pTos->flags = MEM_Str|MEM_Static|MEM_Term; - pTos->z = pOp->p3; - pTos->n = strlen(pTos->z); - pTos->enc = SQLITE_UTF8; - pTos->u.i = sqlite3VdbeIntValue(pTos); - pTos->flags |= MEM_Int; + pTos->flags = MEM_Int; + memcpy(&pTos->u.i, pOp->p3, 8); break; } /* Opcode: Real * * P3 ** -** The string value P3 is converted to a real and pushed on to the stack. +** P3 is a pointer to a 64-bit floating point value. Push that value +** onto the stack. */ case OP_Real: { /* same as TK_FLOAT, */ pTos++; - pTos->flags = MEM_Str|MEM_Static|MEM_Term; - pTos->z = pOp->p3; - pTos->n = strlen(pTos->z); - pTos->enc = SQLITE_UTF8; - pTos->r = sqlite3VdbeRealValue(pTos); - pTos->flags |= MEM_Real; - sqlite3VdbeChangeEncoding(pTos, encoding); + pTos->flags = MEM_Real; + memcpy(&pTos->r, pOp->p3, 8); break; } /* Opcode: String8 * * P3 ** @@ -37043,12 +37981,12 @@ */ case OP_String8: { /* same as TK_STRING */ assert( pOp->p3!=0 ); pOp->opcode = OP_String; pOp->p1 = strlen(pOp->p3); - assert( SQLITE_MAX_SQL_LENGTH < SQLITE_MAX_LENGTH ); - assert( pOp->p1 < SQLITE_MAX_LENGTH ); + assert( SQLITE_MAX_SQL_LENGTH <= SQLITE_MAX_LENGTH ); + assert( pOp->p1 <= SQLITE_MAX_LENGTH ); #ifndef SQLITE_OMIT_UTF16 if( encoding!=SQLITE_UTF8 ){ pTos++; sqlite3VdbeMemSetStr(pTos, pOp->p3, -1, SQLITE_UTF8, SQLITE_STATIC); @@ -37060,11 +37998,11 @@ sqlite3_free(pOp->p3); } pOp->p3type = P3_DYNAMIC; pOp->p3 = pTos->z; pOp->p1 = pTos->n; - assert( pOp->p1 < SQLITE_MAX_LENGTH ); /* Due to SQLITE_MAX_SQL_LENGTH */ + assert( pOp->p1 <= SQLITE_MAX_LENGTH ); /* Due to SQLITE_MAX_SQL_LENGTH */ break; } #endif /* Otherwise fall through to the next case, OP_String */ } @@ -37072,11 +38010,11 @@ /* Opcode: String P1 * P3 ** ** The string value P3 of length P1 (bytes) is pushed onto the stack. */ case OP_String: { - assert( pOp->p1 < SQLITE_MAX_LENGTH ); /* Due to SQLITE_MAX_SQL_LENGTH */ + assert( pOp->p1 <= SQLITE_MAX_LENGTH ); /* Due to SQLITE_MAX_SQL_LENGTH */ pTos++; assert( pOp->p3!=0 ); pTos->flags = MEM_Str|MEM_Static|MEM_Term; pTos->z = pOp->p3; pTos->n = pOp->p1; @@ -37106,12 +38044,12 @@ ** 'Blob' opcode with a binary blob as P3. */ case OP_HexBlob: { /* same as TK_BLOB */ pOp->opcode = OP_Blob; pOp->p1 = strlen(pOp->p3)/2; - assert( SQLITE_MAX_SQL_LENGTH < SQLITE_MAX_LENGTH ); - assert( pOp->p1 < SQLITE_MAX_LENGTH ); + assert( SQLITE_MAX_SQL_LENGTH <= SQLITE_MAX_LENGTH ); + assert( pOp->p1 <= SQLITE_MAX_LENGTH ); if( pOp->p1 ){ char *zBlob = sqlite3HexToBlob(db, pOp->p3); if( !zBlob ) goto no_mem; if( pOp->p3type==P3_DYNAMIC ){ sqlite3_free(pOp->p3); @@ -37138,11 +38076,11 @@ ** the blob as P3. This opcode is transformed to an OP_Blob ** the first time it is executed. */ case OP_Blob: { pTos++; - assert( pOp->p1 < SQLITE_MAX_LENGTH ); /* Due to SQLITE_MAX_SQL_LENGTH */ + assert( pOp->p1 <= SQLITE_MAX_LENGTH ); /* Due to SQLITE_MAX_SQL_LENGTH */ sqlite3VdbeMemSetStr(pTos, pOp->p3, pOp->p1, 0, 0); pTos->enc = encoding; break; } #endif /* SQLITE_OMIT_BLOB_LITERAL */ @@ -38311,14 +39249,14 @@ ** the number of columns is stored in the Cursor.nField element. For ** records on the stack, the next entry down on the stack is an integer ** which is the number of records. */ pC = p->apCsr[p1]; + assert( pC!=0 ); #ifndef SQLITE_OMIT_VIRTUALTABLE assert( pC->pVtabCursor==0 ); #endif - assert( pC!=0 ); if( pC->pCursor!=0 ){ /* The record is stored in a B-Tree */ rc = sqlite3VdbeCursorMoveto(pC); if( rc ) goto abort_due_to_error; zRec = 0; @@ -42172,11 +43110,11 @@ ** ************************************************************************* ** This file contains routines used for analyzing expressions and ** for generating VDBE code that evaluates expressions in SQLite. ** -** $Id: expr.c,v 1.312 2007/09/01 18:24:55 danielk1977 Exp $ +** $Id: expr.c,v 1.316 2007/11/12 09:50:26 danielk1977 Exp $ */ /* ** Return the 'affinity' of the expression pExpr if any. ** @@ -42212,17 +43150,21 @@ ** The collating sequence is marked as "explicit" using the EP_ExpCollate ** flag. An explicit collating sequence will override implicit ** collating sequences. */ SQLITE_PRIVATE Expr *sqlite3ExprSetColl(Parse *pParse, Expr *pExpr, Token *pName){ + char *zColl = 0; /* Dequoted name of collation sequence */ CollSeq *pColl; - if( pExpr==0 ) return 0; - pColl = sqlite3LocateCollSeq(pParse, (char*)pName->z, pName->n); - if( pColl ){ - pExpr->pColl = pColl; - pExpr->flags |= EP_ExpCollate; - } + zColl = sqlite3NameFromToken(pParse->db, pName); + if( pExpr && zColl ){ + pColl = sqlite3LocateCollSeq(pParse, zColl, -1); + if( pColl ){ + pExpr->pColl = pColl; + pExpr->flags |= EP_ExpCollate; + } + } + sqlite3_free(zColl); return pExpr; } /* ** Return the default collation sequence for the expression pExpr. If @@ -43172,10 +44114,11 @@ int cntTab = 0; /* Number of matching table names */ sqlite3 *db = pParse->db; /* The database */ struct SrcList_item *pItem; /* Use for looping over pSrcList items */ struct SrcList_item *pMatch = 0; /* The matching pSrcList item */ NameContext *pTopNC = pNC; /* First namecontext in the list */ + Schema *pSchema = 0; /* Schema of the expression */ assert( pColumnToken && pColumnToken->z ); /* The Z in X.Y.Z cannot be NULL */ zDb = sqlite3NameFromToken(db, pDbToken); zTab = sqlite3NameFromToken(db, pTableToken); zCol = sqlite3NameFromToken(db, pColumnToken); @@ -43210,21 +44153,21 @@ } } } if( 0==(cntTab++) ){ pExpr->iTable = pItem->iCursor; - pExpr->pSchema = pTab->pSchema; + pSchema = pTab->pSchema; pMatch = pItem; } for(j=0, pCol=pTab->aCol; j<pTab->nCol; j++, pCol++){ if( sqlite3StrICmp(pCol->zName, zCol)==0 ){ const char *zColl = pTab->aCol[j].zColl; IdList *pUsing; cnt++; pExpr->iTable = pItem->iCursor; pMatch = pItem; - pExpr->pSchema = pTab->pSchema; + pSchema = pTab->pSchema; /* Substitute the rowid (column -1) for the INTEGER PRIMARY KEY */ pExpr->iColumn = j==pTab->iPKey ? -1 : j; pExpr->affinity = pTab->aCol[j].affinity; if( (pExpr->flags & EP_ExpCollate)==0 ){ pExpr->pColl = sqlite3FindCollSeq(db, ENC(db), zColl,-1, 0); @@ -43274,11 +44217,11 @@ if( pTab ){ int iCol; Column *pCol = pTab->aCol; - pExpr->pSchema = pTab->pSchema; + pSchema = pTab->pSchema; cntTab++; for(iCol=0; iCol < pTab->nCol; iCol++, pCol++) { if( sqlite3StrICmp(pCol->zName, zCol)==0 ){ const char *zColl = pTab->aCol[iCol].zColl; cnt++; @@ -43421,11 +44364,11 @@ pExpr->op = TK_COLUMN; lookupname_end_2: sqlite3_free(zCol); if( cnt==1 ){ assert( pNC!=0 ); - sqlite3AuthRead(pParse, pExpr, pNC->pSrcList); + sqlite3AuthRead(pParse, pExpr, pSchema, pNC->pSrcList); if( pMatch && !pMatch->pSelect ){ pExpr->pTab = pMatch->pTab; } /* Increment the nRef value on all name contexts from TopNC up to ** the point where the name matched. */ @@ -43838,23 +44781,67 @@ return; } #endif /* SQLITE_OMIT_SUBQUERY */ /* +** Duplicate an 8-byte value +*/ +static char *dup8bytes(Vdbe *v, const char *in){ + char *out = sqlite3DbMallocRaw(sqlite3VdbeDb(v), 8); + if( out ){ + memcpy(out, in, 8); + } + return out; +} + +/* +** Generate an instruction that will put the floating point +** value described by z[0..n-1] on the stack. +** +** The z[] string will probably not be zero-terminated. But the +** z[n] character is guaranteed to be something that does not look +** like the continuation of the number. +*/ +static void codeReal(Vdbe *v, const char *z, int n, int negateFlag){ + assert( z || v==0 || sqlite3VdbeDb(v)->mallocFailed ); + if( z ){ + double value; + char *zV; + assert( !isdigit(z[n]) ); + sqlite3AtoF(z, &value); + if( negateFlag ) value = -value; + zV = dup8bytes(v, (char*)&value); + sqlite3VdbeOp3(v, OP_Real, 0, 0, zV, P3_REAL); + } +} + + +/* ** Generate an instruction that will put the integer describe by ** text z[0..n-1] on the stack. -*/ -static void codeInteger(Vdbe *v, const char *z, int n){ +** +** The z[] string will probably not be zero-terminated. But the +** z[n] character is guaranteed to be something that does not look +** like the continuation of the number. +*/ +static void codeInteger(Vdbe *v, const char *z, int n, int negateFlag){ assert( z || v==0 || sqlite3VdbeDb(v)->mallocFailed ); if( z ){ int i; + assert( !isdigit(z[n]) ); if( sqlite3GetInt32(z, &i) ){ + if( negateFlag ) i = -i; sqlite3VdbeAddOp(v, OP_Integer, i, 0); - }else if( sqlite3FitsIn64Bits(z) ){ - sqlite3VdbeOp3(v, OP_Int64, 0, 0, z, n); - }else{ - sqlite3VdbeOp3(v, OP_Real, 0, 0, z, n); + }else if( sqlite3FitsIn64Bits(z, negateFlag) ){ + i64 value; + char *zV; + sqlite3Atoi64(z, &value); + if( negateFlag ) value = -value; + zV = dup8bytes(v, (char*)&value); + sqlite3VdbeOp3(v, OP_Int64, 0, 0, zV, P3_INT64); + }else{ + codeReal(v, z, n, negateFlag); } } } @@ -43926,19 +44913,20 @@ sqlite3ExprCodeGetColumn(v, pExpr->pTab, pExpr->iColumn, pExpr->iTable); } break; } case TK_INTEGER: { - codeInteger(v, (char*)pExpr->token.z, pExpr->token.n); - break; - } - case TK_FLOAT: + codeInteger(v, (char*)pExpr->token.z, pExpr->token.n, 0); + break; + } + case TK_FLOAT: { + codeReal(v, (char*)pExpr->token.z, pExpr->token.n, 0); + break; + } case TK_STRING: { - assert( TK_FLOAT==OP_Real ); - assert( TK_STRING==OP_String8 ); sqlite3DequoteExpr(pParse->db, pExpr); - sqlite3VdbeOp3(v, op, 0, 0, (char*)pExpr->token.z, pExpr->token.n); + sqlite3VdbeOp3(v,OP_String8, 0, 0, (char*)pExpr->token.z, pExpr->token.n); break; } case TK_NULL: { sqlite3VdbeAddOp(v, OP_Null, 0, 0); break; @@ -44036,17 +45024,15 @@ case TK_UMINUS: { Expr *pLeft = pExpr->pLeft; assert( pLeft ); if( pLeft->op==TK_FLOAT || pLeft->op==TK_INTEGER ){ Token *p = &pLeft->token; - char *z = sqlite3MPrintf(pParse->db, "-%.*s", p->n, p->z); if( pLeft->op==TK_FLOAT ){ - sqlite3VdbeOp3(v, OP_Real, 0, 0, z, p->n+1); - }else{ - codeInteger(v, z, p->n+1); - } - sqlite3_free(z); + codeReal(v, (char*)p->z, p->n, 1); + }else{ + codeInteger(v, (char*)p->z, p->n, 1); + } break; } /* Fall through into TK_NOT */ } case TK_BITNOT: @@ -44789,11 +45775,11 @@ ** ************************************************************************* ** This file contains C code routines that used to generate VDBE code ** that implements the ALTER TABLE command. ** -** $Id: alter.c,v 1.32 2007/08/29 14:06:23 danielk1977 Exp $ +** $Id: alter.c,v 1.33 2007/10/20 20:58:57 drh Exp $ */ /* ** The code in this file only exists if we are not omitting the ** ALTER TABLE logic from the build. @@ -45153,11 +46139,11 @@ #endif "tbl_name = %Q, " "name = CASE " "WHEN type='table' THEN %Q " "WHEN name LIKE 'sqlite_autoindex%%' AND type='index' THEN " - "'sqlite_autoindex_' || %Q || substr(name,%d+18,10) " + "'sqlite_autoindex_' || %Q || substr(name,%d+18) " "ELSE name END " "WHERE tbl_name=%Q AND " "(type='table' OR type='index' OR type='trigger');", zDb, SCHEMA_TABLE(iDb), zName, zName, zName, #ifndef SQLITE_OMIT_TRIGGER @@ -45290,11 +46276,11 @@ while( (zEnd>zCol && *zEnd==';') || isspace(*(unsigned char *)zEnd) ){ *zEnd-- = '\0'; } sqlite3NestedParse(pParse, "UPDATE %Q.%s SET " - "sql = substr(sql,1,%d) || ', ' || %Q || substr(sql,%d,length(sql)) " + "sql = substr(sql,1,%d) || ', ' || %Q || substr(sql,%d) " "WHERE type = 'table' AND name = %Q", zDb, SCHEMA_TABLE(iDb), pNew->addColOffset, zCol, pNew->addColOffset+1, zTab ); sqlite3_free(zCol); @@ -45411,11 +46397,11 @@ ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains code associated with the ANALYZE command. ** -** @(#) $Id: analyze.c,v 1.23 2007/08/29 17:43:20 drh Exp $ +** @(#) $Id: analyze.c,v 1.24 2007/11/15 13:10:23 danielk1977 Exp $ */ #ifndef SQLITE_OMIT_ANALYZE /* ** This routine generates code that opens the sqlite_stat1 table on cursor @@ -45708,14 +46694,16 @@ iDb = sqlite3FindDb(db, pName1); if( iDb>=0 ){ analyzeDatabase(pParse, iDb); }else{ z = sqlite3NameFromToken(db, pName1); - pTab = sqlite3LocateTable(pParse, z, 0); - sqlite3_free(z); - if( pTab ){ - analyzeTable(pParse, pTab); + if( z ){ + pTab = sqlite3LocateTable(pParse, z, 0); + sqlite3_free(z); + if( pTab ){ + analyzeTable(pParse, pTab); + } } } }else{ /* Form 3: Analyze the fully qualified table name */ iDb = sqlite3TwoPartName(pParse, pName1, pName2, &pTableName); @@ -45831,11 +46819,11 @@ ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains code used to implement the ATTACH and DETACH commands. ** -** $Id: attach.c,v 1.62 2007/09/03 15:19:35 drh Exp $ +** $Id: attach.c,v 1.63 2007/10/03 08:46:44 danielk1977 Exp $ */ #ifndef SQLITE_OMIT_ATTACH /* ** Resolve an expression that was part of an ATTACH or DETACH statement. This @@ -46019,11 +47007,11 @@ db->aDb[iDb].pBt = 0; db->aDb[iDb].pSchema = 0; } sqlite3ResetInternalSchema(db, 0); db->nDb = iDb; - if( rc==SQLITE_NOMEM ){ + if( rc==SQLITE_NOMEM || rc==SQLITE_IOERR_NOMEM ){ db->mallocFailed = 1; sqlite3_snprintf(sizeof(zErr),zErr, "out of memory"); }else{ sqlite3_snprintf(sizeof(zErr),zErr, "unable to open database: %s", zFile); } @@ -46357,11 +47345,11 @@ ** This file contains code used to implement the sqlite3_set_authorizer() ** API. This facility is an optional feature of the library. Embedded ** systems that do not need this facility may omit it by recompiling ** the library with -DSQLITE_OMIT_AUTHORIZATION=1 ** -** $Id: auth.c,v 1.28 2007/09/01 18:24:55 danielk1977 Exp $ +** $Id: auth.c,v 1.29 2007/09/18 15:55:07 drh Exp $ */ /* ** All of the code in this file may be omitted by defining a single ** macro. @@ -46447,10 +47435,11 @@ ** then generate an error. */ SQLITE_PRIVATE void sqlite3AuthRead( Parse *pParse, /* The parser context */ Expr *pExpr, /* The expression to check authorization on */ + Schema *pSchema, /* The schema of the expression */ SrcList *pTabList /* All table that pExpr might refer to */ ){ sqlite3 *db = pParse->db; int rc; Table *pTab = 0; /* The table being read */ @@ -46460,11 +47449,11 @@ TriggerStack *pStack; /* The stack of current triggers */ int iDb; /* The index of the database the expression refers to */ if( db->xAuth==0 ) return; if( pExpr->op!=TK_COLUMN ) return; - iDb = sqlite3SchemaToIndex(pParse->db, pExpr->pSchema); + iDb = sqlite3SchemaToIndex(pParse->db, pSchema); if( iDb<0 ){ /* An attempt to read a column out of a subquery or other ** temporary table. */ return; } @@ -46600,11 +47589,11 @@ ** creating ID lists ** BEGIN TRANSACTION ** COMMIT ** ROLLBACK ** -** $Id: build.c,v 1.444 2007/09/03 15:19:35 drh Exp $ +** $Id: build.c,v 1.448 2007/11/12 09:50:26 danielk1977 Exp $ */ /* ** This routine is called when a new SQL statement is beginning to ** be parsed. Initialize the pParse structure as needed. @@ -47759,20 +48748,24 @@ /* ** Set the collation function of the most recently parsed table column ** to the CollSeq given. */ -SQLITE_PRIVATE void sqlite3AddCollateType(Parse *pParse, const char *zType, int nType){ +SQLITE_PRIVATE void sqlite3AddCollateType(Parse *pParse, Token *pToken){ Table *p; int i; + char *zColl; /* Dequoted name of collation sequence */ if( (p = pParse->pNewTable)==0 ) return; i = p->nCol-1; - if( sqlite3LocateCollSeq(pParse, zType, nType) ){ + zColl = sqlite3NameFromToken(pParse->db, pToken); + if( !zColl ) return; + + if( sqlite3LocateCollSeq(pParse, zColl, -1) ){ Index *pIdx; - p->aCol[i].zColl = sqlite3DbStrNDup(pParse->db, zType, nType); + p->aCol[i].zColl = zColl; /* If the column is declared as "<name> PRIMARY KEY COLLATE <type>", ** then an index may have been created on this column before the ** collation type was added. Correct this if it is the case. */ @@ -47780,10 +48773,12 @@ assert( pIdx->nColumn==1 ); if( pIdx->aiColumn[0]==i ){ pIdx->azColl[0] = p->aCol[i].zColl; } } + }else{ + sqlite3_free(zColl); } } /* ** This function returns the collation sequence for database native text @@ -48255,10 +49250,11 @@ Table *pSelTab; /* A fake table from which we get the result set */ Select *pSel; /* Copy of the SELECT that implements the view */ int nErr = 0; /* Number of errors encountered */ int n; /* Temporarily holds the number of cursors assigned */ sqlite3 *db = pParse->db; /* Database connection for malloc errors */ + int (*xAuth)(void*,int,const char*,const char*,const char*,const char*); assert( pTable ); #ifndef SQLITE_OMIT_VIRTUALTABLE if( sqlite3VtabCallConnect(pParse, pTable) ){ @@ -48300,11 +49296,18 @@ pSel = sqlite3SelectDup(db, pTable->pSelect); if( pSel ){ n = pParse->nTab; sqlite3SrcListAssignCursors(pParse, pSel->pSrc); pTable->nCol = -1; +#ifndef SQLITE_OMIT_AUTHORIZATION + xAuth = db->xAuth; + db->xAuth = 0; + pSelTab = sqlite3ResultSetOfSelect(pParse, 0, pSel); + db->xAuth = xAuth; +#else pSelTab = sqlite3ResultSetOfSelect(pParse, 0, pSel); +#endif pParse->nTab = n; if( pSelTab ){ assert( pTable->aCol==0 ); pTable->nCol = pSelTab->nCol; pTable->aCol = pSelTab->aCol; @@ -48488,10 +49491,17 @@ } goto exit_drop_table; } iDb = sqlite3SchemaToIndex(db, pTab->pSchema); assert( iDb>=0 && iDb<db->nDb ); + + /* If pTab is a virtual table, call ViewGetColumnNames() to ensure + ** it is initialized. + */ + if( IsVirtual(pTab) && sqlite3ViewGetColumnNames(pParse, pTab) ){ + goto exit_drop_table; + } #ifndef SQLITE_OMIT_AUTHORIZATION { int code; const char *zTab = SCHEMA_TABLE(iDb); const char *zDb = db->aDb[iDb].zName; @@ -48505,13 +49515,10 @@ }else{ code = SQLITE_DROP_VIEW; } #ifndef SQLITE_OMIT_VIRTUALTABLE }else if( IsVirtual(pTab) ){ - if( sqlite3ViewGetColumnNames(pParse, pTab) ){ - goto exit_drop_table; - } code = SQLITE_DROP_VTABLE; zArg2 = pTab->pMod->zName; #endif }else{ if( !OMIT_TEMPDB && iDb==1 ){ @@ -49915,20 +50922,23 @@ if( pName1==0 || pName1->z==0 ){ reindexDatabases(pParse, 0); return; }else if( pName2==0 || pName2->z==0 ){ + char *zColl; assert( pName1->z ); - pColl = sqlite3FindCollSeq(db, ENC(db), (char*)pName1->z, pName1->n, 0); - if( pColl ){ - char *zColl = sqlite3DbStrNDup(db, (const char *)pName1->z, pName1->n); + zColl = sqlite3NameFromToken(pParse->db, pName1); + if( !zColl ) return; + pColl = sqlite3FindCollSeq(db, ENC(db), zColl, -1, 0); + if( pColl ){ if( zColl ){ reindexDatabases(pParse, zColl); sqlite3_free(zColl); } return; } + sqlite3_free(zColl); } iDb = sqlite3TwoPartName(pParse, pName1, pName2, &pObjName); if( iDb<0 ) return; z = sqlite3NameFromToken(db, pObjName); if( z==0 ) return; @@ -50380,11 +51390,11 @@ ** ************************************************************************* ** This file contains C code routines that are called by the parser ** in order to generate code for DELETE FROM statements. ** -** $Id: delete.c,v 1.130 2007/08/16 04:30:40 drh Exp $ +** $Id: delete.c,v 1.131 2007/11/11 18:36:34 drh Exp $ */ /* ** Look up every table that is named in pSrc. If any table is not found, ** add an error message to pParse->zErrMsg and return NULL. If all tables @@ -50644,13 +51654,14 @@ /* This is the beginning of the delete loop when there are ** row triggers. */ if( triggers_exist ){ + int mem1 = pParse->nMem++; addr = sqlite3VdbeAddOp(v, OP_FifoRead, 0, end); - if( !isView ){ - sqlite3VdbeAddOp(v, OP_Dup, 0, 0); + sqlite3VdbeAddOp(v, OP_MemStore, mem1, 0); + if( !isView ){ sqlite3OpenTable(pParse, iCur, iDb, pTab, OP_OpenRead); } sqlite3VdbeAddOp(v, OP_MoveGe, iCur, 0); sqlite3VdbeAddOp(v, OP_Rowid, iCur, 0); sqlite3VdbeAddOp(v, OP_RowData, iCur, 0); @@ -50660,10 +51671,13 @@ } (void)sqlite3CodeRowTrigger(pParse, TK_DELETE, 0, TRIGGER_BEFORE, pTab, -1, oldIdx, (pParse->trigStack)?pParse->trigStack->orconf:OE_Default, addr); + if( !isView ){ + sqlite3VdbeAddOp(v, OP_MemLoad, mem1, 0); + } } if( !isView ){ /* Open cursors for the table we are deleting from and all its ** indices. If there are row triggers, this happens inside the @@ -50853,11 +51867,11 @@ ** ** There is only one exported symbol in this file - the function ** sqliteRegisterBuildinFunctions() found at the bottom of the file. ** All other code has file scope. ** -** $Id: func.c,v 1.174 2007/09/03 11:04:22 danielk1977 Exp $ +** $Id: func.c,v 1.176 2007/11/01 17:38:31 drh Exp $ */ /* ** Return the collating function associated with a function. @@ -51001,11 +52015,11 @@ const unsigned char *z2; int len; int p0type; i64 p1, p2; - assert( argc==3 ); + assert( argc==3 || argc==2 ); p0type = sqlite3_value_type(argv[0]); if( p0type==SQLITE_BLOB ){ len = sqlite3_value_bytes(argv[0]); z = sqlite3_value_blob(argv[0]); if( z==0 ) return; @@ -51017,11 +52031,15 @@ for(z2=z; *z2; len++){ SQLITE_SKIP_UTF8(z2); } } p1 = sqlite3_value_int(argv[1]); - p2 = sqlite3_value_int(argv[2]); + if( argc==3 ){ + p2 = sqlite3_value_int(argv[2]); + }else{ + p2 = SQLITE_MAX_LENGTH; + } if( p1<0 ){ p1 += len; if( p1<0 ){ p2 += p1; p1 = 0; @@ -52140,10 +53158,46 @@ } sqlite3VdbeMemRelease(pRes); } } +#ifdef SQLITE_GROUP_CONCAT +/* +** group_concat(EXPR, ?SEPARATOR?) +*/ +static void groupConcatStep( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + const char *zVal; + char **pzAccumulator; + const char *zSep; + if( sqlite3_value_type(argv[0])==SQLITE_NULL ) return; + zVal = sqlite3_value_text(argv[0]); + pzAccumulator = (char**)sqlite3_aggregate_context(context, sizeof(char*)); + if( pzAccumulator ){ + if( *pzAccumulator==0 ){ + *pzAccumulator = sqlite3_mprintf("%s", zVal); + }else{ + if( argc==2 ){ + zSep = sqlite3_value_text(argv[1]); + }else{ + zSep = ","; + } + *pzAccumulator = sqlite3_mprintf("%z%s%s", *pzAccumulator, zSep, zVal); + } + } +} +static void groupConcatFinalize(sqlite3_context *context){ + char **pzAccum; + pzAccum = sqlite3_aggregate_context(context, 0); + if( pzAccum ){ + sqlite3_result_text(context, *pzAccum, -1, sqlite3_free); + } +} +#endif /*SQLITE_GROUP_CONCAT*/ /* ** This function registered all of the above C functions as SQL ** functions. This should be the only routine in this file with ** external linkage. @@ -52161,10 +53215,11 @@ { "min", 0, 0, SQLITE_UTF8, 1, 0 }, { "max", -1, 1, SQLITE_UTF8, 1, minmaxFunc }, { "max", 0, 1, SQLITE_UTF8, 1, 0 }, { "typeof", 1, 0, SQLITE_UTF8, 0, typeofFunc }, { "length", 1, 0, SQLITE_UTF8, 0, lengthFunc }, + { "substr", 2, 0, SQLITE_UTF8, 0, substrFunc }, { "substr", 3, 0, SQLITE_UTF8, 0, substrFunc }, { "abs", 1, 0, SQLITE_UTF8, 0, absFunc }, { "round", 1, 0, SQLITE_UTF8, 0, roundFunc }, { "round", 2, 0, SQLITE_UTF8, 0, roundFunc }, { "upper", 1, 0, SQLITE_UTF8, 0, upperFunc }, @@ -52218,10 +53273,14 @@ { "sum", 1, 0, 0, sumStep, sumFinalize }, { "total", 1, 0, 0, sumStep, totalFinalize }, { "avg", 1, 0, 0, sumStep, avgFinalize }, { "count", 0, 0, 0, countStep, countFinalize }, { "count", 1, 0, 0, countStep, countFinalize }, +#ifdef SQLITE_GROUP_CONCAT + { "group_concat", 1, 0, 0, groupConcatStep, groupConcatFinalize }, + { "group_concat", 2, 0, 0, groupConcatStep, groupConcatFinalize }, +#endif }; int i; for(i=0; i<sizeof(aFuncs)/sizeof(aFuncs[0]); i++){ void *pArg; @@ -52356,11 +53415,11 @@ ** ************************************************************************* ** This file contains C code routines that are called by the parser ** to handle INSERT statements in SQLite. ** -** $Id: insert.c,v 1.192 2007/09/03 17:30:07 danielk1977 Exp $ +** $Id: insert.c,v 1.193 2007/11/23 15:02:19 drh Exp $ */ /* ** Set P3 of the most recently inserted opcode to a column affinity ** string for index pIdx. A column affinity string has one character @@ -52442,26 +53501,42 @@ sqlite3VdbeChangeP3(v, -1, pTab->zColAff, 0); } /* -** Return non-zero if SELECT statement p opens the table with rootpage -** iTab in database iDb. This is used to see if a statement of the form -** "INSERT INTO <iDb, iTab> SELECT ..." can run without using temporary -** table for the results of the SELECT. -** -** No checking is done for sub-selects that are part of expressions. -*/ -static int selectReadsTable(Select *p, Schema *pSchema, int iTab){ - int i; - struct SrcList_item *pItem; - if( p->pSrc==0 ) return 0; - for(i=0, pItem=p->pSrc->a; i<p->pSrc->nSrc; i++, pItem++){ - if( pItem->pSelect ){ - if( selectReadsTable(pItem->pSelect, pSchema, iTab) ) return 1; - }else{ - if( pItem->pTab->pSchema==pSchema && pItem->pTab->tnum==iTab ) return 1; +** Return non-zero if the table pTab in database iDb or any of its indices +** have been opened at any point in the VDBE program beginning at location +** iStartAddr throught the end of the program. This is used to see if +** a statement of the form "INSERT INTO <iDb, pTab> SELECT ..." can +** run without using temporary table for the results of the SELECT. +*/ +static int readsTable(Vdbe *v, int iStartAddr, int iDb, Table *pTab){ + int i; + int iEnd = sqlite3VdbeCurrentAddr(v); + for(i=iStartAddr; i<iEnd; i++){ + VdbeOp *pOp = sqlite3VdbeGetOp(v, i); + if( pOp->opcode==OP_OpenRead ){ + VdbeOp *pPrior = &pOp[-1]; + int tnum = pOp->p2; + assert( i>iStartAddr ); + assert( pPrior->opcode==OP_Integer ); + if( pPrior->p1==iDb ){ + Index *pIndex; + if( tnum==pTab->tnum ){ + return 1; + } + for(pIndex=pTab->pIndex; pIndex; pIndex=pIndex->pNext){ + if( tnum==pIndex->tnum ){ + return 1; + } + } + } + } + if( pOp->opcode==OP_VOpen && pOp->p3==(const char*)pTab->pVtab ){ + assert( pOp->p3!=0 ); + assert( pOp->p3type==P3_VTAB ); + return 1; } } return 0; } @@ -52824,11 +53899,11 @@ ** ** A temp table must be used if the table being updated is also one ** of the tables being read by the SELECT statement. Also use a ** temp table in the case of row triggers. */ - if( triggers_exist || selectReadsTable(pSelect,pTab->pSchema,pTab->tnum) ){ + if( triggers_exist || readsTable(v, iSelectLoop, iDb, pTab) ){ useTempTable = 1; } if( useTempTable ){ /* Generate the subroutine that SELECT calls to process each row of @@ -52860,11 +53935,11 @@ */ NameContext sNC; memset(&sNC, 0, sizeof(sNC)); sNC.pParse = pParse; srcTab = -1; - useTempTable = 0; + assert( useTempTable==0 ); nColumn = pList ? pList->nExpr : 0; for(i=0; i<nColumn; i++){ if( sqlite3ExprResolveNames(&sNC, pList->a[i].pExpr) ){ goto insert_cleanup; } @@ -54529,10 +55604,19 @@ #ifdef SQLITE_OMIT_GET_TABLE # define sqlite3_free_table 0 # define sqlite3_get_table 0 #endif +#ifdef SQLITE_OMIT_INCRBLOB +#define sqlite3_bind_zeroblob 0 +#define sqlite3_blob_bytes 0 +#define sqlite3_blob_close 0 +#define sqlite3_blob_open 0 +#define sqlite3_blob_read 0 +#define sqlite3_blob_write 0 +#endif + /* ** The following structure contains pointers to all SQLite API routines. ** A pointer to this structure is passed into extensions when they are ** loaded so that the extension can make calls back into the SQLite ** library. @@ -54957,11 +56041,11 @@ ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains code used to implement the PRAGMA command. ** -** $Id: pragma.c,v 1.149 2007/08/31 18:34:59 drh Exp $ +** $Id: pragma.c,v 1.150 2007/11/13 10:30:25 danielk1977 Exp $ */ /* Ignore this whole file if pragmas are disabled */ #if !defined(SQLITE_OMIT_PRAGMA) && !defined(SQLITE_OMIT_PARSER) @@ -55148,12 +56232,19 @@ if( getBoolean(zRight) ){ db->flags |= p->mask; }else{ db->flags &= ~p->mask; } - } - } + + /* Many of the flag-pragmas modify the code generated by the SQL + ** compiler (eg. count_changes). So add an opcode to expire all + ** compiled SQL statements after modifying a pragma value. + */ + sqlite3VdbeAddOp(v, OP_Expire, 0, 0); + } + } + return 1; } } return 0; } @@ -56146,11 +57237,11 @@ ************************************************************************* ** This file contains the implementation of the sqlite3_prepare() ** interface, and routines that contribute to loading the database schema ** from disk. ** -** $Id: prepare.c,v 1.60 2007/08/29 12:31:27 danielk1977 Exp $ +** $Id: prepare.c,v 1.64 2007/11/14 06:48:48 danielk1977 Exp $ */ /* ** Fill the InitData structure with an error message that indicates ** that the database is corrupt. @@ -56432,11 +57523,21 @@ char *zSql; zSql = sqlite3MPrintf(db, "SELECT name, rootpage, sql FROM '%q'.%s", db->aDb[iDb].zName, zMasterName); sqlite3SafetyOff(db); - rc = sqlite3_exec(db, zSql, sqlite3InitCallback, &initData, 0); +#ifndef SQLITE_OMIT_AUTHORIZATION + { + int (*xAuth)(void*,int,const char*,const char*,const char*,const char*); + xAuth = db->xAuth; + db->xAuth = 0; +#endif + rc = sqlite3_exec(db, zSql, sqlite3InitCallback, &initData, 0); +#ifndef SQLITE_OMIT_AUTHORIZATION + db->xAuth = xAuth; + } +#endif if( rc==SQLITE_ABORT ) rc = initData.rc; sqlite3SafetyOn(db); sqlite3_free(zSql); #ifndef SQLITE_OMIT_ANALYZE if( rc==SQLITE_OK ){ @@ -56463,11 +57564,11 @@ rc = SQLITE_OK; } sqlite3BtreeLeave(pDb->pBt); error_out: - if( rc==SQLITE_NOMEM ){ + if( rc==SQLITE_NOMEM || rc==SQLITE_IOERR_NOMEM ){ db->mallocFailed = 1; } return rc; } @@ -56559,11 +57660,11 @@ if( rc==SQLITE_OK && cookie!=db->aDb[iDb].pSchema->schema_cookie ){ allOk = 0; } sqlite3BtreeCloseCursor(curTemp); } - if( rc==SQLITE_NOMEM ){ + if( rc==SQLITE_NOMEM || rc==SQLITE_IOERR_NOMEM ){ db->mallocFailed = 1; } } return allOk; } @@ -56750,18 +57851,21 @@ sqlite3_stmt *pNew; const char *zSql; sqlite3 *db; assert( sqlite3_mutex_held(sqlite3VdbeDb(p)->mutex) ); - zSql = sqlite3VdbeGetSql(p); + zSql = sqlite3_sql((sqlite3_stmt *)p); if( zSql==0 ){ return 0; } db = sqlite3VdbeDb(p); assert( sqlite3_mutex_held(db->mutex) ); rc = sqlite3LockAndPrepare(db, zSql, -1, 0, &pNew, 0); if( rc ){ + if( rc==SQLITE_NOMEM ){ + db->mallocFailed = 1; + } assert( pNew==0 ); return 0; }else{ assert( pNew!=0 ); } @@ -56888,11 +57992,11 @@ ** ************************************************************************* ** This file contains C code routines that are called by the parser ** to handle SELECT statements in SQLite. ** -** $Id: select.c,v 1.359 2007/08/31 17:42:48 danielk1977 Exp $ +** $Id: select.c,v 1.363 2007/11/23 13:42:52 drh Exp $ */ /* ** Delete all the content of a Select structure but do not deallocate @@ -57123,14 +58227,11 @@ pE = sqlite3PExpr(pParse, TK_EQ, pE1c, pE2c, 0); if( pE ){ ExprSetProperty(pE, EP_FromJoin); pE->iRightJoinTable = iRightJoinTable; } - pE = sqlite3ExprAnd(pParse->db,*ppExpr, pE); - if( pE ){ - *ppExpr = pE; - } + *ppExpr = sqlite3ExprAnd(pParse->db,*ppExpr, pE); } /* ** Set the EP_FromJoin property on all terms of the given expression. ** And set the Expr.iRightJoinTable to iTable for every term in the @@ -59196,14 +60297,22 @@ sqlite3DeleteTable(pSubitem->pTab); sqlite3_free(pSubitem->zDatabase); sqlite3_free(pSubitem->zName); sqlite3_free(pSubitem->zAlias); + pSubitem->pTab = 0; + pSubitem->zDatabase = 0; + pSubitem->zName = 0; + pSubitem->zAlias = 0; if( nSubSrc>1 ){ int extra = nSubSrc - 1; for(i=1; i<nSubSrc; i++){ pSrc = sqlite3SrcListAppend(db, pSrc, 0, 0); + if( pSrc==0 ){ + p->pSrc = 0; + return 1; + } } p->pSrc = pSrc; for(i=pSrc->nSrc-1; i-extra>=iFrom; i--){ pSrc->a[i] = pSrc->a[i-extra]; } @@ -59906,10 +61015,13 @@ */ pParse->nHeight += sqlite3SelectExprHeight(p); #endif sqlite3Select(pParse, pItem->pSelect, SRT_EphemTab, pItem->iCursor, p, i, &isAgg, 0); + if( db->mallocFailed ){ + goto select_end; + } #if defined(SQLITE_TEST) || SQLITE_MAX_EXPR_DEPTH>0 pParse->nHeight -= sqlite3SelectExprHeight(p); #endif if( needRestoreContext ){ pParse->zAuthContext = zSavedAuthContext; @@ -59941,10 +61053,20 @@ flattenSubquery(db, pParent, parentTab, *pParentAgg, isAgg) ){ if( isAgg ) *pParentAgg = 1; goto select_end; } #endif + + /* If possible, rewrite the query to use GROUP BY instead of DISTINCT. + ** GROUP BY may use an index, DISTINCT never does. + */ + if( p->isDistinct && !p->isAgg && !p->pGroupBy ){ + p->pGroupBy = sqlite3ExprListDup(db, p->pEList); + pGroupBy = p->pGroupBy; + p->isDistinct = 0; + isDistinct = 0; + } /* If there is an ORDER BY clause, then this sorting ** index might end up being unused if the data can be ** extracted in pre-sorted order. If that is the case, then the ** OP_OpenEphemeral instruction will be changed to an OP_Noop once @@ -59977,10 +61099,11 @@ /* Open a virtual index to use for the distinct set. */ if( isDistinct ){ KeyInfo *pKeyInfo; + assert( isAgg || pGroupBy ); distinct = pParse->nTab++; pKeyInfo = keyInfoFromExprList(pParse, p->pEList); sqlite3VdbeOp3(v, OP_OpenEphemeral, distinct, 0, (char*)pKeyInfo, P3_KEYINFO_HANDOFF); }else{ @@ -60004,11 +61127,12 @@ p->addrOpenEphm[2] = -1; } /* Use the standard inner loop */ - if( selectInnerLoop(pParse, p, pEList, 0, 0, pOrderBy, distinct, eDest, + assert(!isDistinct); + if( selectInnerLoop(pParse, p, pEList, 0, 0, pOrderBy, -1, eDest, iParm, pWInfo->iContinue, pWInfo->iBreak, aff) ){ goto select_end; } /* End the database scan loop. @@ -60066,11 +61190,11 @@ } } if( db->mallocFailed ) goto select_end; /* Processing for aggregates with GROUP BY is very different and - ** much more complex tha aggregates without a GROUP BY. + ** much more complex than aggregates without a GROUP BY. */ if( pGroupBy ){ KeyInfo *pKeyInfo; /* Keying information for the group by clause */ /* Create labels that we will be needing @@ -61395,16 +62519,17 @@ assert(newIdx != -1 || oldIdx != -1); for(p=pTab->pTrigger; p; p=p->pNext){ int fire_this = 0; + sqlite3 *db = pParse->db; /* Determine whether we should code this trigger */ if( p->op==op && p->tr_tm==tr_tm && - (p->pSchema==p->pTabSchema || p->pSchema==pParse->db->aDb[1].pSchema) && + (p->pSchema==p->pTabSchema || p->pSchema==db->aDb[1].pSchema) && (op!=TK_UPDATE||!p->pColumns||checkColumnOverLap(p->pColumns,pChanges)) ){ TriggerStack *pS; /* Pointer to trigger-stack entry */ for(pS=pParse->trigStack; pS && p!=pS->pTrigger; pS=pS->pNext){} if( !pS ){ @@ -61438,12 +62563,12 @@ pParse->trigStack = &trigStackEntry; sqlite3AuthContextPush(pParse, &sContext, p->name); /* code the WHEN clause */ endTrigger = sqlite3VdbeMakeLabel(pParse->pVdbe); - whenExpr = sqlite3ExprDup(pParse->db, p->pWhen); - if( sqlite3ExprResolveNames(&sNC, whenExpr) ){ + whenExpr = sqlite3ExprDup(db, p->pWhen); + if( db->mallocFailed || sqlite3ExprResolveNames(&sNC, whenExpr) ){ pParse->trigStack = trigStackEntry.pNext; sqlite3ExprDelete(whenExpr); return 1; } sqlite3ExprIfFalse(pParse, whenExpr, endTrigger, 1); @@ -61476,11 +62601,11 @@ ** ************************************************************************* ** This file contains C code routines that are called by the parser ** to handle UPDATE statements. ** -** $Id: update.c,v 1.140 2007/08/16 10:09:03 danielk1977 Exp $ +** $Id: update.c,v 1.141 2007/11/11 18:36:34 drh Exp $ */ #ifndef SQLITE_OMIT_VIRTUALTABLE /* Forward declaration */ static void updateVirtualTable( @@ -61781,10 +62906,12 @@ memCnt = pParse->nMem++; sqlite3VdbeAddOp(v, OP_MemInt, 0, memCnt); } if( triggers_exist ){ + int mem1; /* Memory address storing the rowid for next row to update */ + /* Create pseudo-tables for NEW and OLD */ sqlite3VdbeAddOp(v, OP_OpenPseudo, oldIdx, 0); sqlite3VdbeAddOp(v, OP_SetNumColumns, oldIdx, pTab->nCol); sqlite3VdbeAddOp(v, OP_OpenPseudo, newIdx, 0); @@ -61791,14 +62918,14 @@ sqlite3VdbeAddOp(v, OP_SetNumColumns, newIdx, pTab->nCol); /* The top of the update loop for when there are triggers. */ addr = sqlite3VdbeAddOp(v, OP_FifoRead, 0, 0); - - if( !isView ){ - sqlite3VdbeAddOp(v, OP_Dup, 0, 0); - sqlite3VdbeAddOp(v, OP_Dup, 0, 0); + mem1 = pParse->nMem++; + sqlite3VdbeAddOp(v, OP_MemStore, mem1, 0); + + if( !isView ){ /* Open a cursor and make it point to the record that is ** being updated. */ sqlite3OpenTable(pParse, iCur, iDb, pTab, OP_OpenRead); } @@ -61843,10 +62970,15 @@ /* Fire the BEFORE and INSTEAD OF triggers */ if( sqlite3CodeRowTrigger(pParse, TK_UPDATE, pChanges, TRIGGER_BEFORE, pTab, newIdx, oldIdx, onError, addr) ){ goto update_cleanup; + } + + if( !isView ){ + sqlite3VdbeAddOp(v, OP_MemLoad, mem1, 0); + sqlite3VdbeAddOp(v, OP_Dup, 0, 0); } } if( !isView && !IsVirtual(pTab) ){ /* @@ -62110,11 +63242,11 @@ ** This file contains code used to implement the VACUUM command. ** ** Most of the code in this file may be omitted by defining the ** SQLITE_OMIT_VACUUM macro. ** -** $Id: vacuum.c,v 1.73 2007/08/29 12:31:28 danielk1977 Exp $ +** $Id: vacuum.c,v 1.74 2007/10/20 20:58:57 drh Exp $ */ #if !defined(SQLITE_OMIT_VACUUM) && !defined(SQLITE_OMIT_ATTACH) /* ** Execute zSql on database db. Return an error code. @@ -62230,21 +63362,21 @@ /* Query the schema of the main database. Create a mirror schema ** in the temporary database. */ rc = execExecSql(db, - "SELECT 'CREATE TABLE vacuum_db.' || substr(sql,14,100000000) " + "SELECT 'CREATE TABLE vacuum_db.' || substr(sql,14) " " FROM sqlite_master WHERE type='table' AND name!='sqlite_sequence'" " AND rootpage>0" ); if( rc!=SQLITE_OK ) goto end_of_vacuum; rc = execExecSql(db, - "SELECT 'CREATE INDEX vacuum_db.' || substr(sql,14,100000000)" + "SELECT 'CREATE INDEX vacuum_db.' || substr(sql,14)" " FROM sqlite_master WHERE sql LIKE 'CREATE INDEX %' "); if( rc!=SQLITE_OK ) goto end_of_vacuum; rc = execExecSql(db, - "SELECT 'CREATE UNIQUE INDEX vacuum_db.' || substr(sql,21,100000000) " + "SELECT 'CREATE UNIQUE INDEX vacuum_db.' || substr(sql,21) " " FROM sqlite_master WHERE sql LIKE 'CREATE UNIQUE INDEX %'"); if( rc!=SQLITE_OK ) goto end_of_vacuum; /* Loop through the tables in the main database. For each, do ** an "INSERT INTO vacuum_db.xxx SELECT * FROM xxx;" to copy @@ -62370,11 +63502,11 @@ ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains code used to help implement virtual tables. ** -** $Id: vtab.c,v 1.57 2007/09/04 15:38:58 danielk1977 Exp $ +** $Id: vtab.c,v 1.59 2007/09/20 11:32:18 rse Exp $ */ #ifndef SQLITE_OMIT_VIRTUALTABLE static int createModule( sqlite3 *db, /* Database in which module is registered */ @@ -63106,11 +64238,11 @@ sqlite3_vtab *pVtab; sqlite3_module *pMod; void (*xFunc)(sqlite3_context*,int,sqlite3_value**); void *pArg; FuncDef *pNew; - int rc; + int rc = 0; char *zLowerName; unsigned char *z; /* Check to see the left operand is a column in a virtual table */ @@ -63123,11 +64255,11 @@ assert( pVtab!=0 ); assert( pVtab->pModule!=0 ); pMod = (sqlite3_module *)pVtab->pModule; if( pMod->xFindFunction==0 ) return pDef; - /* Call the xFuncFunction method on the virtual table implementation + /* Call the xFindFunction method on the virtual table implementation ** to see if the implementation wants to overload this function */ zLowerName = sqlite3DbStrDup(db, pDef->zName); if( zLowerName ){ for(z=(unsigned char*)zLowerName; *z; z++){ @@ -63174,11 +64306,11 @@ ** generating the code that loops through a table looking for applicable ** rows. Indices are selected and used to speed the search when doing ** so is applicable. Because this module is responsible for selecting ** indices, you might also think of this module as the "query optimizer". ** -** $Id: where.c,v 1.261 2007/09/13 17:54:40 drh Exp $ +** $Id: where.c,v 1.262 2007/11/05 05:12:53 danielk1977 Exp $ */ /* ** The number of bits in a Bitmask. "BMS" means "BitMask Size". */ @@ -64396,10 +65528,11 @@ /* Count the number of possible WHERE clause constraints referring ** to this virtual table */ for(i=nTerm=0, pTerm=pWC->a; i<pWC->nTerm; i++, pTerm++){ if( pTerm->leftCursor != pSrc->iCursor ) continue; if( pTerm->eOperator==WO_IN ) continue; + if( pTerm->eOperator==WO_ISNULL ) continue; nTerm++; } /* If the ORDER BY clause contains only columns in the current ** virtual table then allocate space for the aOrderBy part of @@ -64443,10 +65576,11 @@ pUsage; for(i=j=0, pTerm=pWC->a; i<pWC->nTerm; i++, pTerm++){ if( pTerm->leftCursor != pSrc->iCursor ) continue; if( pTerm->eOperator==WO_IN ) continue; + if( pTerm->eOperator==WO_ISNULL ) continue; pIdxCons[j].iColumn = pTerm->leftColumn; pIdxCons[j].iTermOffset = i; pIdxCons[j].op = pTerm->eOperator; /* The direct assignment in the previous line is possible only because ** the WO_ and SQLITE_INDEX_CONSTRAINT_ codes are identical. The @@ -66050,12 +67184,12 @@ #endif #define sqlite3ParserARG_SDECL Parse *pParse; #define sqlite3ParserARG_PDECL ,Parse *pParse #define sqlite3ParserARG_FETCH Parse *pParse = yypParser->pParse #define sqlite3ParserARG_STORE yypParser->pParse = pParse -#define YYNSTATE 586 -#define YYNRULE 311 +#define YYNSTATE 588 +#define YYNRULE 312 #define YYERRORSYMBOL 138 #define YYERRSYMDT yy495 #define YYFALLBACK 1 #define YY_NO_ACTION (YYNSTATE+YYNRULE+2) #define YY_ACCEPT_ACTION (YYNSTATE+YYNRULE+1) @@ -66107,419 +67241,420 @@ ** yy_reduce_ofst[] For each state, the offset into yy_action for ** shifting non-terminals after a reduce. ** yy_default[] Default action for each state. */ static const YYACTIONTYPE yy_action[] = { - /* 0 */ 290, 898, 122, 585, 407, 170, 2, 437, 61, 61, - /* 10 */ 61, 61, 517, 63, 63, 63, 63, 64, 64, 65, - /* 20 */ 65, 65, 66, 231, 445, 209, 422, 428, 68, 63, - /* 30 */ 63, 63, 63, 64, 64, 65, 65, 65, 66, 231, - /* 40 */ 389, 386, 394, 449, 60, 59, 295, 432, 433, 429, - /* 50 */ 429, 62, 62, 61, 61, 61, 61, 261, 63, 63, - /* 60 */ 63, 63, 64, 64, 65, 65, 65, 66, 231, 290, - /* 70 */ 491, 492, 437, 487, 206, 81, 67, 417, 69, 152, - /* 80 */ 63, 63, 63, 63, 64, 64, 65, 65, 65, 66, - /* 90 */ 231, 67, 460, 69, 152, 422, 428, 571, 262, 58, - /* 100 */ 64, 64, 65, 65, 65, 66, 231, 395, 396, 419, - /* 110 */ 419, 419, 290, 60, 59, 295, 432, 433, 429, 429, - /* 120 */ 62, 62, 61, 61, 61, 61, 315, 63, 63, 63, - /* 130 */ 63, 64, 64, 65, 65, 65, 66, 231, 422, 428, - /* 140 */ 93, 65, 65, 65, 66, 231, 394, 231, 412, 34, - /* 150 */ 56, 296, 440, 441, 408, 486, 60, 59, 295, 432, - /* 160 */ 433, 429, 429, 62, 62, 61, 61, 61, 61, 488, - /* 170 */ 63, 63, 63, 63, 64, 64, 65, 65, 65, 66, - /* 180 */ 231, 290, 255, 522, 293, 569, 112, 406, 520, 449, - /* 190 */ 329, 315, 405, 20, 437, 338, 517, 394, 530, 529, - /* 200 */ 503, 445, 209, 568, 567, 206, 528, 422, 428, 147, - /* 210 */ 148, 395, 396, 412, 41, 208, 149, 531, 370, 487, - /* 220 */ 259, 566, 257, 417, 290, 60, 59, 295, 432, 433, - /* 230 */ 429, 429, 62, 62, 61, 61, 61, 61, 315, 63, - /* 240 */ 63, 63, 63, 64, 64, 65, 65, 65, 66, 231, - /* 250 */ 422, 428, 445, 331, 212, 419, 419, 419, 361, 437, - /* 260 */ 412, 41, 395, 396, 364, 565, 208, 290, 60, 59, - /* 270 */ 295, 432, 433, 429, 429, 62, 62, 61, 61, 61, - /* 280 */ 61, 394, 63, 63, 63, 63, 64, 64, 65, 65, - /* 290 */ 65, 66, 231, 422, 428, 489, 298, 522, 472, 66, - /* 300 */ 231, 211, 472, 224, 409, 284, 532, 20, 447, 521, - /* 310 */ 166, 60, 59, 295, 432, 433, 429, 429, 62, 62, - /* 320 */ 61, 61, 61, 61, 472, 63, 63, 63, 63, 64, - /* 330 */ 64, 65, 65, 65, 66, 231, 207, 478, 315, 76, - /* 340 */ 290, 235, 298, 55, 482, 225, 395, 396, 179, 545, - /* 350 */ 492, 343, 346, 347, 67, 150, 69, 152, 337, 522, - /* 360 */ 412, 35, 348, 237, 249, 368, 422, 428, 576, 20, - /* 370 */ 162, 116, 239, 341, 244, 342, 174, 320, 440, 441, - /* 380 */ 412, 3, 79, 250, 60, 59, 295, 432, 433, 429, - /* 390 */ 429, 62, 62, 61, 61, 61, 61, 172, 63, 63, - /* 400 */ 63, 63, 64, 64, 65, 65, 65, 66, 231, 290, - /* 410 */ 249, 548, 232, 485, 508, 351, 315, 116, 239, 341, - /* 420 */ 244, 342, 174, 179, 315, 523, 343, 346, 347, 250, - /* 430 */ 218, 413, 153, 462, 509, 422, 428, 348, 412, 34, - /* 440 */ 463, 208, 175, 173, 158, 233, 412, 34, 336, 547, - /* 450 */ 447, 321, 166, 60, 59, 295, 432, 433, 429, 429, - /* 460 */ 62, 62, 61, 61, 61, 61, 413, 63, 63, 63, - /* 470 */ 63, 64, 64, 65, 65, 65, 66, 231, 290, 540, - /* 480 */ 333, 515, 502, 539, 454, 569, 300, 19, 329, 142, - /* 490 */ 315, 388, 315, 328, 2, 360, 455, 292, 481, 371, - /* 500 */ 267, 266, 250, 568, 422, 428, 586, 389, 386, 456, - /* 510 */ 206, 493, 412, 49, 412, 49, 301, 583, 889, 157, - /* 520 */ 889, 494, 60, 59, 295, 432, 433, 429, 429, 62, - /* 530 */ 62, 61, 61, 61, 61, 199, 63, 63, 63, 63, - /* 540 */ 64, 64, 65, 65, 65, 66, 231, 290, 315, 179, - /* 550 */ 436, 253, 343, 346, 347, 368, 151, 580, 306, 248, - /* 560 */ 307, 450, 75, 348, 77, 380, 208, 423, 424, 413, - /* 570 */ 412, 27, 317, 422, 428, 438, 1, 22, 583, 888, - /* 580 */ 394, 888, 542, 476, 318, 261, 435, 435, 426, 427, - /* 590 */ 413, 60, 59, 295, 432, 433, 429, 429, 62, 62, - /* 600 */ 61, 61, 61, 61, 326, 63, 63, 63, 63, 64, - /* 610 */ 64, 65, 65, 65, 66, 231, 290, 425, 580, 372, - /* 620 */ 219, 92, 515, 9, 334, 394, 555, 394, 454, 67, - /* 630 */ 394, 69, 152, 397, 398, 399, 318, 234, 435, 435, - /* 640 */ 455, 316, 422, 428, 297, 395, 396, 318, 430, 435, - /* 650 */ 435, 579, 289, 456, 220, 325, 5, 217, 544, 290, - /* 660 */ 60, 59, 295, 432, 433, 429, 429, 62, 62, 61, - /* 670 */ 61, 61, 61, 393, 63, 63, 63, 63, 64, 64, - /* 680 */ 65, 65, 65, 66, 231, 422, 428, 480, 311, 390, - /* 690 */ 395, 396, 395, 396, 205, 395, 396, 821, 271, 515, - /* 700 */ 248, 198, 290, 60, 59, 295, 432, 433, 429, 429, - /* 710 */ 62, 62, 61, 61, 61, 61, 468, 63, 63, 63, - /* 720 */ 63, 64, 64, 65, 65, 65, 66, 231, 422, 428, - /* 730 */ 169, 158, 261, 261, 302, 413, 274, 117, 272, 261, - /* 740 */ 515, 515, 261, 515, 190, 290, 60, 70, 295, 432, - /* 750 */ 433, 429, 429, 62, 62, 61, 61, 61, 61, 377, - /* 760 */ 63, 63, 63, 63, 64, 64, 65, 65, 65, 66, - /* 770 */ 231, 422, 428, 382, 557, 303, 304, 248, 413, 318, - /* 780 */ 558, 435, 435, 559, 538, 358, 538, 385, 290, 194, - /* 790 */ 59, 295, 432, 433, 429, 429, 62, 62, 61, 61, - /* 800 */ 61, 61, 369, 63, 63, 63, 63, 64, 64, 65, - /* 810 */ 65, 65, 66, 231, 422, 428, 394, 273, 248, 248, - /* 820 */ 170, 246, 437, 413, 384, 365, 176, 177, 178, 467, - /* 830 */ 309, 121, 154, 126, 295, 432, 433, 429, 429, 62, - /* 840 */ 62, 61, 61, 61, 61, 315, 63, 63, 63, 63, - /* 850 */ 64, 64, 65, 65, 65, 66, 231, 72, 322, 175, - /* 860 */ 4, 315, 261, 315, 294, 261, 413, 412, 28, 315, - /* 870 */ 261, 315, 319, 72, 322, 315, 4, 418, 443, 443, - /* 880 */ 294, 395, 396, 412, 23, 412, 32, 437, 319, 324, - /* 890 */ 327, 412, 53, 412, 52, 315, 156, 412, 97, 449, - /* 900 */ 315, 192, 315, 275, 315, 324, 376, 469, 500, 315, - /* 910 */ 476, 277, 476, 163, 292, 449, 315, 412, 95, 74, - /* 920 */ 73, 467, 412, 100, 412, 101, 412, 111, 72, 313, - /* 930 */ 314, 412, 113, 417, 446, 74, 73, 479, 412, 16, - /* 940 */ 379, 315, 181, 465, 72, 313, 314, 72, 322, 417, - /* 950 */ 4, 206, 315, 184, 294, 315, 497, 498, 474, 206, - /* 960 */ 171, 339, 319, 412, 98, 419, 419, 419, 420, 421, - /* 970 */ 11, 359, 378, 305, 412, 33, 413, 412, 96, 324, - /* 980 */ 458, 419, 419, 419, 420, 421, 11, 413, 411, 449, - /* 990 */ 411, 160, 410, 315, 410, 466, 221, 222, 223, 103, - /* 1000 */ 83, 471, 315, 507, 506, 315, 620, 475, 315, 74, - /* 1010 */ 73, 245, 203, 21, 279, 412, 24, 437, 72, 313, - /* 1020 */ 314, 280, 315, 417, 412, 54, 505, 412, 114, 315, - /* 1030 */ 412, 115, 504, 201, 145, 547, 240, 510, 524, 200, - /* 1040 */ 315, 511, 202, 315, 412, 25, 315, 241, 315, 18, - /* 1050 */ 315, 412, 36, 315, 254, 419, 419, 419, 420, 421, - /* 1060 */ 11, 256, 412, 37, 258, 412, 26, 315, 412, 38, - /* 1070 */ 412, 39, 412, 40, 260, 412, 42, 315, 512, 315, - /* 1080 */ 126, 315, 437, 315, 187, 375, 276, 266, 265, 412, - /* 1090 */ 43, 291, 315, 252, 315, 126, 206, 581, 8, 412, - /* 1100 */ 44, 412, 29, 412, 30, 412, 45, 350, 363, 126, - /* 1110 */ 315, 543, 315, 126, 412, 46, 412, 47, 315, 355, - /* 1120 */ 381, 551, 315, 171, 552, 315, 90, 562, 578, 90, - /* 1130 */ 288, 366, 412, 48, 412, 31, 582, 367, 268, 269, - /* 1140 */ 412, 10, 270, 554, 412, 50, 564, 412, 51, 278, - /* 1150 */ 281, 282, 575, 144, 442, 403, 323, 226, 444, 461, - /* 1160 */ 464, 242, 503, 550, 561, 513, 161, 392, 400, 516, - /* 1170 */ 401, 345, 402, 7, 312, 83, 227, 332, 228, 82, - /* 1180 */ 330, 57, 408, 416, 168, 78, 459, 123, 210, 414, - /* 1190 */ 84, 335, 340, 299, 496, 500, 490, 229, 495, 243, - /* 1200 */ 104, 247, 499, 501, 230, 285, 415, 215, 514, 518, - /* 1210 */ 525, 526, 519, 236, 527, 473, 238, 352, 477, 286, - /* 1220 */ 182, 356, 533, 354, 119, 183, 185, 87, 546, 130, - /* 1230 */ 186, 535, 188, 140, 362, 191, 553, 216, 373, 374, - /* 1240 */ 131, 560, 308, 132, 133, 572, 577, 136, 263, 134, - /* 1250 */ 139, 536, 573, 391, 91, 94, 404, 574, 99, 214, - /* 1260 */ 102, 621, 622, 431, 164, 434, 165, 71, 141, 17, - /* 1270 */ 439, 448, 451, 155, 6, 452, 470, 110, 167, 453, - /* 1280 */ 457, 124, 13, 213, 120, 80, 12, 125, 159, 483, - /* 1290 */ 484, 85, 310, 105, 180, 251, 106, 118, 86, 107, - /* 1300 */ 241, 344, 349, 353, 143, 534, 127, 357, 171, 189, - /* 1310 */ 264, 108, 287, 128, 549, 129, 193, 537, 541, 14, - /* 1320 */ 195, 88, 196, 556, 197, 137, 138, 135, 15, 563, - /* 1330 */ 570, 109, 283, 146, 204, 383, 387, 899, 584, 899, - /* 1340 */ 899, 899, 899, 899, 89, + /* 0 */ 292, 89, 397, 93, 158, 164, 350, 511, 82, 82, + /* 10 */ 82, 82, 215, 84, 84, 84, 84, 85, 85, 86, + /* 20 */ 86, 86, 87, 210, 437, 310, 497, 482, 90, 84, + /* 30 */ 84, 84, 84, 85, 85, 86, 86, 86, 87, 210, + /* 40 */ 432, 420, 349, 420, 81, 77, 301, 472, 471, 481, + /* 50 */ 481, 83, 83, 82, 82, 82, 82, 210, 84, 84, + /* 60 */ 84, 84, 85, 85, 86, 86, 86, 87, 210, 292, + /* 70 */ 469, 310, 511, 400, 508, 76, 492, 491, 577, 564, + /* 80 */ 84, 84, 84, 84, 85, 85, 86, 86, 86, 87, + /* 90 */ 210, 395, 394, 219, 581, 497, 482, 486, 485, 75, + /* 100 */ 118, 283, 314, 282, 316, 175, 502, 502, 502, 361, + /* 110 */ 455, 453, 276, 81, 77, 301, 472, 471, 481, 481, + /* 120 */ 83, 83, 82, 82, 82, 82, 488, 84, 84, 84, + /* 130 */ 84, 85, 85, 86, 86, 86, 87, 210, 292, 219, + /* 140 */ 375, 520, 524, 428, 511, 194, 118, 283, 314, 282, + /* 150 */ 316, 175, 9, 391, 222, 375, 450, 89, 276, 93, + /* 160 */ 158, 521, 530, 36, 497, 482, 85, 85, 86, 86, + /* 170 */ 86, 87, 210, 222, 305, 455, 453, 530, 45, 549, + /* 180 */ 370, 292, 81, 77, 301, 472, 471, 481, 481, 83, + /* 190 */ 83, 82, 82, 82, 82, 475, 84, 84, 84, 84, + /* 200 */ 85, 85, 86, 86, 86, 87, 210, 497, 482, 511, + /* 210 */ 388, 505, 155, 296, 258, 449, 224, 335, 213, 439, + /* 220 */ 294, 440, 435, 179, 292, 81, 77, 301, 472, 471, + /* 230 */ 481, 481, 83, 83, 82, 82, 82, 82, 222, 84, + /* 240 */ 84, 84, 84, 85, 85, 86, 86, 86, 87, 210, + /* 250 */ 497, 482, 450, 448, 226, 250, 287, 522, 824, 441, + /* 260 */ 545, 188, 95, 1, 169, 260, 578, 450, 81, 77, + /* 270 */ 301, 472, 471, 481, 481, 83, 83, 82, 82, 82, + /* 280 */ 82, 377, 84, 84, 84, 84, 85, 85, 86, 86, + /* 290 */ 86, 87, 210, 247, 353, 249, 88, 292, 522, 174, + /* 300 */ 358, 432, 113, 369, 254, 255, 450, 443, 221, 389, + /* 310 */ 170, 161, 152, 430, 215, 321, 344, 440, 435, 526, + /* 320 */ 546, 149, 151, 497, 482, 450, 235, 392, 327, 583, + /* 330 */ 20, 469, 440, 435, 373, 508, 173, 172, 171, 65, + /* 340 */ 239, 81, 77, 301, 472, 471, 481, 481, 83, 83, + /* 350 */ 82, 82, 82, 82, 295, 84, 84, 84, 84, 85, + /* 360 */ 85, 86, 86, 86, 87, 210, 292, 502, 502, 502, + /* 370 */ 460, 440, 435, 167, 248, 375, 323, 326, 313, 490, + /* 380 */ 167, 375, 529, 323, 326, 313, 546, 328, 576, 157, + /* 390 */ 440, 435, 497, 482, 328, 484, 20, 530, 42, 366, + /* 400 */ 18, 466, 466, 530, 42, 366, 124, 466, 466, 292, + /* 410 */ 81, 77, 301, 472, 471, 481, 481, 83, 83, 82, + /* 420 */ 82, 82, 82, 522, 84, 84, 84, 84, 85, 85, + /* 430 */ 86, 86, 86, 87, 210, 497, 482, 80, 167, 340, + /* 440 */ 555, 323, 326, 313, 319, 340, 901, 139, 552, 8, + /* 450 */ 341, 2, 328, 81, 77, 301, 472, 471, 481, 481, + /* 460 */ 83, 83, 82, 82, 82, 82, 205, 84, 84, 84, + /* 470 */ 84, 85, 85, 86, 86, 86, 87, 210, 292, 533, + /* 480 */ 375, 496, 406, 57, 86, 86, 86, 87, 210, 375, + /* 490 */ 79, 375, 63, 375, 405, 547, 89, 168, 93, 158, + /* 500 */ 400, 159, 530, 32, 497, 482, 528, 404, 124, 480, + /* 510 */ 450, 530, 32, 530, 45, 530, 24, 450, 395, 463, + /* 520 */ 268, 264, 81, 77, 301, 472, 471, 481, 481, 83, + /* 530 */ 83, 82, 82, 82, 82, 522, 84, 84, 84, 84, + /* 540 */ 85, 85, 86, 86, 86, 87, 210, 292, 300, 375, + /* 550 */ 462, 390, 546, 2, 208, 375, 450, 303, 263, 622, + /* 560 */ 266, 410, 20, 425, 450, 443, 89, 424, 93, 158, + /* 570 */ 191, 530, 25, 497, 482, 440, 435, 530, 42, 352, + /* 580 */ 382, 222, 440, 435, 272, 150, 582, 418, 441, 357, + /* 590 */ 188, 81, 77, 301, 472, 471, 481, 481, 83, 83, + /* 600 */ 82, 82, 82, 82, 522, 84, 84, 84, 84, 85, + /* 610 */ 85, 86, 86, 86, 87, 210, 292, 401, 320, 331, + /* 620 */ 270, 440, 435, 406, 366, 539, 466, 466, 365, 440, + /* 630 */ 435, 580, 561, 457, 892, 405, 892, 559, 579, 91, + /* 640 */ 530, 3, 497, 482, 464, 87, 210, 565, 404, 261, + /* 650 */ 345, 359, 403, 457, 891, 566, 891, 535, 573, 292, + /* 660 */ 81, 77, 301, 472, 471, 481, 481, 83, 83, 82, + /* 670 */ 82, 82, 82, 550, 84, 84, 84, 84, 85, 85, + /* 680 */ 86, 86, 86, 87, 210, 497, 482, 409, 544, 574, + /* 690 */ 385, 415, 211, 550, 519, 518, 539, 368, 571, 535, + /* 700 */ 562, 506, 292, 81, 77, 301, 472, 471, 481, 481, + /* 710 */ 83, 83, 82, 82, 82, 82, 375, 84, 84, 84, + /* 720 */ 84, 85, 85, 86, 86, 86, 87, 210, 497, 482, + /* 730 */ 366, 557, 466, 466, 306, 279, 443, 221, 530, 41, + /* 740 */ 535, 387, 229, 535, 535, 292, 81, 94, 301, 472, + /* 750 */ 471, 481, 481, 83, 83, 82, 82, 82, 82, 375, + /* 760 */ 84, 84, 84, 84, 85, 85, 86, 86, 86, 87, + /* 770 */ 210, 497, 482, 477, 551, 309, 189, 279, 308, 312, + /* 780 */ 147, 530, 10, 588, 516, 317, 445, 445, 292, 318, + /* 790 */ 77, 301, 472, 471, 481, 481, 83, 83, 82, 82, + /* 800 */ 82, 82, 375, 84, 84, 84, 84, 85, 85, 86, + /* 810 */ 86, 86, 87, 210, 497, 482, 553, 478, 279, 91, + /* 820 */ 570, 279, 279, 542, 530, 39, 433, 431, 429, 567, + /* 830 */ 19, 164, 145, 511, 301, 472, 471, 481, 481, 83, + /* 840 */ 83, 82, 82, 82, 82, 186, 84, 84, 84, 84, + /* 850 */ 85, 85, 86, 86, 86, 87, 210, 69, 354, 375, + /* 860 */ 4, 375, 21, 375, 299, 470, 511, 168, 375, 363, + /* 870 */ 334, 375, 364, 69, 354, 62, 4, 525, 375, 522, + /* 880 */ 299, 530, 26, 530, 34, 530, 117, 375, 364, 346, + /* 890 */ 530, 49, 228, 530, 51, 375, 153, 174, 511, 432, + /* 900 */ 530, 27, 375, 553, 375, 346, 459, 570, 22, 530, + /* 910 */ 40, 438, 330, 124, 124, 432, 375, 530, 116, 61, + /* 920 */ 66, 567, 516, 317, 530, 35, 530, 115, 68, 379, + /* 930 */ 378, 511, 540, 508, 223, 61, 66, 531, 530, 54, + /* 940 */ 523, 375, 381, 215, 68, 379, 378, 69, 354, 508, + /* 950 */ 4, 215, 295, 375, 299, 375, 367, 276, 199, 261, + /* 960 */ 517, 215, 364, 530, 48, 502, 502, 502, 500, 499, + /* 970 */ 12, 548, 375, 586, 380, 530, 28, 530, 31, 346, + /* 980 */ 585, 502, 502, 502, 500, 499, 12, 307, 123, 432, + /* 990 */ 442, 177, 522, 304, 530, 38, 231, 233, 234, 103, + /* 1000 */ 238, 555, 375, 281, 160, 375, 363, 375, 230, 61, + /* 1010 */ 66, 503, 166, 271, 236, 124, 196, 204, 68, 379, + /* 1020 */ 378, 232, 375, 508, 530, 23, 375, 530, 43, 530, + /* 1030 */ 33, 375, 468, 203, 489, 448, 261, 261, 522, 163, + /* 1040 */ 277, 375, 176, 375, 530, 53, 251, 375, 530, 29, + /* 1050 */ 375, 522, 375, 530, 37, 502, 502, 502, 500, 499, + /* 1060 */ 12, 214, 458, 530, 52, 530, 98, 375, 55, 530, + /* 1070 */ 96, 217, 530, 101, 530, 102, 375, 493, 498, 540, + /* 1080 */ 261, 375, 540, 375, 535, 374, 245, 255, 555, 530, + /* 1090 */ 112, 293, 375, 507, 375, 290, 215, 261, 530, 114, + /* 1100 */ 375, 261, 375, 530, 46, 530, 16, 162, 161, 261, + /* 1110 */ 375, 165, 375, 261, 530, 99, 530, 44, 537, 291, + /* 1120 */ 384, 501, 530, 50, 530, 47, 252, 274, 446, 564, + /* 1130 */ 253, 362, 530, 97, 530, 30, 360, 356, 504, 256, + /* 1140 */ 311, 119, 246, 351, 343, 522, 342, 262, 399, 265, + /* 1150 */ 376, 267, 237, 269, 225, 6, 534, 587, 148, 538, + /* 1160 */ 510, 325, 280, 285, 240, 417, 515, 444, 584, 541, + /* 1170 */ 452, 461, 347, 259, 315, 561, 487, 184, 465, 532, + /* 1180 */ 494, 200, 108, 454, 426, 436, 423, 422, 73, 421, + /* 1190 */ 7, 383, 297, 137, 71, 128, 62, 241, 333, 514, + /* 1200 */ 70, 336, 74, 120, 130, 372, 242, 371, 243, 509, + /* 1210 */ 244, 133, 513, 134, 135, 136, 483, 355, 190, 447, + /* 1220 */ 337, 193, 64, 56, 298, 473, 411, 111, 289, 197, + /* 1230 */ 198, 142, 568, 563, 558, 398, 339, 201, 92, 393, + /* 1240 */ 220, 202, 322, 127, 207, 543, 275, 209, 496, 554, + /* 1250 */ 536, 278, 288, 78, 414, 218, 17, 100, 212, 479, + /* 1260 */ 575, 121, 72, 332, 572, 527, 284, 556, 156, 302, + /* 1270 */ 140, 216, 104, 122, 132, 324, 105, 560, 273, 329, + /* 1280 */ 110, 109, 206, 512, 11, 67, 260, 13, 338, 5, + /* 1290 */ 396, 143, 126, 195, 402, 407, 412, 154, 419, 125, + /* 1300 */ 348, 416, 168, 257, 427, 144, 107, 192, 434, 286, + /* 1310 */ 451, 456, 138, 59, 60, 187, 58, 15, 467, 474, + /* 1320 */ 185, 183, 495, 129, 141, 180, 569, 182, 131, 178, + /* 1330 */ 624, 623, 14, 106, 408, 413, 181, 476, 386, 146, + /* 1340 */ 227, }; static const YYCODETYPE yy_lookahead[] = { - /* 0 */ 16, 139, 140, 141, 168, 21, 144, 23, 69, 70, - /* 10 */ 71, 72, 176, 74, 75, 76, 77, 78, 79, 80, - /* 20 */ 81, 82, 83, 84, 78, 79, 42, 43, 73, 74, + /* 0 */ 16, 217, 218, 219, 220, 21, 223, 23, 69, 70, + /* 10 */ 71, 72, 110, 74, 75, 76, 77, 78, 79, 80, + /* 20 */ 81, 82, 83, 84, 169, 16, 42, 43, 73, 74, /* 30 */ 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, - /* 40 */ 1, 2, 23, 58, 60, 61, 62, 63, 64, 65, - /* 50 */ 66, 67, 68, 69, 70, 71, 72, 147, 74, 75, + /* 40 */ 58, 99, 100, 101, 60, 61, 62, 63, 64, 65, + /* 50 */ 66, 67, 68, 69, 70, 71, 72, 84, 74, 75, /* 60 */ 76, 77, 78, 79, 80, 81, 82, 83, 84, 16, - /* 70 */ 185, 186, 88, 88, 110, 22, 217, 92, 219, 220, + /* 70 */ 88, 16, 88, 147, 92, 22, 42, 43, 185, 186, /* 80 */ 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, - /* 90 */ 84, 217, 218, 219, 220, 42, 43, 238, 188, 46, - /* 100 */ 78, 79, 80, 81, 82, 83, 84, 88, 89, 124, - /* 110 */ 125, 126, 16, 60, 61, 62, 63, 64, 65, 66, - /* 120 */ 67, 68, 69, 70, 71, 72, 147, 74, 75, 76, - /* 130 */ 77, 78, 79, 80, 81, 82, 83, 84, 42, 43, - /* 140 */ 44, 80, 81, 82, 83, 84, 23, 84, 169, 170, - /* 150 */ 19, 164, 165, 166, 23, 169, 60, 61, 62, 63, - /* 160 */ 64, 65, 66, 67, 68, 69, 70, 71, 72, 169, - /* 170 */ 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, - /* 180 */ 84, 16, 14, 147, 150, 147, 21, 167, 168, 58, - /* 190 */ 211, 147, 156, 157, 23, 216, 176, 23, 181, 176, - /* 200 */ 177, 78, 79, 165, 166, 110, 183, 42, 43, 78, - /* 210 */ 79, 88, 89, 169, 170, 228, 180, 181, 123, 88, - /* 220 */ 52, 98, 54, 92, 16, 60, 61, 62, 63, 64, - /* 230 */ 65, 66, 67, 68, 69, 70, 71, 72, 147, 74, + /* 90 */ 84, 165, 166, 84, 181, 42, 43, 63, 64, 46, + /* 100 */ 91, 92, 93, 94, 95, 96, 124, 125, 126, 164, + /* 110 */ 165, 166, 103, 60, 61, 62, 63, 64, 65, 66, + /* 120 */ 67, 68, 69, 70, 71, 72, 92, 74, 75, 76, + /* 130 */ 77, 78, 79, 80, 81, 82, 83, 84, 16, 84, + /* 140 */ 147, 30, 20, 18, 23, 90, 91, 92, 93, 94, + /* 150 */ 95, 96, 19, 227, 228, 147, 23, 217, 103, 219, + /* 160 */ 220, 50, 169, 170, 42, 43, 78, 79, 80, 81, + /* 170 */ 82, 83, 84, 228, 164, 165, 166, 169, 170, 181, + /* 180 */ 55, 16, 60, 61, 62, 63, 64, 65, 66, 67, + /* 190 */ 68, 69, 70, 71, 72, 169, 74, 75, 76, 77, + /* 200 */ 78, 79, 80, 81, 82, 83, 84, 42, 43, 88, + /* 210 */ 142, 143, 147, 102, 221, 11, 148, 209, 210, 94, + /* 220 */ 150, 88, 89, 155, 16, 60, 61, 62, 63, 64, + /* 230 */ 65, 66, 67, 68, 69, 70, 71, 72, 228, 74, /* 240 */ 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, - /* 250 */ 42, 43, 78, 209, 210, 124, 125, 126, 224, 88, - /* 260 */ 169, 170, 88, 89, 230, 227, 228, 16, 60, 61, + /* 250 */ 42, 43, 23, 49, 92, 14, 158, 189, 133, 161, + /* 260 */ 162, 163, 19, 19, 155, 103, 23, 23, 60, 61, /* 270 */ 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, - /* 280 */ 72, 23, 74, 75, 76, 77, 78, 79, 80, 81, - /* 290 */ 82, 83, 84, 42, 43, 160, 16, 147, 161, 83, - /* 300 */ 84, 210, 161, 153, 169, 158, 156, 157, 161, 162, - /* 310 */ 163, 60, 61, 62, 63, 64, 65, 66, 67, 68, - /* 320 */ 69, 70, 71, 72, 161, 74, 75, 76, 77, 78, - /* 330 */ 79, 80, 81, 82, 83, 84, 192, 200, 147, 131, - /* 340 */ 16, 200, 16, 199, 20, 190, 88, 89, 90, 185, - /* 350 */ 186, 93, 94, 95, 217, 22, 219, 220, 147, 147, - /* 360 */ 169, 170, 104, 200, 84, 147, 42, 43, 156, 157, - /* 370 */ 90, 91, 92, 93, 94, 95, 96, 164, 165, 166, - /* 380 */ 169, 170, 131, 103, 60, 61, 62, 63, 64, 65, - /* 390 */ 66, 67, 68, 69, 70, 71, 72, 155, 74, 75, - /* 400 */ 76, 77, 78, 79, 80, 81, 82, 83, 84, 16, - /* 410 */ 84, 11, 221, 20, 30, 16, 147, 91, 92, 93, - /* 420 */ 94, 95, 96, 90, 147, 181, 93, 94, 95, 103, - /* 430 */ 212, 189, 155, 27, 50, 42, 43, 104, 169, 170, - /* 440 */ 34, 228, 43, 201, 202, 147, 169, 170, 206, 49, - /* 450 */ 161, 162, 163, 60, 61, 62, 63, 64, 65, 66, - /* 460 */ 67, 68, 69, 70, 71, 72, 189, 74, 75, 76, - /* 470 */ 77, 78, 79, 80, 81, 82, 83, 84, 16, 25, - /* 480 */ 211, 147, 20, 29, 12, 147, 102, 19, 211, 21, - /* 490 */ 147, 141, 147, 216, 144, 41, 24, 98, 20, 99, - /* 500 */ 100, 101, 103, 165, 42, 43, 0, 1, 2, 37, - /* 510 */ 110, 39, 169, 170, 169, 170, 182, 19, 20, 147, - /* 520 */ 22, 49, 60, 61, 62, 63, 64, 65, 66, 67, - /* 530 */ 68, 69, 70, 71, 72, 155, 74, 75, 76, 77, - /* 540 */ 78, 79, 80, 81, 82, 83, 84, 16, 147, 90, - /* 550 */ 20, 20, 93, 94, 95, 147, 155, 59, 215, 225, - /* 560 */ 215, 20, 130, 104, 132, 227, 228, 42, 43, 189, - /* 570 */ 169, 170, 16, 42, 43, 20, 19, 22, 19, 20, - /* 580 */ 23, 22, 18, 147, 106, 147, 108, 109, 63, 64, - /* 590 */ 189, 60, 61, 62, 63, 64, 65, 66, 67, 68, - /* 600 */ 69, 70, 71, 72, 186, 74, 75, 76, 77, 78, - /* 610 */ 79, 80, 81, 82, 83, 84, 16, 92, 59, 55, - /* 620 */ 212, 21, 147, 19, 147, 23, 188, 23, 12, 217, - /* 630 */ 23, 219, 220, 7, 8, 9, 106, 147, 108, 109, - /* 640 */ 24, 147, 42, 43, 208, 88, 89, 106, 92, 108, - /* 650 */ 109, 244, 245, 37, 145, 39, 191, 182, 94, 16, + /* 280 */ 72, 213, 74, 75, 76, 77, 78, 79, 80, 81, + /* 290 */ 82, 83, 84, 52, 224, 54, 131, 16, 189, 43, + /* 300 */ 230, 58, 21, 99, 100, 101, 23, 78, 79, 241, + /* 310 */ 201, 202, 22, 20, 110, 206, 186, 88, 89, 20, + /* 320 */ 147, 78, 79, 42, 43, 23, 153, 98, 147, 156, + /* 330 */ 157, 88, 88, 89, 147, 92, 99, 100, 101, 131, + /* 340 */ 190, 60, 61, 62, 63, 64, 65, 66, 67, 68, + /* 350 */ 69, 70, 71, 72, 98, 74, 75, 76, 77, 78, + /* 360 */ 79, 80, 81, 82, 83, 84, 16, 124, 125, 126, + /* 370 */ 20, 88, 89, 90, 133, 147, 93, 94, 95, 160, + /* 380 */ 90, 147, 80, 93, 94, 95, 147, 104, 169, 155, + /* 390 */ 88, 89, 42, 43, 104, 156, 157, 169, 170, 106, + /* 400 */ 19, 108, 109, 169, 170, 106, 22, 108, 109, 16, + /* 410 */ 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, + /* 420 */ 70, 71, 72, 189, 74, 75, 76, 77, 78, 79, + /* 430 */ 80, 81, 82, 83, 84, 42, 43, 44, 90, 211, + /* 440 */ 161, 93, 94, 95, 216, 211, 139, 140, 141, 68, + /* 450 */ 216, 144, 104, 60, 61, 62, 63, 64, 65, 66, + /* 460 */ 67, 68, 69, 70, 71, 72, 19, 74, 75, 76, + /* 470 */ 77, 78, 79, 80, 81, 82, 83, 84, 16, 200, + /* 480 */ 147, 97, 12, 21, 80, 81, 82, 83, 84, 147, + /* 490 */ 130, 147, 132, 147, 24, 20, 217, 22, 219, 220, + /* 500 */ 147, 155, 169, 170, 42, 43, 20, 37, 22, 39, + /* 510 */ 23, 169, 170, 169, 170, 169, 170, 23, 165, 49, + /* 520 */ 14, 147, 60, 61, 62, 63, 64, 65, 66, 67, + /* 530 */ 68, 69, 70, 71, 72, 189, 74, 75, 76, 77, + /* 540 */ 78, 79, 80, 81, 82, 83, 84, 16, 215, 147, + /* 550 */ 141, 20, 147, 144, 210, 147, 23, 215, 52, 112, + /* 560 */ 54, 156, 157, 25, 23, 78, 217, 29, 219, 220, + /* 570 */ 155, 169, 170, 42, 43, 88, 89, 169, 170, 41, + /* 580 */ 227, 228, 88, 89, 147, 180, 181, 238, 161, 162, + /* 590 */ 163, 60, 61, 62, 63, 64, 65, 66, 67, 68, + /* 600 */ 69, 70, 71, 72, 189, 74, 75, 76, 77, 78, + /* 610 */ 79, 80, 81, 82, 83, 84, 16, 168, 147, 211, + /* 620 */ 20, 88, 89, 12, 106, 176, 108, 109, 213, 88, + /* 630 */ 89, 176, 177, 19, 20, 24, 22, 20, 183, 22, + /* 640 */ 169, 170, 42, 43, 20, 83, 84, 114, 37, 147, + /* 650 */ 39, 236, 20, 19, 20, 114, 22, 147, 147, 16, /* 660 */ 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, - /* 670 */ 70, 71, 72, 147, 74, 75, 76, 77, 78, 79, - /* 680 */ 80, 81, 82, 83, 84, 42, 43, 80, 142, 143, - /* 690 */ 88, 89, 88, 89, 148, 88, 89, 133, 14, 147, - /* 700 */ 225, 155, 16, 60, 61, 62, 63, 64, 65, 66, - /* 710 */ 67, 68, 69, 70, 71, 72, 114, 74, 75, 76, + /* 670 */ 70, 71, 72, 59, 74, 75, 76, 77, 78, 79, + /* 680 */ 80, 81, 82, 83, 84, 42, 43, 167, 168, 22, + /* 690 */ 188, 59, 182, 59, 91, 92, 176, 16, 203, 147, + /* 700 */ 7, 8, 16, 60, 61, 62, 63, 64, 65, 66, + /* 710 */ 67, 68, 69, 70, 71, 72, 147, 74, 75, 76, /* 720 */ 77, 78, 79, 80, 81, 82, 83, 84, 42, 43, - /* 730 */ 201, 202, 147, 147, 182, 189, 52, 147, 54, 147, - /* 740 */ 147, 147, 147, 147, 155, 16, 60, 61, 62, 63, - /* 750 */ 64, 65, 66, 67, 68, 69, 70, 71, 72, 213, + /* 730 */ 106, 147, 108, 109, 182, 225, 78, 79, 169, 170, + /* 740 */ 147, 239, 147, 147, 147, 16, 60, 61, 62, 63, + /* 750 */ 64, 65, 66, 67, 68, 69, 70, 71, 72, 147, /* 760 */ 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, - /* 770 */ 84, 42, 43, 188, 188, 182, 182, 225, 189, 106, - /* 780 */ 188, 108, 109, 188, 99, 100, 101, 241, 16, 155, + /* 770 */ 84, 42, 43, 92, 147, 182, 22, 225, 182, 182, + /* 780 */ 113, 169, 170, 0, 1, 2, 124, 125, 16, 80, /* 790 */ 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, - /* 800 */ 71, 72, 213, 74, 75, 76, 77, 78, 79, 80, - /* 810 */ 81, 82, 83, 84, 42, 43, 23, 133, 225, 225, - /* 820 */ 21, 225, 23, 189, 239, 236, 99, 100, 101, 22, - /* 830 */ 242, 243, 155, 22, 62, 63, 64, 65, 66, 67, - /* 840 */ 68, 69, 70, 71, 72, 147, 74, 75, 76, 77, - /* 850 */ 78, 79, 80, 81, 82, 83, 84, 16, 17, 43, - /* 860 */ 19, 147, 147, 147, 23, 147, 189, 169, 170, 147, - /* 870 */ 147, 147, 31, 16, 17, 147, 19, 147, 124, 125, - /* 880 */ 23, 88, 89, 169, 170, 169, 170, 88, 31, 48, - /* 890 */ 147, 169, 170, 169, 170, 147, 89, 169, 170, 58, - /* 900 */ 147, 22, 147, 188, 147, 48, 188, 114, 97, 147, - /* 910 */ 147, 188, 147, 19, 98, 58, 147, 169, 170, 78, - /* 920 */ 79, 114, 169, 170, 169, 170, 169, 170, 87, 88, - /* 930 */ 89, 169, 170, 92, 161, 78, 79, 80, 169, 170, - /* 940 */ 91, 147, 155, 22, 87, 88, 89, 16, 17, 92, - /* 950 */ 19, 110, 147, 155, 23, 147, 7, 8, 20, 110, - /* 960 */ 22, 80, 31, 169, 170, 124, 125, 126, 127, 128, - /* 970 */ 129, 208, 123, 208, 169, 170, 189, 169, 170, 48, - /* 980 */ 147, 124, 125, 126, 127, 128, 129, 189, 107, 58, - /* 990 */ 107, 5, 111, 147, 111, 203, 10, 11, 12, 13, - /* 1000 */ 121, 147, 147, 91, 92, 147, 112, 147, 147, 78, - /* 1010 */ 79, 147, 26, 19, 28, 169, 170, 23, 87, 88, - /* 1020 */ 89, 35, 147, 92, 169, 170, 178, 169, 170, 147, - /* 1030 */ 169, 170, 147, 47, 113, 49, 92, 178, 147, 53, - /* 1040 */ 147, 178, 56, 147, 169, 170, 147, 103, 147, 19, - /* 1050 */ 147, 169, 170, 147, 147, 124, 125, 126, 127, 128, - /* 1060 */ 129, 147, 169, 170, 147, 169, 170, 147, 169, 170, - /* 1070 */ 169, 170, 169, 170, 147, 169, 170, 147, 20, 147, - /* 1080 */ 22, 147, 88, 147, 232, 99, 100, 101, 147, 169, - /* 1090 */ 170, 105, 147, 20, 147, 22, 110, 20, 68, 169, - /* 1100 */ 170, 169, 170, 169, 170, 169, 170, 20, 147, 22, - /* 1110 */ 147, 20, 147, 22, 169, 170, 169, 170, 147, 233, - /* 1120 */ 134, 20, 147, 22, 20, 147, 22, 20, 20, 22, - /* 1130 */ 22, 147, 169, 170, 169, 170, 59, 147, 147, 147, - /* 1140 */ 169, 170, 147, 147, 169, 170, 147, 169, 170, 147, - /* 1150 */ 147, 147, 147, 191, 229, 149, 223, 193, 229, 172, - /* 1160 */ 172, 172, 177, 194, 194, 172, 6, 146, 146, 172, - /* 1170 */ 146, 173, 146, 22, 154, 121, 194, 118, 195, 119, - /* 1180 */ 116, 120, 23, 160, 112, 130, 152, 152, 222, 189, - /* 1190 */ 98, 115, 98, 40, 179, 97, 171, 196, 171, 171, - /* 1200 */ 19, 84, 173, 171, 197, 174, 198, 226, 160, 160, - /* 1210 */ 171, 171, 179, 204, 171, 205, 204, 15, 205, 174, - /* 1220 */ 151, 38, 152, 152, 60, 151, 151, 130, 184, 19, - /* 1230 */ 152, 152, 151, 214, 152, 184, 194, 226, 152, 15, - /* 1240 */ 187, 194, 152, 187, 187, 33, 137, 184, 234, 187, - /* 1250 */ 214, 235, 152, 1, 237, 237, 20, 152, 159, 175, - /* 1260 */ 175, 112, 112, 92, 112, 107, 112, 19, 19, 231, - /* 1270 */ 20, 20, 11, 19, 117, 20, 114, 240, 22, 20, - /* 1280 */ 20, 19, 117, 44, 243, 22, 22, 20, 112, 20, - /* 1290 */ 20, 19, 246, 19, 96, 20, 19, 32, 19, 19, - /* 1300 */ 103, 44, 44, 16, 21, 17, 98, 36, 22, 98, - /* 1310 */ 133, 19, 5, 45, 1, 102, 122, 51, 45, 19, - /* 1320 */ 113, 68, 14, 17, 115, 102, 122, 113, 19, 123, - /* 1330 */ 20, 14, 136, 19, 135, 57, 3, 247, 4, 247, - /* 1340 */ 247, 247, 247, 247, 68, -}; -#define YY_SHIFT_USE_DFLT (-62) -#define YY_SHIFT_MAX 387 + /* 800 */ 71, 72, 147, 74, 75, 76, 77, 78, 79, 80, + /* 810 */ 81, 82, 83, 84, 42, 43, 107, 20, 225, 22, + /* 820 */ 111, 225, 225, 147, 169, 170, 7, 8, 9, 22, + /* 830 */ 19, 21, 21, 23, 62, 63, 64, 65, 66, 67, + /* 840 */ 68, 69, 70, 71, 72, 155, 74, 75, 76, 77, + /* 850 */ 78, 79, 80, 81, 82, 83, 84, 16, 17, 147, + /* 860 */ 19, 147, 19, 147, 23, 20, 23, 22, 147, 147, + /* 870 */ 16, 147, 31, 16, 17, 121, 19, 178, 147, 189, + /* 880 */ 23, 169, 170, 169, 170, 169, 170, 147, 31, 48, + /* 890 */ 169, 170, 145, 169, 170, 147, 89, 43, 88, 58, + /* 900 */ 169, 170, 147, 107, 147, 48, 20, 111, 22, 169, + /* 910 */ 170, 20, 20, 22, 22, 58, 147, 169, 170, 78, + /* 920 */ 79, 114, 1, 2, 169, 170, 169, 170, 87, 88, + /* 930 */ 89, 88, 147, 92, 212, 78, 79, 80, 169, 170, + /* 940 */ 178, 147, 91, 110, 87, 88, 89, 16, 17, 92, + /* 950 */ 19, 110, 98, 147, 23, 147, 123, 103, 155, 147, + /* 960 */ 178, 110, 31, 169, 170, 124, 125, 126, 127, 128, + /* 970 */ 129, 147, 147, 27, 123, 169, 170, 169, 170, 48, + /* 980 */ 34, 124, 125, 126, 127, 128, 129, 242, 243, 58, + /* 990 */ 161, 5, 189, 208, 169, 170, 10, 11, 12, 13, + /* 1000 */ 188, 161, 147, 147, 155, 147, 147, 147, 147, 78, + /* 1010 */ 79, 147, 26, 20, 28, 22, 232, 155, 87, 88, + /* 1020 */ 89, 35, 147, 92, 169, 170, 147, 169, 170, 169, + /* 1030 */ 170, 147, 147, 47, 147, 49, 147, 147, 189, 53, + /* 1040 */ 200, 147, 56, 147, 169, 170, 147, 147, 169, 170, + /* 1050 */ 147, 189, 147, 169, 170, 124, 125, 126, 127, 128, + /* 1060 */ 129, 192, 147, 169, 170, 169, 170, 147, 199, 169, + /* 1070 */ 170, 212, 169, 170, 169, 170, 147, 188, 188, 147, + /* 1080 */ 147, 147, 147, 147, 147, 99, 100, 101, 161, 169, + /* 1090 */ 170, 105, 147, 20, 147, 22, 110, 147, 169, 170, + /* 1100 */ 147, 147, 147, 169, 170, 169, 170, 201, 202, 147, + /* 1110 */ 147, 155, 147, 147, 169, 170, 169, 170, 244, 245, + /* 1120 */ 134, 188, 169, 170, 169, 170, 147, 200, 185, 186, + /* 1130 */ 147, 147, 169, 170, 169, 170, 147, 147, 188, 147, + /* 1140 */ 208, 147, 188, 208, 147, 189, 233, 147, 147, 147, + /* 1150 */ 188, 147, 147, 147, 188, 191, 161, 172, 191, 172, + /* 1160 */ 161, 173, 225, 172, 193, 149, 194, 229, 172, 161, + /* 1170 */ 229, 194, 38, 234, 98, 177, 137, 6, 146, 172, + /* 1180 */ 171, 112, 240, 152, 146, 152, 33, 146, 237, 146, + /* 1190 */ 22, 154, 152, 19, 237, 214, 121, 194, 118, 189, + /* 1200 */ 119, 116, 120, 60, 184, 15, 195, 152, 196, 194, + /* 1210 */ 197, 187, 198, 187, 187, 187, 194, 152, 184, 184, + /* 1220 */ 15, 151, 130, 130, 40, 179, 152, 19, 174, 152, + /* 1230 */ 151, 214, 171, 171, 171, 152, 152, 151, 98, 152, + /* 1240 */ 222, 151, 115, 152, 84, 179, 204, 226, 97, 205, + /* 1250 */ 205, 204, 174, 19, 235, 226, 231, 159, 44, 171, + /* 1260 */ 171, 32, 19, 3, 20, 20, 171, 173, 112, 246, + /* 1270 */ 20, 175, 175, 243, 19, 44, 19, 114, 20, 44, + /* 1280 */ 19, 19, 96, 4, 117, 22, 103, 22, 16, 117, + /* 1290 */ 17, 21, 98, 22, 20, 20, 20, 19, 51, 45, + /* 1300 */ 36, 11, 22, 133, 45, 19, 19, 98, 20, 5, + /* 1310 */ 1, 20, 102, 19, 68, 122, 68, 19, 107, 92, + /* 1320 */ 113, 14, 17, 102, 122, 112, 123, 115, 113, 112, + /* 1330 */ 112, 112, 19, 14, 20, 20, 135, 1, 57, 19, + /* 1340 */ 136, +}; +#define YY_SHIFT_USE_DFLT (-99) +#define YY_SHIFT_MAX 389 static const short yy_shift_ofst[] = { - /* 0 */ 39, 841, 986, -16, 841, 931, 931, 258, 123, -36, - /* 10 */ 96, 931, 931, 931, 931, 931, -45, 400, 174, 19, - /* 20 */ 171, -54, -54, 53, 165, 208, 251, 324, 393, 462, - /* 30 */ 531, 600, 643, 686, 643, 643, 643, 643, 643, 643, - /* 40 */ 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, + /* 0 */ 921, 841, 986, -16, 841, 931, 931, 283, 229, -98, + /* 10 */ 393, 931, 931, 931, 931, 931, -45, 204, 487, 494, + /* 20 */ 121, 658, 658, 53, 122, 165, 281, 208, 462, 600, + /* 30 */ 531, 350, 643, 643, 643, 643, 643, 643, 643, 643, + /* 40 */ 643, 643, 643, 643, 643, 643, 643, 686, 643, 643, /* 50 */ 643, 643, 729, 772, 772, 857, 931, 931, 931, 931, /* 60 */ 931, 931, 931, 931, 931, 931, 931, 931, 931, 931, /* 70 */ 931, 931, 931, 931, 931, 931, 931, 931, 931, 931, /* 80 */ 931, 931, 931, 931, 931, 931, 931, 931, 931, 931, - /* 90 */ 931, 931, 931, 931, 931, -61, -61, 6, 6, 280, - /* 100 */ 22, 61, 399, 564, 19, 19, 19, 19, 19, 19, - /* 110 */ 19, 216, 171, 63, -62, -62, 131, 326, 472, 472, - /* 120 */ 498, 559, 506, 799, 19, 799, 19, 19, 19, 19, - /* 130 */ 19, 19, 19, 19, 19, 19, 19, 19, 19, 849, - /* 140 */ 95, -36, -36, -36, -62, -62, -62, -15, -15, 333, - /* 150 */ 459, 478, 557, 530, 541, 616, 602, 793, 604, 607, - /* 160 */ 626, 19, 19, 881, 19, 19, 994, 19, 19, 807, - /* 170 */ 19, 19, 673, 807, 19, 19, 384, 384, 384, 19, - /* 180 */ 19, 673, 19, 19, 673, 19, 454, 685, 19, 19, - /* 190 */ 673, 19, 19, 19, 673, 19, 19, 19, 673, 673, - /* 200 */ 19, 19, 19, 19, 19, 468, 883, 921, 754, 754, - /* 210 */ 432, 406, 406, 406, 816, 406, 406, 811, 879, 879, - /* 220 */ 1160, 1160, 1160, 1160, 1151, -36, 1054, 1059, 1060, 1064, - /* 230 */ 1061, 1159, 1055, 1072, 1072, 1092, 1076, 1092, 1076, 1094, - /* 240 */ 1094, 1153, 1094, 1098, 1094, 1181, 1117, 1159, 1117, 1159, - /* 250 */ 1153, 1094, 1094, 1094, 1181, 1202, 1072, 1202, 1072, 1202, - /* 260 */ 1072, 1072, 1183, 1097, 1202, 1072, 1164, 1164, 1210, 1054, - /* 270 */ 1072, 1224, 1224, 1224, 1224, 1054, 1164, 1210, 1072, 1212, - /* 280 */ 1212, 1072, 1072, 1109, -62, -62, -62, -62, -62, -62, - /* 290 */ 525, 684, 727, 168, 894, 556, 555, 938, 944, 949, - /* 300 */ 912, 1058, 1073, 1087, 1091, 1101, 1104, 1107, 1030, 1108, - /* 310 */ 1077, 1252, 1236, 1149, 1150, 1152, 1154, 1171, 1158, 1248, - /* 320 */ 1250, 1251, 1249, 1261, 1254, 1255, 1256, 1259, 1260, 1263, - /* 330 */ 1157, 1264, 1165, 1263, 1162, 1262, 1267, 1176, 1269, 1270, - /* 340 */ 1265, 1239, 1272, 1257, 1274, 1275, 1277, 1279, 1258, 1280, - /* 350 */ 1198, 1197, 1287, 1288, 1283, 1208, 1271, 1266, 1268, 1286, - /* 360 */ 1273, 1177, 1211, 1292, 1307, 1313, 1213, 1253, 1276, 1194, - /* 370 */ 1300, 1207, 1308, 1209, 1306, 1214, 1223, 1204, 1309, 1206, - /* 380 */ 1310, 1317, 1278, 1199, 1196, 1314, 1333, 1334, -}; -#define YY_REDUCE_USE_DFLT (-165) -#define YY_REDUCE_MAX 289 + /* 90 */ 931, 931, 931, 931, 931, 931, -61, -61, 6, 6, + /* 100 */ 55, 88, 404, 125, 854, 494, 494, 494, 494, 494, + /* 110 */ 494, 494, 562, 121, -27, -99, -99, -99, 243, 9, + /* 120 */ 470, 470, 614, 634, 494, 494, 494, 810, 851, 494, + /* 130 */ 494, 494, 494, 494, 494, 494, 494, 494, 494, 783, + /* 140 */ 810, 494, 833, -98, -98, -98, -99, -99, -99, -18, + /* 150 */ 290, -18, 348, 541, 611, 533, 302, 624, 244, 299, + /* 160 */ 293, 133, 807, 494, 494, 518, 494, 494, 494, 518, + /* 170 */ 807, 111, 111, 111, 494, 494, 494, 819, 494, 518, + /* 180 */ 494, 494, 494, 494, 494, 494, 518, 494, 843, 494, + /* 190 */ 494, 518, 494, 494, 494, 494, -58, 538, 494, 518, + /* 200 */ 494, 494, 494, 494, 518, 709, 494, 121, 946, 946, + /* 210 */ 121, 384, 946, 946, 667, 796, 256, 754, 946, 121, + /* 220 */ 360, 662, 662, 754, 811, 1134, 1076, 1039, 1171, 1069, + /* 230 */ 1069, 1171, 1153, 1171, 1171, 1168, 1153, 1069, 1174, -98, + /* 240 */ 1075, 1080, 1081, 1085, 1082, 1143, 1075, 1190, 1190, 1190, + /* 250 */ 1190, 1069, 1075, 1174, 1143, 1143, 1069, 1205, 1092, 1093, + /* 260 */ 1184, 1069, 1069, 1205, 1069, 1069, 1205, 1069, 1205, 1208, + /* 270 */ 1076, 1076, 1069, 1076, 1140, 1127, 1184, 1140, 1127, 1160, + /* 280 */ 1160, 1208, 1076, 1076, 1151, 1076, -99, -99, -99, -99, + /* 290 */ -99, -99, 34, 241, 506, 237, 603, 381, 693, 447, + /* 300 */ 617, 681, 632, 797, 845, 886, 891, 1073, 993, 892, + /* 310 */ 162, 475, 486, 1234, 1214, 1229, 1243, 1260, 1244, 1245, + /* 320 */ 1156, 1250, 1255, 1231, 1257, 1258, 1261, 1163, 1235, 1262, + /* 330 */ 1186, 1263, 1279, 1167, 1183, 1265, 1172, 1272, 1273, 1270, + /* 340 */ 1263, 1274, 1194, 1275, 1271, 1276, 1278, 1264, 1247, 1254, + /* 350 */ 1290, 1280, 1259, 1170, 1286, 1209, 1287, 1288, 1304, 1309, + /* 360 */ 1210, 1291, 1246, 1248, 1294, 1193, 1211, 1298, 1227, 1207, + /* 370 */ 1307, 1212, 1305, 1213, 1215, 1217, 1221, 1202, 1218, 1219, + /* 380 */ 1313, 1203, 1314, 1315, 1319, 1281, 1201, 1204, 1336, 1320, +}; +#define YY_REDUCE_USE_DFLT (-218) +#define YY_REDUCE_MAX 291 static const short yy_reduce_ofst[] = { - /* 0 */ -138, 277, 546, 137, 401, -21, 44, 36, 38, 242, - /* 10 */ -141, 191, 91, 269, 343, 345, -126, 589, 338, 150, - /* 20 */ 147, -13, 213, 412, 412, 412, 412, 412, 412, 412, - /* 30 */ 412, 412, 412, 412, 412, 412, 412, 412, 412, 412, - /* 40 */ 412, 412, 412, 412, 412, 412, 412, 412, 412, 412, - /* 50 */ 412, 412, 412, 412, 412, 211, 698, 714, 716, 722, - /* 60 */ 724, 728, 748, 753, 755, 757, 762, 769, 794, 805, - /* 70 */ 808, 846, 855, 858, 861, 875, 882, 893, 896, 899, - /* 80 */ 901, 903, 906, 920, 930, 932, 934, 936, 945, 947, - /* 90 */ 963, 965, 971, 975, 978, 412, 412, 412, 412, 20, - /* 100 */ 412, 412, 23, 34, 334, 475, 552, 593, 594, 585, - /* 110 */ 212, 412, 289, 412, 412, 412, 135, -164, -115, 164, - /* 120 */ 407, 407, 350, 141, 436, 163, 596, -90, 763, 218, - /* 130 */ 765, 438, 586, 592, 595, 715, 718, 408, 723, 380, - /* 140 */ 634, 677, 787, 798, 144, 529, 588, -14, 0, 17, - /* 150 */ 244, 155, 298, 155, 155, 418, 372, 477, 490, 494, - /* 160 */ 509, 526, 590, 465, 494, 730, 773, 743, 833, 792, - /* 170 */ 854, 860, 155, 792, 864, 885, 848, 859, 863, 891, - /* 180 */ 907, 155, 914, 917, 155, 927, 852, 886, 941, 961, - /* 190 */ 155, 984, 990, 991, 155, 992, 995, 996, 155, 155, - /* 200 */ 999, 1002, 1003, 1004, 1005, 1006, 962, 964, 925, 929, - /* 210 */ 933, 987, 988, 989, 985, 993, 997, 998, 969, 970, - /* 220 */ 1021, 1022, 1024, 1026, 1020, 1000, 982, 983, 1001, 1007, - /* 230 */ 1008, 1023, 966, 1034, 1035, 1009, 1010, 1012, 1013, 1025, - /* 240 */ 1027, 1015, 1028, 1029, 1032, 1031, 981, 1048, 1011, 1049, - /* 250 */ 1033, 1039, 1040, 1043, 1045, 1069, 1070, 1074, 1071, 1075, - /* 260 */ 1078, 1079, 1014, 1016, 1081, 1082, 1044, 1051, 1019, 1042, - /* 270 */ 1086, 1053, 1056, 1057, 1062, 1047, 1063, 1036, 1090, 1017, - /* 280 */ 1018, 1100, 1105, 1037, 1099, 1084, 1085, 1038, 1041, 1046, + /* 0 */ 307, 234, 68, 279, 346, 8, 228, 405, -74, 109, + /* 10 */ 349, 408, -7, 344, 333, 342, -216, 415, 353, 173, + /* 20 */ 98, 10, -55, -60, -60, -60, -60, -60, -60, -60, + /* 30 */ -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, + /* 40 */ -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, + /* 50 */ -60, -60, -60, -60, -60, 471, 569, 612, 655, 712, + /* 60 */ 714, 716, 721, 724, 731, 740, 748, 755, 757, 769, + /* 70 */ 794, 806, 808, 825, 855, 858, 860, 875, 879, 402, + /* 80 */ 884, 894, 896, 900, 903, 905, 920, 929, 934, 936, + /* 90 */ 945, 947, 953, 955, 963, 965, -60, -60, -60, -60, + /* 100 */ 520, -60, -60, 70, 455, 510, 502, 552, 239, 593, + /* 110 */ 596, 597, -60, 427, -60, -60, -60, -60, 219, 449, + /* 120 */ 943, -107, 874, 874, 937, 935, 966, 927, 956, 859, + /* 130 */ 962, 954, 932, 950, 933, 890, 889, 785, 722, 409, + /* 140 */ 840, 812, 690, 803, 849, 862, 745, 906, 869, -145, + /* 150 */ -87, 26, -2, 65, 130, 181, 187, 150, 374, 150, + /* 160 */ 150, 437, 495, 511, 584, 150, 595, 627, 676, 150, + /* 170 */ 495, 699, 762, 782, 824, 856, 861, 747, 187, 150, + /* 180 */ 864, 885, 887, 899, 915, 979, 150, 983, 829, 984, + /* 190 */ 989, 150, 990, 992, 994, 997, 913, 784, 1000, 150, + /* 200 */ 1001, 1002, 1004, 1005, 150, 964, 1006, 995, 985, 987, + /* 210 */ 999, 988, 991, 996, 971, 967, 998, 972, 1007, 1008, + /* 220 */ -217, 938, 941, 977, 1016, 939, 1009, 942, 1032, 1031, + /* 230 */ 1033, 1038, 951, 1041, 1043, 1037, 957, 1040, 981, 1010, + /* 240 */ 1003, 1011, 1012, 1013, 1014, 1020, 1015, 1024, 1026, 1027, + /* 250 */ 1028, 1055, 1022, 1017, 1034, 1035, 1065, 1070, 1018, 1019, + /* 260 */ 1046, 1074, 1077, 1079, 1083, 1084, 1086, 1087, 1090, 1054, + /* 270 */ 1061, 1062, 1091, 1063, 1042, 1044, 1066, 1047, 1045, 1021, + /* 280 */ 1029, 1078, 1088, 1089, 1094, 1095, 1025, 1098, 1096, 1097, + /* 290 */ 1030, 1023, }; static const YYACTIONTYPE yy_default[] = { - /* 0 */ 592, 816, 897, 707, 897, 816, 897, 897, 843, 711, - /* 10 */ 872, 814, 897, 897, 897, 897, 789, 897, 843, 897, - /* 20 */ 623, 843, 843, 740, 897, 897, 897, 897, 897, 897, - /* 30 */ 897, 897, 741, 897, 818, 813, 809, 811, 810, 817, - /* 40 */ 742, 731, 738, 745, 723, 856, 747, 748, 754, 755, - /* 50 */ 873, 871, 777, 776, 795, 897, 897, 897, 897, 897, - /* 60 */ 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, - /* 70 */ 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, - /* 80 */ 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, - /* 90 */ 897, 897, 897, 897, 897, 779, 800, 778, 788, 616, - /* 100 */ 780, 781, 676, 611, 897, 897, 897, 897, 897, 897, - /* 110 */ 897, 782, 897, 783, 796, 797, 897, 897, 897, 897, - /* 120 */ 897, 897, 592, 707, 897, 707, 897, 897, 897, 897, - /* 130 */ 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, - /* 140 */ 897, 897, 897, 897, 701, 711, 890, 897, 897, 667, - /* 150 */ 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, - /* 160 */ 599, 597, 897, 699, 897, 897, 625, 897, 897, 709, - /* 170 */ 897, 897, 714, 715, 897, 897, 897, 897, 897, 897, - /* 180 */ 897, 613, 897, 897, 688, 897, 849, 897, 897, 897, - /* 190 */ 863, 897, 897, 897, 861, 897, 897, 897, 690, 750, - /* 200 */ 830, 897, 876, 878, 897, 897, 699, 708, 897, 897, - /* 210 */ 812, 734, 734, 734, 646, 734, 734, 649, 744, 744, - /* 220 */ 596, 596, 596, 596, 666, 897, 744, 735, 737, 727, - /* 230 */ 739, 897, 897, 716, 716, 724, 726, 724, 726, 678, - /* 240 */ 678, 663, 678, 649, 678, 822, 827, 897, 827, 897, - /* 250 */ 663, 678, 678, 678, 822, 608, 716, 608, 716, 608, - /* 260 */ 716, 716, 853, 855, 608, 716, 680, 680, 756, 744, - /* 270 */ 716, 687, 687, 687, 687, 744, 680, 756, 716, 875, - /* 280 */ 875, 716, 716, 883, 633, 651, 651, 858, 890, 895, - /* 290 */ 897, 897, 897, 897, 763, 897, 897, 897, 897, 897, - /* 300 */ 897, 897, 897, 897, 897, 897, 897, 897, 836, 897, - /* 310 */ 897, 897, 897, 768, 764, 897, 765, 897, 693, 897, - /* 320 */ 897, 897, 897, 897, 897, 897, 897, 897, 897, 815, - /* 330 */ 897, 728, 897, 736, 897, 897, 897, 897, 897, 897, - /* 340 */ 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, - /* 350 */ 897, 897, 897, 897, 897, 897, 897, 897, 851, 852, - /* 360 */ 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, - /* 370 */ 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, - /* 380 */ 897, 897, 882, 897, 897, 885, 593, 897, 587, 590, - /* 390 */ 589, 591, 595, 598, 620, 621, 622, 600, 601, 602, - /* 400 */ 603, 604, 605, 606, 612, 614, 632, 634, 618, 636, - /* 410 */ 697, 698, 760, 691, 692, 696, 771, 762, 766, 767, - /* 420 */ 769, 770, 784, 785, 787, 793, 799, 802, 786, 791, - /* 430 */ 792, 794, 798, 801, 694, 695, 805, 619, 626, 627, - /* 440 */ 630, 631, 839, 841, 840, 842, 629, 628, 772, 775, - /* 450 */ 807, 808, 864, 865, 866, 867, 868, 803, 717, 806, - /* 460 */ 790, 729, 732, 733, 730, 700, 710, 719, 720, 721, - /* 470 */ 722, 705, 706, 712, 725, 758, 759, 713, 702, 703, - /* 480 */ 704, 804, 761, 773, 774, 637, 638, 768, 639, 640, - /* 490 */ 641, 679, 682, 683, 684, 642, 661, 664, 665, 643, - /* 500 */ 650, 644, 645, 652, 653, 654, 657, 658, 659, 660, - /* 510 */ 655, 656, 823, 824, 828, 826, 825, 647, 648, 662, - /* 520 */ 635, 624, 617, 668, 671, 672, 673, 674, 675, 677, - /* 530 */ 669, 670, 615, 607, 609, 718, 845, 854, 850, 846, - /* 540 */ 847, 848, 610, 819, 820, 681, 752, 753, 844, 857, - /* 550 */ 859, 757, 860, 862, 887, 685, 686, 689, 829, 869, - /* 560 */ 743, 746, 749, 751, 831, 832, 833, 834, 837, 838, - /* 570 */ 835, 870, 874, 877, 879, 880, 881, 884, 886, 891, - /* 580 */ 892, 893, 896, 894, 594, 588, + /* 0 */ 594, 819, 900, 709, 900, 900, 819, 900, 846, 713, + /* 10 */ 875, 900, 817, 900, 900, 900, 791, 900, 846, 900, + /* 20 */ 625, 846, 846, 742, 900, 900, 900, 900, 900, 900, + /* 30 */ 900, 900, 757, 744, 749, 820, 816, 876, 874, 750, + /* 40 */ 813, 859, 821, 743, 756, 733, 812, 900, 740, 747, + /* 50 */ 725, 814, 779, 778, 797, 900, 900, 900, 900, 900, + /* 60 */ 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, + /* 70 */ 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, + /* 80 */ 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, + /* 90 */ 900, 900, 900, 900, 900, 900, 781, 803, 780, 790, + /* 100 */ 618, 782, 783, 613, 678, 900, 900, 900, 900, 900, + /* 110 */ 900, 900, 784, 900, 785, 798, 799, 800, 900, 900, + /* 120 */ 900, 900, 900, 900, 900, 900, 900, 709, 900, 900, + /* 130 */ 900, 900, 900, 900, 900, 900, 900, 900, 900, 594, + /* 140 */ 709, 900, 900, 900, 900, 900, 893, 713, 703, 900, + /* 150 */ 669, 900, 900, 900, 900, 900, 900, 900, 900, 900, + /* 160 */ 900, 900, 711, 833, 900, 752, 881, 900, 900, 716, + /* 170 */ 717, 900, 900, 900, 900, 900, 879, 601, 900, 692, + /* 180 */ 900, 900, 900, 900, 599, 900, 864, 900, 627, 900, + /* 190 */ 900, 866, 900, 900, 900, 900, 900, 852, 900, 690, + /* 200 */ 900, 900, 900, 900, 615, 701, 900, 900, 736, 736, + /* 210 */ 900, 651, 736, 736, 710, 701, 648, 746, 736, 900, + /* 220 */ 815, 900, 900, 746, 900, 856, 680, 886, 598, 718, + /* 230 */ 718, 598, 878, 598, 598, 668, 878, 718, 758, 900, + /* 240 */ 746, 737, 739, 729, 741, 682, 746, 689, 689, 689, + /* 250 */ 689, 718, 746, 758, 682, 682, 718, 610, 900, 858, + /* 260 */ 665, 718, 718, 610, 718, 718, 610, 718, 610, 825, + /* 270 */ 680, 680, 718, 680, 726, 728, 665, 726, 728, 830, + /* 280 */ 830, 825, 680, 680, 651, 680, 861, 635, 653, 653, + /* 290 */ 893, 898, 900, 900, 900, 900, 900, 839, 900, 765, + /* 300 */ 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, + /* 310 */ 900, 900, 900, 900, 900, 900, 900, 595, 900, 900, + /* 320 */ 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, + /* 330 */ 900, 738, 900, 900, 900, 730, 900, 900, 900, 900, + /* 340 */ 818, 900, 900, 900, 900, 900, 900, 900, 900, 854, + /* 350 */ 900, 855, 900, 900, 900, 900, 900, 900, 900, 900, + /* 360 */ 900, 900, 900, 900, 900, 900, 695, 900, 900, 900, + /* 370 */ 900, 900, 900, 767, 900, 900, 900, 900, 766, 770, + /* 380 */ 900, 900, 900, 900, 900, 885, 900, 900, 900, 888, + /* 390 */ 639, 835, 836, 609, 837, 840, 611, 792, 809, 719, + /* 400 */ 841, 636, 806, 896, 871, 870, 869, 868, 838, 634, + /* 410 */ 616, 720, 867, 614, 848, 899, 811, 608, 873, 857, + /* 420 */ 853, 607, 606, 877, 849, 850, 605, 851, 612, 604, + /* 430 */ 810, 603, 777, 602, 774, 624, 880, 640, 822, 823, + /* 440 */ 623, 630, 631, 845, 843, 844, 683, 754, 755, 847, + /* 450 */ 622, 860, 842, 633, 882, 632, 629, 897, 600, 628, + /* 460 */ 647, 862, 589, 686, 808, 597, 697, 696, 883, 770, + /* 470 */ 759, 804, 801, 663, 796, 641, 593, 794, 863, 646, + /* 480 */ 685, 793, 788, 865, 884, 805, 802, 887, 795, 890, + /* 490 */ 642, 789, 787, 687, 644, 688, 652, 786, 691, 772, + /* 500 */ 771, 832, 769, 768, 872, 591, 667, 889, 764, 745, + /* 510 */ 773, 621, 596, 698, 694, 748, 592, 656, 659, 660, + /* 520 */ 661, 662, 693, 657, 763, 658, 807, 775, 826, 706, + /* 530 */ 762, 705, 827, 704, 831, 829, 715, 894, 828, 649, + /* 540 */ 761, 650, 760, 664, 637, 626, 619, 727, 655, 670, + /* 550 */ 895, 673, 590, 700, 714, 708, 645, 707, 674, 751, + /* 560 */ 724, 654, 666, 675, 684, 723, 722, 721, 676, 753, + /* 570 */ 699, 712, 776, 834, 702, 643, 638, 681, 620, 677, + /* 580 */ 679, 671, 672, 617, 732, 735, 734, 731, }; #define YY_SZ_ACTTAB (int)(sizeof(yy_action)/sizeof(yy_action[0])) /* The next table maps tokens into fallback tokens. If a construct ** like the following: @@ -66874,11 +68009,11 @@ /* 57 */ "ccons ::= PRIMARY KEY sortorder onconf autoinc", /* 58 */ "ccons ::= UNIQUE onconf", /* 59 */ "ccons ::= CHECK LP expr RP", /* 60 */ "ccons ::= REFERENCES nm idxlist_opt refargs", /* 61 */ "ccons ::= defer_subclause", - /* 62 */ "ccons ::= COLLATE id", + /* 62 */ "ccons ::= COLLATE ids", /* 63 */ "autoinc ::=", /* 64 */ "autoinc ::= AUTOINCR", /* 65 */ "refargs ::=", /* 66 */ "refargs ::= refargs refarg", /* 67 */ "refarg ::= MATCH nm", @@ -66997,11 +68132,11 @@ /* 180 */ "expr ::= nm DOT nm DOT nm", /* 181 */ "term ::= INTEGER|FLOAT|BLOB", /* 182 */ "term ::= STRING", /* 183 */ "expr ::= REGISTER", /* 184 */ "expr ::= VARIABLE", - /* 185 */ "expr ::= expr COLLATE id", + /* 185 */ "expr ::= expr COLLATE ids", /* 186 */ "expr ::= CAST LP expr AS typetoken RP", /* 187 */ "expr ::= ID LP distinct exprlist RP", /* 188 */ "expr ::= ID LP STAR RP", /* 189 */ "term ::= CTIME_KW", /* 190 */ "expr ::= expr AND expr", @@ -67021,112 +68156,113 @@ /* 204 */ "expr ::= expr likeop expr escape", /* 205 */ "expr ::= expr ISNULL|NOTNULL", /* 206 */ "expr ::= expr IS NULL", /* 207 */ "expr ::= expr NOT NULL", /* 208 */ "expr ::= expr IS NOT NULL", - /* 209 */ "expr ::= NOT|BITNOT expr", - /* 210 */ "expr ::= MINUS expr", - /* 211 */ "expr ::= PLUS expr", - /* 212 */ "between_op ::= BETWEEN", - /* 213 */ "between_op ::= NOT BETWEEN", - /* 214 */ "expr ::= expr between_op expr AND expr", - /* 215 */ "in_op ::= IN", - /* 216 */ "in_op ::= NOT IN", - /* 217 */ "expr ::= expr in_op LP exprlist RP", - /* 218 */ "expr ::= LP select RP", - /* 219 */ "expr ::= expr in_op LP select RP", - /* 220 */ "expr ::= expr in_op nm dbnm", - /* 221 */ "expr ::= EXISTS LP select RP", - /* 222 */ "expr ::= CASE case_operand case_exprlist case_else END", - /* 223 */ "case_exprlist ::= case_exprlist WHEN expr THEN expr", - /* 224 */ "case_exprlist ::= WHEN expr THEN expr", - /* 225 */ "case_else ::= ELSE expr", - /* 226 */ "case_else ::=", - /* 227 */ "case_operand ::= expr", - /* 228 */ "case_operand ::=", - /* 229 */ "exprlist ::= nexprlist", - /* 230 */ "exprlist ::=", - /* 231 */ "nexprlist ::= nexprlist COMMA expr", - /* 232 */ "nexprlist ::= expr", - /* 233 */ "cmd ::= CREATE uniqueflag INDEX ifnotexists nm dbnm ON nm LP idxlist RP", - /* 234 */ "uniqueflag ::= UNIQUE", - /* 235 */ "uniqueflag ::=", - /* 236 */ "idxlist_opt ::=", - /* 237 */ "idxlist_opt ::= LP idxlist RP", - /* 238 */ "idxlist ::= idxlist COMMA idxitem collate sortorder", - /* 239 */ "idxlist ::= idxitem collate sortorder", - /* 240 */ "idxitem ::= nm", - /* 241 */ "collate ::=", - /* 242 */ "collate ::= COLLATE id", - /* 243 */ "cmd ::= DROP INDEX ifexists fullname", - /* 244 */ "cmd ::= VACUUM", - /* 245 */ "cmd ::= VACUUM nm", - /* 246 */ "cmd ::= PRAGMA nm dbnm EQ nmnum", - /* 247 */ "cmd ::= PRAGMA nm dbnm EQ ON", - /* 248 */ "cmd ::= PRAGMA nm dbnm EQ minus_num", - /* 249 */ "cmd ::= PRAGMA nm dbnm LP nmnum RP", - /* 250 */ "cmd ::= PRAGMA nm dbnm", - /* 251 */ "nmnum ::= plus_num", - /* 252 */ "nmnum ::= nm", - /* 253 */ "plus_num ::= plus_opt number", - /* 254 */ "minus_num ::= MINUS number", - /* 255 */ "number ::= INTEGER|FLOAT", - /* 256 */ "plus_opt ::= PLUS", - /* 257 */ "plus_opt ::=", - /* 258 */ "cmd ::= CREATE trigger_decl BEGIN trigger_cmd_list END", - /* 259 */ "trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause", - /* 260 */ "trigger_time ::= BEFORE", - /* 261 */ "trigger_time ::= AFTER", - /* 262 */ "trigger_time ::= INSTEAD OF", - /* 263 */ "trigger_time ::=", - /* 264 */ "trigger_event ::= DELETE|INSERT", - /* 265 */ "trigger_event ::= UPDATE", - /* 266 */ "trigger_event ::= UPDATE OF inscollist", - /* 267 */ "foreach_clause ::=", - /* 268 */ "foreach_clause ::= FOR EACH ROW", - /* 269 */ "when_clause ::=", - /* 270 */ "when_clause ::= WHEN expr", - /* 271 */ "trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI", - /* 272 */ "trigger_cmd_list ::=", - /* 273 */ "trigger_cmd ::= UPDATE orconf nm SET setlist where_opt", - /* 274 */ "trigger_cmd ::= insert_cmd INTO nm inscollist_opt VALUES LP itemlist RP", - /* 275 */ "trigger_cmd ::= insert_cmd INTO nm inscollist_opt select", - /* 276 */ "trigger_cmd ::= DELETE FROM nm where_opt", - /* 277 */ "trigger_cmd ::= select", - /* 278 */ "expr ::= RAISE LP IGNORE RP", - /* 279 */ "expr ::= RAISE LP raisetype COMMA nm RP", - /* 280 */ "raisetype ::= ROLLBACK", - /* 281 */ "raisetype ::= ABORT", - /* 282 */ "raisetype ::= FAIL", - /* 283 */ "cmd ::= DROP TRIGGER ifexists fullname", - /* 284 */ "cmd ::= ATTACH database_kw_opt expr AS expr key_opt", - /* 285 */ "cmd ::= DETACH database_kw_opt expr", - /* 286 */ "key_opt ::=", - /* 287 */ "key_opt ::= KEY expr", - /* 288 */ "database_kw_opt ::= DATABASE", - /* 289 */ "database_kw_opt ::=", - /* 290 */ "cmd ::= REINDEX", - /* 291 */ "cmd ::= REINDEX nm dbnm", - /* 292 */ "cmd ::= ANALYZE", - /* 293 */ "cmd ::= ANALYZE nm dbnm", - /* 294 */ "cmd ::= ALTER TABLE fullname RENAME TO nm", - /* 295 */ "cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt column", - /* 296 */ "add_column_fullname ::= fullname", - /* 297 */ "kwcolumn_opt ::=", - /* 298 */ "kwcolumn_opt ::= COLUMNKW", - /* 299 */ "cmd ::= create_vtab", - /* 300 */ "cmd ::= create_vtab LP vtabarglist RP", - /* 301 */ "create_vtab ::= CREATE VIRTUAL TABLE nm dbnm USING nm", - /* 302 */ "vtabarglist ::= vtabarg", - /* 303 */ "vtabarglist ::= vtabarglist COMMA vtabarg", - /* 304 */ "vtabarg ::=", - /* 305 */ "vtabarg ::= vtabarg vtabargtoken", - /* 306 */ "vtabargtoken ::= ANY", - /* 307 */ "vtabargtoken ::= lp anylist RP", - /* 308 */ "lp ::= LP", - /* 309 */ "anylist ::=", - /* 310 */ "anylist ::= anylist ANY", + /* 209 */ "expr ::= NOT expr", + /* 210 */ "expr ::= BITNOT expr", + /* 211 */ "expr ::= MINUS expr", + /* 212 */ "expr ::= PLUS expr", + /* 213 */ "between_op ::= BETWEEN", + /* 214 */ "between_op ::= NOT BETWEEN", + /* 215 */ "expr ::= expr between_op expr AND expr", + /* 216 */ "in_op ::= IN", + /* 217 */ "in_op ::= NOT IN", + /* 218 */ "expr ::= expr in_op LP exprlist RP", + /* 219 */ "expr ::= LP select RP", + /* 220 */ "expr ::= expr in_op LP select RP", + /* 221 */ "expr ::= expr in_op nm dbnm", + /* 222 */ "expr ::= EXISTS LP select RP", + /* 223 */ "expr ::= CASE case_operand case_exprlist case_else END", + /* 224 */ "case_exprlist ::= case_exprlist WHEN expr THEN expr", + /* 225 */ "case_exprlist ::= WHEN expr THEN expr", + /* 226 */ "case_else ::= ELSE expr", + /* 227 */ "case_else ::=", + /* 228 */ "case_operand ::= expr", + /* 229 */ "case_operand ::=", + /* 230 */ "exprlist ::= nexprlist", + /* 231 */ "exprlist ::=", + /* 232 */ "nexprlist ::= nexprlist COMMA expr", + /* 233 */ "nexprlist ::= expr", + /* 234 */ "cmd ::= CREATE uniqueflag INDEX ifnotexists nm dbnm ON nm LP idxlist RP", + /* 235 */ "uniqueflag ::= UNIQUE", + /* 236 */ "uniqueflag ::=", + /* 237 */ "idxlist_opt ::=", + /* 238 */ "idxlist_opt ::= LP idxlist RP", + /* 239 */ "idxlist ::= idxlist COMMA idxitem collate sortorder", + /* 240 */ "idxlist ::= idxitem collate sortorder", + /* 241 */ "idxitem ::= nm", + /* 242 */ "collate ::=", + /* 243 */ "collate ::= COLLATE ids", + /* 244 */ "cmd ::= DROP INDEX ifexists fullname", + /* 245 */ "cmd ::= VACUUM", + /* 246 */ "cmd ::= VACUUM nm", + /* 247 */ "cmd ::= PRAGMA nm dbnm EQ nmnum", + /* 248 */ "cmd ::= PRAGMA nm dbnm EQ ON", + /* 249 */ "cmd ::= PRAGMA nm dbnm EQ minus_num", + /* 250 */ "cmd ::= PRAGMA nm dbnm LP nmnum RP", + /* 251 */ "cmd ::= PRAGMA nm dbnm", + /* 252 */ "nmnum ::= plus_num", + /* 253 */ "nmnum ::= nm", + /* 254 */ "plus_num ::= plus_opt number", + /* 255 */ "minus_num ::= MINUS number", + /* 256 */ "number ::= INTEGER|FLOAT", + /* 257 */ "plus_opt ::= PLUS", + /* 258 */ "plus_opt ::=", + /* 259 */ "cmd ::= CREATE trigger_decl BEGIN trigger_cmd_list END", + /* 260 */ "trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause", + /* 261 */ "trigger_time ::= BEFORE", + /* 262 */ "trigger_time ::= AFTER", + /* 263 */ "trigger_time ::= INSTEAD OF", + /* 264 */ "trigger_time ::=", + /* 265 */ "trigger_event ::= DELETE|INSERT", + /* 266 */ "trigger_event ::= UPDATE", + /* 267 */ "trigger_event ::= UPDATE OF inscollist", + /* 268 */ "foreach_clause ::=", + /* 269 */ "foreach_clause ::= FOR EACH ROW", + /* 270 */ "when_clause ::=", + /* 271 */ "when_clause ::= WHEN expr", + /* 272 */ "trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI", + /* 273 */ "trigger_cmd_list ::=", + /* 274 */ "trigger_cmd ::= UPDATE orconf nm SET setlist where_opt", + /* 275 */ "trigger_cmd ::= insert_cmd INTO nm inscollist_opt VALUES LP itemlist RP", + /* 276 */ "trigger_cmd ::= insert_cmd INTO nm inscollist_opt select", + /* 277 */ "trigger_cmd ::= DELETE FROM nm where_opt", + /* 278 */ "trigger_cmd ::= select", + /* 279 */ "expr ::= RAISE LP IGNORE RP", + /* 280 */ "expr ::= RAISE LP raisetype COMMA nm RP", + /* 281 */ "raisetype ::= ROLLBACK", + /* 282 */ "raisetype ::= ABORT", + /* 283 */ "raisetype ::= FAIL", + /* 284 */ "cmd ::= DROP TRIGGER ifexists fullname", + /* 285 */ "cmd ::= ATTACH database_kw_opt expr AS expr key_opt", + /* 286 */ "cmd ::= DETACH database_kw_opt expr", + /* 287 */ "key_opt ::=", + /* 288 */ "key_opt ::= KEY expr", + /* 289 */ "database_kw_opt ::= DATABASE", + /* 290 */ "database_kw_opt ::=", + /* 291 */ "cmd ::= REINDEX", + /* 292 */ "cmd ::= REINDEX nm dbnm", + /* 293 */ "cmd ::= ANALYZE", + /* 294 */ "cmd ::= ANALYZE nm dbnm", + /* 295 */ "cmd ::= ALTER TABLE fullname RENAME TO nm", + /* 296 */ "cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt column", + /* 297 */ "add_column_fullname ::= fullname", + /* 298 */ "kwcolumn_opt ::=", + /* 299 */ "kwcolumn_opt ::= COLUMNKW", + /* 300 */ "cmd ::= create_vtab", + /* 301 */ "cmd ::= create_vtab LP vtabarglist RP", + /* 302 */ "create_vtab ::= CREATE VIRTUAL TABLE nm dbnm USING nm", + /* 303 */ "vtabarglist ::= vtabarg", + /* 304 */ "vtabarglist ::= vtabarglist COMMA vtabarg", + /* 305 */ "vtabarg ::=", + /* 306 */ "vtabarg ::= vtabarg vtabargtoken", + /* 307 */ "vtabargtoken ::= ANY", + /* 308 */ "vtabargtoken ::= lp anylist RP", + /* 309 */ "lp ::= LP", + /* 310 */ "anylist ::=", + /* 311 */ "anylist ::= anylist ANY", }; #endif /* NDEBUG */ #if YYSTACKDEPTH<=0 @@ -67666,10 +68802,11 @@ { 170, 3 }, { 170, 4 }, { 170, 2 }, { 170, 2 }, { 170, 2 }, + { 170, 2 }, { 219, 1 }, { 219, 2 }, { 170, 5 }, { 220, 1 }, { 220, 2 }, @@ -67841,22 +68978,22 @@ case 55: case 82: case 83: case 84: case 85: - case 256: case 257: - case 267: + case 258: case 268: - case 288: + case 269: case 289: - case 297: + case 290: case 298: - case 302: + case 299: case 303: - case 305: - case 309: + case 304: + case 306: + case 310: { } break; case 3: { sqlite3FinishCoding(pParse); } @@ -67902,22 +69039,22 @@ case 79: case 90: case 101: case 112: case 113: - case 212: - case 215: + case 213: + case 216: {yygotominor.yy46 = 0;} break; case 23: case 24: case 64: case 78: case 100: case 111: - case 213: - case 216: + case 214: + case 217: {yygotominor.yy46 = 1;} break; case 26: { sqlite3EndTable(pParse,&yymsp[-1].minor.yy410,&yymsp[0].minor.yy0,0); @@ -67944,11 +69081,11 @@ case 32: case 33: case 34: case 35: case 36: - case 255: + case 256: {yygotominor.yy410 = yymsp[0].minor.yy0;} break; case 38: {sqlite3AddColumnType(pParse,&yymsp[0].minor.yy410);} break; @@ -67955,16 +69092,16 @@ case 39: case 42: case 119: case 120: case 131: - case 240: - case 242: - case 251: + case 241: + case 243: case 252: case 253: case 254: + case 255: {yygotominor.yy410 = yymsp[0].minor.yy410;} break; case 40: { yygotominor.yy410.z = yymsp[-3].minor.yy410.z; @@ -68016,11 +69153,11 @@ break; case 61: {sqlite3DeferForeignKey(pParse,yymsp[0].minor.yy46);} break; case 62: -{sqlite3AddCollateType(pParse, (char*)yymsp[0].minor.yy410.z, yymsp[0].minor.yy410.n);} +{sqlite3AddCollateType(pParse, &yymsp[0].minor.yy410);} break; case 65: { yygotominor.yy46 = OE_Restrict * 0x010101; } break; case 66: @@ -68134,18 +69271,18 @@ { yygotominor.yy219 = sqlite3SelectNew(pParse,yymsp[-6].minor.yy174,yymsp[-5].minor.yy373,yymsp[-4].minor.yy172,yymsp[-3].minor.yy174,yymsp[-2].minor.yy172,yymsp[-1].minor.yy174,yymsp[-7].minor.yy46,yymsp[0].minor.yy234.pLimit,yymsp[0].minor.yy234.pOffset); } break; case 114: - case 237: + case 238: {yygotominor.yy174 = yymsp[-1].minor.yy174;} break; case 115: case 141: case 149: - case 230: - case 236: + case 231: + case 237: {yygotominor.yy174 = 0;} break; case 116: { yygotominor.yy174 = sqlite3ExprListAppend(pParse,yymsp[-2].minor.yy174,yymsp[-1].minor.yy172,yymsp[0].minor.yy410.n?&yymsp[0].minor.yy410:0); @@ -68224,20 +69361,20 @@ case 145: case 152: case 159: case 174: case 202: - case 225: - case 227: + case 226: + case 228: {yygotominor.yy172 = yymsp[0].minor.yy172;} break; case 138: case 151: case 158: case 203: - case 226: - case 228: + case 227: + case 229: {yygotominor.yy172 = 0;} break; case 139: case 171: {yygotominor.yy432 = yymsp[-1].minor.yy432;} @@ -68246,11 +69383,11 @@ case 170: {yygotominor.yy432 = 0;} break; case 142: case 150: - case 229: + case 230: {yygotominor.yy174 = yymsp[0].minor.yy174;} break; case 143: { yygotominor.yy174 = sqlite3ExprListAppend(pParse,yymsp[-3].minor.yy174,yymsp[-1].minor.yy172,0); @@ -68305,15 +69442,15 @@ break; case 165: {sqlite3Insert(pParse, yymsp[-3].minor.yy373, 0, 0, yymsp[-2].minor.yy432, yymsp[-5].minor.yy46);} break; case 168: - case 231: + case 232: {yygotominor.yy174 = sqlite3ExprListAppend(pParse,yymsp[-2].minor.yy174,yymsp[0].minor.yy172,0);} break; case 169: - case 232: + case 233: {yygotominor.yy174 = sqlite3ExprListAppend(pParse,0,yymsp[0].minor.yy172,0);} break; case 172: {yygotominor.yy432 = sqlite3IdListAppend(pParse->db,yymsp[-2].minor.yy432,&yymsp[0].minor.yy410);} break; @@ -68453,28 +69590,29 @@ yygotominor.yy172 = sqlite3PExpr(pParse, TK_NOTNULL, yymsp[-3].minor.yy172, 0, 0); sqlite3ExprSpan(yygotominor.yy172,&yymsp[-3].minor.yy172->span,&yymsp[0].minor.yy0); } break; case 209: + case 210: { yygotominor.yy172 = sqlite3PExpr(pParse, yymsp[-1].major, yymsp[0].minor.yy172, 0, 0); sqlite3ExprSpan(yygotominor.yy172,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy172->span); } break; - case 210: + case 211: { yygotominor.yy172 = sqlite3PExpr(pParse, TK_UMINUS, yymsp[0].minor.yy172, 0, 0); sqlite3ExprSpan(yygotominor.yy172,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy172->span); } break; - case 211: + case 212: { yygotominor.yy172 = sqlite3PExpr(pParse, TK_UPLUS, yymsp[0].minor.yy172, 0, 0); sqlite3ExprSpan(yygotominor.yy172,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy172->span); } break; - case 214: + case 215: { ExprList *pList = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy172, 0); pList = sqlite3ExprListAppend(pParse,pList, yymsp[0].minor.yy172, 0); yygotominor.yy172 = sqlite3PExpr(pParse, TK_BETWEEN, yymsp[-4].minor.yy172, 0, 0); if( yygotominor.yy172 ){ @@ -68484,11 +69622,11 @@ } if( yymsp[-3].minor.yy46 ) yygotominor.yy172 = sqlite3PExpr(pParse, TK_NOT, yygotominor.yy172, 0, 0); sqlite3ExprSpan(yygotominor.yy172,&yymsp[-4].minor.yy172->span,&yymsp[0].minor.yy172->span); } break; - case 217: + case 218: { yygotominor.yy172 = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy172, 0, 0); if( yygotominor.yy172 ){ yygotominor.yy172->pList = yymsp[-1].minor.yy174; sqlite3ExprSetHeight(yygotominor.yy172); @@ -68497,11 +69635,11 @@ } if( yymsp[-3].minor.yy46 ) yygotominor.yy172 = sqlite3PExpr(pParse, TK_NOT, yygotominor.yy172, 0, 0); sqlite3ExprSpan(yygotominor.yy172,&yymsp[-4].minor.yy172->span,&yymsp[0].minor.yy0); } break; - case 218: + case 219: { yygotominor.yy172 = sqlite3PExpr(pParse, TK_SELECT, 0, 0, 0); if( yygotominor.yy172 ){ yygotominor.yy172->pSelect = yymsp[-1].minor.yy219; sqlite3ExprSetHeight(yygotominor.yy172); @@ -68509,11 +69647,11 @@ sqlite3SelectDelete(yymsp[-1].minor.yy219); } sqlite3ExprSpan(yygotominor.yy172,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0); } break; - case 219: + case 220: { yygotominor.yy172 = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy172, 0, 0); if( yygotominor.yy172 ){ yygotominor.yy172->pSelect = yymsp[-1].minor.yy219; sqlite3ExprSetHeight(yygotominor.yy172); @@ -68522,11 +69660,11 @@ } if( yymsp[-3].minor.yy46 ) yygotominor.yy172 = sqlite3PExpr(pParse, TK_NOT, yygotominor.yy172, 0, 0); sqlite3ExprSpan(yygotominor.yy172,&yymsp[-4].minor.yy172->span,&yymsp[0].minor.yy0); } break; - case 220: + case 221: { SrcList *pSrc = sqlite3SrcListAppend(pParse->db, 0,&yymsp[-1].minor.yy410,&yymsp[0].minor.yy410); yygotominor.yy172 = sqlite3PExpr(pParse, TK_IN, yymsp[-3].minor.yy172, 0, 0); if( yygotominor.yy172 ){ yygotominor.yy172->pSelect = sqlite3SelectNew(pParse, 0,pSrc,0,0,0,0,0,0,0); @@ -68536,11 +69674,11 @@ } if( yymsp[-2].minor.yy46 ) yygotominor.yy172 = sqlite3PExpr(pParse, TK_NOT, yygotominor.yy172, 0, 0); sqlite3ExprSpan(yygotominor.yy172,&yymsp[-3].minor.yy172->span,yymsp[0].minor.yy410.z?&yymsp[0].minor.yy410:&yymsp[-1].minor.yy410); } break; - case 221: + case 222: { Expr *p = yygotominor.yy172 = sqlite3PExpr(pParse, TK_EXISTS, 0, 0, 0); if( p ){ p->pSelect = yymsp[-1].minor.yy219; sqlite3ExprSpan(p,&yymsp[-3].minor.yy0,&yymsp[0].minor.yy0); @@ -68548,11 +69686,11 @@ }else{ sqlite3SelectDelete(yymsp[-1].minor.yy219); } } break; - case 222: + case 223: { yygotominor.yy172 = sqlite3PExpr(pParse, TK_CASE, yymsp[-3].minor.yy172, yymsp[-1].minor.yy172, 0); if( yygotominor.yy172 ){ yygotominor.yy172->pList = yymsp[-2].minor.yy174; sqlite3ExprSetHeight(yygotominor.yy172); @@ -68560,125 +69698,125 @@ sqlite3ExprListDelete(yymsp[-2].minor.yy174); } sqlite3ExprSpan(yygotominor.yy172, &yymsp[-4].minor.yy0, &yymsp[0].minor.yy0); } break; - case 223: + case 224: { yygotominor.yy174 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy174, yymsp[-2].minor.yy172, 0); yygotominor.yy174 = sqlite3ExprListAppend(pParse,yygotominor.yy174, yymsp[0].minor.yy172, 0); } break; - case 224: + case 225: { yygotominor.yy174 = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy172, 0); yygotominor.yy174 = sqlite3ExprListAppend(pParse,yygotominor.yy174, yymsp[0].minor.yy172, 0); } break; - case 233: + case 234: { sqlite3CreateIndex(pParse, &yymsp[-6].minor.yy410, &yymsp[-5].minor.yy410, sqlite3SrcListAppend(pParse->db,0,&yymsp[-3].minor.yy410,0), yymsp[-1].minor.yy174, yymsp[-9].minor.yy46, &yymsp[-10].minor.yy0, &yymsp[0].minor.yy0, SQLITE_SO_ASC, yymsp[-7].minor.yy46); } break; - case 234: - case 281: + case 235: + case 282: {yygotominor.yy46 = OE_Abort;} break; - case 235: + case 236: {yygotominor.yy46 = OE_None;} break; - case 238: + case 239: { Expr *p = 0; if( yymsp[-1].minor.yy410.n>0 ){ p = sqlite3PExpr(pParse, TK_COLUMN, 0, 0, 0); - if( p ) p->pColl = sqlite3LocateCollSeq(pParse, (char*)yymsp[-1].minor.yy410.z, yymsp[-1].minor.yy410.n); + sqlite3ExprSetColl(pParse, p, &yymsp[-1].minor.yy410); } yygotominor.yy174 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy174, p, &yymsp[-2].minor.yy410); sqlite3ExprListCheckLength(pParse, yygotominor.yy174, SQLITE_MAX_COLUMN, "index"); if( yygotominor.yy174 ) yygotominor.yy174->a[yygotominor.yy174->nExpr-1].sortOrder = yymsp[0].minor.yy46; } break; - case 239: + case 240: { Expr *p = 0; if( yymsp[-1].minor.yy410.n>0 ){ p = sqlite3PExpr(pParse, TK_COLUMN, 0, 0, 0); - if( p ) p->pColl = sqlite3LocateCollSeq(pParse, (char*)yymsp[-1].minor.yy410.z, yymsp[-1].minor.yy410.n); + sqlite3ExprSetColl(pParse, p, &yymsp[-1].minor.yy410); } yygotominor.yy174 = sqlite3ExprListAppend(pParse,0, p, &yymsp[-2].minor.yy410); sqlite3ExprListCheckLength(pParse, yygotominor.yy174, SQLITE_MAX_COLUMN, "index"); if( yygotominor.yy174 ) yygotominor.yy174->a[yygotominor.yy174->nExpr-1].sortOrder = yymsp[0].minor.yy46; } break; - case 241: + case 242: {yygotominor.yy410.z = 0; yygotominor.yy410.n = 0;} break; - case 243: + case 244: {sqlite3DropIndex(pParse, yymsp[0].minor.yy373, yymsp[-1].minor.yy46);} break; - case 244: case 245: + case 246: {sqlite3Vacuum(pParse);} break; - case 246: + case 247: {sqlite3Pragma(pParse,&yymsp[-3].minor.yy410,&yymsp[-2].minor.yy410,&yymsp[0].minor.yy410,0);} break; - case 247: + case 248: {sqlite3Pragma(pParse,&yymsp[-3].minor.yy410,&yymsp[-2].minor.yy410,&yymsp[0].minor.yy0,0);} break; - case 248: + case 249: { sqlite3Pragma(pParse,&yymsp[-3].minor.yy410,&yymsp[-2].minor.yy410,&yymsp[0].minor.yy410,1); } break; - case 249: + case 250: {sqlite3Pragma(pParse,&yymsp[-4].minor.yy410,&yymsp[-3].minor.yy410,&yymsp[-1].minor.yy410,0);} break; - case 250: + case 251: {sqlite3Pragma(pParse,&yymsp[-1].minor.yy410,&yymsp[0].minor.yy410,0,0);} break; - case 258: + case 259: { Token all; all.z = yymsp[-3].minor.yy410.z; all.n = (yymsp[0].minor.yy0.z - yymsp[-3].minor.yy410.z) + yymsp[0].minor.yy0.n; sqlite3FinishTrigger(pParse, yymsp[-1].minor.yy243, &all); } break; - case 259: + case 260: { sqlite3BeginTrigger(pParse, &yymsp[-7].minor.yy410, &yymsp[-6].minor.yy410, yymsp[-5].minor.yy46, yymsp[-4].minor.yy370.a, yymsp[-4].minor.yy370.b, yymsp[-2].minor.yy373, yymsp[0].minor.yy172, yymsp[-10].minor.yy46, yymsp[-8].minor.yy46); yygotominor.yy410 = (yymsp[-6].minor.yy410.n==0?yymsp[-7].minor.yy410:yymsp[-6].minor.yy410); } break; - case 260: - case 263: + case 261: + case 264: { yygotominor.yy46 = TK_BEFORE; } break; - case 261: + case 262: { yygotominor.yy46 = TK_AFTER; } break; - case 262: + case 263: { yygotominor.yy46 = TK_INSTEAD;} break; - case 264: case 265: + case 266: {yygotominor.yy370.a = yymsp[0].major; yygotominor.yy370.b = 0;} break; - case 266: + case 267: {yygotominor.yy370.a = TK_UPDATE; yygotominor.yy370.b = yymsp[0].minor.yy432;} break; - case 269: + case 270: { yygotominor.yy172 = 0; } break; - case 270: + case 271: { yygotominor.yy172 = yymsp[0].minor.yy172; } break; - case 271: + case 272: { if( yymsp[-2].minor.yy243 ){ yymsp[-2].minor.yy243->pLast->pNext = yymsp[-1].minor.yy243; }else{ yymsp[-2].minor.yy243 = yymsp[-1].minor.yy243; @@ -68685,118 +69823,118 @@ } yymsp[-2].minor.yy243->pLast = yymsp[-1].minor.yy243; yygotominor.yy243 = yymsp[-2].minor.yy243; } break; - case 272: + case 273: { yygotominor.yy243 = 0; } break; - case 273: + case 274: { yygotominor.yy243 = sqlite3TriggerUpdateStep(pParse->db, &yymsp[-3].minor.yy410, yymsp[-1].minor.yy174, yymsp[0].minor.yy172, yymsp[-4].minor.yy46); } break; - case 274: + case 275: {yygotominor.yy243 = sqlite3TriggerInsertStep(pParse->db, &yymsp[-5].minor.yy410, yymsp[-4].minor.yy432, yymsp[-1].minor.yy174, 0, yymsp[-7].minor.yy46);} break; - case 275: + case 276: {yygotominor.yy243 = sqlite3TriggerInsertStep(pParse->db, &yymsp[-2].minor.yy410, yymsp[-1].minor.yy432, 0, yymsp[0].minor.yy219, yymsp[-4].minor.yy46);} break; - case 276: + case 277: {yygotominor.yy243 = sqlite3TriggerDeleteStep(pParse->db, &yymsp[-1].minor.yy410, yymsp[0].minor.yy172);} break; - case 277: + case 278: {yygotominor.yy243 = sqlite3TriggerSelectStep(pParse->db, yymsp[0].minor.yy219); } break; - case 278: + case 279: { yygotominor.yy172 = sqlite3PExpr(pParse, TK_RAISE, 0, 0, 0); if( yygotominor.yy172 ){ yygotominor.yy172->iColumn = OE_Ignore; sqlite3ExprSpan(yygotominor.yy172, &yymsp[-3].minor.yy0, &yymsp[0].minor.yy0); } } break; - case 279: + case 280: { yygotominor.yy172 = sqlite3PExpr(pParse, TK_RAISE, 0, 0, &yymsp[-1].minor.yy410); if( yygotominor.yy172 ) { yygotominor.yy172->iColumn = yymsp[-3].minor.yy46; sqlite3ExprSpan(yygotominor.yy172, &yymsp[-5].minor.yy0, &yymsp[0].minor.yy0); } } break; - case 280: + case 281: {yygotominor.yy46 = OE_Rollback;} break; - case 282: + case 283: {yygotominor.yy46 = OE_Fail;} break; - case 283: + case 284: { sqlite3DropTrigger(pParse,yymsp[0].minor.yy373,yymsp[-1].minor.yy46); } break; - case 284: + case 285: { sqlite3Attach(pParse, yymsp[-3].minor.yy172, yymsp[-1].minor.yy172, yymsp[0].minor.yy386); } break; - case 285: + case 286: { sqlite3Detach(pParse, yymsp[0].minor.yy172); } break; - case 286: + case 287: { yygotominor.yy386 = 0; } break; - case 287: + case 288: { yygotominor.yy386 = yymsp[0].minor.yy172; } break; - case 290: + case 291: {sqlite3Reindex(pParse, 0, 0);} break; - case 291: + case 292: {sqlite3Reindex(pParse, &yymsp[-1].minor.yy410, &yymsp[0].minor.yy410);} break; - case 292: + case 293: {sqlite3Analyze(pParse, 0, 0);} break; - case 293: + case 294: {sqlite3Analyze(pParse, &yymsp[-1].minor.yy410, &yymsp[0].minor.yy410);} break; - case 294: + case 295: { sqlite3AlterRenameTable(pParse,yymsp[-3].minor.yy373,&yymsp[0].minor.yy410); } break; - case 295: + case 296: { sqlite3AlterFinishAddColumn(pParse, &yymsp[0].minor.yy410); } break; - case 296: + case 297: { sqlite3AlterBeginAddColumn(pParse, yymsp[0].minor.yy373); } break; - case 299: + case 300: {sqlite3VtabFinishParse(pParse,0);} break; - case 300: + case 301: {sqlite3VtabFinishParse(pParse,&yymsp[0].minor.yy0);} break; - case 301: + case 302: { sqlite3VtabBeginParse(pParse, &yymsp[-3].minor.yy410, &yymsp[-2].minor.yy410, &yymsp[0].minor.yy410); } break; - case 304: + case 305: {sqlite3VtabArgInit(pParse);} break; - case 306: case 307: case 308: - case 310: + case 309: + case 311: {sqlite3VtabArgExtend(pParse,&yymsp[0].minor.yy0);} break; }; yygoto = yyRuleInfo[yyruleno].lhs; yysize = yyRuleInfo[yyruleno].nrhs; @@ -69133,12 +70271,12 @@ "WHERENAMEAFTEREPLACEANDEFAULTAUTOINCREMENTCASTCOLUMNCOMMITCONFLICT" "CROSSCURRENT_TIMESTAMPRIMARYDEFERREDISTINCTDROPFAILFROMFULLGLOB" "YIFINTOFFSETISNULLORDERESTRICTOUTERIGHTROLLBACKROWUNIONUSINGVACUUM" "VIEWINITIALLY"; static const unsigned char aHash[127] = { - 63, 92, 109, 61, 0, 38, 0, 0, 69, 0, 64, 0, 0, - 102, 4, 65, 7, 0, 108, 72, 103, 99, 0, 22, 0, 0, + 63, 92, 109, 61, 0, 39, 0, 0, 69, 0, 64, 0, 0, + 101, 4, 65, 7, 0, 108, 72, 103, 99, 0, 22, 0, 0, 113, 0, 111, 106, 0, 18, 80, 0, 1, 0, 0, 56, 57, 0, 55, 11, 0, 33, 77, 89, 0, 110, 88, 0, 0, 45, 0, 90, 54, 0, 20, 0, 114, 34, 19, 0, 10, 97, 28, 83, 0, 0, 116, 93, 47, 115, 41, 12, 44, 0, 78, 0, 87, 29, 0, 86, 0, 0, 0, 82, 79, 84, 75, 96, 6, @@ -69148,26 +70286,26 @@ }; static const unsigned char aNext[116] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, - 17, 0, 0, 0, 36, 39, 0, 0, 25, 0, 0, 31, 0, + 17, 0, 0, 0, 36, 38, 0, 0, 25, 0, 0, 31, 0, 0, 0, 43, 52, 0, 0, 0, 53, 0, 0, 0, 0, 0, 0, 0, 0, 0, 51, 0, 0, 0, 0, 26, 0, 8, 46, - 2, 0, 0, 0, 0, 0, 0, 0, 3, 58, 66, 0, 13, - 0, 91, 85, 0, 94, 0, 74, 0, 0, 62, 0, 35, 101, + 3, 0, 0, 0, 0, 0, 0, 0, 2, 58, 66, 0, 13, + 0, 91, 85, 0, 94, 0, 74, 0, 0, 0, 62, 35, 102, 0, 0, 105, 23, 30, 60, 70, 0, 0, 59, 0, 0, }; static const unsigned char aLen[116] = { - 6, 7, 3, 6, 6, 7, 7, 3, 4, 6, 4, 5, 3, + 6, 3, 7, 6, 6, 7, 7, 3, 4, 6, 4, 5, 3, 10, 9, 5, 4, 4, 3, 8, 2, 6, 11, 2, 7, 5, - 5, 4, 6, 7, 10, 6, 5, 6, 6, 5, 6, 4, 9, + 5, 4, 6, 7, 10, 6, 5, 6, 6, 5, 6, 9, 4, 2, 5, 5, 7, 5, 9, 6, 7, 7, 3, 4, 4, 7, 3, 10, 4, 7, 6, 12, 6, 6, 9, 4, 6, 5, 4, 7, 6, 5, 6, 7, 5, 4, 5, 6, 5, 7, 3, 7, 13, 2, 2, 4, 6, 6, 8, 5, 17, 12, 7, 8, 8, - 2, 4, 4, 4, 4, 4, 2, 2, 4, 6, 2, 3, 6, + 2, 4, 4, 4, 4, 4, 2, 2, 4, 2, 6, 3, 6, 5, 8, 5, 5, 8, 3, 5, 5, 6, 4, 9, 3, }; static const unsigned short int aOffset[116] = { 0, 2, 2, 6, 10, 13, 18, 23, 25, 26, 31, 33, 37, 40, 47, 55, 58, 61, 63, 65, 70, 71, 76, 85, 86, 91, @@ -69178,11 +70316,11 @@ 346, 348, 350, 359, 363, 369, 375, 383, 388, 388, 404, 411, 418, 419, 426, 430, 434, 438, 442, 445, 447, 449, 452, 452, 455, 458, 464, 468, 476, 480, 485, 493, 496, 501, 506, 512, 516, 521, }; static const unsigned char aCode[116] = { - TK_BEFORE, TK_FOREIGN, TK_FOR, TK_IGNORE, TK_LIKE_KW, + TK_BEFORE, TK_FOR, TK_FOREIGN, TK_IGNORE, TK_LIKE_KW, TK_EXPLAIN, TK_INSTEAD, TK_ADD, TK_DESC, TK_ESCAPE, TK_EACH, TK_CHECK, TK_KEY, TK_CONSTRAINT, TK_INTERSECT, TK_TABLE, TK_JOIN_KW, TK_THEN, TK_END, TK_DATABASE, TK_AS, TK_SELECT, TK_TRANSACTION,TK_ON, TK_JOIN_KW, TK_ALTER, TK_RAISE, TK_ELSE, TK_EXCEPT, TK_TRIGGER, @@ -69198,11 +70336,11 @@ TK_REPLACE, TK_AND, TK_DEFAULT, TK_AUTOINCR, TK_TO, TK_IN, TK_CAST, TK_COLUMNKW, TK_COMMIT, TK_CONFLICT, TK_JOIN_KW, TK_CTIME_KW, TK_CTIME_KW, TK_PRIMARY, TK_DEFERRED, TK_DISTINCT, TK_IS, TK_DROP, TK_FAIL, TK_FROM, TK_JOIN_KW, TK_LIKE_KW, TK_BY, TK_IF, TK_INTO, - TK_OFFSET, TK_OF, TK_SET, TK_ISNULL, TK_ORDER, + TK_OF, TK_OFFSET, TK_SET, TK_ISNULL, TK_ORDER, TK_RESTRICT, TK_JOIN_KW, TK_JOIN_KW, TK_ROLLBACK, TK_ROW, TK_UNION, TK_USING, TK_VACUUM, TK_VIEW, TK_INITIALLY, TK_ALL, }; int h, i; @@ -69953,11 +71091,11 @@ ** Main file for the SQLite library. The routines in this file ** implement the programmer interface to the library. Routines in ** other files are for internal use by SQLite and should not be ** accessed by users of the library. ** -** $Id: main.c,v 1.404 2007/09/03 15:19:35 drh Exp $ +** $Id: main.c,v 1.407 2007/10/12 19:35:49 drh Exp $ */ /* ** The version of the library */ @@ -70171,10 +71309,11 @@ */ SQLITE_PRIVATE void sqlite3RollbackAll(sqlite3 *db){ int i; int inTrans = 0; assert( sqlite3_mutex_held(db->mutex) ); + sqlite3MallocEnterBenignBlock(1); /* Enter benign region */ for(i=0; i<db->nDb; i++){ if( db->aDb[i].pBt ){ if( sqlite3BtreeIsInTrans(db->aDb[i].pBt) ){ inTrans = 1; } @@ -70181,10 +71320,12 @@ sqlite3BtreeRollback(db->aDb[i].pBt); db->aDb[i].inTrans = 0; } } sqlite3VtabRollback(db); + sqlite3MallocLeaveBenignBlock(); /* Leave benign region */ + if( db->flags&SQLITE_InternChanges ){ sqlite3ExpirePreparedStatements(db); sqlite3ResetInternalSchema(db, 0); } @@ -71206,11 +72347,11 @@ #ifndef SQLITE_OMIT_GLOBALRECOVER /* ** This function is now an anachronism. It used to be used to recover from a ** malloc() failure, but SQLite now does this automatically. */ -SQLITE_API int sqlite3_global_recover(){ +SQLITE_API int sqlite3_global_recover(void){ return SQLITE_OK; } #endif /* @@ -71419,5 +72560,37925 @@ sqlite3_mutex_leave(db->mutex); return rc; } /************** End of main.c ************************************************/ +/****************************************************************************** +** This file is an amalgamation of separate C source files from the SQLite +** Full Text Search extension 2 (fts3). By combining all the individual C +** code files into this single large file, the entire code can be compiled +** as a one translation unit. This allows many compilers to do optimizations +** that would not be possible if the files were compiled separately. It also +** makes the code easier to import into other projects. +** +** This amalgamation was generated on 2007-11-25 16:04:39 UTC. +*/ +/************** Begin file fts3.c ********************************************/ +/* +** 2006 Oct 10 +** +** 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 is an SQLite module implementing full-text search. +*/ + +/* +** The code in this file is only compiled if: +** +** * The FTS3 module is being built as an extension +** (in which case SQLITE_CORE is not defined), or +** +** * The FTS3 module is being built into the core of +** SQLite (in which case SQLITE_ENABLE_FTS3 is defined). +*/ + +/* TODO(shess) Consider exporting this comment to an HTML file or the +** wiki. +*/ +/* The full-text index is stored in a series of b+tree (-like) +** structures called segments which map terms to doclists. The +** structures are like b+trees in layout, but are constructed from the +** bottom up in optimal fashion and are not updatable. Since trees +** are built from the bottom up, things will be described from the +** bottom up. +** +** +**** Varints **** +** The basic unit of encoding is a variable-length integer called a +** varint. We encode variable-length integers in little-endian order +** using seven bits * per byte as follows: +** +** KEY: +** A = 0xxxxxxx 7 bits of data and one flag bit +** B = 1xxxxxxx 7 bits of data and one flag bit +** +** 7 bits - A +** 14 bits - BA +** 21 bits - BBA +** and so on. +** +** This is identical to how sqlite encodes varints (see util.c). +** +** +**** Document lists **** +** A doclist (document list) holds a docid-sorted list of hits for a +** given term. Doclists hold docids, and can optionally associate +** token positions and offsets with docids. +** +** A DL_POSITIONS_OFFSETS doclist is stored like this: +** +** array { +** varint docid; +** array { (position list for column 0) +** varint position; (delta from previous position plus POS_BASE) +** varint startOffset; (delta from previous startOffset) +** varint endOffset; (delta from startOffset) +** } +** array { +** varint POS_COLUMN; (marks start of position list for new column) +** varint column; (index of new column) +** array { +** varint position; (delta from previous position plus POS_BASE) +** varint startOffset;(delta from previous startOffset) +** varint endOffset; (delta from startOffset) +** } +** } +** varint POS_END; (marks end of positions for this document. +** } +** +** Here, array { X } means zero or more occurrences of X, adjacent in +** memory. A "position" is an index of a token in the token stream +** generated by the tokenizer, while an "offset" is a byte offset, +** both based at 0. Note that POS_END and POS_COLUMN occur in the +** same logical place as the position element, and act as sentinals +** ending a position list array. +** +** A DL_POSITIONS doclist omits the startOffset and endOffset +** information. A DL_DOCIDS doclist omits both the position and +** offset information, becoming an array of varint-encoded docids. +** +** On-disk data is stored as type DL_DEFAULT, so we don't serialize +** the type. Due to how deletion is implemented in the segmentation +** system, on-disk doclists MUST store at least positions. +** +** +**** Segment leaf nodes **** +** Segment leaf nodes store terms and doclists, ordered by term. Leaf +** nodes are written using LeafWriter, and read using LeafReader (to +** iterate through a single leaf node's data) and LeavesReader (to +** iterate through a segment's entire leaf layer). Leaf nodes have +** the format: +** +** varint iHeight; (height from leaf level, always 0) +** varint nTerm; (length of first term) +** char pTerm[nTerm]; (content of first term) +** varint nDoclist; (length of term's associated doclist) +** char pDoclist[nDoclist]; (content of doclist) +** array { +** (further terms are delta-encoded) +** varint nPrefix; (length of prefix shared with previous term) +** varint nSuffix; (length of unshared suffix) +** char pTermSuffix[nSuffix];(unshared suffix of next term) +** varint nDoclist; (length of term's associated doclist) +** char pDoclist[nDoclist]; (content of doclist) +** } +** +** Here, array { X } means zero or more occurrences of X, adjacent in +** memory. +** +** Leaf nodes are broken into blocks which are stored contiguously in +** the %_segments table in sorted order. This means that when the end +** of a node is reached, the next term is in the node with the next +** greater node id. +** +** New data is spilled to a new leaf node when the current node +** exceeds LEAF_MAX bytes (default 2048). New data which itself is +** larger than STANDALONE_MIN (default 1024) is placed in a standalone +** node (a leaf node with a single term and doclist). The goal of +** these settings is to pack together groups of small doclists while +** making it efficient to directly access large doclists. The +** assumption is that large doclists represent terms which are more +** likely to be query targets. +** +** TODO(shess) It may be useful for blocking decisions to be more +** dynamic. For instance, it may make more sense to have a 2.5k leaf +** node rather than splitting into 2k and .5k nodes. My intuition is +** that this might extend through 2x or 4x the pagesize. +** +** +**** Segment interior nodes **** +** Segment interior nodes store blockids for subtree nodes and terms +** to describe what data is stored by the each subtree. Interior +** nodes are written using InteriorWriter, and read using +** InteriorReader. InteriorWriters are created as needed when +** SegmentWriter creates new leaf nodes, or when an interior node +** itself grows too big and must be split. The format of interior +** nodes: +** +** varint iHeight; (height from leaf level, always >0) +** varint iBlockid; (block id of node's leftmost subtree) +** optional { +** varint nTerm; (length of first term) +** char pTerm[nTerm]; (content of first term) +** array { +** (further terms are delta-encoded) +** varint nPrefix; (length of shared prefix with previous term) +** varint nSuffix; (length of unshared suffix) +** char pTermSuffix[nSuffix]; (unshared suffix of next term) +** } +** } +** +** Here, optional { X } means an optional element, while array { X } +** means zero or more occurrences of X, adjacent in memory. +** +** An interior node encodes n terms separating n+1 subtrees. The +** subtree blocks are contiguous, so only the first subtree's blockid +** is encoded. The subtree at iBlockid will contain all terms less +** than the first term encoded (or all terms if no term is encoded). +** Otherwise, for terms greater than or equal to pTerm[i] but less +** than pTerm[i+1], the subtree for that term will be rooted at +** iBlockid+i. Interior nodes only store enough term data to +** distinguish adjacent children (if the rightmost term of the left +** child is "something", and the leftmost term of the right child is +** "wicked", only "w" is stored). +** +** New data is spilled to a new interior node at the same height when +** the current node exceeds INTERIOR_MAX bytes (default 2048). +** INTERIOR_MIN_TERMS (default 7) keeps large terms from monopolizing +** interior nodes and making the tree too skinny. The interior nodes +** at a given height are naturally tracked by interior nodes at +** height+1, and so on. +** +** +**** Segment directory **** +** The segment directory in table %_segdir stores meta-information for +** merging and deleting segments, and also the root node of the +** segment's tree. +** +** The root node is the top node of the segment's tree after encoding +** the entire segment, restricted to ROOT_MAX bytes (default 1024). +** This could be either a leaf node or an interior node. If the top +** node requires more than ROOT_MAX bytes, it is flushed to %_segments +** and a new root interior node is generated (which should always fit +** within ROOT_MAX because it only needs space for 2 varints, the +** height and the blockid of the previous root). +** +** The meta-information in the segment directory is: +** level - segment level (see below) +** idx - index within level +** - (level,idx uniquely identify a segment) +** start_block - first leaf node +** leaves_end_block - last leaf node +** end_block - last block (including interior nodes) +** root - contents of root node +** +** If the root node is a leaf node, then start_block, +** leaves_end_block, and end_block are all 0. +** +** +**** Segment merging **** +** To amortize update costs, segments are groups into levels and +** merged in matches. Each increase in level represents exponentially +** more documents. +** +** New documents (actually, document updates) are tokenized and +** written individually (using LeafWriter) to a level 0 segment, with +** incrementing idx. When idx reaches MERGE_COUNT (default 16), all +** level 0 segments are merged into a single level 1 segment. Level 1 +** is populated like level 0, and eventually MERGE_COUNT level 1 +** segments are merged to a single level 2 segment (representing +** MERGE_COUNT^2 updates), and so on. +** +** A segment merge traverses all segments at a given level in +** parallel, performing a straightforward sorted merge. Since segment +** leaf nodes are written in to the %_segments table in order, this +** merge traverses the underlying sqlite disk structures efficiently. +** After the merge, all segment blocks from the merged level are +** deleted. +** +** MERGE_COUNT controls how often we merge segments. 16 seems to be +** somewhat of a sweet spot for insertion performance. 32 and 64 show +** very similar performance numbers to 16 on insertion, though they're +** a tiny bit slower (perhaps due to more overhead in merge-time +** sorting). 8 is about 20% slower than 16, 4 about 50% slower than +** 16, 2 about 66% slower than 16. +** +** At query time, high MERGE_COUNT increases the number of segments +** which need to be scanned and merged. For instance, with 100k docs +** inserted: +** +** MERGE_COUNT segments +** 16 25 +** 8 12 +** 4 10 +** 2 6 +** +** This appears to have only a moderate impact on queries for very +** frequent terms (which are somewhat dominated by segment merge +** costs), and infrequent and non-existent terms still seem to be fast +** even with many segments. +** +** TODO(shess) That said, it would be nice to have a better query-side +** argument for MERGE_COUNT of 16. Also, it's possible/likely that +** optimizations to things like doclist merging will swing the sweet +** spot around. +** +** +** +**** Handling of deletions and updates **** +** Since we're using a segmented structure, with no docid-oriented +** index into the term index, we clearly cannot simply update the term +** index when a document is deleted or updated. For deletions, we +** write an empty doclist (varint(docid) varint(POS_END)), for updates +** we simply write the new doclist. Segment merges overwrite older +** data for a particular docid with newer data, so deletes or updates +** will eventually overtake the earlier data and knock it out. The +** query logic likewise merges doclists so that newer data knocks out +** older data. +** +** TODO(shess) Provide a VACUUM type operation to clear out all +** deletions and duplications. This would basically be a forced merge +** into a single segment. +*/ + +#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) + +#if defined(SQLITE_ENABLE_FTS3) && !defined(SQLITE_CORE) +# define SQLITE_CORE 1 +#endif + +#include <assert.h> +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <ctype.h> + +/************** Include fts3.h in the middle of fts3.c ***********************/ +/************** Begin file fts3.h ********************************************/ +/* +** 2006 Oct 10 +** +** 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 header file is used by programs that want to link against the +** FTS3 library. All it does is declare the sqlite3Fts3Init() interface. +*/ +/************** Include sqlite3.h in the middle of fts3.h ********************/ +/************** Begin file sqlite3.h *****************************************/ +/* +** 2001 September 15 +** +** 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 header file defines the interface that the SQLite library +** presents to client programs. If a C-function, structure, datatype, +** or constant definition does not appear in this file, then it is +** not a published API of SQLite, is subject to change without +** notice, and should not be referenced by programs that use SQLite. +** +** Some of the definitions that are in this file are marked as +** "experimental". Experimental interfaces are normally new +** features recently added to SQLite. We do not anticipate changes +** to experimental interfaces but reserve to make minor changes if +** experience from use "in the wild" suggest such changes are prudent. +** +** The official C-language API documentation for SQLite is derived +** from comments in this file. This file is the authoritative source +** on how SQLite interfaces are suppose to operate. +** +** The name of this file under configuration management is "sqlite.h.in". +** The makefile makes some minor changes to this file (such as inserting +** the version number) and changes its name to "sqlite3.h" as +** part of the build process. +** +** @(#) $Id: sqlite.h.in,v 1.271 2007/11/21 15:24:01 drh Exp $ +*/ +#ifndef _SQLITE3_H_ +#define _SQLITE3_H_ +#include <stdarg.h> /* Needed for the definition of va_list */ + +/* +** Make sure we can call this stuff from C++. +*/ +#if 0 +extern "C" { +#endif + + +/* +** Add the ability to override 'extern' +*/ +#ifndef SQLITE_EXTERN +# define SQLITE_EXTERN extern +#endif + +/* +** Make sure these symbols where not defined by some previous header +** file. +*/ +#ifdef SQLITE_VERSION +# undef SQLITE_VERSION +#endif +#ifdef SQLITE_VERSION_NUMBER +# undef SQLITE_VERSION_NUMBER +#endif + +/* +** CAPI3REF: Compile-Time Library Version Numbers +** +** The version of the SQLite library is contained in the sqlite3.h +** header file in a #define named SQLITE_VERSION. The SQLITE_VERSION +** macro resolves to a string constant. +** +** The format of the version string is "X.Y.Z", where +** X is the major version number, Y is the minor version number and Z +** is the release number. The X.Y.Z might be followed by "alpha" or "beta". +** For example "3.1.1beta". +** +** The X value is always 3 in SQLite. The X value only changes when +** backwards compatibility is broken and we intend to never break +** backwards compatibility. The Y value only changes when +** there are major feature enhancements that are forwards compatible +** but not backwards compatible. The Z value is incremented with +** each release but resets back to 0 when Y is incremented. +** +** The SQLITE_VERSION_NUMBER is an integer with the value +** (X*1000000 + Y*1000 + Z). For example, for version "3.1.1beta", +** SQLITE_VERSION_NUMBER is set to 3001001. To detect if they are using +** version 3.1.1 or greater at compile time, programs may use the test +** (SQLITE_VERSION_NUMBER>=3001001). +** +** See also: [sqlite3_libversion()] and [sqlite3_libversion_number()]. +*/ +#define SQLITE_VERSION "3.5.2" +#define SQLITE_VERSION_NUMBER 3005002 + +/* +** CAPI3REF: Run-Time Library Version Numbers +** +** These routines return values equivalent to the header constants +** [SQLITE_VERSION] and [SQLITE_VERSION_NUMBER]. The values returned +** by this routines should only be different from the header values +** if you compile your program using an sqlite3.h header from a +** different version of SQLite that the version of the library you +** link against. +** +** The sqlite3_version[] string constant contains the text of the +** [SQLITE_VERSION] string. The sqlite3_libversion() function returns +** a poiner to the sqlite3_version[] string constant. The function +** is provided for DLL users who can only access functions and not +** constants within the DLL. +*/ +SQLITE_EXTERN const char sqlite3_version[]; +const char *sqlite3_libversion(void); +int sqlite3_libversion_number(void); + +/* +** CAPI3REF: Test To See If The Library Is Threadsafe +** +** This routine returns TRUE (nonzero) if SQLite was compiled with +** all of its mutexes enabled and is thus threadsafe. It returns +** zero if the particular build is for single-threaded operation +** only. +** +** Really all this routine does is return true if SQLite was compiled +** with the -DSQLITE_THREADSAFE=1 option and false if +** compiled with -DSQLITE_THREADSAFE=0. If SQLite uses an +** application-defined mutex subsystem, malloc subsystem, collating +** sequence, VFS, SQL function, progress callback, commit hook, +** extension, or other accessories and these add-ons are not +** threadsafe, then clearly the combination will not be threadsafe +** either. Hence, this routine never reports that the library +** is guaranteed to be threadsafe, only when it is guaranteed not +** to be. +** +** This is an experimental API and may go away or change in future +** releases. +*/ +int sqlite3_threadsafe(void); + +/* +** CAPI3REF: Database Connection Handle +** +** Each open SQLite database is represented by pointer to an instance of the +** opaque structure named "sqlite3". It is useful to think of an sqlite3 +** pointer as an object. The [sqlite3_open()], [sqlite3_open16()], and +** [sqlite3_open_v2()] interfaces are its constructors +** and [sqlite3_close()] is its destructor. There are many other interfaces +** (such as [sqlite3_prepare_v2()], [sqlite3_create_function()], and +** [sqlite3_busy_timeout()] to name but three) that are methods on this +** object. +*/ +typedef struct sqlite3 sqlite3; + + +/* +** CAPI3REF: 64-Bit Integer Types +** +** Some compilers do not support the "long long" datatype. So we have +** to do compiler-specific typedefs for 64-bit signed and unsigned integers. +** +** Many SQLite interface functions require a 64-bit integer arguments. +** Those interfaces are declared using this typedef. +*/ +#ifdef SQLITE_INT64_TYPE + typedef SQLITE_INT64_TYPE sqlite_int64; + typedef unsigned SQLITE_INT64_TYPE sqlite_uint64; +#elif defined(_MSC_VER) || defined(__BORLANDC__) + typedef __int64 sqlite_int64; + typedef unsigned __int64 sqlite_uint64; +#else + typedef long long int sqlite_int64; + typedef unsigned long long int sqlite_uint64; +#endif +typedef sqlite_int64 sqlite3_int64; +typedef sqlite_uint64 sqlite3_uint64; + +/* +** If compiling for a processor that lacks floating point support, +** substitute integer for floating-point +*/ +#ifdef SQLITE_OMIT_FLOATING_POINT +# define double sqlite3_int64 +#endif + +/* +** CAPI3REF: Closing A Database Connection +** +** Call this function with a pointer to a structure that was previously +** returned from [sqlite3_open()], [sqlite3_open16()], or +** [sqlite3_open_v2()] and the corresponding database will by +** closed. +** +** All SQL statements prepared using [sqlite3_prepare_v2()] or +** [sqlite3_prepare16_v2()] must be destroyed using [sqlite3_finalize()] +** before this routine is called. Otherwise, SQLITE_BUSY is returned and the +** database connection remains open. +** +** Passing this routine a database connection that has already been +** closed results in undefined behavior. If other interfaces that +** reference the same database connection are pending (either in the +** same thread or in different threads) when this routine is called, +** then the behavior is undefined and is almost certainly undesirable. +*/ +int sqlite3_close(sqlite3 *); + +/* +** The type for a callback function. +** This is legacy and deprecated. It is included for historical +** compatibility and is not documented. +*/ +typedef int (*sqlite3_callback)(void*,int,char**, char**); + +/* +** CAPI3REF: One-Step Query Execution Interface +** +** This interface is used to do a one-time evaluatation of zero +** or more SQL statements. UTF-8 text of the SQL statements to +** be evaluted is passed in as the second parameter. The statements +** are prepared one by one using [sqlite3_prepare()], evaluated +** using [sqlite3_step()], then destroyed using [sqlite3_finalize()]. +** +** If one or more of the SQL statements are queries, then +** the callback function specified by the 3rd parameter is +** invoked once for each row of the query result. This callback +** should normally return 0. If the callback returns a non-zero +** value then the query is aborted, all subsequent SQL statements +** are skipped and the sqlite3_exec() function returns the [SQLITE_ABORT]. +** +** The 4th parameter to this interface is an arbitrary pointer that is +** passed through to the callback function as its first parameter. +** +** The 2nd parameter to the callback function is the number of +** columns in the query result. The 3rd parameter to the callback +** is an array of strings holding the values for each column +** as extracted using [sqlite3_column_text()]. +** The 4th parameter to the callback is an array of strings +** obtained using [sqlite3_column_name()] and holding +** the names of each column. +** +** The callback function may be NULL, even for queries. A NULL +** callback is not an error. It just means that no callback +** will be invoked. +** +** If an error occurs while parsing or evaluating the SQL (but +** not while executing the callback) then an appropriate error +** message is written into memory obtained from [sqlite3_malloc()] and +** *errmsg is made to point to that message. The calling function +** is responsible for freeing the memory using [sqlite3_free()]. +** If errmsg==NULL, then no error message is ever written. +** +** The return value is is SQLITE_OK if there are no errors and +** some other [SQLITE_OK | return code] if there is an error. +** The particular return value depends on the type of error. +** +*/ +int sqlite3_exec( + sqlite3*, /* An open database */ + const char *sql, /* SQL to be evaluted */ + int (*callback)(void*,int,char**,char**), /* Callback function */ + void *, /* 1st argument to callback */ + char **errmsg /* Error msg written here */ +); + +/* +** CAPI3REF: Result Codes +** KEYWORDS: SQLITE_OK +** +** Many SQLite functions return an integer result code from the set shown +** above in order to indicates success or failure. +** +** The result codes above are the only ones returned by SQLite in its +** default configuration. However, the [sqlite3_extended_result_codes()] +** API can be used to set a database connectoin to return more detailed +** result codes. +** +** See also: [SQLITE_IOERR_READ | extended result codes] +** +*/ +#define SQLITE_OK 0 /* Successful result */ +/* beginning-of-error-codes */ +#define SQLITE_ERROR 1 /* SQL error or missing database */ +#define SQLITE_INTERNAL 2 /* NOT USED. Internal logic error in SQLite */ +#define SQLITE_PERM 3 /* Access permission denied */ +#define SQLITE_ABORT 4 /* Callback routine requested an abort */ +#define SQLITE_BUSY 5 /* The database file is locked */ +#define SQLITE_LOCKED 6 /* A table in the database is locked */ +#define SQLITE_NOMEM 7 /* A malloc() failed */ +#define SQLITE_READONLY 8 /* Attempt to write a readonly database */ +#define SQLITE_INTERRUPT 9 /* Operation terminated by sqlite3_interrupt()*/ +#define SQLITE_IOERR 10 /* Some kind of disk I/O error occurred */ +#define SQLITE_CORRUPT 11 /* The database disk image is malformed */ +#define SQLITE_NOTFOUND 12 /* NOT USED. Table or record not found */ +#define SQLITE_FULL 13 /* Insertion failed because database is full */ +#define SQLITE_CANTOPEN 14 /* Unable to open the database file */ +#define SQLITE_PROTOCOL 15 /* NOT USED. Database lock protocol error */ +#define SQLITE_EMPTY 16 /* Database is empty */ +#define SQLITE_SCHEMA 17 /* The database schema changed */ +#define SQLITE_TOOBIG 18 /* String or BLOB exceeds size limit */ +#define SQLITE_CONSTRAINT 19 /* Abort due to constraint violation */ +#define SQLITE_MISMATCH 20 /* Data type mismatch */ +#define SQLITE_MISUSE 21 /* Library used incorrectly */ +#define SQLITE_NOLFS 22 /* Uses OS features not supported on host */ +#define SQLITE_AUTH 23 /* Authorization denied */ +#define SQLITE_FORMAT 24 /* Auxiliary database format error */ +#define SQLITE_RANGE 25 /* 2nd parameter to sqlite3_bind out of range */ +#define SQLITE_NOTADB 26 /* File opened that is not a database file */ +#define SQLITE_ROW 100 /* sqlite3_step() has another row ready */ +#define SQLITE_DONE 101 /* sqlite3_step() has finished executing */ +/* end-of-error-codes */ + +/* +** CAPI3REF: Extended Result Codes +** +** In its default configuration, SQLite API routines return one of 26 integer +** result codes described at result-codes. However, experience has shown that +** many of these result codes are too course-grained. They do not provide as +** much information about problems as users might like. In an effort to +** address this, newer versions of SQLite (version 3.3.8 and later) include +** support for additional result codes that provide more detailed information +** about errors. The extended result codes are enabled (or disabled) for +** each database +** connection using the [sqlite3_extended_result_codes()] API. +** +** Some of the available extended result codes are listed above. +** We expect the number of extended result codes will be expand +** over time. Software that uses extended result codes should expect +** to see new result codes in future releases of SQLite. +** +** The symbolic name for an extended result code always contains a related +** primary result code as a prefix. Primary result codes contain a single +** "_" character. Extended result codes contain two or more "_" characters. +** The numeric value of an extended result code can be converted to its +** corresponding primary result code by masking off the lower 8 bytes. +** +** The SQLITE_OK result code will never be extended. It will always +** be exactly zero. +*/ +#define SQLITE_IOERR_READ (SQLITE_IOERR | (1<<8)) +#define SQLITE_IOERR_SHORT_READ (SQLITE_IOERR | (2<<8)) +#define SQLITE_IOERR_WRITE (SQLITE_IOERR | (3<<8)) +#define SQLITE_IOERR_FSYNC (SQLITE_IOERR | (4<<8)) +#define SQLITE_IOERR_DIR_FSYNC (SQLITE_IOERR | (5<<8)) +#define SQLITE_IOERR_TRUNCATE (SQLITE_IOERR | (6<<8)) +#define SQLITE_IOERR_FSTAT (SQLITE_IOERR | (7<<8)) +#define SQLITE_IOERR_UNLOCK (SQLITE_IOERR | (8<<8)) +#define SQLITE_IOERR_RDLOCK (SQLITE_IOERR | (9<<8)) +#define SQLITE_IOERR_DELETE (SQLITE_IOERR | (10<<8)) +#define SQLITE_IOERR_BLOCKED (SQLITE_IOERR | (11<<8)) +#define SQLITE_IOERR_NOMEM (SQLITE_IOERR | (12<<8)) + +/* +** CAPI3REF: Flags For File Open Operations +** +** Combination of the following bit values are used as the +** third argument to the [sqlite3_open_v2()] interface and +** as fourth argument to the xOpen method of the +** [sqlite3_vfs] object. +** +*/ +#define SQLITE_OPEN_READONLY 0x00000001 +#define SQLITE_OPEN_READWRITE 0x00000002 +#define SQLITE_OPEN_CREATE 0x00000004 +#define SQLITE_OPEN_DELETEONCLOSE 0x00000008 +#define SQLITE_OPEN_EXCLUSIVE 0x00000010 +#define SQLITE_OPEN_MAIN_DB 0x00000100 +#define SQLITE_OPEN_TEMP_DB 0x00000200 +#define SQLITE_OPEN_TRANSIENT_DB 0x00000400 +#define SQLITE_OPEN_MAIN_JOURNAL 0x00000800 +#define SQLITE_OPEN_TEMP_JOURNAL 0x00001000 +#define SQLITE_OPEN_SUBJOURNAL 0x00002000 +#define SQLITE_OPEN_MASTER_JOURNAL 0x00004000 + +/* +** CAPI3REF: Device Characteristics +** +** The xDeviceCapabilities method of the [sqlite3_io_methods] +** object returns an integer which is a vector of the following +** bit values expressing I/O characteristics of the mass storage +** device that holds the file that the [sqlite3_io_methods] +** refers to. +** +** The SQLITE_IOCAP_ATOMIC property means that all writes of +** any size are atomic. The SQLITE_IOCAP_ATOMICnnn values +** mean that writes of blocks that are nnn bytes in size and +** are aligned to an address which is an integer multiple of +** nnn are atomic. The SQLITE_IOCAP_SAFE_APPEND value means +** that when data is appended to a file, the data is appended +** first then the size of the file is extended, never the other +** way around. The SQLITE_IOCAP_SEQUENTIAL property means that +** information is written to disk in the same order as calls +** to xWrite(). +*/ +#define SQLITE_IOCAP_ATOMIC 0x00000001 +#define SQLITE_IOCAP_ATOMIC512 0x00000002 +#define SQLITE_IOCAP_ATOMIC1K 0x00000004 +#define SQLITE_IOCAP_ATOMIC2K 0x00000008 +#define SQLITE_IOCAP_ATOMIC4K 0x00000010 +#define SQLITE_IOCAP_ATOMIC8K 0x00000020 +#define SQLITE_IOCAP_ATOMIC16K 0x00000040 +#define SQLITE_IOCAP_ATOMIC32K 0x00000080 +#define SQLITE_IOCAP_ATOMIC64K 0x00000100 +#define SQLITE_IOCAP_SAFE_APPEND 0x00000200 +#define SQLITE_IOCAP_SEQUENTIAL 0x00000400 + +/* +** CAPI3REF: File Locking Levels +** +** SQLite uses one of the following integer values as the second +** argument to calls it makes to the xLock() and xUnlock() methods +** of an [sqlite3_io_methods] object. +*/ +#define SQLITE_LOCK_NONE 0 +#define SQLITE_LOCK_SHARED 1 +#define SQLITE_LOCK_RESERVED 2 +#define SQLITE_LOCK_PENDING 3 +#define SQLITE_LOCK_EXCLUSIVE 4 + +/* +** CAPI3REF: Synchronization Type Flags +** +** When SQLite invokes the xSync() method of an [sqlite3_io_methods] +** object it uses a combination of the following integer values as +** the second argument. +** +** When the SQLITE_SYNC_DATAONLY flag is used, it means that the +** sync operation only needs to flush data to mass storage. Inode +** information need not be flushed. The SQLITE_SYNC_NORMAL means +** to use normal fsync() semantics. The SQLITE_SYNC_FULL flag means +** to use Mac OS-X style fullsync instead of fsync(). +*/ +#define SQLITE_SYNC_NORMAL 0x00002 +#define SQLITE_SYNC_FULL 0x00003 +#define SQLITE_SYNC_DATAONLY 0x00010 + + +/* +** CAPI3REF: OS Interface Open File Handle +** +** An [sqlite3_file] object represents an open file in the OS +** interface layer. Individual OS interface implementations will +** want to subclass this object by appending additional fields +** for their own use. The pMethods entry is a pointer to an +** [sqlite3_io_methods] object that defines methods for performing +** I/O operations on the open file. +*/ +typedef struct sqlite3_file sqlite3_file; +struct sqlite3_file { + const struct sqlite3_io_methods *pMethods; /* Methods for an open file */ +}; + +/* +** CAPI3REF: OS Interface File Virtual Methods Object +** +** Every file opened by the [sqlite3_vfs] xOpen method contains a pointer to +** an instance of the this object. This object defines the +** methods used to perform various operations against the open file. +** +** The flags argument to xSync may be one of [SQLITE_SYNC_NORMAL] or +** [SQLITE_SYNC_FULL]. The first choice is the normal fsync(). +* The second choice is an +** OS-X style fullsync. The SQLITE_SYNC_DATA flag may be ORed in to +** indicate that only the data of the file and not its inode needs to be +** synced. +** +** The integer values to xLock() and xUnlock() are one of +** <ul> +** <li> [SQLITE_LOCK_NONE], +** <li> [SQLITE_LOCK_SHARED], +** <li> [SQLITE_LOCK_RESERVED], +** <li> [SQLITE_LOCK_PENDING], or +** <li> [SQLITE_LOCK_EXCLUSIVE]. +** </ul> +** xLock() increases the lock. xUnlock() decreases the lock. +** The xCheckReservedLock() method looks +** to see if any database connection, either in this +** process or in some other process, is holding an RESERVED, +** PENDING, or EXCLUSIVE lock on the file. It returns true +** if such a lock exists and false if not. +** +** The xFileControl() method is a generic interface that allows custom +** VFS implementations to directly control an open file using the +** [sqlite3_file_control()] interface. The second "op" argument +** is an integer opcode. The third +** argument is a generic pointer which is intended to be a pointer +** to a structure that may contain arguments or space in which to +** write return values. Potential uses for xFileControl() might be +** functions to enable blocking locks with timeouts, to change the +** locking strategy (for example to use dot-file locks), to inquire +** about the status of a lock, or to break stale locks. The SQLite +** core reserves opcodes less than 100 for its own use. +** A [SQLITE_FCNTL_LOCKSTATE | list of opcodes] less than 100 is available. +** Applications that define a custom xFileControl method should use opcodes +** greater than 100 to avoid conflicts. +** +** The xSectorSize() method returns the sector size of the +** device that underlies the file. The sector size is the +** minimum write that can be performed without disturbing +** other bytes in the file. The xDeviceCharacteristics() +** method returns a bit vector describing behaviors of the +** underlying device: +** +** <ul> +** <li> [SQLITE_IOCAP_ATOMIC] +** <li> [SQLITE_IOCAP_ATOMIC512] +** <li> [SQLITE_IOCAP_ATOMIC1K] +** <li> [SQLITE_IOCAP_ATOMIC2K] +** <li> [SQLITE_IOCAP_ATOMIC4K] +** <li> [SQLITE_IOCAP_ATOMIC8K] +** <li> [SQLITE_IOCAP_ATOMIC16K] +** <li> [SQLITE_IOCAP_ATOMIC32K] +** <li> [SQLITE_IOCAP_ATOMIC64K] +** <li> [SQLITE_IOCAP_SAFE_APPEND] +** <li> [SQLITE_IOCAP_SEQUENTIAL] +** </ul> +** +** The SQLITE_IOCAP_ATOMIC property means that all writes of +** any size are atomic. The SQLITE_IOCAP_ATOMICnnn values +** mean that writes of blocks that are nnn bytes in size and +** are aligned to an address which is an integer multiple of +** nnn are atomic. The SQLITE_IOCAP_SAFE_APPEND value means +** that when data is appended to a file, the data is appended +** first then the size of the file is extended, never the other +** way around. The SQLITE_IOCAP_SEQUENTIAL property means that +** information is written to disk in the same order as calls +** to xWrite(). +*/ +typedef struct sqlite3_io_methods sqlite3_io_methods; +struct sqlite3_io_methods { + int iVersion; + int (*xClose)(sqlite3_file*); + int (*xRead)(sqlite3_file*, void*, int iAmt, sqlite3_int64 iOfst); + int (*xWrite)(sqlite3_file*, const void*, int iAmt, sqlite3_int64 iOfst); + int (*xTruncate)(sqlite3_file*, sqlite3_int64 size); + int (*xSync)(sqlite3_file*, int flags); + int (*xFileSize)(sqlite3_file*, sqlite3_int64 *pSize); + int (*xLock)(sqlite3_file*, int); + int (*xUnlock)(sqlite3_file*, int); + int (*xCheckReservedLock)(sqlite3_file*); + int (*xFileControl)(sqlite3_file*, int op, void *pArg); + int (*xSectorSize)(sqlite3_file*); + int (*xDeviceCharacteristics)(sqlite3_file*); + /* Additional methods may be added in future releases */ +}; + +/* +** CAPI3REF: Standard File Control Opcodes +** +** These integer constants are opcodes for the xFileControl method +** of the [sqlite3_io_methods] object and to the [sqlite3_file_control()] +** interface. +** +** The [SQLITE_FCNTL_LOCKSTATE] opcode is used for debugging. This +** opcode cases the xFileControl method to write the current state of +** the lock (one of [SQLITE_LOCK_NONE], [SQLITE_LOCK_SHARED], +** [SQLITE_LOCK_RESERVED], [SQLITE_LOCK_PENDING], or [SQLITE_LOCK_EXCLUSIVE]) +** into an integer that the pArg argument points to. This capability +** is used during testing and only needs to be supported when SQLITE_TEST +** is defined. +*/ +#define SQLITE_FCNTL_LOCKSTATE 1 + +/* +** CAPI3REF: Mutex Handle +** +** The mutex module within SQLite defines [sqlite3_mutex] to be an +** abstract type for a mutex object. The SQLite core never looks +** at the internal representation of an [sqlite3_mutex]. It only +** deals with pointers to the [sqlite3_mutex] object. +** +** Mutexes are created using [sqlite3_mutex_alloc()]. +*/ +typedef struct sqlite3_mutex sqlite3_mutex; + +/* +** CAPI3REF: OS Interface Object +** +** An instance of this object defines the interface between the +** SQLite core and the underlying operating system. The "vfs" +** in the name of the object stands for "virtual file system". +** +** The iVersion field is initially 1 but may be larger for future +** versions of SQLite. Additional fields may be appended to this +** object when the iVersion value is increased. +** +** The szOsFile field is the size of the subclassed [sqlite3_file] +** structure used by this VFS. mxPathname is the maximum length of +** a pathname in this VFS. +** +** Registered vfs modules are kept on a linked list formed by +** the pNext pointer. The [sqlite3_vfs_register()] +** and [sqlite3_vfs_unregister()] interfaces manage this list +** in a thread-safe way. The [sqlite3_vfs_find()] interface +** searches the list. +** +** The pNext field is the only fields in the sqlite3_vfs +** structure that SQLite will ever modify. SQLite will only access +** or modify this field while holding a particular static mutex. +** The application should never modify anything within the sqlite3_vfs +** object once the object has been registered. +** +** The zName field holds the name of the VFS module. The name must +** be unique across all VFS modules. +** +** SQLite will guarantee that the zFilename string passed to +** xOpen() is a full pathname as generated by xFullPathname() and +** that the string will be valid and unchanged until xClose() is +** called. So the [sqlite3_file] can store a pointer to the +** filename if it needs to remember the filename for some reason. +** +** The flags argument to xOpen() is a copy of the flags argument +** to [sqlite3_open_v2()]. If [sqlite3_open()] or [sqlite3_open16()] +** is used, then flags is [SQLITE_OPEN_READWRITE] | [SQLITE_OPEN_CREATE]. +** If xOpen() opens a file read-only then it sets *pOutFlags to +** include [SQLITE_OPEN_READONLY]. Other bits in *pOutFlags may be +** set. +** +** SQLite will also add one of the following flags to the xOpen() +** call, depending on the object being opened: +** +** <ul> +** <li> [SQLITE_OPEN_MAIN_DB] +** <li> [SQLITE_OPEN_MAIN_JOURNAL] +** <li> [SQLITE_OPEN_TEMP_DB] +** <li> [SQLITE_OPEN_TEMP_JOURNAL] +** <li> [SQLITE_OPEN_TRANSIENT_DB] +** <li> [SQLITE_OPEN_SUBJOURNAL] +** <li> [SQLITE_OPEN_MASTER_JOURNAL] +** </ul> +** +** The file I/O implementation can use the object type flags to +** changes the way it deals with files. For example, an application +** that does not care about crash recovery or rollback, might make +** the open of a journal file a no-op. Writes to this journal are +** also a no-op. Any attempt to read the journal return SQLITE_IOERR. +** Or the implementation might recognize the a database file will +** be doing page-aligned sector reads and writes in a random order +** and set up its I/O subsystem accordingly. +** +** SQLite might also add one of the following flags to the xOpen +** method: +** +** <ul> +** <li> [SQLITE_OPEN_DELETEONCLOSE] +** <li> [SQLITE_OPEN_EXCLUSIVE] +** </ul> +** +** The [SQLITE_OPEN_DELETEONCLOSE] flag means the file should be +** deleted when it is closed. This will always be set for TEMP +** databases and journals and for subjournals. The +** [SQLITE_OPEN_EXCLUSIVE] flag means the file should be opened +** for exclusive access. This flag is set for all files except +** for the main database file. +** +** Space to hold the [sqlite3_file] structure passed as the third +** argument to xOpen is allocated by caller (the SQLite core). +** szOsFile bytes are allocated for this object. The xOpen method +** fills in the allocated space. +** +** The flags argument to xAccess() may be [SQLITE_ACCESS_EXISTS] +** to test for the existance of a file, +** or [SQLITE_ACCESS_READWRITE] to test to see +** if a file is readable and writable, or [SQLITE_ACCESS_READ] +** to test to see if a file is at least readable. The file can be a +** directory. +** +** SQLite will always allocate at least mxPathname+1 byte for +** the output buffers for xGetTempname and xFullPathname. The exact +** size of the output buffer is also passed as a parameter to both +** methods. If the output buffer is not large enough, SQLITE_CANTOPEN +** should be returned. As this is handled as a fatal error by SQLite, +** vfs implementations should endevour to prevent this by setting +** mxPathname to a sufficiently large value. +** +** The xRandomness(), xSleep(), and xCurrentTime() interfaces +** are not strictly a part of the filesystem, but they are +** included in the VFS structure for completeness. +** The xRandomness() function attempts to return nBytes bytes +** of good-quality randomness into zOut. The return value is +** the actual number of bytes of randomness obtained. The +** xSleep() method cause the calling thread to sleep for at +** least the number of microseconds given. The xCurrentTime() +** method returns a Julian Day Number for the current date and +** time. +*/ +typedef struct sqlite3_vfs sqlite3_vfs; +struct sqlite3_vfs { + int iVersion; /* Structure version number */ + int szOsFile; /* Size of subclassed sqlite3_file */ + int mxPathname; /* Maximum file pathname length */ + sqlite3_vfs *pNext; /* Next registered VFS */ + const char *zName; /* Name of this virtual file system */ + void *pAppData; /* Pointer to application-specific data */ + int (*xOpen)(sqlite3_vfs*, const char *zName, sqlite3_file*, + int flags, int *pOutFlags); + int (*xDelete)(sqlite3_vfs*, const char *zName, int syncDir); + int (*xAccess)(sqlite3_vfs*, const char *zName, int flags); + int (*xGetTempname)(sqlite3_vfs*, int nOut, char *zOut); + int (*xFullPathname)(sqlite3_vfs*, const char *zName, int nOut, char *zOut); + void *(*xDlOpen)(sqlite3_vfs*, const char *zFilename); + void (*xDlError)(sqlite3_vfs*, int nByte, char *zErrMsg); + void *(*xDlSym)(sqlite3_vfs*,void*, const char *zSymbol); + void (*xDlClose)(sqlite3_vfs*, void*); + int (*xRandomness)(sqlite3_vfs*, int nByte, char *zOut); + int (*xSleep)(sqlite3_vfs*, int microseconds); + int (*xCurrentTime)(sqlite3_vfs*, double*); + /* New fields may be appended in figure versions. The iVersion + ** value will increment whenever this happens. */ +}; + +/* +** CAPI3REF: Flags for the xAccess VFS method +** +** These integer constants can be used as the third parameter to +** the xAccess method of an [sqlite3_vfs] object. They determine +** the kind of what kind of permissions the xAccess method is +** looking for. With SQLITE_ACCESS_EXISTS, the xAccess method +** simply checks to see if the file exists. With SQLITE_ACCESS_READWRITE, +** the xAccess method checks to see if the file is both readable +** and writable. With SQLITE_ACCESS_READ the xAccess method +** checks to see if the file is readable. +*/ +#define SQLITE_ACCESS_EXISTS 0 +#define SQLITE_ACCESS_READWRITE 1 +#define SQLITE_ACCESS_READ 2 + +/* +** CAPI3REF: Enable Or Disable Extended Result Codes +** +** This routine enables or disables the +** [SQLITE_IOERR_READ | extended result codes] feature. +** By default, SQLite API routines return one of only 26 integer +** [SQLITE_OK | result codes]. When extended result codes +** are enabled by this routine, the repetoire of result codes can be +** much larger and can (hopefully) provide more detailed information +** about the cause of an error. +** +** The second argument is a boolean value that turns extended result +** codes on and off. Extended result codes are off by default for +** backwards compatibility with older versions of SQLite. +*/ +int sqlite3_extended_result_codes(sqlite3*, int onoff); + +/* +** CAPI3REF: Last Insert Rowid +** +** Each entry in an SQLite table has a unique 64-bit signed integer key +** called the "rowid". The rowid is always available as an undeclared +** column named ROWID, OID, or _ROWID_. If the table has a column of +** type INTEGER PRIMARY KEY then that column is another an alias for the +** rowid. +** +** This routine returns the rowid of the most recent successful INSERT into +** the database from the database connection given in the first +** argument. If no successful inserts have ever occurred on this database +** connection, zero is returned. +** +** If an INSERT occurs within a trigger, then the rowid of the +** inserted row is returned by this routine as long as the trigger +** is running. But once the trigger terminates, the value returned +** by this routine reverts to the last value inserted before the +** trigger fired. +** +** An INSERT that fails due to a constraint violation is not a +** successful insert and does not change the value returned by this +** routine. Thus INSERT OR FAIL, INSERT OR IGNORE, INSERT OR ROLLBACK, +** and INSERT OR ABORT make no changes to the return value of this +** routine when their insertion fails. When INSERT OR REPLACE +** encounters a constraint violation, it does not fail. The +** INSERT continues to completion after deleting rows that caused +** the constraint problem so INSERT OR REPLACE will always change +** the return value of this interface. +** +** If another thread does a new insert on the same database connection +** while this routine is running and thus changes the last insert rowid, +** then the return value of this routine is undefined. +*/ +sqlite3_int64 sqlite3_last_insert_rowid(sqlite3*); + +/* +** CAPI3REF: Count The Number Of Rows Modified +** +** This function returns the number of database rows that were changed +** (or inserted or deleted) by the most recent SQL statement. Only +** changes that are directly specified by the INSERT, UPDATE, or +** DELETE statement are counted. Auxiliary changes caused by +** triggers are not counted. Use the [sqlite3_total_changes()] function +** to find the total number of changes including changes caused by triggers. +** +** Within the body of a trigger, the sqlite3_changes() interface can be +** called to find the number of +** changes in the most recently completed INSERT, UPDATE, or DELETE +** statement within the body of the trigger. +** +** All changes are counted, even if they were later undone by a +** ROLLBACK or ABORT. Except, changes associated with creating and +** dropping tables are not counted. +** +** If a callback invokes [sqlite3_exec()] or [sqlite3_step()] recursively, +** then the changes in the inner, recursive call are counted together +** with the changes in the outer call. +** +** SQLite implements the command "DELETE FROM table" without a WHERE clause +** by dropping and recreating the table. (This is much faster than going +** through and deleting individual elements from the table.) Because of +** this optimization, the change count for "DELETE FROM table" will be +** zero regardless of the number of elements that were originally in the +** table. To get an accurate count of the number of rows deleted, use +** "DELETE FROM table WHERE 1" instead. +** +** If another thread makes changes on the same database connection +** while this routine is running then the return value of this routine +** is undefined. +*/ +int sqlite3_changes(sqlite3*); + +/* +** CAPI3REF: Total Number Of Rows Modified +*** +** This function returns the number of database rows that have been +** modified by INSERT, UPDATE or DELETE statements since the database handle +** was opened. This includes UPDATE, INSERT and DELETE statements executed +** as part of trigger programs. All changes are counted as soon as the +** statement that makes them is completed (when the statement handle is +** passed to [sqlite3_reset()] or [sqlite3_finalize()]). +** +** See also the [sqlite3_change()] interface. +** +** SQLite implements the command "DELETE FROM table" without a WHERE clause +** by dropping and recreating the table. (This is much faster than going +** through and deleting individual elements form the table.) Because of +** this optimization, the change count for "DELETE FROM table" will be +** zero regardless of the number of elements that were originally in the +** table. To get an accurate count of the number of rows deleted, use +** "DELETE FROM table WHERE 1" instead. +** +** If another thread makes changes on the same database connection +** while this routine is running then the return value of this routine +** is undefined. +*/ +int sqlite3_total_changes(sqlite3*); + +/* +** CAPI3REF: Interrupt A Long-Running Query +** +** This function causes any pending database operation to abort and +** return at its earliest opportunity. This routine is typically +** called in response to a user action such as pressing "Cancel" +** or Ctrl-C where the user wants a long query operation to halt +** immediately. +** +** It is safe to call this routine from a thread different from the +** thread that is currently running the database operation. But it +** is not safe to call this routine with a database connection that +** is closed or might close before sqlite3_interrupt() returns. +** +** The SQL operation that is interrupted will return [SQLITE_INTERRUPT]. +** If an interrupted operation was an update that is inside an +** explicit transaction, then the entire transaction will be rolled +** back automatically. +*/ +void sqlite3_interrupt(sqlite3*); + +/* +** CAPI3REF: Determine If An SQL Statement Is Complete +** +** These functions return true if the given input string comprises +** one or more complete SQL statements. For the sqlite3_complete() call, +** the parameter must be a nul-terminated UTF-8 string. For +** sqlite3_complete16(), a nul-terminated machine byte order UTF-16 string +** is required. +** +** These routines are useful for command-line input to determine if the +** currently entered text forms one or more complete SQL statements or +** if additional input is needed before sending the statements into +** SQLite for parsing. The algorithm is simple. If the +** last token other than spaces and comments is a semicolon, then return +** true. Actually, the algorithm is a little more complicated than that +** in order to deal with triggers, but the basic idea is the same: the +** statement is not complete unless it ends in a semicolon. +*/ +int sqlite3_complete(const char *sql); +int sqlite3_complete16(const void *sql); + +/* +** CAPI3REF: Register A Callback To Handle SQLITE_BUSY Errors +** +** This routine identifies a callback function that might be invoked +** whenever an attempt is made to open a database table +** that another thread or process has locked. +** If the busy callback is NULL, then [SQLITE_BUSY] +** (or sometimes [SQLITE_IOERR_BLOCKED]) +** is returned immediately upon encountering the lock. +** If the busy callback is not NULL, then the +** callback will be invoked with two arguments. The +** first argument to the handler is a copy of the void* pointer which +** is the third argument to this routine. The second argument to +** the handler is the number of times that the busy handler has +** been invoked for this locking event. If the +** busy callback returns 0, then no additional attempts are made to +** access the database and [SQLITE_BUSY] or [SQLITE_IOERR_BLOCKED] is returned. +** If the callback returns non-zero, then another attempt is made to open the +** database for reading and the cycle repeats. +** +** The presence of a busy handler does not guarantee that +** it will be invoked when there is lock contention. +** If SQLite determines that invoking the busy handler could result in +** a deadlock, it will return [SQLITE_BUSY] instead. +** Consider a scenario where one process is holding a read lock that +** it is trying to promote to a reserved lock and +** a second process is holding a reserved lock that it is trying +** to promote to an exclusive lock. The first process cannot proceed +** because it is blocked by the second and the second process cannot +** proceed because it is blocked by the first. If both processes +** invoke the busy handlers, neither will make any progress. Therefore, +** SQLite returns [SQLITE_BUSY] for the first process, hoping that this +** will induce the first process to release its read lock and allow +** the second process to proceed. +** +** The default busy callback is NULL. +** +** The [SQLITE_BUSY] error is converted to [SQLITE_IOERR_BLOCKED] when +** SQLite is in the middle of a large transaction where all the +** changes will not fit into the in-memory cache. SQLite will +** already hold a RESERVED lock on the database file, but it needs +** to promote this lock to EXCLUSIVE so that it can spill cache +** pages into the database file without harm to concurrent +** readers. If it is unable to promote the lock, then the in-memory +** cache will be left in an inconsistent state and so the error +** code is promoted from the relatively benign [SQLITE_BUSY] to +** the more severe [SQLITE_IOERR_BLOCKED]. This error code promotion +** forces an automatic rollback of the changes. See the +** <a href="http://www.sqlite.org/cvstrac/wiki?p=CorruptionFollowingBusyError"> +** CorruptionFollowingBusyError</a> wiki page for a discussion of why +** this is important. +** +** Sqlite is re-entrant, so the busy handler may start a new query. +** (It is not clear why anyone would every want to do this, but it +** is allowed, in theory.) But the busy handler may not close the +** database. Closing the database from a busy handler will delete +** data structures out from under the executing query and will +** probably result in a segmentation fault or other runtime error. +** +** There can only be a single busy handler defined for each database +** connection. Setting a new busy handler clears any previous one. +** Note that calling [sqlite3_busy_timeout()] will also set or clear +** the busy handler. +** +** When operating in [sqlite3_enable_shared_cache | shared cache mode], +** only a single busy handler can be defined for each database file. +** So if two database connections share a single cache, then changing +** the busy handler on one connection will also change the busy +** handler in the other connection. The busy handler is invoked +** in the thread that was running when the SQLITE_BUSY was hit. +*/ +int sqlite3_busy_handler(sqlite3*, int(*)(void*,int), void*); + +/* +** CAPI3REF: Set A Busy Timeout +** +** This routine sets a busy handler that sleeps for a while when a +** table is locked. The handler will sleep multiple times until +** at least "ms" milliseconds of sleeping have been done. After +** "ms" milliseconds of sleeping, the handler returns 0 which +** causes [sqlite3_step()] to return [SQLITE_BUSY] or [SQLITE_IOERR_BLOCKED]. +** +** Calling this routine with an argument less than or equal to zero +** turns off all busy handlers. +** +** There can only be a single busy handler for a particular database +** connection. If another busy handler was defined +** (using [sqlite3_busy_handler()]) prior to calling +** this routine, that other busy handler is cleared. +*/ +int sqlite3_busy_timeout(sqlite3*, int ms); + +/* +** CAPI3REF: Convenience Routines For Running Queries +** +** This next routine is a convenience wrapper around [sqlite3_exec()]. +** Instead of invoking a user-supplied callback for each row of the +** result, this routine remembers each row of the result in memory +** obtained from [sqlite3_malloc()], then returns all of the result after the +** query has finished. +** +** As an example, suppose the query result where this table: +** +** <blockquote><pre> +** Name | Age +** ----------------------- +** Alice | 43 +** Bob | 28 +** Cindy | 21 +** </pre></blockquote> +** +** If the 3rd argument were &azResult then after the function returns +** azResult will contain the following data: +** +** <blockquote><pre> +** azResult[0] = "Name"; +** azResult[1] = "Age"; +** azResult[2] = "Alice"; +** azResult[3] = "43"; +** azResult[4] = "Bob"; +** azResult[5] = "28"; +** azResult[6] = "Cindy"; +** azResult[7] = "21"; +** </pre></blockquote> +** +** Notice that there is an extra row of data containing the column +** headers. But the *nrow return value is still 3. *ncolumn is +** set to 2. In general, the number of values inserted into azResult +** will be ((*nrow) + 1)*(*ncolumn). +** +** After the calling function has finished using the result, it should +** pass the result data pointer to sqlite3_free_table() in order to +** release the memory that was malloc-ed. Because of the way the +** [sqlite3_malloc()] happens, the calling function must not try to call +** [sqlite3_free()] directly. Only [sqlite3_free_table()] is able to release +** the memory properly and safely. +** +** The return value of this routine is the same as from [sqlite3_exec()]. +*/ +int sqlite3_get_table( + sqlite3*, /* An open database */ + const char *sql, /* SQL to be executed */ + char ***resultp, /* Result written to a char *[] that this points to */ + int *nrow, /* Number of result rows written here */ + int *ncolumn, /* Number of result columns written here */ + char **errmsg /* Error msg written here */ +); +void sqlite3_free_table(char **result); + +/* +** CAPI3REF: Formatted String Printing Functions +** +** These routines are workalikes of the "printf()" family of functions +** from the standard C library. +** +** The sqlite3_mprintf() and sqlite3_vmprintf() routines write their +** results into memory obtained from [sqlite3_malloc()]. +** The strings returned by these two routines should be +** released by [sqlite3_free()]. Both routines return a +** NULL pointer if [sqlite3_malloc()] is unable to allocate enough +** memory to hold the resulting string. +** +** In sqlite3_snprintf() routine is similar to "snprintf()" from +** the standard C library. The result is written into the +** buffer supplied as the second parameter whose size is given by +** the first parameter. Note that the order of the +** first two parameters is reversed from snprintf(). This is an +** historical accident that cannot be fixed without breaking +** backwards compatibility. Note also that sqlite3_snprintf() +** returns a pointer to its buffer instead of the number of +** characters actually written into the buffer. We admit that +** the number of characters written would be a more useful return +** value but we cannot change the implementation of sqlite3_snprintf() +** now without breaking compatibility. +** +** As long as the buffer size is greater than zero, sqlite3_snprintf() +** guarantees that the buffer is always zero-terminated. The first +** parameter "n" is the total size of the buffer, including space for +** the zero terminator. So the longest string that can be completely +** written will be n-1 characters. +** +** These routines all implement some additional formatting +** options that are useful for constructing SQL statements. +** All of the usual printf formatting options apply. In addition, there +** is are "%q", "%Q", and "%z" options. +** +** The %q option works like %s in that it substitutes a null-terminated +** string from the argument list. But %q also doubles every '\'' character. +** %q is designed for use inside a string literal. By doubling each '\'' +** character it escapes that character and allows it to be inserted into +** the string. +** +** For example, so some string variable contains text as follows: +** +** <blockquote><pre> +** char *zText = "It's a happy day!"; +** </pre></blockquote> +** +** One can use this text in an SQL statement as follows: +** +** <blockquote><pre> +** char *zSQL = sqlite3_mprintf("INSERT INTO table VALUES('%q')", zText); +** sqlite3_exec(db, zSQL, 0, 0, 0); +** sqlite3_free(zSQL); +** </pre></blockquote> +** +** Because the %q format string is used, the '\'' character in zText +** is escaped and the SQL generated is as follows: +** +** <blockquote><pre> +** INSERT INTO table1 VALUES('It''s a happy day!') +** </pre></blockquote> +** +** This is correct. Had we used %s instead of %q, the generated SQL +** would have looked like this: +** +** <blockquote><pre> +** INSERT INTO table1 VALUES('It's a happy day!'); +** </pre></blockquote> +** +** This second example is an SQL syntax error. As a general rule you +** should always use %q instead of %s when inserting text into a string +** literal. +** +** The %Q option works like %q except it also adds single quotes around +** the outside of the total string. Or if the parameter in the argument +** list is a NULL pointer, %Q substitutes the text "NULL" (without single +** quotes) in place of the %Q option. So, for example, one could say: +** +** <blockquote><pre> +** char *zSQL = sqlite3_mprintf("INSERT INTO table VALUES(%Q)", zText); +** sqlite3_exec(db, zSQL, 0, 0, 0); +** sqlite3_free(zSQL); +** </pre></blockquote> +** +** The code above will render a correct SQL statement in the zSQL +** variable even if the zText variable is a NULL pointer. +** +** The "%z" formatting option works exactly like "%s" with the +** addition that after the string has been read and copied into +** the result, [sqlite3_free()] is called on the input string. +*/ +char *sqlite3_mprintf(const char*,...); +char *sqlite3_vmprintf(const char*, va_list); +char *sqlite3_snprintf(int,char*,const char*, ...); + +/* +** CAPI3REF: Memory Allocation Subsystem +** +** The SQLite core uses these three routines for all of its own +** internal memory allocation needs. (See the exception below.) +** +** The default implementation +** of the memory allocation subsystem uses the malloc(), realloc() +** and free() provided by the standard C library. However, if +** SQLite is compiled with the following C preprocessor macro +** +** <blockquote> SQLITE_MEMORY_SIZE=<i>NNN</i> </blockquote> +** +** where <i>NNN</i> is an integer, then SQLite create a static +** array of at least <i>NNN</i> bytes in size and use that array +** for all of its dynamic memory allocation needs. +** +** In SQLite version 3.5.0 and 3.5.1, it was possible to define +** the SQLITE_OMIT_MEMORY_ALLOCATION which would cause the built-in +** implementation of these routines to be omitted. That capability +** is no longer provided. Only built-in memory allocators can be +** used. +** +** <b>Exception:</b> The windows OS interface layer calls +** the system malloc() and free() directly when converting +** filenames between the UTF-8 encoding used by SQLite +** and whatever filename encoding is used by the particular windows +** installation. Memory allocation errors are detected, but +** they are reported back as [SQLITE_CANTOPEN] or +** [SQLITE_IOERR] rather than [SQLITE_NOMEM]. +*/ +void *sqlite3_malloc(int); +void *sqlite3_realloc(void*, int); +void sqlite3_free(void*); + +/* +** CAPI3REF: Memory Allocator Statistics +** +** In addition to the basic three allocation routines +** [sqlite3_malloc()], [sqlite3_free()], and [sqlite3_realloc()], +** the memory allocation subsystem included with the SQLite +** sources provides the interfaces shown below. +** +** The first of these two routines returns the amount of memory +** currently outstanding (malloced but not freed). The second +** returns the largest instantaneous amount of outstanding +** memory. The highwater mark is reset if the argument is +** true. +** +** The value returned may or may not include allocation +** overhead, depending on which built-in memory allocator +** implementation is used. +*/ +sqlite3_int64 sqlite3_memory_used(void); +sqlite3_int64 sqlite3_memory_highwater(int resetFlag); + +/* +** CAPI3REF: Compile-Time Authorization Callbacks +*** +** This routine registers a authorizer callback with the SQLite library. +** The authorizer callback is invoked as SQL statements are being compiled +** by [sqlite3_prepare()] or its variants [sqlite3_prepare_v2()], +** [sqlite3_prepare16()] and [sqlite3_prepare16_v2()]. At various +** points during the compilation process, as logic is being created +** to perform various actions, the authorizer callback is invoked to +** see if those actions are allowed. The authorizer callback should +** return SQLITE_OK to allow the action, [SQLITE_IGNORE] to disallow the +** specific action but allow the SQL statement to continue to be +** compiled, or [SQLITE_DENY] to cause the entire SQL statement to be +** rejected with an error. +** +** Depending on the action, the [SQLITE_IGNORE] and [SQLITE_DENY] return +** codes might mean something different or they might mean the same +** thing. If the action is, for example, to perform a delete opertion, +** then [SQLITE_IGNORE] and [SQLITE_DENY] both cause the statement compilation +** to fail with an error. But if the action is to read a specific column +** from a specific table, then [SQLITE_DENY] will cause the entire +** statement to fail but [SQLITE_IGNORE] will cause a NULL value to be +** read instead of the actual column value. +** +** The first parameter to the authorizer callback is a copy of +** the third parameter to the sqlite3_set_authorizer() interface. +** The second parameter to the callback is an integer +** [SQLITE_COPY | action code] that specifies the particular action +** to be authorized. The available action codes are +** [SQLITE_COPY | documented separately]. The third through sixth +** parameters to the callback are strings that contain additional +** details about the action to be authorized. +** +** An authorizer is used when preparing SQL statements from an untrusted +** source, to ensure that the SQL statements do not try to access data +** that they are not allowed to see, or that they do not try to +** execute malicious statements that damage the database. For +** example, an application may allow a user to enter arbitrary +** SQL queries for evaluation by a database. But the application does +** not want the user to be able to make arbitrary changes to the +** database. An authorizer could then be put in place while the +** user-entered SQL is being prepared that disallows everything +** except SELECT statements. +** +** Only a single authorizer can be in place on a database connection +** at a time. Each call to sqlite3_set_authorizer overrides the +** previous call. A NULL authorizer means that no authorization +** callback is invoked. The default authorizer is NULL. +** +** Note that the authorizer callback is invoked only during +** [sqlite3_prepare()] or its variants. Authorization is not +** performed during statement evaluation in [sqlite3_step()]. +*/ +int sqlite3_set_authorizer( + sqlite3*, + int (*xAuth)(void*,int,const char*,const char*,const char*,const char*), + void *pUserData +); + +/* +** CAPI3REF: Authorizer Return Codes +** +** The [sqlite3_set_authorizer | authorizer callback function] must +** return either [SQLITE_OK] or one of these two constants in order +** to signal SQLite whether or not the action is permitted. See the +** [sqlite3_set_authorizer | authorizer documentation] for additional +** information. +*/ +#define SQLITE_DENY 1 /* Abort the SQL statement with an error */ +#define SQLITE_IGNORE 2 /* Don't allow access, but don't generate an error */ + +/* +** CAPI3REF: Authorizer Action Codes +** +** The [sqlite3_set_authorizer()] interface registers a callback function +** that is invoked to authorizer certain SQL statement actions. The +** second parameter to the callback is an integer code that specifies +** what action is being authorized. These are the integer action codes that +** the authorizer callback may be passed. +** +** These action code values signify what kind of operation is to be +** authorized. The 3rd and 4th parameters to the authorization callback +** function will be parameters or NULL depending on which of these +** codes is used as the second parameter. The 5th parameter to the +** authorizer callback is the name of the database ("main", "temp", +** etc.) if applicable. The 6th parameter to the authorizer callback +** is the name of the inner-most trigger or view that is responsible for +** the access attempt or NULL if this access attempt is directly from +** top-level SQL code. +*/ +/******************************************* 3rd ************ 4th ***********/ +#define SQLITE_CREATE_INDEX 1 /* Index Name Table Name */ +#define SQLITE_CREATE_TABLE 2 /* Table Name NULL */ +#define SQLITE_CREATE_TEMP_INDEX 3 /* Index Name Table Name */ +#define SQLITE_CREATE_TEMP_TABLE 4 /* Table Name NULL */ +#define SQLITE_CREATE_TEMP_TRIGGER 5 /* Trigger Name Table Name */ +#define SQLITE_CREATE_TEMP_VIEW 6 /* View Name NULL */ +#define SQLITE_CREATE_TRIGGER 7 /* Trigger Name Table Name */ +#define SQLITE_CREATE_VIEW 8 /* View Name NULL */ +#define SQLITE_DELETE 9 /* Table Name NULL */ +#define SQLITE_DROP_INDEX 10 /* Index Name Table Name */ +#define SQLITE_DROP_TABLE 11 /* Table Name NULL */ +#define SQLITE_DROP_TEMP_INDEX 12 /* Index Name Table Name */ +#define SQLITE_DROP_TEMP_TABLE 13 /* Table Name NULL */ +#define SQLITE_DROP_TEMP_TRIGGER 14 /* Trigger Name Table Name */ +#define SQLITE_DROP_TEMP_VIEW 15 /* View Name NULL */ +#define SQLITE_DROP_TRIGGER 16 /* Trigger Name Table Name */ +#define SQLITE_DROP_VIEW 17 /* View Name NULL */ +#define SQLITE_INSERT 18 /* Table Name NULL */ +#define SQLITE_PRAGMA 19 /* Pragma Name 1st arg or NULL */ +#define SQLITE_READ 20 /* Table Name Column Name */ +#define SQLITE_SELECT 21 /* NULL NULL */ +#define SQLITE_TRANSACTION 22 /* NULL NULL */ +#define SQLITE_UPDATE 23 /* Table Name Column Name */ +#define SQLITE_ATTACH 24 /* Filename NULL */ +#define SQLITE_DETACH 25 /* Database Name NULL */ +#define SQLITE_ALTER_TABLE 26 /* Database Name Table Name */ +#define SQLITE_REINDEX 27 /* Index Name NULL */ +#define SQLITE_ANALYZE 28 /* Table Name NULL */ +#define SQLITE_CREATE_VTABLE 29 /* Table Name Module Name */ +#define SQLITE_DROP_VTABLE 30 /* Table Name Module Name */ +#define SQLITE_FUNCTION 31 /* Function Name NULL */ +#define SQLITE_COPY 0 /* No longer used */ + +/* +** CAPI3REF: Tracing And Profiling Functions +** +** These routines register callback functions that can be used for +** tracing and profiling the execution of SQL statements. +** The callback function registered by sqlite3_trace() is invoked +** at the first [sqlite3_step()] for the evaluation of an SQL statement. +** The callback function registered by sqlite3_profile() is invoked +** as each SQL statement finishes and includes +** information on how long that statement ran. +** +** The sqlite3_profile() API is currently considered experimental and +** is subject to change. +*/ +void *sqlite3_trace(sqlite3*, void(*xTrace)(void*,const char*), void*); +void *sqlite3_profile(sqlite3*, + void(*xProfile)(void*,const char*,sqlite3_uint64), void*); + +/* +** CAPI3REF: Query Progress Callbacks +** +** This routine configures a callback function - the progress callback - that +** is invoked periodically during long running calls to [sqlite3_exec()], +** [sqlite3_step()] and [sqlite3_get_table()]. An example use for this +** interface is to keep a GUI updated during a large query. +** +** The progress callback is invoked once for every N virtual machine opcodes, +** where N is the second argument to this function. The progress callback +** itself is identified by the third argument to this function. The fourth +** argument to this function is a void pointer passed to the progress callback +** function each time it is invoked. +** +** If a call to [sqlite3_exec()], [sqlite3_step()], or [sqlite3_get_table()] +** results in fewer than N opcodes being executed, then the progress +** callback is never invoked. +** +** Only a single progress callback function may be registered for each +** open database connection. Every call to sqlite3_progress_handler() +** overwrites the results of the previous call. +** To remove the progress callback altogether, pass NULL as the third +** argument to this function. +** +** If the progress callback returns a result other than 0, then the current +** query is immediately terminated and any database changes rolled back. +** The containing [sqlite3_exec()], [sqlite3_step()], or +** [sqlite3_get_table()] call returns SQLITE_INTERRUPT. This feature +** can be used, for example, to implement the "Cancel" button on a +** progress dialog box in a GUI. +*/ +void sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*); + +/* +** CAPI3REF: Opening A New Database Connection +** +** Open the sqlite database file "filename". The "filename" is UTF-8 +** encoded for [sqlite3_open()] and [sqlite3_open_v2()] and UTF-16 encoded +** in the native byte order for [sqlite3_open16()]. +** An [sqlite3*] handle is returned in *ppDb, even +** if an error occurs. If the database is opened (or created) successfully, +** then [SQLITE_OK] is returned. Otherwise an error code is returned. The +** [sqlite3_errmsg()] or [sqlite3_errmsg16()] routines can be used to obtain +** an English language description of the error. +** +** The default encoding for the database will be UTF-8 if +** [sqlite3_open()] or [sqlite3_open_v2()] is called and +** UTF-16 if [sqlite3_open16()] is used. +** +** Whether or not an error occurs when it is opened, resources associated +** with the [sqlite3*] handle should be released by passing it to +** [sqlite3_close()] when it is no longer required. +** +** The [sqlite3_open_v2()] interface works like [sqlite3_open()] except that +** provides two additional parameters for additional control over the +** new database connection. The flags parameter can be one of: +** +** <ol> +** <li> [SQLITE_OPEN_READONLY] +** <li> [SQLITE_OPEN_READWRITE] +** <li> [SQLITE_OPEN_READWRITE] | [SQLITE_OPEN_CREATE] +** </ol> +** +** The first value opens the database read-only. If the database does +** not previously exist, an error is returned. The second option opens +** the database for reading and writing if possible, or reading only if +** if the file is write protected. In either case the database must already +** exist or an error is returned. The third option opens the database +** for reading and writing and creates it if it does not already exist. +** The third options is behavior that is always used for [sqlite3_open()] +** and [sqlite3_open16()]. +** +** If the filename is ":memory:", then an private +** in-memory database is created for the connection. This in-memory +** database will vanish when the database connection is closed. Future +** version of SQLite might make use of additional special filenames +** that begin with the ":" character. It is recommended that +** when a database filename really does begin with +** ":" that you prefix the filename with a pathname like "./" to +** avoid ambiguity. +** +** If the filename is an empty string, then a private temporary +** on-disk database will be created. This private database will be +** automatically deleted as soon as the database connection is closed. +** +** The fourth parameter to sqlite3_open_v2() is the name of the +** [sqlite3_vfs] object that defines the operating system +** interface that the new database connection should use. If the +** fourth parameter is a NULL pointer then the default [sqlite3_vfs] +** object is used. +** +** <b>Note to windows users:</b> The encoding used for the filename argument +** of [sqlite3_open()] and [sqlite3_open_v2()] must be UTF-8, not whatever +** codepage is currently defined. Filenames containing international +** characters must be converted to UTF-8 prior to passing them into +** [sqlite3_open()] or [sqlite3_open_v2()]. +*/ +int sqlite3_open( + const char *filename, /* Database filename (UTF-8) */ + sqlite3 **ppDb /* OUT: SQLite db handle */ +); +int sqlite3_open16( + const void *filename, /* Database filename (UTF-16) */ + sqlite3 **ppDb /* OUT: SQLite db handle */ +); +int sqlite3_open_v2( + const char *filename, /* Database filename (UTF-8) */ + sqlite3 **ppDb, /* OUT: SQLite db handle */ + int flags, /* Flags */ + const char *zVfs /* Name of VFS module to use */ +); + +/* +** CAPI3REF: Error Codes And Messages +** +** The sqlite3_errcode() interface returns the numeric +** [SQLITE_OK | result code] or [SQLITE_IOERR_READ | extended result code] +** for the most recent failed sqlite3_* API call associated +** with [sqlite3] handle 'db'. If a prior API call failed but the +** most recent API call succeeded, the return value from sqlite3_errcode() +** is undefined. +** +** The sqlite3_errmsg() and sqlite3_errmsg16() return English-language +** text that describes the error, as either UTF8 or UTF16 respectively. +** Memory to hold the error message string is managed internally. The +** string may be overwritten or deallocated by subsequent calls to SQLite +** interface functions. +** +** Calls to many sqlite3_* functions set the error code and string returned +** by [sqlite3_errcode()], [sqlite3_errmsg()], and [sqlite3_errmsg16()] +** (overwriting the previous values). Note that calls to [sqlite3_errcode()], +** [sqlite3_errmsg()], and [sqlite3_errmsg16()] themselves do not affect the +** results of future invocations. Calls to API routines that do not return +** an error code (example: [sqlite3_data_count()]) do not +** change the error code returned by this routine. Interfaces that are +** not associated with a specific database connection (examples: +** [sqlite3_mprintf()] or [sqlite3_enable_shared_cache()] do not change +** the return code. +** +** Assuming no other intervening sqlite3_* API calls are made, the error +** code returned by this function is associated with the same error as +** the strings returned by [sqlite3_errmsg()] and [sqlite3_errmsg16()]. +*/ +int sqlite3_errcode(sqlite3 *db); +const char *sqlite3_errmsg(sqlite3*); +const void *sqlite3_errmsg16(sqlite3*); + +/* +** CAPI3REF: SQL Statement Object +** +** Instance of this object represent single SQL statements. This +** is variously known as a "prepared statement" or a +** "compiled SQL statement" or simply as a "statement". +** +** The life of a statement object goes something like this: +** +** <ol> +** <li> Create the object using [sqlite3_prepare_v2()] or a related +** function. +** <li> Bind values to host parameters using +** [sqlite3_bind_blob | sqlite3_bind_* interfaces]. +** <li> Run the SQL by calling [sqlite3_step()] one or more times. +** <li> Reset the statement using [sqlite3_reset()] then go back +** to step 2. Do this zero or more times. +** <li> Destroy the object using [sqlite3_finalize()]. +** </ol> +** +** Refer to documentation on individual methods above for additional +** information. +*/ +typedef struct sqlite3_stmt sqlite3_stmt; + +/* +** CAPI3REF: Compiling An SQL Statement +** +** To execute an SQL query, it must first be compiled into a byte-code +** program using one of these routines. +** +** The first argument "db" is an [sqlite3 | SQLite database handle] +** obtained from a prior call to [sqlite3_open()], [sqlite3_open_v2()] +** or [sqlite3_open16()]. +** The second argument "zSql" is the statement to be compiled, encoded +** as either UTF-8 or UTF-16. The sqlite3_prepare() and sqlite3_prepare_v2() +** interfaces uses UTF-8 and sqlite3_prepare16() and sqlite3_prepare16_v2() +** use UTF-16. +** +** If the nByte argument is less +** than zero, then zSql is read up to the first zero terminator. If +** nByte is non-negative, then it is the maximum number of +** bytes read from zSql. When nByte is non-negative, the +** zSql string ends at either the first '\000' character or +** until the nByte-th byte, whichever comes first. +** +** *pzTail is made to point to the first byte past the end of the first +** SQL statement in zSql. This routine only compiles the first statement +** in zSql, so *pzTail is left pointing to what remains uncompiled. +** +** *ppStmt is left pointing to a compiled +** [sqlite3_stmt | SQL statement structure] that can be +** executed using [sqlite3_step()]. Or if there is an error, *ppStmt may be +** set to NULL. If the input text contained no SQL (if the input is and +** empty string or a comment) then *ppStmt is set to NULL. The calling +** procedure is responsible for deleting the compiled SQL statement +** using [sqlite3_finalize()] after it has finished with it. +** +** On success, [SQLITE_OK] is returned. Otherwise an +** [SQLITE_ERROR | error code] is returned. +** +** The sqlite3_prepare_v2() and sqlite3_prepare16_v2() interfaces are +** recommended for all new programs. The two older interfaces are retained +** for backwards compatibility, but their use is discouraged. +** In the "v2" interfaces, the prepared statement +** that is returned (the [sqlite3_stmt] object) contains a copy of the +** original SQL text. This causes the [sqlite3_step()] interface to +** behave a differently in two ways: +** +** <ol> +** <li> +** If the database schema changes, instead of returning [SQLITE_SCHEMA] as it +** always used to do, [sqlite3_step()] will automatically recompile the SQL +** statement and try to run it again. If the schema has changed in a way +** that makes the statement no longer valid, [sqlite3_step()] will still +** return [SQLITE_SCHEMA]. But unlike the legacy behavior, [SQLITE_SCHEMA] is +** now a fatal error. Calling [sqlite3_prepare_v2()] again will not make the +** error go away. Note: use [sqlite3_errmsg()] to find the text of the parsing +** error that results in an [SQLITE_SCHEMA] return. +** </li> +** +** <li> +** When an error occurs, +** [sqlite3_step()] will return one of the detailed +** [SQLITE_ERROR | result codes] or +** [SQLITE_IOERR_READ | extended result codes] such as directly. +** The legacy behavior was that [sqlite3_step()] would only return a generic +** [SQLITE_ERROR] result code and you would have to make a second call to +** [sqlite3_reset()] in order to find the underlying cause of the problem. +** With the "v2" prepare interfaces, the underlying reason for the error is +** returned immediately. +** </li> +** </ol> +*/ +int sqlite3_prepare( + sqlite3 *db, /* Database handle */ + const char *zSql, /* SQL statement, UTF-8 encoded */ + int nByte, /* Maximum length of zSql in bytes. */ + sqlite3_stmt **ppStmt, /* OUT: Statement handle */ + const char **pzTail /* OUT: Pointer to unused portion of zSql */ +); +int sqlite3_prepare_v2( + sqlite3 *db, /* Database handle */ + const char *zSql, /* SQL statement, UTF-8 encoded */ + int nByte, /* Maximum length of zSql in bytes. */ + sqlite3_stmt **ppStmt, /* OUT: Statement handle */ + const char **pzTail /* OUT: Pointer to unused portion of zSql */ +); +int sqlite3_prepare16( + sqlite3 *db, /* Database handle */ + const void *zSql, /* SQL statement, UTF-16 encoded */ + int nByte, /* Maximum length of zSql in bytes. */ + sqlite3_stmt **ppStmt, /* OUT: Statement handle */ + const void **pzTail /* OUT: Pointer to unused portion of zSql */ +); +int sqlite3_prepare16_v2( + sqlite3 *db, /* Database handle */ + const void *zSql, /* SQL statement, UTF-16 encoded */ + int nByte, /* Maximum length of zSql in bytes. */ + sqlite3_stmt **ppStmt, /* OUT: Statement handle */ + const void **pzTail /* OUT: Pointer to unused portion of zSql */ +); + +/* +** Retrieve the original SQL statement associated with a compiled statement +** in UTF-8 encoding. +** +** If the compiled SQL statement passed as an argument was compiled using +** either sqlite3_prepare_v2 or sqlite3_prepare16_v2, then this function +** returns a pointer to a nul-terminated string containing a copy of +** the original SQL statement. The pointer is valid until the statement +** is deleted using sqlite3_finalize(). +** +** If the statement was compiled using either of the legacy interfaces +** sqlite3_prepare() or sqlite3_prepare16(), this function returns NULL. +** +****** EXPERIMENTAL - subject to change without notice ************** +*/ +const char *sqlite3_sql(sqlite3_stmt *pStmt); + +/* +** CAPI3REF: Dynamically Typed Value Object +** +** SQLite uses dynamic typing for the values it stores. Values can +** be integers, floating point values, strings, BLOBs, or NULL. When +** passing around values internally, each value is represented as +** an instance of the sqlite3_value object. +*/ +typedef struct Mem sqlite3_value; + +/* +** CAPI3REF: SQL Function Context Object +** +** The context in which an SQL function executes is stored in an +** sqlite3_context object. A pointer to such an object is the +** first parameter to user-defined SQL functions. +*/ +typedef struct sqlite3_context sqlite3_context; + +/* +** CAPI3REF: Binding Values To Prepared Statements +** +** In the SQL strings input to [sqlite3_prepare_v2()] and its variants, +** one or more literals can be replace by a parameter in one of these +** forms: +** +** <ul> +** <li> ? +** <li> ?NNN +** <li> :AAA +** <li> @AAA +** <li> $VVV +** </ul> +** +** In the parameter forms shown above NNN is an integer literal, +** AAA is an alphanumeric identifier and VVV is a variable name according +** to the syntax rules of the TCL programming language. +** The values of these parameters (also called "host parameter names") +** can be set using the sqlite3_bind_*() routines defined here. +** +** The first argument to the sqlite3_bind_*() routines always is a pointer +** to the [sqlite3_stmt] object returned from [sqlite3_prepare_v2()] or +** its variants. The second +** argument is the index of the parameter to be set. The first parameter has +** an index of 1. When the same named parameter is used more than once, second +** and subsequent +** occurrences have the same index as the first occurrence. The index for +** named parameters can be looked up using the +** [sqlite3_bind_parameter_name()] API if desired. The index for "?NNN" +** parametes is the value of NNN. +** The NNN value must be between 1 and the compile-time +** parameter SQLITE_MAX_VARIABLE_NUMBER (default value: 999). +** See <a href="limits.html">limits.html</a> for additional information. +** +** The third argument is the value to bind to the parameter. +** +** In those +** routines that have a fourth argument, its value is the number of bytes +** in the parameter. To be clear: the value is the number of bytes in the +** string, not the number of characters. The number +** of bytes does not include the zero-terminator at the end of strings. +** If the fourth parameter is negative, the length of the string is +** number of bytes up to the first zero terminator. +** +** The fifth argument to sqlite3_bind_blob(), sqlite3_bind_text(), and +** sqlite3_bind_text16() is a destructor used to dispose of the BLOB or +** text after SQLite has finished with it. If the fifth argument is the +** special value [SQLITE_STATIC], then the library assumes that the information +** is in static, unmanaged space and does not need to be freed. If the +** fifth argument has the value [SQLITE_TRANSIENT], then SQLite makes its +** own private copy of the data immediately, before the sqlite3_bind_*() +** routine returns. +** +** The sqlite3_bind_zeroblob() routine binds a BLOB of length n that +** is filled with zeros. A zeroblob uses a fixed amount of memory +** (just an integer to hold it size) while it is being processed. +** Zeroblobs are intended to serve as place-holders for BLOBs whose +** content is later written using +** [sqlite3_blob_open | increment BLOB I/O] routines. A negative +** value for the zeroblob results in a zero-length BLOB. +** +** The sqlite3_bind_*() routines must be called after +** [sqlite3_prepare_v2()] (and its variants) or [sqlite3_reset()] and +** before [sqlite3_step()]. +** Bindings are not cleared by the [sqlite3_reset()] routine. +** Unbound parameters are interpreted as NULL. +** +** These routines return [SQLITE_OK] on success or an error code if +** anything goes wrong. [SQLITE_RANGE] is returned if the parameter +** index is out of range. [SQLITE_NOMEM] is returned if malloc fails. +** [SQLITE_MISUSE] is returned if these routines are called on a virtual +** machine that is the wrong state or which has already been finalized. +*/ +int sqlite3_bind_blob(sqlite3_stmt*, int, const void*, int n, void(*)(void*)); +int sqlite3_bind_double(sqlite3_stmt*, int, double); +int sqlite3_bind_int(sqlite3_stmt*, int, int); +int sqlite3_bind_int64(sqlite3_stmt*, int, sqlite3_int64); +int sqlite3_bind_null(sqlite3_stmt*, int); +int sqlite3_bind_text(sqlite3_stmt*, int, const char*, int n, void(*)(void*)); +int sqlite3_bind_text16(sqlite3_stmt*, int, const void*, int, void(*)(void*)); +int sqlite3_bind_value(sqlite3_stmt*, int, const sqlite3_value*); +int sqlite3_bind_zeroblob(sqlite3_stmt*, int, int n); + +/* +** CAPI3REF: Number Of Host Parameters +** +** Return the largest host parameter index in the precompiled statement given +** as the argument. When the host parameters are of the forms like ":AAA" +** or "?", then they are assigned sequential increasing numbers beginning +** with one, so the value returned is the number of parameters. However +** if the same host parameter name is used multiple times, each occurrance +** is given the same number, so the value returned in that case is the number +** of unique host parameter names. If host parameters of the form "?NNN" +** are used (where NNN is an integer) then there might be gaps in the +** numbering and the value returned by this interface is the index of the +** host parameter with the largest index value. +** +** The prepared statement must not be [sqlite3_finalize | finalized] +** prior to this routine returnning. Otherwise the results are undefined +** and probably undesirable. +*/ +int sqlite3_bind_parameter_count(sqlite3_stmt*); + +/* +** CAPI3REF: Name Of A Host Parameter +** +** This routine returns a pointer to the name of the n-th parameter in a +** [sqlite3_stmt | prepared statement]. +** Host parameters of the form ":AAA" or "@AAA" or "$VVV" have a name +** which is the string ":AAA" or "@AAA" or "$VVV". +** In other words, the initial ":" or "$" or "@" +** is included as part of the name. +** Parameters of the form "?" or "?NNN" have no name. +** +** The first bound parameter has an index of 1, not 0. +** +** If the value n is out of range or if the n-th parameter is nameless, +** then NULL is returned. The returned string is always in the +** UTF-8 encoding even if the named parameter was originally specified +** as UTF-16 in [sqlite3_prepare16()] or [sqlite3_prepare16_v2()]. +*/ +const char *sqlite3_bind_parameter_name(sqlite3_stmt*, int); + +/* +** CAPI3REF: Index Of A Parameter With A Given Name +** +** This routine returns the index of a host parameter with the given name. +** The name must match exactly. If no parameter with the given name is +** found, return 0. Parameter names must be UTF8. +*/ +int sqlite3_bind_parameter_index(sqlite3_stmt*, const char *zName); + +/* +** CAPI3REF: Reset All Bindings On A Prepared Statement +** +** Contrary to the intuition of many, [sqlite3_reset()] does not +** reset the [sqlite3_bind_blob | bindings] on a +** [sqlite3_stmt | prepared statement]. Use this routine to +** reset all host parameters to NULL. +*/ +int sqlite3_clear_bindings(sqlite3_stmt*); + +/* +** CAPI3REF: Number Of Columns In A Result Set +** +** Return the number of columns in the result set returned by the +** [sqlite3_stmt | compiled SQL statement]. This routine returns 0 +** if pStmt is an SQL statement that does not return data (for +** example an UPDATE). +*/ +int sqlite3_column_count(sqlite3_stmt *pStmt); + +/* +** CAPI3REF: Column Names In A Result Set +** +** These routines return the name assigned to a particular column +** in the result set of a SELECT statement. The sqlite3_column_name() +** interface returns a pointer to a UTF8 string and sqlite3_column_name16() +** returns a pointer to a UTF16 string. The first parameter is the +** [sqlite3_stmt | prepared statement] that implements the SELECT statement. +** The second parameter is the column number. The left-most column is +** number 0. +** +** The returned string pointer is valid until either the +** [sqlite3_stmt | prepared statement] is destroyed by [sqlite3_finalize()] +** or until the next call sqlite3_column_name() or sqlite3_column_name16() +** on the same column. +** +** If sqlite3_malloc() fails during the processing of either routine +** (for example during a conversion from UTF-8 to UTF-16) then a +** NULL pointer is returned. +*/ +const char *sqlite3_column_name(sqlite3_stmt*, int N); +const void *sqlite3_column_name16(sqlite3_stmt*, int N); + +/* +** CAPI3REF: Source Of Data In A Query Result +** +** These routines provide a means to determine what column of what +** table in which database a result of a SELECT statement comes from. +** The name of the database or table or column can be returned as +** either a UTF8 or UTF16 string. The _database_ routines return +** the database name, the _table_ routines return the table name, and +** the origin_ routines return the column name. +** The returned string is valid until +** the [sqlite3_stmt | prepared statement] is destroyed using +** [sqlite3_finalize()] or until the same information is requested +** again in a different encoding. +** +** The names returned are the original un-aliased names of the +** database, table, and column. +** +** The first argument to the following calls is a +** [sqlite3_stmt | compiled SQL statement]. +** These functions return information about the Nth column returned by +** the statement, where N is the second function argument. +** +** If the Nth column returned by the statement is an expression +** or subquery and is not a column value, then all of these functions +** return NULL. Otherwise, they return the +** name of the attached database, table and column that query result +** column was extracted from. +** +** As with all other SQLite APIs, those postfixed with "16" return UTF-16 +** encoded strings, the other functions return UTF-8. +** +** These APIs are only available if the library was compiled with the +** SQLITE_ENABLE_COLUMN_METADATA preprocessor symbol defined. +** +** If two or more threads call one or more of these routines against the same +** prepared statement and column at the same time then the results are +** undefined. +*/ +const char *sqlite3_column_database_name(sqlite3_stmt*,int); +const void *sqlite3_column_database_name16(sqlite3_stmt*,int); +const char *sqlite3_column_table_name(sqlite3_stmt*,int); +const void *sqlite3_column_table_name16(sqlite3_stmt*,int); +const char *sqlite3_column_origin_name(sqlite3_stmt*,int); +const void *sqlite3_column_origin_name16(sqlite3_stmt*,int); + +/* +** CAPI3REF: Declared Datatype Of A Query Result +** +** The first parameter is a [sqlite3_stmt | compiled SQL statement]. +** If this statement is a SELECT statement and the Nth column of the +** returned result set of that SELECT is a table column (not an +** expression or subquery) then the declared type of the table +** column is returned. If the Nth column of the result set is an +** expression or subquery, then a NULL pointer is returned. +** The returned string is always UTF-8 encoded. For example, in +** the database schema: +** +** CREATE TABLE t1(c1 VARIANT); +** +** And the following statement compiled: +** +** SELECT c1 + 1, c1 FROM t1; +** +** Then this routine would return the string "VARIANT" for the second +** result column (i==1), and a NULL pointer for the first result column +** (i==0). +** +** SQLite uses dynamic run-time typing. So just because a column +** is declared to contain a particular type does not mean that the +** data stored in that column is of the declared type. SQLite is +** strongly typed, but the typing is dynamic not static. Type +** is associated with individual values, not with the containers +** used to hold those values. +*/ +const char *sqlite3_column_decltype(sqlite3_stmt *, int i); +const void *sqlite3_column_decltype16(sqlite3_stmt*,int); + +/* +** CAPI3REF: Evaluate An SQL Statement +** +** After an [sqlite3_stmt | SQL statement] has been prepared with a call +** to either [sqlite3_prepare_v2()] or [sqlite3_prepare16_v2()] or to one of +** the legacy interfaces [sqlite3_prepare()] or [sqlite3_prepare16()], +** then this function must be called one or more times to evaluate the +** statement. +** +** The details of the behavior of this sqlite3_step() interface depend +** on whether the statement was prepared using the newer "v2" interface +** [sqlite3_prepare_v2()] and [sqlite3_prepare16_v2()] or the older legacy +** interface [sqlite3_prepare()] and [sqlite3_prepare16()]. The use of the +** new "v2" interface is recommended for new applications but the legacy +** interface will continue to be supported. +** +** In the lagacy interface, the return value will be either [SQLITE_BUSY], +** [SQLITE_DONE], [SQLITE_ROW], [SQLITE_ERROR], or [SQLITE_MISUSE]. +** With the "v2" interface, any of the other [SQLITE_OK | result code] +** or [SQLITE_IOERR_READ | extended result code] might be returned as +** well. +** +** [SQLITE_BUSY] means that the database engine was unable to acquire the +** database locks it needs to do its job. If the statement is a COMMIT +** or occurs outside of an explicit transaction, then you can retry the +** statement. If the statement is not a COMMIT and occurs within a +** explicit transaction then you should rollback the transaction before +** continuing. +** +** [SQLITE_DONE] means that the statement has finished executing +** successfully. sqlite3_step() should not be called again on this virtual +** machine without first calling [sqlite3_reset()] to reset the virtual +** machine back to its initial state. +** +** If the SQL statement being executed returns any data, then +** [SQLITE_ROW] is returned each time a new row of data is ready +** for processing by the caller. The values may be accessed using +** the [sqlite3_column_int | column access functions]. +** sqlite3_step() is called again to retrieve the next row of data. +** +** [SQLITE_ERROR] means that a run-time error (such as a constraint +** violation) has occurred. sqlite3_step() should not be called again on +** the VM. More information may be found by calling [sqlite3_errmsg()]. +** With the legacy interface, a more specific error code (example: +** [SQLITE_INTERRUPT], [SQLITE_SCHEMA], [SQLITE_CORRUPT], and so forth) +** can be obtained by calling [sqlite3_reset()] on the +** [sqlite3_stmt | prepared statement]. In the "v2" interface, +** the more specific error code is returned directly by sqlite3_step(). +** +** [SQLITE_MISUSE] means that the this routine was called inappropriately. +** Perhaps it was called on a [sqlite3_stmt | prepared statement] that has +** already been [sqlite3_finalize | finalized] or on one that had +** previously returned [SQLITE_ERROR] or [SQLITE_DONE]. Or it could +** be the case that the same database connection is being used by two or +** more threads at the same moment in time. +** +** <b>Goofy Interface Alert:</b> +** In the legacy interface, +** the sqlite3_step() API always returns a generic error code, +** [SQLITE_ERROR], following any error other than [SQLITE_BUSY] +** and [SQLITE_MISUSE]. You must call [sqlite3_reset()] or +** [sqlite3_finalize()] in order to find one of the specific +** [SQLITE_ERROR | result codes] that better describes the error. +** We admit that this is a goofy design. The problem has been fixed +** with the "v2" interface. If you prepare all of your SQL statements +** using either [sqlite3_prepare_v2()] or [sqlite3_prepare16_v2()] instead +** of the legacy [sqlite3_prepare()] and [sqlite3_prepare16()], then the +** more specific [SQLITE_ERROR | result codes] are returned directly +** by sqlite3_step(). The use of the "v2" interface is recommended. +*/ +int sqlite3_step(sqlite3_stmt*); + +/* +** CAPI3REF: +** +** Return the number of values in the current row of the result set. +** +** After a call to [sqlite3_step()] that returns [SQLITE_ROW], this routine +** will return the same value as the [sqlite3_column_count()] function. +** After [sqlite3_step()] has returned an [SQLITE_DONE], [SQLITE_BUSY], or +** a [SQLITE_ERROR | error code], or before [sqlite3_step()] has been +** called on the [sqlite3_stmt | prepared statement] for the first time, +** this routine returns zero. +*/ +int sqlite3_data_count(sqlite3_stmt *pStmt); + +/* +** CAPI3REF: Fundamental Datatypes +** +** Every value in SQLite has one of five fundamental datatypes: +** +** <ul> +** <li> 64-bit signed integer +** <li> 64-bit IEEE floating point number +** <li> string +** <li> BLOB +** <li> NULL +** </ul> +** +** These constants are codes for each of those types. +** +** Note that the SQLITE_TEXT constant was also used in SQLite version 2 +** for a completely different meaning. Software that links against both +** SQLite version 2 and SQLite version 3 should use SQLITE3_TEXT not +** SQLITE_TEXT. +*/ +#define SQLITE_INTEGER 1 +#define SQLITE_FLOAT 2 +#define SQLITE_BLOB 4 +#define SQLITE_NULL 5 +#ifdef SQLITE_TEXT +# undef SQLITE_TEXT +#else +# define SQLITE_TEXT 3 +#endif +#define SQLITE3_TEXT 3 + +/* +** CAPI3REF: Results Values From A Query +** +** These routines return information about +** a single column of the current result row of a query. In every +** case the first argument is a pointer to the +** [sqlite3_stmt | SQL statement] that is being +** evaluated (the [sqlite3_stmt*] that was returned from +** [sqlite3_prepare_v2()] or one of its variants) and +** the second argument is the index of the column for which information +** should be returned. The left-most column of the result set +** has an index of 0. +** +** If the SQL statement is not currently point to a valid row, or if the +** the column index is out of range, the result is undefined. +** These routines may only be called when the most recent call to +** [sqlite3_step()] has returned [SQLITE_ROW] and neither +** [sqlite3_reset()] nor [sqlite3_finalize()] has been call subsequently. +** If any of these routines are called after [sqlite3_reset()] or +** [sqlite3_finalize()] or after [sqlite3_step()] has returned +** something other than [SQLITE_ROW], the results are undefined. +** If [sqlite3_step()] or [sqlite3_reset()] or [sqlite3_finalize()] +** are called from a different thread while any of these routines +** are pending, then the results are undefined. +** +** The sqlite3_column_type() routine returns +** [SQLITE_INTEGER | datatype code] for the initial data type +** of the result column. The returned value is one of [SQLITE_INTEGER], +** [SQLITE_FLOAT], [SQLITE_TEXT], [SQLITE_BLOB], or [SQLITE_NULL]. The value +** returned by sqlite3_column_type() is only meaningful if no type +** conversions have occurred as described below. After a type conversion, +** the value returned by sqlite3_column_type() is undefined. Future +** versions of SQLite may change the behavior of sqlite3_column_type() +** following a type conversion. +** +** If the result is a BLOB or UTF-8 string then the sqlite3_column_bytes() +** routine returns the number of bytes in that BLOB or string. +** If the result is a UTF-16 string, then sqlite3_column_bytes() converts +** the string to UTF-8 and then returns the number of bytes. +** If the result is a numeric value then sqlite3_column_bytes() uses +** [sqlite3_snprintf()] to convert that value to a UTF-8 string and returns +** the number of bytes in that string. +** The value returned does not include the zero terminator at the end +** of the string. For clarity: the value returned is the number of +** bytes in the string, not the number of characters. +** +** Strings returned by sqlite3_column_text() and sqlite3_column_text16(), +** even zero-length strings, are always zero terminated. The return +** value from sqlite3_column_blob() for a zero-length blob is an arbitrary +** pointer, possibly even a NULL pointer. +** +** The sqlite3_column_bytes16() routine is similar to sqlite3_column_bytes() +** but leaves the result in UTF-16 instead of UTF-8. +** The zero terminator is not included in this count. +** +** These routines attempt to convert the value where appropriate. For +** example, if the internal representation is FLOAT and a text result +** is requested, [sqlite3_snprintf()] is used internally to do the conversion +** automatically. The following table details the conversions that +** are applied: +** +** <blockquote> +** <table border="1"> +** <tr><th> Internal<br>Type <th> Requested<br>Type <th> Conversion +** +** <tr><td> NULL <td> INTEGER <td> Result is 0 +** <tr><td> NULL <td> FLOAT <td> Result is 0.0 +** <tr><td> NULL <td> TEXT <td> Result is NULL pointer +** <tr><td> NULL <td> BLOB <td> Result is NULL pointer +** <tr><td> INTEGER <td> FLOAT <td> Convert from integer to float +** <tr><td> INTEGER <td> TEXT <td> ASCII rendering of the integer +** <tr><td> INTEGER <td> BLOB <td> Same as for INTEGER->TEXT +** <tr><td> FLOAT <td> INTEGER <td> Convert from float to integer +** <tr><td> FLOAT <td> TEXT <td> ASCII rendering of the float +** <tr><td> FLOAT <td> BLOB <td> Same as FLOAT->TEXT +** <tr><td> TEXT <td> INTEGER <td> Use atoi() +** <tr><td> TEXT <td> FLOAT <td> Use atof() +** <tr><td> TEXT <td> BLOB <td> No change +** <tr><td> BLOB <td> INTEGER <td> Convert to TEXT then use atoi() +** <tr><td> BLOB <td> FLOAT <td> Convert to TEXT then use atof() +** <tr><td> BLOB <td> TEXT <td> Add a zero terminator if needed +** </table> +** </blockquote> +** +** The table above makes reference to standard C library functions atoi() +** and atof(). SQLite does not really use these functions. It has its +** on equavalent internal routines. The atoi() and atof() names are +** used in the table for brevity and because they are familiar to most +** C programmers. +** +** Note that when type conversions occur, pointers returned by prior +** calls to sqlite3_column_blob(), sqlite3_column_text(), and/or +** sqlite3_column_text16() may be invalidated. +** Type conversions and pointer invalidations might occur +** in the following cases: +** +** <ul> +** <li><p> The initial content is a BLOB and sqlite3_column_text() +** or sqlite3_column_text16() is called. A zero-terminator might +** need to be added to the string.</p></li> +** +** <li><p> The initial content is UTF-8 text and sqlite3_column_bytes16() or +** sqlite3_column_text16() is called. The content must be converted +** to UTF-16.</p></li> +** +** <li><p> The initial content is UTF-16 text and sqlite3_column_bytes() or +** sqlite3_column_text() is called. The content must be converted +** to UTF-8.</p></li> +** </ul> +** +** Conversions between UTF-16be and UTF-16le are always done in place and do +** not invalidate a prior pointer, though of course the content of the buffer +** that the prior pointer points to will have been modified. Other kinds +** of conversion are done in place when it is possible, but sometime it is +** not possible and in those cases prior pointers are invalidated. +** +** The safest and easiest to remember policy is to invoke these routines +** in one of the following ways: +** +** <ul> +** <li>sqlite3_column_text() followed by sqlite3_column_bytes()</li> +** <li>sqlite3_column_blob() followed by sqlite3_column_bytes()</li> +** <li>sqlite3_column_text16() followed by sqlite3_column_bytes16()</li> +** </ul> +** +** In other words, you should call sqlite3_column_text(), sqlite3_column_blob(), +** or sqlite3_column_text16() first to force the result into the desired +** format, then invoke sqlite3_column_bytes() or sqlite3_column_bytes16() to +** find the size of the result. Do not mix call to sqlite3_column_text() or +** sqlite3_column_blob() with calls to sqlite3_column_bytes16(). And do not +** mix calls to sqlite3_column_text16() with calls to sqlite3_column_bytes(). +** +** The pointers returned are valid until a type conversion occurs as +** described above, or until [sqlite3_step()] or [sqlite3_reset()] or +** [sqlite3_finalize()] is called. The memory space used to hold strings +** and blobs is freed automatically. Do <b>not</b> pass the pointers returned +** [sqlite3_column_blob()], [sqlite3_column_text()], etc. into +** [sqlite3_free()]. +** +** If a memory allocation error occurs during the evaluation of any +** of these routines, a default value is returned. The default value +** is either the integer 0, the floating point number 0.0, or a NULL +** pointer. Subsequent calls to [sqlite3_errcode()] will return +** [SQLITE_NOMEM]. +*/ +const void *sqlite3_column_blob(sqlite3_stmt*, int iCol); +int sqlite3_column_bytes(sqlite3_stmt*, int iCol); +int sqlite3_column_bytes16(sqlite3_stmt*, int iCol); +double sqlite3_column_double(sqlite3_stmt*, int iCol); +int sqlite3_column_int(sqlite3_stmt*, int iCol); +sqlite3_int64 sqlite3_column_int64(sqlite3_stmt*, int iCol); +const unsigned char *sqlite3_column_text(sqlite3_stmt*, int iCol); +const void *sqlite3_column_text16(sqlite3_stmt*, int iCol); +int sqlite3_column_type(sqlite3_stmt*, int iCol); +sqlite3_value *sqlite3_column_value(sqlite3_stmt*, int iCol); + +/* +** CAPI3REF: Destroy A Prepared Statement Object +** +** The sqlite3_finalize() function is called to delete a +** [sqlite3_stmt | compiled SQL statement]. If the statement was +** executed successfully, or not executed at all, then SQLITE_OK is returned. +** If execution of the statement failed then an +** [SQLITE_ERROR | error code] or [SQLITE_IOERR_READ | extended error code] +** is returned. +** +** This routine can be called at any point during the execution of the +** [sqlite3_stmt | virtual machine]. If the virtual machine has not +** completed execution when this routine is called, that is like +** encountering an error or an interrupt. (See [sqlite3_interrupt()].) +** Incomplete updates may be rolled back and transactions cancelled, +** depending on the circumstances, and the +** [SQLITE_ERROR | result code] returned will be [SQLITE_ABORT]. +*/ +int sqlite3_finalize(sqlite3_stmt *pStmt); + +/* +** CAPI3REF: Reset A Prepared Statement Object +** +** The sqlite3_reset() function is called to reset a +** [sqlite3_stmt | compiled SQL statement] object. +** back to it's initial state, ready to be re-executed. +** Any SQL statement variables that had values bound to them using +** the [sqlite3_bind_blob | sqlite3_bind_*() API] retain their values. +** Use [sqlite3_clear_bindings()] to reset the bindings. +*/ +int sqlite3_reset(sqlite3_stmt *pStmt); + +/* +** CAPI3REF: Create Or Redefine SQL Functions +** +** The following two functions are used to add SQL functions or aggregates +** or to redefine the behavior of existing SQL functions or aggregates. The +** difference only between the two is that the second parameter, the +** name of the (scalar) function or aggregate, is encoded in UTF-8 for +** sqlite3_create_function() and UTF-16 for sqlite3_create_function16(). +** +** The first argument is the [sqlite3 | database handle] that holds the +** SQL function or aggregate is to be added or redefined. If a single +** program uses more than one database handle internally, then SQL +** functions or aggregates must be added individually to each database +** handle with which they will be used. +** +** The second parameter is the name of the SQL function to be created +** or redefined. +** The length of the name is limited to 255 bytes, exclusive of the +** zero-terminator. Note that the name length limit is in bytes, not +** characters. Any attempt to create a function with a longer name +** will result in an SQLITE_ERROR error. +** +** The third parameter is the number of arguments that the SQL function or +** aggregate takes. If this parameter is negative, then the SQL function or +** aggregate may take any number of arguments. +** +** The fourth parameter, eTextRep, specifies what +** [SQLITE_UTF8 | text encoding] this SQL function prefers for +** its parameters. Any SQL function implementation should be able to work +** work with UTF-8, UTF-16le, or UTF-16be. But some implementations may be +** more efficient with one encoding than another. It is allowed to +** invoke sqlite3_create_function() or sqlite3_create_function16() multiple +** times with the same function but with different values of eTextRep. +** When multiple implementations of the same function are available, SQLite +** will pick the one that involves the least amount of data conversion. +** If there is only a single implementation which does not care what +** text encoding is used, then the fourth argument should be +** [SQLITE_ANY]. +** +** The fifth parameter is an arbitrary pointer. The implementation +** of the function can gain access to this pointer using +** [sqlite3_user_data()]. +** +** The seventh, eighth and ninth parameters, xFunc, xStep and xFinal, are +** pointers to C-language functions that implement the SQL +** function or aggregate. A scalar SQL function requires an implementation of +** the xFunc callback only, NULL pointers should be passed as the xStep +** and xFinal parameters. An aggregate SQL function requires an implementation +** of xStep and xFinal and NULL should be passed for xFunc. To delete an +** existing SQL function or aggregate, pass NULL for all three function +** callback. +** +** It is permitted to register multiple implementations of the same +** functions with the same name but with either differing numbers of +** arguments or differing perferred text encodings. SQLite will use +** the implementation most closely matches the way in which the +** SQL function is used. +*/ +int sqlite3_create_function( + sqlite3 *, + const char *zFunctionName, + int nArg, + int eTextRep, + void*, + void (*xFunc)(sqlite3_context*,int,sqlite3_value**), + void (*xStep)(sqlite3_context*,int,sqlite3_value**), + void (*xFinal)(sqlite3_context*) +); +int sqlite3_create_function16( + sqlite3*, + const void *zFunctionName, + int nArg, + int eTextRep, + void*, + void (*xFunc)(sqlite3_context*,int,sqlite3_value**), + void (*xStep)(sqlite3_context*,int,sqlite3_value**), + void (*xFinal)(sqlite3_context*) +); + +/* +** CAPI3REF: Text Encodings +** +** These constant define integer codes that represent the various +** text encodings supported by SQLite. +*/ +#define SQLITE_UTF8 1 +#define SQLITE_UTF16LE 2 +#define SQLITE_UTF16BE 3 +#define SQLITE_UTF16 4 /* Use native byte order */ +#define SQLITE_ANY 5 /* sqlite3_create_function only */ +#define SQLITE_UTF16_ALIGNED 8 /* sqlite3_create_collation only */ + +/* +** CAPI3REF: Obsolete Functions +** +** These functions are all now obsolete. In order to maintain +** backwards compatibility with older code, we continue to support +** these functions. However, new development projects should avoid +** the use of these functions. To help encourage people to avoid +** using these functions, we are not going to tell you want they do. +*/ +int sqlite3_aggregate_count(sqlite3_context*); +int sqlite3_expired(sqlite3_stmt*); +int sqlite3_transfer_bindings(sqlite3_stmt*, sqlite3_stmt*); +int sqlite3_global_recover(void); +void sqlite3_thread_cleanup(void); +int sqlite3_memory_alarm(void(*)(void*,sqlite3_int64,int),void*,sqlite3_int64); + +/* +** CAPI3REF: Obtaining SQL Function Parameter Values +** +** The C-language implementation of SQL functions and aggregates uses +** this set of interface routines to access the parameter values on +** the function or aggregate. +** +** The xFunc (for scalar functions) or xStep (for aggregates) parameters +** to [sqlite3_create_function()] and [sqlite3_create_function16()] +** define callbacks that implement the SQL functions and aggregates. +** The 4th parameter to these callbacks is an array of pointers to +** [sqlite3_value] objects. There is one [sqlite3_value] object for +** each parameter to the SQL function. These routines are used to +** extract values from the [sqlite3_value] objects. +** +** These routines work just like the corresponding +** [sqlite3_column_blob | sqlite3_column_* routines] except that +** these routines take a single [sqlite3_value*] pointer instead +** of an [sqlite3_stmt*] pointer and an integer column number. +** +** The sqlite3_value_text16() interface extracts a UTF16 string +** in the native byte-order of the host machine. The +** sqlite3_value_text16be() and sqlite3_value_text16le() interfaces +** extract UTF16 strings as big-endian and little-endian respectively. +** +** The sqlite3_value_numeric_type() interface attempts to apply +** numeric affinity to the value. This means that an attempt is +** made to convert the value to an integer or floating point. If +** such a conversion is possible without loss of information (in order +** words if the value is original a string that looks like a number) +** then it is done. Otherwise no conversion occurs. The +** [SQLITE_INTEGER | datatype] after conversion is returned. +** +** Please pay particular attention to the fact that the pointer that +** is returned from [sqlite3_value_blob()], [sqlite3_value_text()], or +** [sqlite3_value_text16()] can be invalidated by a subsequent call to +** [sqlite3_value_bytes()], [sqlite3_value_bytes16()], [sqlite3_value_text()], +** or [sqlite3_value_text16()]. +** +** These routines must be called from the same thread as +** the SQL function that supplied the sqlite3_value* parameters. +** Or, if the sqlite3_value* argument comes from the [sqlite3_column_value()] +** interface, then these routines should be called from the same thread +** that ran [sqlite3_column_value()]. +*/ +const void *sqlite3_value_blob(sqlite3_value*); +int sqlite3_value_bytes(sqlite3_value*); +int sqlite3_value_bytes16(sqlite3_value*); +double sqlite3_value_double(sqlite3_value*); +int sqlite3_value_int(sqlite3_value*); +sqlite3_int64 sqlite3_value_int64(sqlite3_value*); +const unsigned char *sqlite3_value_text(sqlite3_value*); +const void *sqlite3_value_text16(sqlite3_value*); +const void *sqlite3_value_text16le(sqlite3_value*); +const void *sqlite3_value_text16be(sqlite3_value*); +int sqlite3_value_type(sqlite3_value*); +int sqlite3_value_numeric_type(sqlite3_value*); + +/* +** CAPI3REF: Obtain Aggregate Function Context +** +** The implementation of aggregate SQL functions use this routine to allocate +** a structure for storing their state. The first time this routine +** is called for a particular aggregate, a new structure of size nBytes +** is allocated, zeroed, and returned. On subsequent calls (for the +** same aggregate instance) the same buffer is returned. The implementation +** of the aggregate can use the returned buffer to accumulate data. +** +** The buffer allocated is freed automatically by SQLite whan the aggregate +** query concludes. +** +** The first parameter should be a copy of the +** [sqlite3_context | SQL function context] that is the first +** parameter to the callback routine that implements the aggregate +** function. +** +** This routine must be called from the same thread in which +** the aggregate SQL function is running. +*/ +void *sqlite3_aggregate_context(sqlite3_context*, int nBytes); + +/* +** CAPI3REF: User Data For Functions +** +** The pUserData parameter to the [sqlite3_create_function()] +** and [sqlite3_create_function16()] routines +** used to register user functions is available to +** the implementation of the function using this call. +** +** This routine must be called from the same thread in which +** the SQL function is running. +*/ +void *sqlite3_user_data(sqlite3_context*); + +/* +** CAPI3REF: Function Auxiliary Data +** +** The following two functions may be used by scalar SQL functions to +** associate meta-data with argument values. If the same value is passed to +** multiple invocations of the same SQL function during query execution, under +** some circumstances the associated meta-data may be preserved. This may +** be used, for example, to add a regular-expression matching scalar +** function. The compiled version of the regular expression is stored as +** meta-data associated with the SQL value passed as the regular expression +** pattern. The compiled regular expression can be reused on multiple +** invocations of the same function so that the original pattern string +** does not need to be recompiled on each invocation. +** +** The sqlite3_get_auxdata() interface returns a pointer to the meta-data +** associated with the Nth argument value to the current SQL function +** call, where N is the second parameter. If no meta-data has been set for +** that value, then a NULL pointer is returned. +** +** The sqlite3_set_auxdata() is used to associate meta-data with an SQL +** function argument. The third parameter is a pointer to the meta-data +** to be associated with the Nth user function argument value. The fourth +** parameter specifies a destructor that will be called on the meta- +** data pointer to release it when it is no longer required. If the +** destructor is NULL, it is not invoked. +** +** In practice, meta-data is preserved between function calls for +** expressions that are constant at compile time. This includes literal +** values and SQL variables. +** +** These routines must be called from the same thread in which +** the SQL function is running. +*/ +void *sqlite3_get_auxdata(sqlite3_context*, int); +void sqlite3_set_auxdata(sqlite3_context*, int, void*, void (*)(void*)); + + +/* +** CAPI3REF: Constants Defining Special Destructor Behavior +** +** These are special value for the destructor that is passed in as the +** final argument to routines like [sqlite3_result_blob()]. If the destructor +** argument is SQLITE_STATIC, it means that the content pointer is constant +** and will never change. It does not need to be destroyed. The +** SQLITE_TRANSIENT value means that the content will likely change in +** the near future and that SQLite should make its own private copy of +** the content before returning. +** +** The typedef is necessary to work around problems in certain +** C++ compilers. See ticket #2191. +*/ +typedef void (*sqlite3_destructor_type)(void*); +#define SQLITE_STATIC ((sqlite3_destructor_type)0) +#define SQLITE_TRANSIENT ((sqlite3_destructor_type)-1) + +/* +** CAPI3REF: Setting The Result Of An SQL Function +** +** These routines are used by the xFunc or xFinal callbacks that +** implement SQL functions and aggregates. See +** [sqlite3_create_function()] and [sqlite3_create_function16()] +** for additional information. +** +** These functions work very much like the +** [sqlite3_bind_blob | sqlite3_bind_*] family of functions used +** to bind values to host parameters in prepared statements. +** Refer to the +** [sqlite3_bind_blob | sqlite3_bind_* documentation] for +** additional information. +** +** The sqlite3_result_error() and sqlite3_result_error16() functions +** cause the implemented SQL function to throw an exception. The +** parameter to sqlite3_result_error() or sqlite3_result_error16() +** is the text of an error message. +** +** The sqlite3_result_toobig() cause the function implementation +** to throw and error indicating that a string or BLOB is to long +** to represent. +** +** These routines must be called from within the same thread as +** the SQL function associated with the [sqlite3_context] pointer. +*/ +void sqlite3_result_blob(sqlite3_context*, const void*, int, void(*)(void*)); +void sqlite3_result_double(sqlite3_context*, double); +void sqlite3_result_error(sqlite3_context*, const char*, int); +void sqlite3_result_error16(sqlite3_context*, const void*, int); +void sqlite3_result_error_toobig(sqlite3_context*); +void sqlite3_result_error_nomem(sqlite3_context*); +void sqlite3_result_int(sqlite3_context*, int); +void sqlite3_result_int64(sqlite3_context*, sqlite3_int64); +void sqlite3_result_null(sqlite3_context*); +void sqlite3_result_text(sqlite3_context*, const char*, int, void(*)(void*)); +void sqlite3_result_text16(sqlite3_context*, const void*, int, void(*)(void*)); +void sqlite3_result_text16le(sqlite3_context*, const void*, int,void(*)(void*)); +void sqlite3_result_text16be(sqlite3_context*, const void*, int,void(*)(void*)); +void sqlite3_result_value(sqlite3_context*, sqlite3_value*); +void sqlite3_result_zeroblob(sqlite3_context*, int n); + +/* +** CAPI3REF: Define New Collating Sequences +** +** These functions are used to add new collation sequences to the +** [sqlite3*] handle specified as the first argument. +** +** The name of the new collation sequence is specified as a UTF-8 string +** for sqlite3_create_collation() and sqlite3_create_collation_v2() +** and a UTF-16 string for sqlite3_create_collation16(). In all cases +** the name is passed as the second function argument. +** +** The third argument may be one of the constants [SQLITE_UTF8], +** [SQLITE_UTF16LE] or [SQLITE_UTF16BE], indicating that the user-supplied +** routine expects to be passed pointers to strings encoded using UTF-8, +** UTF-16 little-endian or UTF-16 big-endian respectively. The +** third argument might also be [SQLITE_UTF16_ALIGNED] to indicate that +** the routine expects pointers to 16-bit word aligned strings +** of UTF16 in the native byte order of the host computer. +** +** A pointer to the user supplied routine must be passed as the fifth +** argument. If it is NULL, this is the same as deleting the collation +** sequence (so that SQLite cannot call it anymore). Each time the user +** supplied function is invoked, it is passed a copy of the void* passed as +** the fourth argument to sqlite3_create_collation() or +** sqlite3_create_collation16() as its first parameter. +** +** The remaining arguments to the user-supplied routine are two strings, +** each represented by a [length, data] pair and encoded in the encoding +** that was passed as the third argument when the collation sequence was +** registered. The user routine should return negative, zero or positive if +** the first string is less than, equal to, or greater than the second +** string. i.e. (STRING1 - STRING2). +** +** The sqlite3_create_collation_v2() works like sqlite3_create_collation() +** excapt that it takes an extra argument which is a destructor for +** the collation. The destructor is called when the collation is +** destroyed and is passed a copy of the fourth parameter void* pointer +** of the sqlite3_create_collation_v2(). Collations are destroyed when +** they are overridden by later calls to the collation creation functions +** or when the [sqlite3*] database handle is closed using [sqlite3_close()]. +** +** The sqlite3_create_collation_v2() interface is experimental and +** subject to change in future releases. The other collation creation +** functions are stable. +*/ +int sqlite3_create_collation( + sqlite3*, + const char *zName, + int eTextRep, + void*, + int(*xCompare)(void*,int,const void*,int,const void*) +); +int sqlite3_create_collation_v2( + sqlite3*, + const char *zName, + int eTextRep, + void*, + int(*xCompare)(void*,int,const void*,int,const void*), + void(*xDestroy)(void*) +); +int sqlite3_create_collation16( + sqlite3*, + const char *zName, + int eTextRep, + void*, + int(*xCompare)(void*,int,const void*,int,const void*) +); + +/* +** CAPI3REF: 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 handle to be called whenever an undefined collation sequence is +** required. +** +** If the function is registered using the sqlite3_collation_needed() API, +** then it is passed the names of undefined collation sequences as strings +** encoded in UTF-8. If sqlite3_collation_needed16() is used, the names +** are passed as UTF-16 in machine native byte order. A call to either +** function replaces any existing callback. +** +** When the callback is invoked, the first argument passed is a copy +** of the second argument to sqlite3_collation_needed() or +** sqlite3_collation_needed16(). The second argument is the database +** handle. The third argument is one of [SQLITE_UTF8], [SQLITE_UTF16BE], or +** [SQLITE_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 +** [sqlite3_create_collation()], [sqlite3_create_collation16()], or +** [sqlite3_create_collation_v2()]. +*/ +int sqlite3_collation_needed( + sqlite3*, + void*, + void(*)(void*,sqlite3*,int eTextRep,const char*) +); +int sqlite3_collation_needed16( + sqlite3*, + void*, + void(*)(void*,sqlite3*,int eTextRep,const void*) +); + +/* +** Specify the key for an encrypted database. This routine should be +** called right after sqlite3_open(). +** +** The code to implement this API is not available in the public release +** of SQLite. +*/ +int sqlite3_key( + sqlite3 *db, /* Database to be rekeyed */ + const void *pKey, int nKey /* The key */ +); + +/* +** Change the key on an open database. If the current database is not +** encrypted, this routine will encrypt it. If pNew==0 or nNew==0, the +** database is decrypted. +** +** The code to implement this API is not available in the public release +** of SQLite. +*/ +int sqlite3_rekey( + sqlite3 *db, /* Database to be rekeyed */ + const void *pKey, int nKey /* The new key */ +); + +/* +** CAPI3REF: Suspend Execution For A Short Time +** +** This function causes the current thread to suspend execution +** a number of milliseconds specified in its parameter. +** +** If the operating system does not support sleep requests with +** millisecond time resolution, then the time will be rounded up to +** the nearest second. The number of milliseconds of sleep actually +** requested from the operating system is returned. +** +** SQLite implements this interface by calling the xSleep() +** method of the default [sqlite3_vfs] object. +*/ +int sqlite3_sleep(int); + +/* +** CAPI3REF: Name Of The Folder Holding Temporary Files +** +** If this global variable is made to point to a string which is +** the name of a folder (a.ka. directory), then all temporary files +** created by SQLite will be placed in that directory. If this variable +** is NULL pointer, then SQLite does a search for an appropriate temporary +** file directory. +** +** It is not safe to modify this variable once a database connection +** has been opened. It is intended that this variable be set once +** as part of process initialization and before any SQLite interface +** routines have been call and remain unchanged thereafter. +*/ +SQLITE_EXTERN char *sqlite3_temp_directory; + +/* +** CAPI3REF: Test To See If The Database Is In Auto-Commit Mode +** +** Test to see whether or not the database connection is in autocommit +** mode. Return TRUE if it is and FALSE if not. Autocommit mode is on +** by default. Autocommit is disabled by a BEGIN statement and reenabled +** by the next COMMIT or ROLLBACK. +** +** If certain kinds of errors occur on a statement within a multi-statement +** transactions (errors including [SQLITE_FULL], [SQLITE_IOERR], +** [SQLITE_NOMEM], [SQLITE_BUSY], and [SQLITE_INTERRUPT]) then the +** transaction might be rolled back automatically. The only way to +** find out if SQLite automatically rolled back the transaction after +** an error is to use this function. +** +** If another thread changes the autocommit status of the database +** connection while this routine is running, then the return value +** is undefined. +*/ +int sqlite3_get_autocommit(sqlite3*); + +/* +** CAPI3REF: Find The Database Handle Associated With A Prepared Statement +** +** Return the [sqlite3*] database handle to which a +** [sqlite3_stmt | prepared statement] belongs. +** This is the same database handle that was +** the first argument to the [sqlite3_prepare_v2()] or its variants +** that was used to create the statement in the first place. +*/ +sqlite3 *sqlite3_db_handle(sqlite3_stmt*); + + +/* +** CAPI3REF: Commit And Rollback Notification Callbacks +** +** These routines +** register callback functions to be invoked whenever a transaction +** is committed or rolled back. The pArg argument is passed through +** to the callback. If the callback on a commit hook function +** returns non-zero, then the commit is converted into a rollback. +** +** If another function was previously registered, its pArg value is returned. +** Otherwise NULL is returned. +** +** Registering a NULL function disables the callback. +** +** For the purposes of this API, a transaction is said to have been +** rolled back if an explicit "ROLLBACK" statement is executed, or +** an error or constraint causes an implicit rollback to occur. The +** callback is not invoked if a transaction is automatically rolled +** back because the database connection is closed. +** +** These are experimental interfaces and are subject to change. +*/ +void *sqlite3_commit_hook(sqlite3*, int(*)(void*), void*); +void *sqlite3_rollback_hook(sqlite3*, void(*)(void *), void*); + +/* +** CAPI3REF: Data Change Notification Callbacks +** +** Register a callback function with the database connection identified by the +** first argument to be invoked whenever a row is updated, inserted or deleted. +** Any callback set by a previous call to this function for the same +** database connection is overridden. +** +** The second argument is a pointer to the function to invoke when a +** row is updated, inserted or deleted. The first argument to the callback is +** a copy of the third argument to sqlite3_update_hook(). The second callback +** argument is one of SQLITE_INSERT, SQLITE_DELETE or SQLITE_UPDATE, depending +** on the operation that caused the callback to be invoked. The third and +** fourth arguments to the callback contain pointers to the database and +** table name containing the affected row. The final callback parameter is +** the rowid of the row. In the case of an update, this is the rowid after +** the update takes place. +** +** The update hook is not invoked when internal system tables are +** modified (i.e. sqlite_master and sqlite_sequence). +** +** If another function was previously registered, its pArg value is returned. +** Otherwise NULL is returned. +*/ +void *sqlite3_update_hook( + sqlite3*, + void(*)(void *,int ,char const *,char const *,sqlite3_int64), + void* +); + +/* +** CAPI3REF: Enable Or Disable Shared Pager Cache +** +** This routine enables or disables the sharing of the database cache +** and schema data structures between connections to the same database. +** Sharing is enabled if the argument is true and disabled if the argument +** is false. +** +** Beginning in SQLite version 3.5.0, cache sharing is enabled and disabled +** for an entire process. In prior versions of SQLite, sharing was +** enabled or disabled for each thread separately. +** +** The cache sharing mode set by this interface effects all subsequent +** calls to [sqlite3_open()], [sqlite3_open_v2()], and [sqlite3_open16()]. +** Existing database connections continue use the sharing mode that was +** in effect at the time they were opened. +** +** Virtual tables cannot be used with a shared cache. When shared +** cache is enabled, the [sqlite3_create_module()] API used to register +** virtual tables will always return an error. +** +** This routine returns [SQLITE_OK] if shared cache was +** enabled or disabled successfully. An [SQLITE_ERROR | error code] +** is returned otherwise. +** +** Shared cache is disabled by default. But this might change in +** future releases of SQLite. Applications that care about shared +** cache setting should set it explicitly. +*/ +int sqlite3_enable_shared_cache(int); + +/* +** CAPI3REF: Attempt To Free Heap Memory +** +** Attempt to free N bytes of heap memory by deallocating non-essential +** memory allocations held by the database library (example: memory +** used to cache database pages to improve performance). +*/ +int sqlite3_release_memory(int); + +/* +** CAPI3REF: Impose A Limit On Heap Size +** +** Place a "soft" limit on the amount of heap memory that may be allocated +** by SQLite. If an internal allocation is requested +** that would exceed the specified limit, [sqlite3_release_memory()] is +** invoked one or more times to free up some space before the allocation +** is made. +** +** The limit is called "soft", because if [sqlite3_release_memory()] cannot +** free sufficient memory to prevent the limit from being exceeded, +** the memory is allocated anyway and the current operation proceeds. +** +** A negative or zero value for N means that there is no soft heap limit and +** [sqlite3_release_memory()] will only be called when memory is exhausted. +** The default value for the soft heap limit is zero. +** +** SQLite makes a best effort to honor the soft heap limit. But if it +** is unable to reduce memory usage below the soft limit, execution will +** continue without error or notification. This is why the limit is +** called a "soft" limit. It is advisory only. +** +** Prior to SQLite version 3.5.0, this routine only constrained the memory +** allocated by a single thread - the same thread in which this routine +** runs. Beginning with SQLite version 3.5.0, the soft heap limit is +** applied to all threads. The value specified for the soft heap limit +** is an upper bound on the total memory allocation for all threads. In +** version 3.5.0 there is no mechanism for limiting the heap usage for +** individual threads. +*/ +void sqlite3_soft_heap_limit(int); + +/* +** CAPI3REF: Extract Metadata About A Column Of A Table +** +** This routine +** returns meta-data about a specific column of a specific database +** table accessible using the connection handle passed as the first function +** argument. +** +** The column is identified by the second, third and fourth parameters to +** this function. The second parameter is either the name of the database +** (i.e. "main", "temp" or an attached database) containing the specified +** table or NULL. If it is NULL, then all attached databases are searched +** for the table using the same algorithm as the database engine uses to +** resolve unqualified table references. +** +** The third and fourth parameters to this function are the table and column +** name of the desired column, respectively. Neither of these parameters +** may be NULL. +** +** Meta information is returned by writing to the memory locations passed as +** the 5th and subsequent parameters to this function. Any of these +** arguments may be NULL, in which case the corresponding element of meta +** information is ommitted. +** +** <pre> +** Parameter Output Type Description +** ----------------------------------- +** +** 5th const char* Data type +** 6th const char* Name of the default collation sequence +** 7th int True if the column has a NOT NULL constraint +** 8th int True if the column is part of the PRIMARY KEY +** 9th int True if the column is AUTOINCREMENT +** </pre> +** +** +** The memory pointed to by the character pointers returned for the +** declaration type and collation sequence is valid only until the next +** call to any sqlite API function. +** +** If the specified table is actually a view, then an error is returned. +** +** If the specified column is "rowid", "oid" or "_rowid_" and an +** INTEGER PRIMARY KEY column has been explicitly declared, then the output +** parameters are set for the explicitly declared column. If there is no +** explicitly declared IPK column, then the output parameters are set as +** follows: +** +** <pre> +** data type: "INTEGER" +** collation sequence: "BINARY" +** not null: 0 +** primary key: 1 +** auto increment: 0 +** </pre> +** +** This function may load one or more schemas from database files. If an +** error occurs during this process, or if the requested table or column +** cannot be found, an SQLITE error code is returned and an error message +** left in the database handle (to be retrieved using sqlite3_errmsg()). +** +** This API is only available if the library was compiled with the +** SQLITE_ENABLE_COLUMN_METADATA preprocessor symbol defined. +*/ +int sqlite3_table_column_metadata( + sqlite3 *db, /* Connection handle */ + const char *zDbName, /* Database name or NULL */ + const char *zTableName, /* Table name */ + const char *zColumnName, /* Column name */ + char const **pzDataType, /* OUTPUT: Declared data type */ + char const **pzCollSeq, /* OUTPUT: Collation sequence name */ + int *pNotNull, /* OUTPUT: True if NOT NULL constraint exists */ + int *pPrimaryKey, /* OUTPUT: True if column part of PK */ + int *pAutoinc /* OUTPUT: True if column is auto-increment */ +); + +/* +** CAPI3REF: Load An Extension +** +** Attempt to load an SQLite extension library contained in the file +** zFile. The entry point is zProc. zProc may be 0 in which case the +** name of the entry point defaults to "sqlite3_extension_init". +** +** Return [SQLITE_OK] on success and [SQLITE_ERROR] if something goes wrong. +** +** If an error occurs and pzErrMsg is not 0, then fill *pzErrMsg with +** error message text. The calling function should free this memory +** by calling [sqlite3_free()]. +** +** Extension loading must be enabled using [sqlite3_enable_load_extension()] +** prior to calling this API or an error will be returned. +*/ +int sqlite3_load_extension( + sqlite3 *db, /* Load the extension into this database connection */ + const char *zFile, /* Name of the shared library containing extension */ + const char *zProc, /* Entry point. Derived from zFile if 0 */ + char **pzErrMsg /* Put error message here if not 0 */ +); + +/* +** CAPI3REF: Enable Or Disable Extension Loading +** +** So as not to open security holes in older applications that are +** unprepared to deal with extension loading, and as a means of disabling +** extension loading while evaluating user-entered SQL, the following +** API is provided to turn the [sqlite3_load_extension()] mechanism on and +** off. It is off by default. See ticket #1863. +** +** Call this routine with onoff==1 to turn extension loading on +** and call it with onoff==0 to turn it back off again. +*/ +int sqlite3_enable_load_extension(sqlite3 *db, int onoff); + +/* +** CAPI3REF: Make Arrangements To Automatically Load An Extension +** +** Register an extension entry point that is automatically invoked +** whenever a new database connection is opened using +** [sqlite3_open()], [sqlite3_open16()], or [sqlite3_open_v2()]. +** +** This API can be invoked at program startup in order to register +** one or more statically linked extensions that will be available +** to all new database connections. +** +** Duplicate extensions are detected so calling this routine multiple +** times with the same extension is harmless. +** +** This routine stores a pointer to the extension in an array +** that is obtained from malloc(). If you run a memory leak +** checker on your program and it reports a leak because of this +** array, then invoke [sqlite3_reset_auto_extension()] prior +** to shutdown to free the memory. +** +** Automatic extensions apply across all threads. +** +** This interface is experimental and is subject to change or +** removal in future releases of SQLite. +*/ +int sqlite3_auto_extension(void *xEntryPoint); + + +/* +** CAPI3REF: Reset Automatic Extension Loading +** +** Disable all previously registered automatic extensions. This +** routine undoes the effect of all prior [sqlite3_automatic_extension()] +** calls. +** +** This call disabled automatic extensions in all threads. +** +** This interface is experimental and is subject to change or +** removal in future releases of SQLite. +*/ +void sqlite3_reset_auto_extension(void); + + +/* +****** EXPERIMENTAL - subject to change without notice ************** +** +** The interface to the virtual-table mechanism is currently considered +** to be experimental. The interface might change in incompatible ways. +** If this is a problem for you, do not use the interface at this time. +** +** When the virtual-table mechanism stablizes, we will declare the +** interface fixed, support it indefinitely, and remove this comment. +*/ + +/* +** Structures used by the virtual table interface +*/ +typedef struct sqlite3_vtab sqlite3_vtab; +typedef struct sqlite3_index_info sqlite3_index_info; +typedef struct sqlite3_vtab_cursor sqlite3_vtab_cursor; +typedef struct sqlite3_module sqlite3_module; + +/* +** A module is a class of virtual tables. Each module is defined +** by an instance of the following structure. This structure consists +** mostly of methods for the module. +*/ +struct sqlite3_module { + int iVersion; + int (*xCreate)(sqlite3*, void *pAux, + int argc, const char *const*argv, + sqlite3_vtab **ppVTab, char**); + int (*xConnect)(sqlite3*, void *pAux, + int argc, const char *const*argv, + sqlite3_vtab **ppVTab, char**); + int (*xBestIndex)(sqlite3_vtab *pVTab, sqlite3_index_info*); + int (*xDisconnect)(sqlite3_vtab *pVTab); + int (*xDestroy)(sqlite3_vtab *pVTab); + int (*xOpen)(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor); + int (*xClose)(sqlite3_vtab_cursor*); + int (*xFilter)(sqlite3_vtab_cursor*, int idxNum, const char *idxStr, + int argc, sqlite3_value **argv); + int (*xNext)(sqlite3_vtab_cursor*); + int (*xEof)(sqlite3_vtab_cursor*); + int (*xColumn)(sqlite3_vtab_cursor*, sqlite3_context*, int); + int (*xRowid)(sqlite3_vtab_cursor*, sqlite3_int64 *pRowid); + int (*xUpdate)(sqlite3_vtab *, int, sqlite3_value **, sqlite3_int64 *); + int (*xBegin)(sqlite3_vtab *pVTab); + int (*xSync)(sqlite3_vtab *pVTab); + int (*xCommit)(sqlite3_vtab *pVTab); + int (*xRollback)(sqlite3_vtab *pVTab); + int (*xFindFunction)(sqlite3_vtab *pVtab, int nArg, const char *zName, + void (**pxFunc)(sqlite3_context*,int,sqlite3_value**), + void **ppArg); + + int (*xRename)(sqlite3_vtab *pVtab, const char *zNew); +}; + +/* +** The sqlite3_index_info structure and its substructures is used to +** pass information into and receive the reply from the xBestIndex +** method of an sqlite3_module. The fields under **Inputs** are the +** inputs to xBestIndex and are read-only. xBestIndex inserts its +** results into the **Outputs** fields. +** +** The aConstraint[] array records WHERE clause constraints of the +** form: +** +** column OP expr +** +** Where OP is =, <, <=, >, or >=. The particular operator is stored +** in aConstraint[].op. The index of the column is stored in +** aConstraint[].iColumn. aConstraint[].usable is TRUE if the +** expr on the right-hand side can be evaluated (and thus the constraint +** is usable) and false if it cannot. +** +** The optimizer automatically inverts terms of the form "expr OP column" +** and makes other simplifications to the WHERE clause in an attempt to +** get as many WHERE clause terms into the form shown above as possible. +** The aConstraint[] array only reports WHERE clause terms in the correct +** form that refer to the particular virtual table being queried. +** +** Information about the ORDER BY clause is stored in aOrderBy[]. +** Each term of aOrderBy records a column of the ORDER BY clause. +** +** The xBestIndex method must fill aConstraintUsage[] with information +** about what parameters to pass to xFilter. If argvIndex>0 then +** the right-hand side of the corresponding aConstraint[] is evaluated +** and becomes the argvIndex-th entry in argv. If aConstraintUsage[].omit +** is true, then the constraint is assumed to be fully handled by the +** virtual table and is not checked again by SQLite. +** +** The idxNum and idxPtr values are recorded and passed into xFilter. +** sqlite3_free() is used to free idxPtr if needToFreeIdxPtr is true. +** +** The orderByConsumed means that output from xFilter will occur in +** the correct order to satisfy the ORDER BY clause so that no separate +** sorting step is required. +** +** The estimatedCost value is an estimate of the cost of doing the +** particular lookup. A full scan of a table with N entries should have +** a cost of N. A binary search of a table of N entries should have a +** cost of approximately log(N). +*/ +struct sqlite3_index_info { + /* Inputs */ + int nConstraint; /* Number of entries in aConstraint */ + struct sqlite3_index_constraint { + int iColumn; /* Column on left-hand side of constraint */ + unsigned char op; /* Constraint operator */ + unsigned char usable; /* True if this constraint is usable */ + int iTermOffset; /* Used internally - xBestIndex should ignore */ + } *aConstraint; /* Table of WHERE clause constraints */ + int nOrderBy; /* Number of terms in the ORDER BY clause */ + struct sqlite3_index_orderby { + int iColumn; /* Column number */ + unsigned char desc; /* True for DESC. False for ASC. */ + } *aOrderBy; /* The ORDER BY clause */ + + /* Outputs */ + struct sqlite3_index_constraint_usage { + int argvIndex; /* if >0, constraint is part of argv to xFilter */ + unsigned char omit; /* Do not code a test for this constraint */ + } *aConstraintUsage; + int idxNum; /* Number used to identify the index */ + char *idxStr; /* String, possibly obtained from sqlite3_malloc */ + int needToFreeIdxStr; /* Free idxStr using sqlite3_free() if true */ + int orderByConsumed; /* True if output is already ordered */ + double estimatedCost; /* Estimated cost of using this index */ +}; +#define SQLITE_INDEX_CONSTRAINT_EQ 2 +#define SQLITE_INDEX_CONSTRAINT_GT 4 +#define SQLITE_INDEX_CONSTRAINT_LE 8 +#define SQLITE_INDEX_CONSTRAINT_LT 16 +#define SQLITE_INDEX_CONSTRAINT_GE 32 +#define SQLITE_INDEX_CONSTRAINT_MATCH 64 + +/* +** This routine is used to register a new module name with an SQLite +** connection. Module names must be registered before creating new +** virtual tables on the module, or before using preexisting virtual +** tables of the module. +*/ +int sqlite3_create_module( + sqlite3 *db, /* SQLite connection to register module with */ + const char *zName, /* Name of the module */ + const sqlite3_module *, /* Methods for the module */ + void * /* Client data for xCreate/xConnect */ +); + +/* +** This routine is identical to the sqlite3_create_module() method above, +** except that it allows a destructor function to be specified. It is +** even more experimental than the rest of the virtual tables API. +*/ +int sqlite3_create_module_v2( + sqlite3 *db, /* SQLite connection to register module with */ + const char *zName, /* Name of the module */ + const sqlite3_module *, /* Methods for the module */ + void *, /* Client data for xCreate/xConnect */ + void(*xDestroy)(void*) /* Module destructor function */ +); + +/* +** Every module implementation uses a subclass of the following structure +** to describe a particular instance of the module. Each subclass will +** be tailored to the specific needs of the module implementation. The +** purpose of this superclass is to define certain fields that are common +** to all module implementations. +** +** Virtual tables methods can set an error message by assigning a +** string obtained from sqlite3_mprintf() to zErrMsg. The method should +** take care that any prior string is freed by a call to sqlite3_free() +** prior to assigning a new string to zErrMsg. After the error message +** is delivered up to the client application, the string will be automatically +** freed by sqlite3_free() and the zErrMsg field will be zeroed. Note +** that sqlite3_mprintf() and sqlite3_free() are used on the zErrMsg field +** since virtual tables are commonly implemented in loadable extensions which +** do not have access to sqlite3MPrintf() or sqlite3Free(). +*/ +struct sqlite3_vtab { + const sqlite3_module *pModule; /* The module for this virtual table */ + int nRef; /* Used internally */ + char *zErrMsg; /* Error message from sqlite3_mprintf() */ + /* Virtual table implementations will typically add additional fields */ +}; + +/* Every module implementation uses a subclass of the following structure +** to describe cursors that point into the virtual table and are used +** to loop through the virtual table. Cursors are created using the +** xOpen method of the module. Each module implementation will define +** the content of a cursor structure to suit its own needs. +** +** This superclass exists in order to define fields of the cursor that +** are common to all implementations. +*/ +struct sqlite3_vtab_cursor { + sqlite3_vtab *pVtab; /* Virtual table of this cursor */ + /* Virtual table implementations will typically add additional fields */ +}; + +/* +** The xCreate and xConnect methods of a module use the following API +** to declare the format (the names and datatypes of the columns) of +** the virtual tables they implement. +*/ +int sqlite3_declare_vtab(sqlite3*, const char *zCreateTable); + +/* +** Virtual tables can provide alternative implementations of functions +** using the xFindFunction method. But global versions of those functions +** must exist in order to be overloaded. +** +** This API makes sure a global version of a function with a particular +** name and number of parameters exists. If no such function exists +** before this API is called, a new function is created. The implementation +** of the new function always causes an exception to be thrown. So +** the new function is not good for anything by itself. Its only +** purpose is to be a place-holder function that can be overloaded +** by virtual tables. +** +** This API should be considered part of the virtual table interface, +** which is experimental and subject to change. +*/ +int sqlite3_overload_function(sqlite3*, const char *zFuncName, int nArg); + +/* +** The interface to the virtual-table mechanism defined above (back up +** to a comment remarkably similar to this one) is currently considered +** to be experimental. The interface might change in incompatible ways. +** If this is a problem for you, do not use the interface at this time. +** +** When the virtual-table mechanism stabilizes, we will declare the +** interface fixed, support it indefinitely, and remove this comment. +** +****** EXPERIMENTAL - subject to change without notice ************** +*/ + +/* +** CAPI3REF: A Handle To An Open BLOB +** +** An instance of the following opaque structure is used to +** represent an blob-handle. A blob-handle is created by +** [sqlite3_blob_open()] and destroyed by [sqlite3_blob_close()]. +** The [sqlite3_blob_read()] and [sqlite3_blob_write()] interfaces +** can be used to read or write small subsections of the blob. +** The [sqlite3_blob_bytes()] interface returns the size of the +** blob in bytes. +*/ +typedef struct sqlite3_blob sqlite3_blob; + +/* +** CAPI3REF: Open A BLOB For Incremental I/O +** +** Open a handle to the blob located in row iRow,, column zColumn, +** table zTable in database zDb. i.e. the same blob that would +** be selected by: +** +** <pre> +** SELECT zColumn FROM zDb.zTable WHERE rowid = iRow; +** </pre> +** +** If the flags parameter is non-zero, the blob is opened for +** read and write access. If it is zero, the blob is opened for read +** access. +** +** On success, [SQLITE_OK] is returned and the new +** [sqlite3_blob | blob handle] is written to *ppBlob. +** Otherwise an error code is returned and +** any value written to *ppBlob should not be used by the caller. +** This function sets the database-handle error code and message +** accessible via [sqlite3_errcode()] and [sqlite3_errmsg()]. +*/ +int sqlite3_blob_open( + sqlite3*, + const char *zDb, + const char *zTable, + const char *zColumn, + sqlite3_int64 iRow, + int flags, + sqlite3_blob **ppBlob +); + +/* +** CAPI3REF: Close A BLOB Handle +** +** Close an open [sqlite3_blob | blob handle]. +*/ +int sqlite3_blob_close(sqlite3_blob *); + +/* +** CAPI3REF: Return The Size Of An Open BLOB +** +** Return the size in bytes of the blob accessible via the open +** [sqlite3_blob | blob-handle] passed as an argument. +*/ +int sqlite3_blob_bytes(sqlite3_blob *); + +/* +** CAPI3REF: Read Data From A BLOB Incrementally +** +** This function is used to read data from an open +** [sqlite3_blob | blob-handle] into a caller supplied buffer. +** n bytes of data are copied into buffer +** z from the open blob, starting at offset iOffset. +** +** On success, SQLITE_OK is returned. Otherwise, an +** [SQLITE_ERROR | SQLite error code] or an +** [SQLITE_IOERR_READ | extended error code] is returned. +*/ +int sqlite3_blob_read(sqlite3_blob *, void *z, int n, int iOffset); + +/* +** CAPI3REF: Write Data Into A BLOB Incrementally +** +** This function is used to write data into an open +** [sqlite3_blob | blob-handle] from a user supplied buffer. +** n bytes of data are copied from the buffer +** pointed to by z into the open blob, starting at offset iOffset. +** +** If the [sqlite3_blob | blob-handle] passed as the first argument +** was not opened for writing (the flags parameter to [sqlite3_blob_open()] +*** was zero), this function returns [SQLITE_READONLY]. +** +** This function may only modify the contents of the blob, it is +** not possible to increase the size of a blob using this API. If +** offset iOffset is less than n bytes from the end of the blob, +** [SQLITE_ERROR] is returned and no data is written. +** +** On success, SQLITE_OK is returned. Otherwise, an +** [SQLITE_ERROR | SQLite error code] or an +** [SQLITE_IOERR_READ | extended error code] is returned. +*/ +int sqlite3_blob_write(sqlite3_blob *, const void *z, int n, int iOffset); + +/* +** CAPI3REF: Virtual File System Objects +** +** A virtual filesystem (VFS) is an [sqlite3_vfs] object +** that SQLite uses to interact +** with the underlying operating system. Most builds come with a +** single default VFS that is appropriate for the host computer. +** New VFSes can be registered and existing VFSes can be unregistered. +** The following interfaces are provided. +** +** The sqlite3_vfs_find() interface returns a pointer to a VFS given its +** name. Names are case sensitive. If there is no match, a NULL +** pointer is returned. If zVfsName is NULL then the default +** VFS is returned. +** +** New VFSes are registered with sqlite3_vfs_register(). Each +** new VFS becomes the default VFS if the makeDflt flag is set. +** The same VFS can be registered multiple times without injury. +** To make an existing VFS into the default VFS, register it again +** with the makeDflt flag set. If two different VFSes with the +** same name are registered, the behavior is undefined. If a +** VFS is registered with a name that is NULL or an empty string, +** then the behavior is undefined. +** +** Unregister a VFS with the sqlite3_vfs_unregister() interface. +** If the default VFS is unregistered, another VFS is chosen as +** the default. The choice for the new VFS is arbitrary. +*/ +sqlite3_vfs *sqlite3_vfs_find(const char *zVfsName); +int sqlite3_vfs_register(sqlite3_vfs*, int makeDflt); +int sqlite3_vfs_unregister(sqlite3_vfs*); + +/* +** CAPI3REF: Mutexes +** +** The SQLite core uses these routines for thread +** synchronization. Though they are intended for internal +** use by SQLite, code that links against SQLite is +** permitted to use any of these routines. +** +** The SQLite source code contains multiple implementations +** of these mutex routines. An appropriate implementation +** is selected automatically at compile-time. The following +** implementations are available in the SQLite core: +** +** <ul> +** <li> SQLITE_MUTEX_OS2 +** <li> SQLITE_MUTEX_PTHREAD +** <li> SQLITE_MUTEX_W32 +** <li> SQLITE_MUTEX_NOOP +** </ul> +** +** The SQLITE_MUTEX_NOOP implementation is a set of routines +** that does no real locking and is appropriate for use in +** a single-threaded application. The SQLITE_MUTEX_OS2, +** SQLITE_MUTEX_PTHREAD, and SQLITE_MUTEX_W32 implementations +** are appropriate for use on os/2, unix, and windows. +** +** If SQLite is compiled with the SQLITE_MUTEX_APPDEF preprocessor +** macro defined (with "-DSQLITE_MUTEX_APPDEF=1"), then no mutex +** implementation is included with the library. The +** mutex interface routines defined here become external +** references in the SQLite library for which implementations +** must be provided by the application. This facility allows an +** application that links against SQLite to provide its own mutex +** implementation without having to modify the SQLite core. +** +** The sqlite3_mutex_alloc() routine allocates a new +** mutex and returns a pointer to it. If it returns NULL +** that means that a mutex could not be allocated. SQLite +** will unwind its stack and return an error. The argument +** to sqlite3_mutex_alloc() is one of these integer constants: +** +** <ul> +** <li> SQLITE_MUTEX_FAST +** <li> SQLITE_MUTEX_RECURSIVE +** <li> SQLITE_MUTEX_STATIC_MASTER +** <li> SQLITE_MUTEX_STATIC_MEM +** <li> SQLITE_MUTEX_STATIC_MEM2 +** <li> SQLITE_MUTEX_STATIC_PRNG +** <li> SQLITE_MUTEX_STATIC_LRU +** </ul> +** +** The first two constants cause sqlite3_mutex_alloc() to create +** a new mutex. The new mutex is recursive when SQLITE_MUTEX_RECURSIVE +** is used but not necessarily so when SQLITE_MUTEX_FAST is used. +** The mutex implementation does not need to make a distinction +** between SQLITE_MUTEX_RECURSIVE and SQLITE_MUTEX_FAST if it does +** not want to. But SQLite will only request a recursive mutex in +** cases where it really needs one. If a faster non-recursive mutex +** implementation is available on the host platform, the mutex subsystem +** might return such a mutex in response to SQLITE_MUTEX_FAST. +** +** The other allowed parameters to sqlite3_mutex_alloc() each return +** a pointer to a static preexisting mutex. Four static mutexes are +** used by the current version of SQLite. Future versions of SQLite +** may add additional static mutexes. Static mutexes are for internal +** use by SQLite only. Applications that use SQLite mutexes should +** use only the dynamic mutexes returned by SQLITE_MUTEX_FAST or +** SQLITE_MUTEX_RECURSIVE. +** +** Note that if one of the dynamic mutex parameters (SQLITE_MUTEX_FAST +** or SQLITE_MUTEX_RECURSIVE) is used then sqlite3_mutex_alloc() +** returns a different mutex on every call. But for the static +** mutex types, the same mutex is returned on every call that has +** the same type number. +** +** The sqlite3_mutex_free() routine deallocates a previously +** allocated dynamic mutex. SQLite is careful to deallocate every +** dynamic mutex that it allocates. The dynamic mutexes must not be in +** use when they are deallocated. Attempting to deallocate a static +** mutex results in undefined behavior. SQLite never deallocates +** a static mutex. +** +** The sqlite3_mutex_enter() and sqlite3_mutex_try() routines attempt +** to enter a mutex. If another thread is already within the mutex, +** sqlite3_mutex_enter() will block and sqlite3_mutex_try() will return +** SQLITE_BUSY. The sqlite3_mutex_try() interface returns SQLITE_OK +** upon successful entry. Mutexes created using SQLITE_MUTEX_RECURSIVE can +** be entered multiple times by the same thread. In such cases the, +** mutex must be exited an equal number of times before another thread +** can enter. If the same thread tries to enter any other kind of mutex +** more than once, the behavior is undefined. SQLite will never exhibit +** such behavior in its own use of mutexes. +** +** Some systems (ex: windows95) do not the operation implemented by +** sqlite3_mutex_try(). On those systems, sqlite3_mutex_try() will +** always return SQLITE_BUSY. The SQLite core only ever uses +** sqlite3_mutex_try() as an optimization so this is acceptable behavior. +** +** The sqlite3_mutex_leave() routine exits a mutex that was +** previously entered by the same thread. The behavior +** is undefined if the mutex is not currently entered by the +** calling thread or is not currently allocated. SQLite will +** never do either. +** +** See also: [sqlite3_mutex_held()] and [sqlite3_mutex_notheld()]. +*/ +sqlite3_mutex *sqlite3_mutex_alloc(int); +void sqlite3_mutex_free(sqlite3_mutex*); +void sqlite3_mutex_enter(sqlite3_mutex*); +int sqlite3_mutex_try(sqlite3_mutex*); +void sqlite3_mutex_leave(sqlite3_mutex*); + +/* +** CAPI3REF: Mutex Verifcation Routines +** +** The sqlite3_mutex_held() and sqlite3_mutex_notheld() routines +** are intended for use inside assert() statements. The SQLite core +** never uses these routines except inside an assert() and applications +** are advised to follow the lead of the core. The core only +** provides implementations for these routines when it is compiled +** with the SQLITE_DEBUG flag. External mutex implementations +** are only required to provide these routines if SQLITE_DEBUG is +** defined and if NDEBUG is not defined. +** +** These routines should return true if the mutex in their argument +** is held or not held, respectively, by the calling thread. +** +** The implementation is not required to provided versions of these +** routines that actually work. +** If the implementation does not provide working +** versions of these routines, it should at least provide stubs +** that always return true so that one does not get spurious +** assertion failures. +** +** If the argument to sqlite3_mutex_held() is a NULL pointer then +** the routine should return 1. This seems counter-intuitive since +** clearly the mutex cannot be held if it does not exist. But the +** the reason the mutex does not exist is because the build is not +** using mutexes. And we do not want the assert() containing the +** call to sqlite3_mutex_held() to fail, so a non-zero return is +** the appropriate thing to do. The sqlite3_mutex_notheld() +** interface should also return 1 when given a NULL pointer. +*/ +int sqlite3_mutex_held(sqlite3_mutex*); +int sqlite3_mutex_notheld(sqlite3_mutex*); + +/* +** CAPI3REF: Mutex Types +** +** The [sqlite3_mutex_alloc()] interface takes a single argument +** which is one of these integer constants. +*/ +#define SQLITE_MUTEX_FAST 0 +#define SQLITE_MUTEX_RECURSIVE 1 +#define SQLITE_MUTEX_STATIC_MASTER 2 +#define SQLITE_MUTEX_STATIC_MEM 3 /* sqlite3_malloc() */ +#define SQLITE_MUTEX_STATIC_MEM2 4 /* sqlite3_release_memory() */ +#define SQLITE_MUTEX_STATIC_PRNG 5 /* sqlite3_random() */ +#define SQLITE_MUTEX_STATIC_LRU 6 /* lru page list */ + +/* +** CAPI3REF: Low-Level Control Of Database Files +** +** The [sqlite3_file_control()] interface makes a direct call to the +** xFileControl method for the [sqlite3_io_methods] object associated +** with a particular database identified by the second argument. The +** name of the database is the name assigned to the database by the +** <a href="lang_attach.html">ATTACH</a> SQL command that opened the +** database. To control the main database file, use the name "main" +** or a NULL pointer. The third and fourth parameters to this routine +** are passed directly through to the second and third parameters of +** the xFileControl method. The return value of the xFileControl +** method becomes the return value of this routine. +** +** If the second parameter (zDbName) does not match the name of any +** open database file, then SQLITE_ERROR is returned. This error +** code is not remembered and will not be recalled by [sqlite3_errcode()] +** or [sqlite3_errmsg()]. The underlying xFileControl method might +** also return SQLITE_ERROR. There is no way to distinguish between +** an incorrect zDbName and an SQLITE_ERROR return from the underlying +** xFileControl method. +** +** See also: [SQLITE_FCNTL_LOCKSTATE] +*/ +int sqlite3_file_control(sqlite3*, const char *zDbName, int op, void*); + +/* +** Undo the hack that converts floating point types to integer for +** builds on processors without floating point support. +*/ +#ifdef SQLITE_OMIT_FLOATING_POINT +# undef double +#endif + +#if 0 +} /* End of the 'extern "C"' block */ +#endif +#endif + +/************** End of sqlite3.h *********************************************/ +/************** Continuing where we left off in fts3.h ***********************/ + +#if 0 +extern "C" { +#endif /* __cplusplus */ + +int sqlite3Fts3Init(sqlite3 *db); + +#if 0 +} /* extern "C" */ +#endif /* __cplusplus */ + +/************** End of fts3.h ************************************************/ +/************** Continuing where we left off in fts3.c ***********************/ +/************** Include fts3_hash.h in the middle of fts3.c ******************/ +/************** Begin file fts3_hash.h ***************************************/ +/* +** 2001 September 22 +** +** 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 is the header file for the generic hash-table implemenation +** used in SQLite. We've modified it slightly to serve as a standalone +** hash table implementation for the full-text indexing module. +** +*/ +#ifndef _FTS3_HASH_H_ +#define _FTS3_HASH_H_ + +/* Forward declarations of structures. */ +typedef struct fts3Hash fts3Hash; +typedef struct fts3HashElem fts3HashElem; + +/* A complete hash table is an instance of the following structure. +** The internals of this structure are intended to be opaque -- client +** code should not attempt to access or modify the fields of this structure +** directly. Change this structure only by using the routines below. +** However, many of the "procedures" and "functions" for modifying and +** accessing this structure are really macros, so we can't really make +** this structure opaque. +*/ +struct fts3Hash { + char keyClass; /* HASH_INT, _POINTER, _STRING, _BINARY */ + char copyKey; /* True if copy of key made on insert */ + int count; /* Number of entries in this table */ + fts3HashElem *first; /* The first element of the array */ + int htsize; /* Number of buckets in the hash table */ + struct _fts3ht { /* the hash table */ + int count; /* Number of entries with this hash */ + fts3HashElem *chain; /* Pointer to first entry with this hash */ + } *ht; +}; + +/* Each element in the hash table is an instance of the following +** structure. All elements are stored on a single doubly-linked list. +** +** Again, this structure is intended to be opaque, but it can't really +** be opaque because it is used by macros. +*/ +struct fts3HashElem { + fts3HashElem *next, *prev; /* Next and previous elements in the table */ + void *data; /* Data associated with this element */ + void *pKey; int nKey; /* Key associated with this element */ +}; + +/* +** There are 2 different modes of operation for a hash table: +** +** FTS3_HASH_STRING pKey points to a string that is nKey bytes long +** (including the null-terminator, if any). Case +** is respected in comparisons. +** +** FTS3_HASH_BINARY pKey points to binary data nKey bytes long. +** memcmp() is used to compare keys. +** +** A copy of the key is made if the copyKey parameter to fts3HashInit is 1. +*/ +#define FTS3_HASH_STRING 1 +#define FTS3_HASH_BINARY 2 + +/* +** Access routines. To delete, insert a NULL pointer. +*/ +void sqlite3Fts3HashInit(fts3Hash*, int keytype, int copyKey); +void *sqlite3Fts3HashInsert(fts3Hash*, const void *pKey, int nKey, void *pData); +void *sqlite3Fts3HashFind(const fts3Hash*, const void *pKey, int nKey); +void sqlite3Fts3HashClear(fts3Hash*); + +/* +** Shorthand for the functions above +*/ +#define fts3HashInit sqlite3Fts3HashInit +#define fts3HashInsert sqlite3Fts3HashInsert +#define fts3HashFind sqlite3Fts3HashFind +#define fts3HashClear sqlite3Fts3HashClear + +/* +** Macros for looping over all elements of a hash table. The idiom is +** like this: +** +** fts3Hash h; +** fts3HashElem *p; +** ... +** for(p=fts3HashFirst(&h); p; p=fts3HashNext(p)){ +** SomeStructure *pData = fts3HashData(p); +** // do something with pData +** } +*/ +#define fts3HashFirst(H) ((H)->first) +#define fts3HashNext(E) ((E)->next) +#define fts3HashData(E) ((E)->data) +#define fts3HashKey(E) ((E)->pKey) +#define fts3HashKeysize(E) ((E)->nKey) + +/* +** Number of entries in a hash table +*/ +#define fts3HashCount(H) ((H)->count) + +#endif /* _FTS3_HASH_H_ */ + +/************** End of fts3_hash.h *******************************************/ +/************** Continuing where we left off in fts3.c ***********************/ +/************** Include fts3_tokenizer.h in the middle of fts3.c *************/ +/************** Begin file fts3_tokenizer.h **********************************/ +/* +** 2006 July 10 +** +** The author disclaims copyright to this source code. +** +************************************************************************* +** Defines the interface to tokenizers used by fulltext-search. There +** are three basic components: +** +** sqlite3_tokenizer_module is a singleton defining the tokenizer +** interface functions. This is essentially the class structure for +** tokenizers. +** +** sqlite3_tokenizer is used to define a particular tokenizer, perhaps +** including customization information defined at creation time. +** +** sqlite3_tokenizer_cursor is generated by a tokenizer to generate +** tokens from a particular input. +*/ +#ifndef _FTS3_TOKENIZER_H_ +#define _FTS3_TOKENIZER_H_ + +/* TODO(shess) Only used for SQLITE_OK and SQLITE_DONE at this time. +** If tokenizers are to be allowed to call sqlite3_*() functions, then +** we will need a way to register the API consistently. +*/ +/************** Include sqlite3.h in the middle of fts3_tokenizer.h **********/ +/************** Begin file sqlite3.h *****************************************/ +/* +** 2001 September 15 +** +** 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 header file defines the interface that the SQLite library +** presents to client programs. If a C-function, structure, datatype, +** or constant definition does not appear in this file, then it is +** not a published API of SQLite, is subject to change without +** notice, and should not be referenced by programs that use SQLite. +** +** Some of the definitions that are in this file are marked as +** "experimental". Experimental interfaces are normally new +** features recently added to SQLite. We do not anticipate changes +** to experimental interfaces but reserve to make minor changes if +** experience from use "in the wild" suggest such changes are prudent. +** +** The official C-language API documentation for SQLite is derived +** from comments in this file. This file is the authoritative source +** on how SQLite interfaces are suppose to operate. +** +** The name of this file under configuration management is "sqlite.h.in". +** The makefile makes some minor changes to this file (such as inserting +** the version number) and changes its name to "sqlite3.h" as +** part of the build process. +** +** @(#) $Id: sqlite.h.in,v 1.271 2007/11/21 15:24:01 drh Exp $ +*/ +#ifndef _SQLITE3_H_ +#define _SQLITE3_H_ + +/* +** Make sure we can call this stuff from C++. +*/ +#if 0 +extern "C" { +#endif + + +/* +** Add the ability to override 'extern' +*/ +#ifndef SQLITE_EXTERN +# define SQLITE_EXTERN extern +#endif + +/* +** Make sure these symbols where not defined by some previous header +** file. +*/ +#ifdef SQLITE_VERSION +# undef SQLITE_VERSION +#endif +#ifdef SQLITE_VERSION_NUMBER +# undef SQLITE_VERSION_NUMBER +#endif + +/* +** CAPI3REF: Compile-Time Library Version Numbers +** +** The version of the SQLite library is contained in the sqlite3.h +** header file in a #define named SQLITE_VERSION. The SQLITE_VERSION +** macro resolves to a string constant. +** +** The format of the version string is "X.Y.Z", where +** X is the major version number, Y is the minor version number and Z +** is the release number. The X.Y.Z might be followed by "alpha" or "beta". +** For example "3.1.1beta". +** +** The X value is always 3 in SQLite. The X value only changes when +** backwards compatibility is broken and we intend to never break +** backwards compatibility. The Y value only changes when +** there are major feature enhancements that are forwards compatible +** but not backwards compatible. The Z value is incremented with +** each release but resets back to 0 when Y is incremented. +** +** The SQLITE_VERSION_NUMBER is an integer with the value +** (X*1000000 + Y*1000 + Z). For example, for version "3.1.1beta", +** SQLITE_VERSION_NUMBER is set to 3001001. To detect if they are using +** version 3.1.1 or greater at compile time, programs may use the test +** (SQLITE_VERSION_NUMBER>=3001001). +** +** See also: [sqlite3_libversion()] and [sqlite3_libversion_number()]. +*/ +#define SQLITE_VERSION "3.5.2" +#define SQLITE_VERSION_NUMBER 3005002 + +/* +** CAPI3REF: Run-Time Library Version Numbers +** +** These routines return values equivalent to the header constants +** [SQLITE_VERSION] and [SQLITE_VERSION_NUMBER]. The values returned +** by this routines should only be different from the header values +** if you compile your program using an sqlite3.h header from a +** different version of SQLite that the version of the library you +** link against. +** +** The sqlite3_version[] string constant contains the text of the +** [SQLITE_VERSION] string. The sqlite3_libversion() function returns +** a poiner to the sqlite3_version[] string constant. The function +** is provided for DLL users who can only access functions and not +** constants within the DLL. +*/ +SQLITE_EXTERN const char sqlite3_version[]; +const char *sqlite3_libversion(void); +int sqlite3_libversion_number(void); + +/* +** CAPI3REF: Test To See If The Library Is Threadsafe +** +** This routine returns TRUE (nonzero) if SQLite was compiled with +** all of its mutexes enabled and is thus threadsafe. It returns +** zero if the particular build is for single-threaded operation +** only. +** +** Really all this routine does is return true if SQLite was compiled +** with the -DSQLITE_THREADSAFE=1 option and false if +** compiled with -DSQLITE_THREADSAFE=0. If SQLite uses an +** application-defined mutex subsystem, malloc subsystem, collating +** sequence, VFS, SQL function, progress callback, commit hook, +** extension, or other accessories and these add-ons are not +** threadsafe, then clearly the combination will not be threadsafe +** either. Hence, this routine never reports that the library +** is guaranteed to be threadsafe, only when it is guaranteed not +** to be. +** +** This is an experimental API and may go away or change in future +** releases. +*/ +int sqlite3_threadsafe(void); + +/* +** CAPI3REF: Database Connection Handle +** +** Each open SQLite database is represented by pointer to an instance of the +** opaque structure named "sqlite3". It is useful to think of an sqlite3 +** pointer as an object. The [sqlite3_open()], [sqlite3_open16()], and +** [sqlite3_open_v2()] interfaces are its constructors +** and [sqlite3_close()] is its destructor. There are many other interfaces +** (such as [sqlite3_prepare_v2()], [sqlite3_create_function()], and +** [sqlite3_busy_timeout()] to name but three) that are methods on this +** object. +*/ +typedef struct sqlite3 sqlite3; + + +/* +** CAPI3REF: 64-Bit Integer Types +** +** Some compilers do not support the "long long" datatype. So we have +** to do compiler-specific typedefs for 64-bit signed and unsigned integers. +** +** Many SQLite interface functions require a 64-bit integer arguments. +** Those interfaces are declared using this typedef. +*/ +#ifdef SQLITE_INT64_TYPE + typedef SQLITE_INT64_TYPE sqlite_int64; + typedef unsigned SQLITE_INT64_TYPE sqlite_uint64; +#elif defined(_MSC_VER) || defined(__BORLANDC__) + typedef __int64 sqlite_int64; + typedef unsigned __int64 sqlite_uint64; +#else + typedef long long int sqlite_int64; + typedef unsigned long long int sqlite_uint64; +#endif +typedef sqlite_int64 sqlite3_int64; +typedef sqlite_uint64 sqlite3_uint64; + +/* +** If compiling for a processor that lacks floating point support, +** substitute integer for floating-point +*/ +#ifdef SQLITE_OMIT_FLOATING_POINT +# define double sqlite3_int64 +#endif + +/* +** CAPI3REF: Closing A Database Connection +** +** Call this function with a pointer to a structure that was previously +** returned from [sqlite3_open()], [sqlite3_open16()], or +** [sqlite3_open_v2()] and the corresponding database will by +** closed. +** +** All SQL statements prepared using [sqlite3_prepare_v2()] or +** [sqlite3_prepare16_v2()] must be destroyed using [sqlite3_finalize()] +** before this routine is called. Otherwise, SQLITE_BUSY is returned and the +** database connection remains open. +** +** Passing this routine a database connection that has already been +** closed results in undefined behavior. If other interfaces that +** reference the same database connection are pending (either in the +** same thread or in different threads) when this routine is called, +** then the behavior is undefined and is almost certainly undesirable. +*/ +int sqlite3_close(sqlite3 *); + +/* +** The type for a callback function. +** This is legacy and deprecated. It is included for historical +** compatibility and is not documented. +*/ +typedef int (*sqlite3_callback)(void*,int,char**, char**); + +/* +** CAPI3REF: One-Step Query Execution Interface +** +** This interface is used to do a one-time evaluatation of zero +** or more SQL statements. UTF-8 text of the SQL statements to +** be evaluted is passed in as the second parameter. The statements +** are prepared one by one using [sqlite3_prepare()], evaluated +** using [sqlite3_step()], then destroyed using [sqlite3_finalize()]. +** +** If one or more of the SQL statements are queries, then +** the callback function specified by the 3rd parameter is +** invoked once for each row of the query result. This callback +** should normally return 0. If the callback returns a non-zero +** value then the query is aborted, all subsequent SQL statements +** are skipped and the sqlite3_exec() function returns the [SQLITE_ABORT]. +** +** The 4th parameter to this interface is an arbitrary pointer that is +** passed through to the callback function as its first parameter. +** +** The 2nd parameter to the callback function is the number of +** columns in the query result. The 3rd parameter to the callback +** is an array of strings holding the values for each column +** as extracted using [sqlite3_column_text()]. +** The 4th parameter to the callback is an array of strings +** obtained using [sqlite3_column_name()] and holding +** the names of each column. +** +** The callback function may be NULL, even for queries. A NULL +** callback is not an error. It just means that no callback +** will be invoked. +** +** If an error occurs while parsing or evaluating the SQL (but +** not while executing the callback) then an appropriate error +** message is written into memory obtained from [sqlite3_malloc()] and +** *errmsg is made to point to that message. The calling function +** is responsible for freeing the memory using [sqlite3_free()]. +** If errmsg==NULL, then no error message is ever written. +** +** The return value is is SQLITE_OK if there are no errors and +** some other [SQLITE_OK | return code] if there is an error. +** The particular return value depends on the type of error. +** +*/ +int sqlite3_exec( + sqlite3*, /* An open database */ + const char *sql, /* SQL to be evaluted */ + int (*callback)(void*,int,char**,char**), /* Callback function */ + void *, /* 1st argument to callback */ + char **errmsg /* Error msg written here */ +); + +/* +** CAPI3REF: Result Codes +** KEYWORDS: SQLITE_OK +** +** Many SQLite functions return an integer result code from the set shown +** above in order to indicates success or failure. +** +** The result codes above are the only ones returned by SQLite in its +** default configuration. However, the [sqlite3_extended_result_codes()] +** API can be used to set a database connectoin to return more detailed +** result codes. +** +** See also: [SQLITE_IOERR_READ | extended result codes] +** +*/ +#define SQLITE_OK 0 /* Successful result */ +/* beginning-of-error-codes */ +#define SQLITE_ERROR 1 /* SQL error or missing database */ +#define SQLITE_INTERNAL 2 /* NOT USED. Internal logic error in SQLite */ +#define SQLITE_PERM 3 /* Access permission denied */ +#define SQLITE_ABORT 4 /* Callback routine requested an abort */ +#define SQLITE_BUSY 5 /* The database file is locked */ +#define SQLITE_LOCKED 6 /* A table in the database is locked */ +#define SQLITE_NOMEM 7 /* A malloc() failed */ +#define SQLITE_READONLY 8 /* Attempt to write a readonly database */ +#define SQLITE_INTERRUPT 9 /* Operation terminated by sqlite3_interrupt()*/ +#define SQLITE_IOERR 10 /* Some kind of disk I/O error occurred */ +#define SQLITE_CORRUPT 11 /* The database disk image is malformed */ +#define SQLITE_NOTFOUND 12 /* NOT USED. Table or record not found */ +#define SQLITE_FULL 13 /* Insertion failed because database is full */ +#define SQLITE_CANTOPEN 14 /* Unable to open the database file */ +#define SQLITE_PROTOCOL 15 /* NOT USED. Database lock protocol error */ +#define SQLITE_EMPTY 16 /* Database is empty */ +#define SQLITE_SCHEMA 17 /* The database schema changed */ +#define SQLITE_TOOBIG 18 /* String or BLOB exceeds size limit */ +#define SQLITE_CONSTRAINT 19 /* Abort due to constraint violation */ +#define SQLITE_MISMATCH 20 /* Data type mismatch */ +#define SQLITE_MISUSE 21 /* Library used incorrectly */ +#define SQLITE_NOLFS 22 /* Uses OS features not supported on host */ +#define SQLITE_AUTH 23 /* Authorization denied */ +#define SQLITE_FORMAT 24 /* Auxiliary database format error */ +#define SQLITE_RANGE 25 /* 2nd parameter to sqlite3_bind out of range */ +#define SQLITE_NOTADB 26 /* File opened that is not a database file */ +#define SQLITE_ROW 100 /* sqlite3_step() has another row ready */ +#define SQLITE_DONE 101 /* sqlite3_step() has finished executing */ +/* end-of-error-codes */ + +/* +** CAPI3REF: Extended Result Codes +** +** In its default configuration, SQLite API routines return one of 26 integer +** result codes described at result-codes. However, experience has shown that +** many of these result codes are too course-grained. They do not provide as +** much information about problems as users might like. In an effort to +** address this, newer versions of SQLite (version 3.3.8 and later) include +** support for additional result codes that provide more detailed information +** about errors. The extended result codes are enabled (or disabled) for +** each database +** connection using the [sqlite3_extended_result_codes()] API. +** +** Some of the available extended result codes are listed above. +** We expect the number of extended result codes will be expand +** over time. Software that uses extended result codes should expect +** to see new result codes in future releases of SQLite. +** +** The symbolic name for an extended result code always contains a related +** primary result code as a prefix. Primary result codes contain a single +** "_" character. Extended result codes contain two or more "_" characters. +** The numeric value of an extended result code can be converted to its +** corresponding primary result code by masking off the lower 8 bytes. +** +** The SQLITE_OK result code will never be extended. It will always +** be exactly zero. +*/ +#define SQLITE_IOERR_READ (SQLITE_IOERR | (1<<8)) +#define SQLITE_IOERR_SHORT_READ (SQLITE_IOERR | (2<<8)) +#define SQLITE_IOERR_WRITE (SQLITE_IOERR | (3<<8)) +#define SQLITE_IOERR_FSYNC (SQLITE_IOERR | (4<<8)) +#define SQLITE_IOERR_DIR_FSYNC (SQLITE_IOERR | (5<<8)) +#define SQLITE_IOERR_TRUNCATE (SQLITE_IOERR | (6<<8)) +#define SQLITE_IOERR_FSTAT (SQLITE_IOERR | (7<<8)) +#define SQLITE_IOERR_UNLOCK (SQLITE_IOERR | (8<<8)) +#define SQLITE_IOERR_RDLOCK (SQLITE_IOERR | (9<<8)) +#define SQLITE_IOERR_DELETE (SQLITE_IOERR | (10<<8)) +#define SQLITE_IOERR_BLOCKED (SQLITE_IOERR | (11<<8)) +#define SQLITE_IOERR_NOMEM (SQLITE_IOERR | (12<<8)) + +/* +** CAPI3REF: Flags For File Open Operations +** +** Combination of the following bit values are used as the +** third argument to the [sqlite3_open_v2()] interface and +** as fourth argument to the xOpen method of the +** [sqlite3_vfs] object. +** +*/ +#define SQLITE_OPEN_READONLY 0x00000001 +#define SQLITE_OPEN_READWRITE 0x00000002 +#define SQLITE_OPEN_CREATE 0x00000004 +#define SQLITE_OPEN_DELETEONCLOSE 0x00000008 +#define SQLITE_OPEN_EXCLUSIVE 0x00000010 +#define SQLITE_OPEN_MAIN_DB 0x00000100 +#define SQLITE_OPEN_TEMP_DB 0x00000200 +#define SQLITE_OPEN_TRANSIENT_DB 0x00000400 +#define SQLITE_OPEN_MAIN_JOURNAL 0x00000800 +#define SQLITE_OPEN_TEMP_JOURNAL 0x00001000 +#define SQLITE_OPEN_SUBJOURNAL 0x00002000 +#define SQLITE_OPEN_MASTER_JOURNAL 0x00004000 + +/* +** CAPI3REF: Device Characteristics +** +** The xDeviceCapabilities method of the [sqlite3_io_methods] +** object returns an integer which is a vector of the following +** bit values expressing I/O characteristics of the mass storage +** device that holds the file that the [sqlite3_io_methods] +** refers to. +** +** The SQLITE_IOCAP_ATOMIC property means that all writes of +** any size are atomic. The SQLITE_IOCAP_ATOMICnnn values +** mean that writes of blocks that are nnn bytes in size and +** are aligned to an address which is an integer multiple of +** nnn are atomic. The SQLITE_IOCAP_SAFE_APPEND value means +** that when data is appended to a file, the data is appended +** first then the size of the file is extended, never the other +** way around. The SQLITE_IOCAP_SEQUENTIAL property means that +** information is written to disk in the same order as calls +** to xWrite(). +*/ +#define SQLITE_IOCAP_ATOMIC 0x00000001 +#define SQLITE_IOCAP_ATOMIC512 0x00000002 +#define SQLITE_IOCAP_ATOMIC1K 0x00000004 +#define SQLITE_IOCAP_ATOMIC2K 0x00000008 +#define SQLITE_IOCAP_ATOMIC4K 0x00000010 +#define SQLITE_IOCAP_ATOMIC8K 0x00000020 +#define SQLITE_IOCAP_ATOMIC16K 0x00000040 +#define SQLITE_IOCAP_ATOMIC32K 0x00000080 +#define SQLITE_IOCAP_ATOMIC64K 0x00000100 +#define SQLITE_IOCAP_SAFE_APPEND 0x00000200 +#define SQLITE_IOCAP_SEQUENTIAL 0x00000400 + +/* +** CAPI3REF: File Locking Levels +** +** SQLite uses one of the following integer values as the second +** argument to calls it makes to the xLock() and xUnlock() methods +** of an [sqlite3_io_methods] object. +*/ +#define SQLITE_LOCK_NONE 0 +#define SQLITE_LOCK_SHARED 1 +#define SQLITE_LOCK_RESERVED 2 +#define SQLITE_LOCK_PENDING 3 +#define SQLITE_LOCK_EXCLUSIVE 4 + +/* +** CAPI3REF: Synchronization Type Flags +** +** When SQLite invokes the xSync() method of an [sqlite3_io_methods] +** object it uses a combination of the following integer values as +** the second argument. +** +** When the SQLITE_SYNC_DATAONLY flag is used, it means that the +** sync operation only needs to flush data to mass storage. Inode +** information need not be flushed. The SQLITE_SYNC_NORMAL means +** to use normal fsync() semantics. The SQLITE_SYNC_FULL flag means +** to use Mac OS-X style fullsync instead of fsync(). +*/ +#define SQLITE_SYNC_NORMAL 0x00002 +#define SQLITE_SYNC_FULL 0x00003 +#define SQLITE_SYNC_DATAONLY 0x00010 + + +/* +** CAPI3REF: OS Interface Open File Handle +** +** An [sqlite3_file] object represents an open file in the OS +** interface layer. Individual OS interface implementations will +** want to subclass this object by appending additional fields +** for their own use. The pMethods entry is a pointer to an +** [sqlite3_io_methods] object that defines methods for performing +** I/O operations on the open file. +*/ +typedef struct sqlite3_file sqlite3_file; +struct sqlite3_file { + const struct sqlite3_io_methods *pMethods; /* Methods for an open file */ +}; + +/* +** CAPI3REF: OS Interface File Virtual Methods Object +** +** Every file opened by the [sqlite3_vfs] xOpen method contains a pointer to +** an instance of the this object. This object defines the +** methods used to perform various operations against the open file. +** +** The flags argument to xSync may be one of [SQLITE_SYNC_NORMAL] or +** [SQLITE_SYNC_FULL]. The first choice is the normal fsync(). +* The second choice is an +** OS-X style fullsync. The SQLITE_SYNC_DATA flag may be ORed in to +** indicate that only the data of the file and not its inode needs to be +** synced. +** +** The integer values to xLock() and xUnlock() are one of +** <ul> +** <li> [SQLITE_LOCK_NONE], +** <li> [SQLITE_LOCK_SHARED], +** <li> [SQLITE_LOCK_RESERVED], +** <li> [SQLITE_LOCK_PENDING], or +** <li> [SQLITE_LOCK_EXCLUSIVE]. +** </ul> +** xLock() increases the lock. xUnlock() decreases the lock. +** The xCheckReservedLock() method looks +** to see if any database connection, either in this +** process or in some other process, is holding an RESERVED, +** PENDING, or EXCLUSIVE lock on the file. It returns true +** if such a lock exists and false if not. +** +** The xFileControl() method is a generic interface that allows custom +** VFS implementations to directly control an open file using the +** [sqlite3_file_control()] interface. The second "op" argument +** is an integer opcode. The third +** argument is a generic pointer which is intended to be a pointer +** to a structure that may contain arguments or space in which to +** write return values. Potential uses for xFileControl() might be +** functions to enable blocking locks with timeouts, to change the +** locking strategy (for example to use dot-file locks), to inquire +** about the status of a lock, or to break stale locks. The SQLite +** core reserves opcodes less than 100 for its own use. +** A [SQLITE_FCNTL_LOCKSTATE | list of opcodes] less than 100 is available. +** Applications that define a custom xFileControl method should use opcodes +** greater than 100 to avoid conflicts. +** +** The xSectorSize() method returns the sector size of the +** device that underlies the file. The sector size is the +** minimum write that can be performed without disturbing +** other bytes in the file. The xDeviceCharacteristics() +** method returns a bit vector describing behaviors of the +** underlying device: +** +** <ul> +** <li> [SQLITE_IOCAP_ATOMIC] +** <li> [SQLITE_IOCAP_ATOMIC512] +** <li> [SQLITE_IOCAP_ATOMIC1K] +** <li> [SQLITE_IOCAP_ATOMIC2K] +** <li> [SQLITE_IOCAP_ATOMIC4K] +** <li> [SQLITE_IOCAP_ATOMIC8K] +** <li> [SQLITE_IOCAP_ATOMIC16K] +** <li> [SQLITE_IOCAP_ATOMIC32K] +** <li> [SQLITE_IOCAP_ATOMIC64K] +** <li> [SQLITE_IOCAP_SAFE_APPEND] +** <li> [SQLITE_IOCAP_SEQUENTIAL] +** </ul> +** +** The SQLITE_IOCAP_ATOMIC property means that all writes of +** any size are atomic. The SQLITE_IOCAP_ATOMICnnn values +** mean that writes of blocks that are nnn bytes in size and +** are aligned to an address which is an integer multiple of +** nnn are atomic. The SQLITE_IOCAP_SAFE_APPEND value means +** that when data is appended to a file, the data is appended +** first then the size of the file is extended, never the other +** way around. The SQLITE_IOCAP_SEQUENTIAL property means that +** information is written to disk in the same order as calls +** to xWrite(). +*/ +typedef struct sqlite3_io_methods sqlite3_io_methods; +struct sqlite3_io_methods { + int iVersion; + int (*xClose)(sqlite3_file*); + int (*xRead)(sqlite3_file*, void*, int iAmt, sqlite3_int64 iOfst); + int (*xWrite)(sqlite3_file*, const void*, int iAmt, sqlite3_int64 iOfst); + int (*xTruncate)(sqlite3_file*, sqlite3_int64 size); + int (*xSync)(sqlite3_file*, int flags); + int (*xFileSize)(sqlite3_file*, sqlite3_int64 *pSize); + int (*xLock)(sqlite3_file*, int); + int (*xUnlock)(sqlite3_file*, int); + int (*xCheckReservedLock)(sqlite3_file*); + int (*xFileControl)(sqlite3_file*, int op, void *pArg); + int (*xSectorSize)(sqlite3_file*); + int (*xDeviceCharacteristics)(sqlite3_file*); + /* Additional methods may be added in future releases */ +}; + +/* +** CAPI3REF: Standard File Control Opcodes +** +** These integer constants are opcodes for the xFileControl method +** of the [sqlite3_io_methods] object and to the [sqlite3_file_control()] +** interface. +** +** The [SQLITE_FCNTL_LOCKSTATE] opcode is used for debugging. This +** opcode cases the xFileControl method to write the current state of +** the lock (one of [SQLITE_LOCK_NONE], [SQLITE_LOCK_SHARED], +** [SQLITE_LOCK_RESERVED], [SQLITE_LOCK_PENDING], or [SQLITE_LOCK_EXCLUSIVE]) +** into an integer that the pArg argument points to. This capability +** is used during testing and only needs to be supported when SQLITE_TEST +** is defined. +*/ +#define SQLITE_FCNTL_LOCKSTATE 1 + +/* +** CAPI3REF: Mutex Handle +** +** The mutex module within SQLite defines [sqlite3_mutex] to be an +** abstract type for a mutex object. The SQLite core never looks +** at the internal representation of an [sqlite3_mutex]. It only +** deals with pointers to the [sqlite3_mutex] object. +** +** Mutexes are created using [sqlite3_mutex_alloc()]. +*/ +typedef struct sqlite3_mutex sqlite3_mutex; + +/* +** CAPI3REF: OS Interface Object +** +** An instance of this object defines the interface between the +** SQLite core and the underlying operating system. The "vfs" +** in the name of the object stands for "virtual file system". +** +** The iVersion field is initially 1 but may be larger for future +** versions of SQLite. Additional fields may be appended to this +** object when the iVersion value is increased. +** +** The szOsFile field is the size of the subclassed [sqlite3_file] +** structure used by this VFS. mxPathname is the maximum length of +** a pathname in this VFS. +** +** Registered vfs modules are kept on a linked list formed by +** the pNext pointer. The [sqlite3_vfs_register()] +** and [sqlite3_vfs_unregister()] interfaces manage this list +** in a thread-safe way. The [sqlite3_vfs_find()] interface +** searches the list. +** +** The pNext field is the only fields in the sqlite3_vfs +** structure that SQLite will ever modify. SQLite will only access +** or modify this field while holding a particular static mutex. +** The application should never modify anything within the sqlite3_vfs +** object once the object has been registered. +** +** The zName field holds the name of the VFS module. The name must +** be unique across all VFS modules. +** +** SQLite will guarantee that the zFilename string passed to +** xOpen() is a full pathname as generated by xFullPathname() and +** that the string will be valid and unchanged until xClose() is +** called. So the [sqlite3_file] can store a pointer to the +** filename if it needs to remember the filename for some reason. +** +** The flags argument to xOpen() is a copy of the flags argument +** to [sqlite3_open_v2()]. If [sqlite3_open()] or [sqlite3_open16()] +** is used, then flags is [SQLITE_OPEN_READWRITE] | [SQLITE_OPEN_CREATE]. +** If xOpen() opens a file read-only then it sets *pOutFlags to +** include [SQLITE_OPEN_READONLY]. Other bits in *pOutFlags may be +** set. +** +** SQLite will also add one of the following flags to the xOpen() +** call, depending on the object being opened: +** +** <ul> +** <li> [SQLITE_OPEN_MAIN_DB] +** <li> [SQLITE_OPEN_MAIN_JOURNAL] +** <li> [SQLITE_OPEN_TEMP_DB] +** <li> [SQLITE_OPEN_TEMP_JOURNAL] +** <li> [SQLITE_OPEN_TRANSIENT_DB] +** <li> [SQLITE_OPEN_SUBJOURNAL] +** <li> [SQLITE_OPEN_MASTER_JOURNAL] +** </ul> +** +** The file I/O implementation can use the object type flags to +** changes the way it deals with files. For example, an application +** that does not care about crash recovery or rollback, might make +** the open of a journal file a no-op. Writes to this journal are +** also a no-op. Any attempt to read the journal return SQLITE_IOERR. +** Or the implementation might recognize the a database file will +** be doing page-aligned sector reads and writes in a random order +** and set up its I/O subsystem accordingly. +** +** SQLite might also add one of the following flags to the xOpen +** method: +** +** <ul> +** <li> [SQLITE_OPEN_DELETEONCLOSE] +** <li> [SQLITE_OPEN_EXCLUSIVE] +** </ul> +** +** The [SQLITE_OPEN_DELETEONCLOSE] flag means the file should be +** deleted when it is closed. This will always be set for TEMP +** databases and journals and for subjournals. The +** [SQLITE_OPEN_EXCLUSIVE] flag means the file should be opened +** for exclusive access. This flag is set for all files except +** for the main database file. +** +** Space to hold the [sqlite3_file] structure passed as the third +** argument to xOpen is allocated by caller (the SQLite core). +** szOsFile bytes are allocated for this object. The xOpen method +** fills in the allocated space. +** +** The flags argument to xAccess() may be [SQLITE_ACCESS_EXISTS] +** to test for the existance of a file, +** or [SQLITE_ACCESS_READWRITE] to test to see +** if a file is readable and writable, or [SQLITE_ACCESS_READ] +** to test to see if a file is at least readable. The file can be a +** directory. +** +** SQLite will always allocate at least mxPathname+1 byte for +** the output buffers for xGetTempname and xFullPathname. The exact +** size of the output buffer is also passed as a parameter to both +** methods. If the output buffer is not large enough, SQLITE_CANTOPEN +** should be returned. As this is handled as a fatal error by SQLite, +** vfs implementations should endevour to prevent this by setting +** mxPathname to a sufficiently large value. +** +** The xRandomness(), xSleep(), and xCurrentTime() interfaces +** are not strictly a part of the filesystem, but they are +** included in the VFS structure for completeness. +** The xRandomness() function attempts to return nBytes bytes +** of good-quality randomness into zOut. The return value is +** the actual number of bytes of randomness obtained. The +** xSleep() method cause the calling thread to sleep for at +** least the number of microseconds given. The xCurrentTime() +** method returns a Julian Day Number for the current date and +** time. +*/ +typedef struct sqlite3_vfs sqlite3_vfs; +struct sqlite3_vfs { + int iVersion; /* Structure version number */ + int szOsFile; /* Size of subclassed sqlite3_file */ + int mxPathname; /* Maximum file pathname length */ + sqlite3_vfs *pNext; /* Next registered VFS */ + const char *zName; /* Name of this virtual file system */ + void *pAppData; /* Pointer to application-specific data */ + int (*xOpen)(sqlite3_vfs*, const char *zName, sqlite3_file*, + int flags, int *pOutFlags); + int (*xDelete)(sqlite3_vfs*, const char *zName, int syncDir); + int (*xAccess)(sqlite3_vfs*, const char *zName, int flags); + int (*xGetTempname)(sqlite3_vfs*, int nOut, char *zOut); + int (*xFullPathname)(sqlite3_vfs*, const char *zName, int nOut, char *zOut); + void *(*xDlOpen)(sqlite3_vfs*, const char *zFilename); + void (*xDlError)(sqlite3_vfs*, int nByte, char *zErrMsg); + void *(*xDlSym)(sqlite3_vfs*,void*, const char *zSymbol); + void (*xDlClose)(sqlite3_vfs*, void*); + int (*xRandomness)(sqlite3_vfs*, int nByte, char *zOut); + int (*xSleep)(sqlite3_vfs*, int microseconds); + int (*xCurrentTime)(sqlite3_vfs*, double*); + /* New fields may be appended in figure versions. The iVersion + ** value will increment whenever this happens. */ +}; + +/* +** CAPI3REF: Flags for the xAccess VFS method +** +** These integer constants can be used as the third parameter to +** the xAccess method of an [sqlite3_vfs] object. They determine +** the kind of what kind of permissions the xAccess method is +** looking for. With SQLITE_ACCESS_EXISTS, the xAccess method +** simply checks to see if the file exists. With SQLITE_ACCESS_READWRITE, +** the xAccess method checks to see if the file is both readable +** and writable. With SQLITE_ACCESS_READ the xAccess method +** checks to see if the file is readable. +*/ +#define SQLITE_ACCESS_EXISTS 0 +#define SQLITE_ACCESS_READWRITE 1 +#define SQLITE_ACCESS_READ 2 + +/* +** CAPI3REF: Enable Or Disable Extended Result Codes +** +** This routine enables or disables the +** [SQLITE_IOERR_READ | extended result codes] feature. +** By default, SQLite API routines return one of only 26 integer +** [SQLITE_OK | result codes]. When extended result codes +** are enabled by this routine, the repetoire of result codes can be +** much larger and can (hopefully) provide more detailed information +** about the cause of an error. +** +** The second argument is a boolean value that turns extended result +** codes on and off. Extended result codes are off by default for +** backwards compatibility with older versions of SQLite. +*/ +int sqlite3_extended_result_codes(sqlite3*, int onoff); + +/* +** CAPI3REF: Last Insert Rowid +** +** Each entry in an SQLite table has a unique 64-bit signed integer key +** called the "rowid". The rowid is always available as an undeclared +** column named ROWID, OID, or _ROWID_. If the table has a column of +** type INTEGER PRIMARY KEY then that column is another an alias for the +** rowid. +** +** This routine returns the rowid of the most recent successful INSERT into +** the database from the database connection given in the first +** argument. If no successful inserts have ever occurred on this database +** connection, zero is returned. +** +** If an INSERT occurs within a trigger, then the rowid of the +** inserted row is returned by this routine as long as the trigger +** is running. But once the trigger terminates, the value returned +** by this routine reverts to the last value inserted before the +** trigger fired. +** +** An INSERT that fails due to a constraint violation is not a +** successful insert and does not change the value returned by this +** routine. Thus INSERT OR FAIL, INSERT OR IGNORE, INSERT OR ROLLBACK, +** and INSERT OR ABORT make no changes to the return value of this +** routine when their insertion fails. When INSERT OR REPLACE +** encounters a constraint violation, it does not fail. The +** INSERT continues to completion after deleting rows that caused +** the constraint problem so INSERT OR REPLACE will always change +** the return value of this interface. +** +** If another thread does a new insert on the same database connection +** while this routine is running and thus changes the last insert rowid, +** then the return value of this routine is undefined. +*/ +sqlite3_int64 sqlite3_last_insert_rowid(sqlite3*); + +/* +** CAPI3REF: Count The Number Of Rows Modified +** +** This function returns the number of database rows that were changed +** (or inserted or deleted) by the most recent SQL statement. Only +** changes that are directly specified by the INSERT, UPDATE, or +** DELETE statement are counted. Auxiliary changes caused by +** triggers are not counted. Use the [sqlite3_total_changes()] function +** to find the total number of changes including changes caused by triggers. +** +** Within the body of a trigger, the sqlite3_changes() interface can be +** called to find the number of +** changes in the most recently completed INSERT, UPDATE, or DELETE +** statement within the body of the trigger. +** +** All changes are counted, even if they were later undone by a +** ROLLBACK or ABORT. Except, changes associated with creating and +** dropping tables are not counted. +** +** If a callback invokes [sqlite3_exec()] or [sqlite3_step()] recursively, +** then the changes in the inner, recursive call are counted together +** with the changes in the outer call. +** +** SQLite implements the command "DELETE FROM table" without a WHERE clause +** by dropping and recreating the table. (This is much faster than going +** through and deleting individual elements from the table.) Because of +** this optimization, the change count for "DELETE FROM table" will be +** zero regardless of the number of elements that were originally in the +** table. To get an accurate count of the number of rows deleted, use +** "DELETE FROM table WHERE 1" instead. +** +** If another thread makes changes on the same database connection +** while this routine is running then the return value of this routine +** is undefined. +*/ +int sqlite3_changes(sqlite3*); + +/* +** CAPI3REF: Total Number Of Rows Modified +*** +** This function returns the number of database rows that have been +** modified by INSERT, UPDATE or DELETE statements since the database handle +** was opened. This includes UPDATE, INSERT and DELETE statements executed +** as part of trigger programs. All changes are counted as soon as the +** statement that makes them is completed (when the statement handle is +** passed to [sqlite3_reset()] or [sqlite3_finalize()]). +** +** See also the [sqlite3_change()] interface. +** +** SQLite implements the command "DELETE FROM table" without a WHERE clause +** by dropping and recreating the table. (This is much faster than going +** through and deleting individual elements form the table.) Because of +** this optimization, the change count for "DELETE FROM table" will be +** zero regardless of the number of elements that were originally in the +** table. To get an accurate count of the number of rows deleted, use +** "DELETE FROM table WHERE 1" instead. +** +** If another thread makes changes on the same database connection +** while this routine is running then the return value of this routine +** is undefined. +*/ +int sqlite3_total_changes(sqlite3*); + +/* +** CAPI3REF: Interrupt A Long-Running Query +** +** This function causes any pending database operation to abort and +** return at its earliest opportunity. This routine is typically +** called in response to a user action such as pressing "Cancel" +** or Ctrl-C where the user wants a long query operation to halt +** immediately. +** +** It is safe to call this routine from a thread different from the +** thread that is currently running the database operation. But it +** is not safe to call this routine with a database connection that +** is closed or might close before sqlite3_interrupt() returns. +** +** The SQL operation that is interrupted will return [SQLITE_INTERRUPT]. +** If an interrupted operation was an update that is inside an +** explicit transaction, then the entire transaction will be rolled +** back automatically. +*/ +void sqlite3_interrupt(sqlite3*); + +/* +** CAPI3REF: Determine If An SQL Statement Is Complete +** +** These functions return true if the given input string comprises +** one or more complete SQL statements. For the sqlite3_complete() call, +** the parameter must be a nul-terminated UTF-8 string. For +** sqlite3_complete16(), a nul-terminated machine byte order UTF-16 string +** is required. +** +** These routines are useful for command-line input to determine if the +** currently entered text forms one or more complete SQL statements or +** if additional input is needed before sending the statements into +** SQLite for parsing. The algorithm is simple. If the +** last token other than spaces and comments is a semicolon, then return +** true. Actually, the algorithm is a little more complicated than that +** in order to deal with triggers, but the basic idea is the same: the +** statement is not complete unless it ends in a semicolon. +*/ +int sqlite3_complete(const char *sql); +int sqlite3_complete16(const void *sql); + +/* +** CAPI3REF: Register A Callback To Handle SQLITE_BUSY Errors +** +** This routine identifies a callback function that might be invoked +** whenever an attempt is made to open a database table +** that another thread or process has locked. +** If the busy callback is NULL, then [SQLITE_BUSY] +** (or sometimes [SQLITE_IOERR_BLOCKED]) +** is returned immediately upon encountering the lock. +** If the busy callback is not NULL, then the +** callback will be invoked with two arguments. The +** first argument to the handler is a copy of the void* pointer which +** is the third argument to this routine. The second argument to +** the handler is the number of times that the busy handler has +** been invoked for this locking event. If the +** busy callback returns 0, then no additional attempts are made to +** access the database and [SQLITE_BUSY] or [SQLITE_IOERR_BLOCKED] is returned. +** If the callback returns non-zero, then another attempt is made to open the +** database for reading and the cycle repeats. +** +** The presence of a busy handler does not guarantee that +** it will be invoked when there is lock contention. +** If SQLite determines that invoking the busy handler could result in +** a deadlock, it will return [SQLITE_BUSY] instead. +** Consider a scenario where one process is holding a read lock that +** it is trying to promote to a reserved lock and +** a second process is holding a reserved lock that it is trying +** to promote to an exclusive lock. The first process cannot proceed +** because it is blocked by the second and the second process cannot +** proceed because it is blocked by the first. If both processes +** invoke the busy handlers, neither will make any progress. Therefore, +** SQLite returns [SQLITE_BUSY] for the first process, hoping that this +** will induce the first process to release its read lock and allow +** the second process to proceed. +** +** The default busy callback is NULL. +** +** The [SQLITE_BUSY] error is converted to [SQLITE_IOERR_BLOCKED] when +** SQLite is in the middle of a large transaction where all the +** changes will not fit into the in-memory cache. SQLite will +** already hold a RESERVED lock on the database file, but it needs +** to promote this lock to EXCLUSIVE so that it can spill cache +** pages into the database file without harm to concurrent +** readers. If it is unable to promote the lock, then the in-memory +** cache will be left in an inconsistent state and so the error +** code is promoted from the relatively benign [SQLITE_BUSY] to +** the more severe [SQLITE_IOERR_BLOCKED]. This error code promotion +** forces an automatic rollback of the changes. See the +** <a href="http://www.sqlite.org/cvstrac/wiki?p=CorruptionFollowingBusyError"> +** CorruptionFollowingBusyError</a> wiki page for a discussion of why +** this is important. +** +** Sqlite is re-entrant, so the busy handler may start a new query. +** (It is not clear why anyone would every want to do this, but it +** is allowed, in theory.) But the busy handler may not close the +** database. Closing the database from a busy handler will delete +** data structures out from under the executing query and will +** probably result in a segmentation fault or other runtime error. +** +** There can only be a single busy handler defined for each database +** connection. Setting a new busy handler clears any previous one. +** Note that calling [sqlite3_busy_timeout()] will also set or clear +** the busy handler. +** +** When operating in [sqlite3_enable_shared_cache | shared cache mode], +** only a single busy handler can be defined for each database file. +** So if two database connections share a single cache, then changing +** the busy handler on one connection will also change the busy +** handler in the other connection. The busy handler is invoked +** in the thread that was running when the SQLITE_BUSY was hit. +*/ +int sqlite3_busy_handler(sqlite3*, int(*)(void*,int), void*); + +/* +** CAPI3REF: Set A Busy Timeout +** +** This routine sets a busy handler that sleeps for a while when a +** table is locked. The handler will sleep multiple times until +** at least "ms" milliseconds of sleeping have been done. After +** "ms" milliseconds of sleeping, the handler returns 0 which +** causes [sqlite3_step()] to return [SQLITE_BUSY] or [SQLITE_IOERR_BLOCKED]. +** +** Calling this routine with an argument less than or equal to zero +** turns off all busy handlers. +** +** There can only be a single busy handler for a particular database +** connection. If another busy handler was defined +** (using [sqlite3_busy_handler()]) prior to calling +** this routine, that other busy handler is cleared. +*/ +int sqlite3_busy_timeout(sqlite3*, int ms); + +/* +** CAPI3REF: Convenience Routines For Running Queries +** +** This next routine is a convenience wrapper around [sqlite3_exec()]. +** Instead of invoking a user-supplied callback for each row of the +** result, this routine remembers each row of the result in memory +** obtained from [sqlite3_malloc()], then returns all of the result after the +** query has finished. +** +** As an example, suppose the query result where this table: +** +** <blockquote><pre> +** Name | Age +** ----------------------- +** Alice | 43 +** Bob | 28 +** Cindy | 21 +** </pre></blockquote> +** +** If the 3rd argument were &azResult then after the function returns +** azResult will contain the following data: +** +** <blockquote><pre> +** azResult[0] = "Name"; +** azResult[1] = "Age"; +** azResult[2] = "Alice"; +** azResult[3] = "43"; +** azResult[4] = "Bob"; +** azResult[5] = "28"; +** azResult[6] = "Cindy"; +** azResult[7] = "21"; +** </pre></blockquote> +** +** Notice that there is an extra row of data containing the column +** headers. But the *nrow return value is still 3. *ncolumn is +** set to 2. In general, the number of values inserted into azResult +** will be ((*nrow) + 1)*(*ncolumn). +** +** After the calling function has finished using the result, it should +** pass the result data pointer to sqlite3_free_table() in order to +** release the memory that was malloc-ed. Because of the way the +** [sqlite3_malloc()] happens, the calling function must not try to call +** [sqlite3_free()] directly. Only [sqlite3_free_table()] is able to release +** the memory properly and safely. +** +** The return value of this routine is the same as from [sqlite3_exec()]. +*/ +int sqlite3_get_table( + sqlite3*, /* An open database */ + const char *sql, /* SQL to be executed */ + char ***resultp, /* Result written to a char *[] that this points to */ + int *nrow, /* Number of result rows written here */ + int *ncolumn, /* Number of result columns written here */ + char **errmsg /* Error msg written here */ +); +void sqlite3_free_table(char **result); + +/* +** CAPI3REF: Formatted String Printing Functions +** +** These routines are workalikes of the "printf()" family of functions +** from the standard C library. +** +** The sqlite3_mprintf() and sqlite3_vmprintf() routines write their +** results into memory obtained from [sqlite3_malloc()]. +** The strings returned by these two routines should be +** released by [sqlite3_free()]. Both routines return a +** NULL pointer if [sqlite3_malloc()] is unable to allocate enough +** memory to hold the resulting string. +** +** In sqlite3_snprintf() routine is similar to "snprintf()" from +** the standard C library. The result is written into the +** buffer supplied as the second parameter whose size is given by +** the first parameter. Note that the order of the +** first two parameters is reversed from snprintf(). This is an +** historical accident that cannot be fixed without breaking +** backwards compatibility. Note also that sqlite3_snprintf() +** returns a pointer to its buffer instead of the number of +** characters actually written into the buffer. We admit that +** the number of characters written would be a more useful return +** value but we cannot change the implementation of sqlite3_snprintf() +** now without breaking compatibility. +** +** As long as the buffer size is greater than zero, sqlite3_snprintf() +** guarantees that the buffer is always zero-terminated. The first +** parameter "n" is the total size of the buffer, including space for +** the zero terminator. So the longest string that can be completely +** written will be n-1 characters. +** +** These routines all implement some additional formatting +** options that are useful for constructing SQL statements. +** All of the usual printf formatting options apply. In addition, there +** is are "%q", "%Q", and "%z" options. +** +** The %q option works like %s in that it substitutes a null-terminated +** string from the argument list. But %q also doubles every '\'' character. +** %q is designed for use inside a string literal. By doubling each '\'' +** character it escapes that character and allows it to be inserted into +** the string. +** +** For example, so some string variable contains text as follows: +** +** <blockquote><pre> +** char *zText = "It's a happy day!"; +** </pre></blockquote> +** +** One can use this text in an SQL statement as follows: +** +** <blockquote><pre> +** char *zSQL = sqlite3_mprintf("INSERT INTO table VALUES('%q')", zText); +** sqlite3_exec(db, zSQL, 0, 0, 0); +** sqlite3_free(zSQL); +** </pre></blockquote> +** +** Because the %q format string is used, the '\'' character in zText +** is escaped and the SQL generated is as follows: +** +** <blockquote><pre> +** INSERT INTO table1 VALUES('It''s a happy day!') +** </pre></blockquote> +** +** This is correct. Had we used %s instead of %q, the generated SQL +** would have looked like this: +** +** <blockquote><pre> +** INSERT INTO table1 VALUES('It's a happy day!'); +** </pre></blockquote> +** +** This second example is an SQL syntax error. As a general rule you +** should always use %q instead of %s when inserting text into a string +** literal. +** +** The %Q option works like %q except it also adds single quotes around +** the outside of the total string. Or if the parameter in the argument +** list is a NULL pointer, %Q substitutes the text "NULL" (without single +** quotes) in place of the %Q option. So, for example, one could say: +** +** <blockquote><pre> +** char *zSQL = sqlite3_mprintf("INSERT INTO table VALUES(%Q)", zText); +** sqlite3_exec(db, zSQL, 0, 0, 0); +** sqlite3_free(zSQL); +** </pre></blockquote> +** +** The code above will render a correct SQL statement in the zSQL +** variable even if the zText variable is a NULL pointer. +** +** The "%z" formatting option works exactly like "%s" with the +** addition that after the string has been read and copied into +** the result, [sqlite3_free()] is called on the input string. +*/ +char *sqlite3_mprintf(const char*,...); +char *sqlite3_vmprintf(const char*, va_list); +char *sqlite3_snprintf(int,char*,const char*, ...); + +/* +** CAPI3REF: Memory Allocation Subsystem +** +** The SQLite core uses these three routines for all of its own +** internal memory allocation needs. (See the exception below.) +** +** The default implementation +** of the memory allocation subsystem uses the malloc(), realloc() +** and free() provided by the standard C library. However, if +** SQLite is compiled with the following C preprocessor macro +** +** <blockquote> SQLITE_MEMORY_SIZE=<i>NNN</i> </blockquote> +** +** where <i>NNN</i> is an integer, then SQLite create a static +** array of at least <i>NNN</i> bytes in size and use that array +** for all of its dynamic memory allocation needs. +** +** In SQLite version 3.5.0 and 3.5.1, it was possible to define +** the SQLITE_OMIT_MEMORY_ALLOCATION which would cause the built-in +** implementation of these routines to be omitted. That capability +** is no longer provided. Only built-in memory allocators can be +** used. +** +** <b>Exception:</b> The windows OS interface layer calls +** the system malloc() and free() directly when converting +** filenames between the UTF-8 encoding used by SQLite +** and whatever filename encoding is used by the particular windows +** installation. Memory allocation errors are detected, but +** they are reported back as [SQLITE_CANTOPEN] or +** [SQLITE_IOERR] rather than [SQLITE_NOMEM]. +*/ +void *sqlite3_malloc(int); +void *sqlite3_realloc(void*, int); +void sqlite3_free(void*); + +/* +** CAPI3REF: Memory Allocator Statistics +** +** In addition to the basic three allocation routines +** [sqlite3_malloc()], [sqlite3_free()], and [sqlite3_realloc()], +** the memory allocation subsystem included with the SQLite +** sources provides the interfaces shown below. +** +** The first of these two routines returns the amount of memory +** currently outstanding (malloced but not freed). The second +** returns the largest instantaneous amount of outstanding +** memory. The highwater mark is reset if the argument is +** true. +** +** The value returned may or may not include allocation +** overhead, depending on which built-in memory allocator +** implementation is used. +*/ +sqlite3_int64 sqlite3_memory_used(void); +sqlite3_int64 sqlite3_memory_highwater(int resetFlag); + +/* +** CAPI3REF: Compile-Time Authorization Callbacks +*** +** This routine registers a authorizer callback with the SQLite library. +** The authorizer callback is invoked as SQL statements are being compiled +** by [sqlite3_prepare()] or its variants [sqlite3_prepare_v2()], +** [sqlite3_prepare16()] and [sqlite3_prepare16_v2()]. At various +** points during the compilation process, as logic is being created +** to perform various actions, the authorizer callback is invoked to +** see if those actions are allowed. The authorizer callback should +** return SQLITE_OK to allow the action, [SQLITE_IGNORE] to disallow the +** specific action but allow the SQL statement to continue to be +** compiled, or [SQLITE_DENY] to cause the entire SQL statement to be +** rejected with an error. +** +** Depending on the action, the [SQLITE_IGNORE] and [SQLITE_DENY] return +** codes might mean something different or they might mean the same +** thing. If the action is, for example, to perform a delete opertion, +** then [SQLITE_IGNORE] and [SQLITE_DENY] both cause the statement compilation +** to fail with an error. But if the action is to read a specific column +** from a specific table, then [SQLITE_DENY] will cause the entire +** statement to fail but [SQLITE_IGNORE] will cause a NULL value to be +** read instead of the actual column value. +** +** The first parameter to the authorizer callback is a copy of +** the third parameter to the sqlite3_set_authorizer() interface. +** The second parameter to the callback is an integer +** [SQLITE_COPY | action code] that specifies the particular action +** to be authorized. The available action codes are +** [SQLITE_COPY | documented separately]. The third through sixth +** parameters to the callback are strings that contain additional +** details about the action to be authorized. +** +** An authorizer is used when preparing SQL statements from an untrusted +** source, to ensure that the SQL statements do not try to access data +** that they are not allowed to see, or that they do not try to +** execute malicious statements that damage the database. For +** example, an application may allow a user to enter arbitrary +** SQL queries for evaluation by a database. But the application does +** not want the user to be able to make arbitrary changes to the +** database. An authorizer could then be put in place while the +** user-entered SQL is being prepared that disallows everything +** except SELECT statements. +** +** Only a single authorizer can be in place on a database connection +** at a time. Each call to sqlite3_set_authorizer overrides the +** previous call. A NULL authorizer means that no authorization +** callback is invoked. The default authorizer is NULL. +** +** Note that the authorizer callback is invoked only during +** [sqlite3_prepare()] or its variants. Authorization is not +** performed during statement evaluation in [sqlite3_step()]. +*/ +int sqlite3_set_authorizer( + sqlite3*, + int (*xAuth)(void*,int,const char*,const char*,const char*,const char*), + void *pUserData +); + +/* +** CAPI3REF: Authorizer Return Codes +** +** The [sqlite3_set_authorizer | authorizer callback function] must +** return either [SQLITE_OK] or one of these two constants in order +** to signal SQLite whether or not the action is permitted. See the +** [sqlite3_set_authorizer | authorizer documentation] for additional +** information. +*/ +#define SQLITE_DENY 1 /* Abort the SQL statement with an error */ +#define SQLITE_IGNORE 2 /* Don't allow access, but don't generate an error */ + +/* +** CAPI3REF: Authorizer Action Codes +** +** The [sqlite3_set_authorizer()] interface registers a callback function +** that is invoked to authorizer certain SQL statement actions. The +** second parameter to the callback is an integer code that specifies +** what action is being authorized. These are the integer action codes that +** the authorizer callback may be passed. +** +** These action code values signify what kind of operation is to be +** authorized. The 3rd and 4th parameters to the authorization callback +** function will be parameters or NULL depending on which of these +** codes is used as the second parameter. The 5th parameter to the +** authorizer callback is the name of the database ("main", "temp", +** etc.) if applicable. The 6th parameter to the authorizer callback +** is the name of the inner-most trigger or view that is responsible for +** the access attempt or NULL if this access attempt is directly from +** top-level SQL code. +*/ +/******************************************* 3rd ************ 4th ***********/ +#define SQLITE_CREATE_INDEX 1 /* Index Name Table Name */ +#define SQLITE_CREATE_TABLE 2 /* Table Name NULL */ +#define SQLITE_CREATE_TEMP_INDEX 3 /* Index Name Table Name */ +#define SQLITE_CREATE_TEMP_TABLE 4 /* Table Name NULL */ +#define SQLITE_CREATE_TEMP_TRIGGER 5 /* Trigger Name Table Name */ +#define SQLITE_CREATE_TEMP_VIEW 6 /* View Name NULL */ +#define SQLITE_CREATE_TRIGGER 7 /* Trigger Name Table Name */ +#define SQLITE_CREATE_VIEW 8 /* View Name NULL */ +#define SQLITE_DELETE 9 /* Table Name NULL */ +#define SQLITE_DROP_INDEX 10 /* Index Name Table Name */ +#define SQLITE_DROP_TABLE 11 /* Table Name NULL */ +#define SQLITE_DROP_TEMP_INDEX 12 /* Index Name Table Name */ +#define SQLITE_DROP_TEMP_TABLE 13 /* Table Name NULL */ +#define SQLITE_DROP_TEMP_TRIGGER 14 /* Trigger Name Table Name */ +#define SQLITE_DROP_TEMP_VIEW 15 /* View Name NULL */ +#define SQLITE_DROP_TRIGGER 16 /* Trigger Name Table Name */ +#define SQLITE_DROP_VIEW 17 /* View Name NULL */ +#define SQLITE_INSERT 18 /* Table Name NULL */ +#define SQLITE_PRAGMA 19 /* Pragma Name 1st arg or NULL */ +#define SQLITE_READ 20 /* Table Name Column Name */ +#define SQLITE_SELECT 21 /* NULL NULL */ +#define SQLITE_TRANSACTION 22 /* NULL NULL */ +#define SQLITE_UPDATE 23 /* Table Name Column Name */ +#define SQLITE_ATTACH 24 /* Filename NULL */ +#define SQLITE_DETACH 25 /* Database Name NULL */ +#define SQLITE_ALTER_TABLE 26 /* Database Name Table Name */ +#define SQLITE_REINDEX 27 /* Index Name NULL */ +#define SQLITE_ANALYZE 28 /* Table Name NULL */ +#define SQLITE_CREATE_VTABLE 29 /* Table Name Module Name */ +#define SQLITE_DROP_VTABLE 30 /* Table Name Module Name */ +#define SQLITE_FUNCTION 31 /* Function Name NULL */ +#define SQLITE_COPY 0 /* No longer used */ + +/* +** CAPI3REF: Tracing And Profiling Functions +** +** These routines register callback functions that can be used for +** tracing and profiling the execution of SQL statements. +** The callback function registered by sqlite3_trace() is invoked +** at the first [sqlite3_step()] for the evaluation of an SQL statement. +** The callback function registered by sqlite3_profile() is invoked +** as each SQL statement finishes and includes +** information on how long that statement ran. +** +** The sqlite3_profile() API is currently considered experimental and +** is subject to change. +*/ +void *sqlite3_trace(sqlite3*, void(*xTrace)(void*,const char*), void*); +void *sqlite3_profile(sqlite3*, + void(*xProfile)(void*,const char*,sqlite3_uint64), void*); + +/* +** CAPI3REF: Query Progress Callbacks +** +** This routine configures a callback function - the progress callback - that +** is invoked periodically during long running calls to [sqlite3_exec()], +** [sqlite3_step()] and [sqlite3_get_table()]. An example use for this +** interface is to keep a GUI updated during a large query. +** +** The progress callback is invoked once for every N virtual machine opcodes, +** where N is the second argument to this function. The progress callback +** itself is identified by the third argument to this function. The fourth +** argument to this function is a void pointer passed to the progress callback +** function each time it is invoked. +** +** If a call to [sqlite3_exec()], [sqlite3_step()], or [sqlite3_get_table()] +** results in fewer than N opcodes being executed, then the progress +** callback is never invoked. +** +** Only a single progress callback function may be registered for each +** open database connection. Every call to sqlite3_progress_handler() +** overwrites the results of the previous call. +** To remove the progress callback altogether, pass NULL as the third +** argument to this function. +** +** If the progress callback returns a result other than 0, then the current +** query is immediately terminated and any database changes rolled back. +** The containing [sqlite3_exec()], [sqlite3_step()], or +** [sqlite3_get_table()] call returns SQLITE_INTERRUPT. This feature +** can be used, for example, to implement the "Cancel" button on a +** progress dialog box in a GUI. +*/ +void sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*); + +/* +** CAPI3REF: Opening A New Database Connection +** +** Open the sqlite database file "filename". The "filename" is UTF-8 +** encoded for [sqlite3_open()] and [sqlite3_open_v2()] and UTF-16 encoded +** in the native byte order for [sqlite3_open16()]. +** An [sqlite3*] handle is returned in *ppDb, even +** if an error occurs. If the database is opened (or created) successfully, +** then [SQLITE_OK] is returned. Otherwise an error code is returned. The +** [sqlite3_errmsg()] or [sqlite3_errmsg16()] routines can be used to obtain +** an English language description of the error. +** +** The default encoding for the database will be UTF-8 if +** [sqlite3_open()] or [sqlite3_open_v2()] is called and +** UTF-16 if [sqlite3_open16()] is used. +** +** Whether or not an error occurs when it is opened, resources associated +** with the [sqlite3*] handle should be released by passing it to +** [sqlite3_close()] when it is no longer required. +** +** The [sqlite3_open_v2()] interface works like [sqlite3_open()] except that +** provides two additional parameters for additional control over the +** new database connection. The flags parameter can be one of: +** +** <ol> +** <li> [SQLITE_OPEN_READONLY] +** <li> [SQLITE_OPEN_READWRITE] +** <li> [SQLITE_OPEN_READWRITE] | [SQLITE_OPEN_CREATE] +** </ol> +** +** The first value opens the database read-only. If the database does +** not previously exist, an error is returned. The second option opens +** the database for reading and writing if possible, or reading only if +** if the file is write protected. In either case the database must already +** exist or an error is returned. The third option opens the database +** for reading and writing and creates it if it does not already exist. +** The third options is behavior that is always used for [sqlite3_open()] +** and [sqlite3_open16()]. +** +** If the filename is ":memory:", then an private +** in-memory database is created for the connection. This in-memory +** database will vanish when the database connection is closed. Future +** version of SQLite might make use of additional special filenames +** that begin with the ":" character. It is recommended that +** when a database filename really does begin with +** ":" that you prefix the filename with a pathname like "./" to +** avoid ambiguity. +** +** If the filename is an empty string, then a private temporary +** on-disk database will be created. This private database will be +** automatically deleted as soon as the database connection is closed. +** +** The fourth parameter to sqlite3_open_v2() is the name of the +** [sqlite3_vfs] object that defines the operating system +** interface that the new database connection should use. If the +** fourth parameter is a NULL pointer then the default [sqlite3_vfs] +** object is used. +** +** <b>Note to windows users:</b> The encoding used for the filename argument +** of [sqlite3_open()] and [sqlite3_open_v2()] must be UTF-8, not whatever +** codepage is currently defined. Filenames containing international +** characters must be converted to UTF-8 prior to passing them into +** [sqlite3_open()] or [sqlite3_open_v2()]. +*/ +int sqlite3_open( + const char *filename, /* Database filename (UTF-8) */ + sqlite3 **ppDb /* OUT: SQLite db handle */ +); +int sqlite3_open16( + const void *filename, /* Database filename (UTF-16) */ + sqlite3 **ppDb /* OUT: SQLite db handle */ +); +int sqlite3_open_v2( + const char *filename, /* Database filename (UTF-8) */ + sqlite3 **ppDb, /* OUT: SQLite db handle */ + int flags, /* Flags */ + const char *zVfs /* Name of VFS module to use */ +); + +/* +** CAPI3REF: Error Codes And Messages +** +** The sqlite3_errcode() interface returns the numeric +** [SQLITE_OK | result code] or [SQLITE_IOERR_READ | extended result code] +** for the most recent failed sqlite3_* API call associated +** with [sqlite3] handle 'db'. If a prior API call failed but the +** most recent API call succeeded, the return value from sqlite3_errcode() +** is undefined. +** +** The sqlite3_errmsg() and sqlite3_errmsg16() return English-language +** text that describes the error, as either UTF8 or UTF16 respectively. +** Memory to hold the error message string is managed internally. The +** string may be overwritten or deallocated by subsequent calls to SQLite +** interface functions. +** +** Calls to many sqlite3_* functions set the error code and string returned +** by [sqlite3_errcode()], [sqlite3_errmsg()], and [sqlite3_errmsg16()] +** (overwriting the previous values). Note that calls to [sqlite3_errcode()], +** [sqlite3_errmsg()], and [sqlite3_errmsg16()] themselves do not affect the +** results of future invocations. Calls to API routines that do not return +** an error code (example: [sqlite3_data_count()]) do not +** change the error code returned by this routine. Interfaces that are +** not associated with a specific database connection (examples: +** [sqlite3_mprintf()] or [sqlite3_enable_shared_cache()] do not change +** the return code. +** +** Assuming no other intervening sqlite3_* API calls are made, the error +** code returned by this function is associated with the same error as +** the strings returned by [sqlite3_errmsg()] and [sqlite3_errmsg16()]. +*/ +int sqlite3_errcode(sqlite3 *db); +const char *sqlite3_errmsg(sqlite3*); +const void *sqlite3_errmsg16(sqlite3*); + +/* +** CAPI3REF: SQL Statement Object +** +** Instance of this object represent single SQL statements. This +** is variously known as a "prepared statement" or a +** "compiled SQL statement" or simply as a "statement". +** +** The life of a statement object goes something like this: +** +** <ol> +** <li> Create the object using [sqlite3_prepare_v2()] or a related +** function. +** <li> Bind values to host parameters using +** [sqlite3_bind_blob | sqlite3_bind_* interfaces]. +** <li> Run the SQL by calling [sqlite3_step()] one or more times. +** <li> Reset the statement using [sqlite3_reset()] then go back +** to step 2. Do this zero or more times. +** <li> Destroy the object using [sqlite3_finalize()]. +** </ol> +** +** Refer to documentation on individual methods above for additional +** information. +*/ +typedef struct sqlite3_stmt sqlite3_stmt; + +/* +** CAPI3REF: Compiling An SQL Statement +** +** To execute an SQL query, it must first be compiled into a byte-code +** program using one of these routines. +** +** The first argument "db" is an [sqlite3 | SQLite database handle] +** obtained from a prior call to [sqlite3_open()], [sqlite3_open_v2()] +** or [sqlite3_open16()]. +** The second argument "zSql" is the statement to be compiled, encoded +** as either UTF-8 or UTF-16. The sqlite3_prepare() and sqlite3_prepare_v2() +** interfaces uses UTF-8 and sqlite3_prepare16() and sqlite3_prepare16_v2() +** use UTF-16. +** +** If the nByte argument is less +** than zero, then zSql is read up to the first zero terminator. If +** nByte is non-negative, then it is the maximum number of +** bytes read from zSql. When nByte is non-negative, the +** zSql string ends at either the first '\000' character or +** until the nByte-th byte, whichever comes first. +** +** *pzTail is made to point to the first byte past the end of the first +** SQL statement in zSql. This routine only compiles the first statement +** in zSql, so *pzTail is left pointing to what remains uncompiled. +** +** *ppStmt is left pointing to a compiled +** [sqlite3_stmt | SQL statement structure] that can be +** executed using [sqlite3_step()]. Or if there is an error, *ppStmt may be +** set to NULL. If the input text contained no SQL (if the input is and +** empty string or a comment) then *ppStmt is set to NULL. The calling +** procedure is responsible for deleting the compiled SQL statement +** using [sqlite3_finalize()] after it has finished with it. +** +** On success, [SQLITE_OK] is returned. Otherwise an +** [SQLITE_ERROR | error code] is returned. +** +** The sqlite3_prepare_v2() and sqlite3_prepare16_v2() interfaces are +** recommended for all new programs. The two older interfaces are retained +** for backwards compatibility, but their use is discouraged. +** In the "v2" interfaces, the prepared statement +** that is returned (the [sqlite3_stmt] object) contains a copy of the +** original SQL text. This causes the [sqlite3_step()] interface to +** behave a differently in two ways: +** +** <ol> +** <li> +** If the database schema changes, instead of returning [SQLITE_SCHEMA] as it +** always used to do, [sqlite3_step()] will automatically recompile the SQL +** statement and try to run it again. If the schema has changed in a way +** that makes the statement no longer valid, [sqlite3_step()] will still +** return [SQLITE_SCHEMA]. But unlike the legacy behavior, [SQLITE_SCHEMA] is +** now a fatal error. Calling [sqlite3_prepare_v2()] again will not make the +** error go away. Note: use [sqlite3_errmsg()] to find the text of the parsing +** error that results in an [SQLITE_SCHEMA] return. +** </li> +** +** <li> +** When an error occurs, +** [sqlite3_step()] will return one of the detailed +** [SQLITE_ERROR | result codes] or +** [SQLITE_IOERR_READ | extended result codes] such as directly. +** The legacy behavior was that [sqlite3_step()] would only return a generic +** [SQLITE_ERROR] result code and you would have to make a second call to +** [sqlite3_reset()] in order to find the underlying cause of the problem. +** With the "v2" prepare interfaces, the underlying reason for the error is +** returned immediately. +** </li> +** </ol> +*/ +int sqlite3_prepare( + sqlite3 *db, /* Database handle */ + const char *zSql, /* SQL statement, UTF-8 encoded */ + int nByte, /* Maximum length of zSql in bytes. */ + sqlite3_stmt **ppStmt, /* OUT: Statement handle */ + const char **pzTail /* OUT: Pointer to unused portion of zSql */ +); +int sqlite3_prepare_v2( + sqlite3 *db, /* Database handle */ + const char *zSql, /* SQL statement, UTF-8 encoded */ + int nByte, /* Maximum length of zSql in bytes. */ + sqlite3_stmt **ppStmt, /* OUT: Statement handle */ + const char **pzTail /* OUT: Pointer to unused portion of zSql */ +); +int sqlite3_prepare16( + sqlite3 *db, /* Database handle */ + const void *zSql, /* SQL statement, UTF-16 encoded */ + int nByte, /* Maximum length of zSql in bytes. */ + sqlite3_stmt **ppStmt, /* OUT: Statement handle */ + const void **pzTail /* OUT: Pointer to unused portion of zSql */ +); +int sqlite3_prepare16_v2( + sqlite3 *db, /* Database handle */ + const void *zSql, /* SQL statement, UTF-16 encoded */ + int nByte, /* Maximum length of zSql in bytes. */ + sqlite3_stmt **ppStmt, /* OUT: Statement handle */ + const void **pzTail /* OUT: Pointer to unused portion of zSql */ +); + +/* +** Retrieve the original SQL statement associated with a compiled statement +** in UTF-8 encoding. +** +** If the compiled SQL statement passed as an argument was compiled using +** either sqlite3_prepare_v2 or sqlite3_prepare16_v2, then this function +** returns a pointer to a nul-terminated string containing a copy of +** the original SQL statement. The pointer is valid until the statement +** is deleted using sqlite3_finalize(). +** +** If the statement was compiled using either of the legacy interfaces +** sqlite3_prepare() or sqlite3_prepare16(), this function returns NULL. +** +****** EXPERIMENTAL - subject to change without notice ************** +*/ +const char *sqlite3_sql(sqlite3_stmt *pStmt); + +/* +** CAPI3REF: Dynamically Typed Value Object +** +** SQLite uses dynamic typing for the values it stores. Values can +** be integers, floating point values, strings, BLOBs, or NULL. When +** passing around values internally, each value is represented as +** an instance of the sqlite3_value object. +*/ +typedef struct Mem sqlite3_value; + +/* +** CAPI3REF: SQL Function Context Object +** +** The context in which an SQL function executes is stored in an +** sqlite3_context object. A pointer to such an object is the +** first parameter to user-defined SQL functions. +*/ +typedef struct sqlite3_context sqlite3_context; + +/* +** CAPI3REF: Binding Values To Prepared Statements +** +** In the SQL strings input to [sqlite3_prepare_v2()] and its variants, +** one or more literals can be replace by a parameter in one of these +** forms: +** +** <ul> +** <li> ? +** <li> ?NNN +** <li> :AAA +** <li> @AAA +** <li> $VVV +** </ul> +** +** In the parameter forms shown above NNN is an integer literal, +** AAA is an alphanumeric identifier and VVV is a variable name according +** to the syntax rules of the TCL programming language. +** The values of these parameters (also called "host parameter names") +** can be set using the sqlite3_bind_*() routines defined here. +** +** The first argument to the sqlite3_bind_*() routines always is a pointer +** to the [sqlite3_stmt] object returned from [sqlite3_prepare_v2()] or +** its variants. The second +** argument is the index of the parameter to be set. The first parameter has +** an index of 1. When the same named parameter is used more than once, second +** and subsequent +** occurrences have the same index as the first occurrence. The index for +** named parameters can be looked up using the +** [sqlite3_bind_parameter_name()] API if desired. The index for "?NNN" +** parametes is the value of NNN. +** The NNN value must be between 1 and the compile-time +** parameter SQLITE_MAX_VARIABLE_NUMBER (default value: 999). +** See <a href="limits.html">limits.html</a> for additional information. +** +** The third argument is the value to bind to the parameter. +** +** In those +** routines that have a fourth argument, its value is the number of bytes +** in the parameter. To be clear: the value is the number of bytes in the +** string, not the number of characters. The number +** of bytes does not include the zero-terminator at the end of strings. +** If the fourth parameter is negative, the length of the string is +** number of bytes up to the first zero terminator. +** +** The fifth argument to sqlite3_bind_blob(), sqlite3_bind_text(), and +** sqlite3_bind_text16() is a destructor used to dispose of the BLOB or +** text after SQLite has finished with it. If the fifth argument is the +** special value [SQLITE_STATIC], then the library assumes that the information +** is in static, unmanaged space and does not need to be freed. If the +** fifth argument has the value [SQLITE_TRANSIENT], then SQLite makes its +** own private copy of the data immediately, before the sqlite3_bind_*() +** routine returns. +** +** The sqlite3_bind_zeroblob() routine binds a BLOB of length n that +** is filled with zeros. A zeroblob uses a fixed amount of memory +** (just an integer to hold it size) while it is being processed. +** Zeroblobs are intended to serve as place-holders for BLOBs whose +** content is later written using +** [sqlite3_blob_open | increment BLOB I/O] routines. A negative +** value for the zeroblob results in a zero-length BLOB. +** +** The sqlite3_bind_*() routines must be called after +** [sqlite3_prepare_v2()] (and its variants) or [sqlite3_reset()] and +** before [sqlite3_step()]. +** Bindings are not cleared by the [sqlite3_reset()] routine. +** Unbound parameters are interpreted as NULL. +** +** These routines return [SQLITE_OK] on success or an error code if +** anything goes wrong. [SQLITE_RANGE] is returned if the parameter +** index is out of range. [SQLITE_NOMEM] is returned if malloc fails. +** [SQLITE_MISUSE] is returned if these routines are called on a virtual +** machine that is the wrong state or which has already been finalized. +*/ +int sqlite3_bind_blob(sqlite3_stmt*, int, const void*, int n, void(*)(void*)); +int sqlite3_bind_double(sqlite3_stmt*, int, double); +int sqlite3_bind_int(sqlite3_stmt*, int, int); +int sqlite3_bind_int64(sqlite3_stmt*, int, sqlite3_int64); +int sqlite3_bind_null(sqlite3_stmt*, int); +int sqlite3_bind_text(sqlite3_stmt*, int, const char*, int n, void(*)(void*)); +int sqlite3_bind_text16(sqlite3_stmt*, int, const void*, int, void(*)(void*)); +int sqlite3_bind_value(sqlite3_stmt*, int, const sqlite3_value*); +int sqlite3_bind_zeroblob(sqlite3_stmt*, int, int n); + +/* +** CAPI3REF: Number Of Host Parameters +** +** Return the largest host parameter index in the precompiled statement given +** as the argument. When the host parameters are of the forms like ":AAA" +** or "?", then they are assigned sequential increasing numbers beginning +** with one, so the value returned is the number of parameters. However +** if the same host parameter name is used multiple times, each occurrance +** is given the same number, so the value returned in that case is the number +** of unique host parameter names. If host parameters of the form "?NNN" +** are used (where NNN is an integer) then there might be gaps in the +** numbering and the value returned by this interface is the index of the +** host parameter with the largest index value. +** +** The prepared statement must not be [sqlite3_finalize | finalized] +** prior to this routine returnning. Otherwise the results are undefined +** and probably undesirable. +*/ +int sqlite3_bind_parameter_count(sqlite3_stmt*); + +/* +** CAPI3REF: Name Of A Host Parameter +** +** This routine returns a pointer to the name of the n-th parameter in a +** [sqlite3_stmt | prepared statement]. +** Host parameters of the form ":AAA" or "@AAA" or "$VVV" have a name +** which is the string ":AAA" or "@AAA" or "$VVV". +** In other words, the initial ":" or "$" or "@" +** is included as part of the name. +** Parameters of the form "?" or "?NNN" have no name. +** +** The first bound parameter has an index of 1, not 0. +** +** If the value n is out of range or if the n-th parameter is nameless, +** then NULL is returned. The returned string is always in the +** UTF-8 encoding even if the named parameter was originally specified +** as UTF-16 in [sqlite3_prepare16()] or [sqlite3_prepare16_v2()]. +*/ +const char *sqlite3_bind_parameter_name(sqlite3_stmt*, int); + +/* +** CAPI3REF: Index Of A Parameter With A Given Name +** +** This routine returns the index of a host parameter with the given name. +** The name must match exactly. If no parameter with the given name is +** found, return 0. Parameter names must be UTF8. +*/ +int sqlite3_bind_parameter_index(sqlite3_stmt*, const char *zName); + +/* +** CAPI3REF: Reset All Bindings On A Prepared Statement +** +** Contrary to the intuition of many, [sqlite3_reset()] does not +** reset the [sqlite3_bind_blob | bindings] on a +** [sqlite3_stmt | prepared statement]. Use this routine to +** reset all host parameters to NULL. +*/ +int sqlite3_clear_bindings(sqlite3_stmt*); + +/* +** CAPI3REF: Number Of Columns In A Result Set +** +** Return the number of columns in the result set returned by the +** [sqlite3_stmt | compiled SQL statement]. This routine returns 0 +** if pStmt is an SQL statement that does not return data (for +** example an UPDATE). +*/ +int sqlite3_column_count(sqlite3_stmt *pStmt); + +/* +** CAPI3REF: Column Names In A Result Set +** +** These routines return the name assigned to a particular column +** in the result set of a SELECT statement. The sqlite3_column_name() +** interface returns a pointer to a UTF8 string and sqlite3_column_name16() +** returns a pointer to a UTF16 string. The first parameter is the +** [sqlite3_stmt | prepared statement] that implements the SELECT statement. +** The second parameter is the column number. The left-most column is +** number 0. +** +** The returned string pointer is valid until either the +** [sqlite3_stmt | prepared statement] is destroyed by [sqlite3_finalize()] +** or until the next call sqlite3_column_name() or sqlite3_column_name16() +** on the same column. +** +** If sqlite3_malloc() fails during the processing of either routine +** (for example during a conversion from UTF-8 to UTF-16) then a +** NULL pointer is returned. +*/ +const char *sqlite3_column_name(sqlite3_stmt*, int N); +const void *sqlite3_column_name16(sqlite3_stmt*, int N); + +/* +** CAPI3REF: Source Of Data In A Query Result +** +** These routines provide a means to determine what column of what +** table in which database a result of a SELECT statement comes from. +** The name of the database or table or column can be returned as +** either a UTF8 or UTF16 string. The _database_ routines return +** the database name, the _table_ routines return the table name, and +** the origin_ routines return the column name. +** The returned string is valid until +** the [sqlite3_stmt | prepared statement] is destroyed using +** [sqlite3_finalize()] or until the same information is requested +** again in a different encoding. +** +** The names returned are the original un-aliased names of the +** database, table, and column. +** +** The first argument to the following calls is a +** [sqlite3_stmt | compiled SQL statement]. +** These functions return information about the Nth column returned by +** the statement, where N is the second function argument. +** +** If the Nth column returned by the statement is an expression +** or subquery and is not a column value, then all of these functions +** return NULL. Otherwise, they return the +** name of the attached database, table and column that query result +** column was extracted from. +** +** As with all other SQLite APIs, those postfixed with "16" return UTF-16 +** encoded strings, the other functions return UTF-8. +** +** These APIs are only available if the library was compiled with the +** SQLITE_ENABLE_COLUMN_METADATA preprocessor symbol defined. +** +** If two or more threads call one or more of these routines against the same +** prepared statement and column at the same time then the results are +** undefined. +*/ +const char *sqlite3_column_database_name(sqlite3_stmt*,int); +const void *sqlite3_column_database_name16(sqlite3_stmt*,int); +const char *sqlite3_column_table_name(sqlite3_stmt*,int); +const void *sqlite3_column_table_name16(sqlite3_stmt*,int); +const char *sqlite3_column_origin_name(sqlite3_stmt*,int); +const void *sqlite3_column_origin_name16(sqlite3_stmt*,int); + +/* +** CAPI3REF: Declared Datatype Of A Query Result +** +** The first parameter is a [sqlite3_stmt | compiled SQL statement]. +** If this statement is a SELECT statement and the Nth column of the +** returned result set of that SELECT is a table column (not an +** expression or subquery) then the declared type of the table +** column is returned. If the Nth column of the result set is an +** expression or subquery, then a NULL pointer is returned. +** The returned string is always UTF-8 encoded. For example, in +** the database schema: +** +** CREATE TABLE t1(c1 VARIANT); +** +** And the following statement compiled: +** +** SELECT c1 + 1, c1 FROM t1; +** +** Then this routine would return the string "VARIANT" for the second +** result column (i==1), and a NULL pointer for the first result column +** (i==0). +** +** SQLite uses dynamic run-time typing. So just because a column +** is declared to contain a particular type does not mean that the +** data stored in that column is of the declared type. SQLite is +** strongly typed, but the typing is dynamic not static. Type +** is associated with individual values, not with the containers +** used to hold those values. +*/ +const char *sqlite3_column_decltype(sqlite3_stmt *, int i); +const void *sqlite3_column_decltype16(sqlite3_stmt*,int); + +/* +** CAPI3REF: Evaluate An SQL Statement +** +** After an [sqlite3_stmt | SQL statement] has been prepared with a call +** to either [sqlite3_prepare_v2()] or [sqlite3_prepare16_v2()] or to one of +** the legacy interfaces [sqlite3_prepare()] or [sqlite3_prepare16()], +** then this function must be called one or more times to evaluate the +** statement. +** +** The details of the behavior of this sqlite3_step() interface depend +** on whether the statement was prepared using the newer "v2" interface +** [sqlite3_prepare_v2()] and [sqlite3_prepare16_v2()] or the older legacy +** interface [sqlite3_prepare()] and [sqlite3_prepare16()]. The use of the +** new "v2" interface is recommended for new applications but the legacy +** interface will continue to be supported. +** +** In the lagacy interface, the return value will be either [SQLITE_BUSY], +** [SQLITE_DONE], [SQLITE_ROW], [SQLITE_ERROR], or [SQLITE_MISUSE]. +** With the "v2" interface, any of the other [SQLITE_OK | result code] +** or [SQLITE_IOERR_READ | extended result code] might be returned as +** well. +** +** [SQLITE_BUSY] means that the database engine was unable to acquire the +** database locks it needs to do its job. If the statement is a COMMIT +** or occurs outside of an explicit transaction, then you can retry the +** statement. If the statement is not a COMMIT and occurs within a +** explicit transaction then you should rollback the transaction before +** continuing. +** +** [SQLITE_DONE] means that the statement has finished executing +** successfully. sqlite3_step() should not be called again on this virtual +** machine without first calling [sqlite3_reset()] to reset the virtual +** machine back to its initial state. +** +** If the SQL statement being executed returns any data, then +** [SQLITE_ROW] is returned each time a new row of data is ready +** for processing by the caller. The values may be accessed using +** the [sqlite3_column_int | column access functions]. +** sqlite3_step() is called again to retrieve the next row of data. +** +** [SQLITE_ERROR] means that a run-time error (such as a constraint +** violation) has occurred. sqlite3_step() should not be called again on +** the VM. More information may be found by calling [sqlite3_errmsg()]. +** With the legacy interface, a more specific error code (example: +** [SQLITE_INTERRUPT], [SQLITE_SCHEMA], [SQLITE_CORRUPT], and so forth) +** can be obtained by calling [sqlite3_reset()] on the +** [sqlite3_stmt | prepared statement]. In the "v2" interface, +** the more specific error code is returned directly by sqlite3_step(). +** +** [SQLITE_MISUSE] means that the this routine was called inappropriately. +** Perhaps it was called on a [sqlite3_stmt | prepared statement] that has +** already been [sqlite3_finalize | finalized] or on one that had +** previously returned [SQLITE_ERROR] or [SQLITE_DONE]. Or it could +** be the case that the same database connection is being used by two or +** more threads at the same moment in time. +** +** <b>Goofy Interface Alert:</b> +** In the legacy interface, +** the sqlite3_step() API always returns a generic error code, +** [SQLITE_ERROR], following any error other than [SQLITE_BUSY] +** and [SQLITE_MISUSE]. You must call [sqlite3_reset()] or +** [sqlite3_finalize()] in order to find one of the specific +** [SQLITE_ERROR | result codes] that better describes the error. +** We admit that this is a goofy design. The problem has been fixed +** with the "v2" interface. If you prepare all of your SQL statements +** using either [sqlite3_prepare_v2()] or [sqlite3_prepare16_v2()] instead +** of the legacy [sqlite3_prepare()] and [sqlite3_prepare16()], then the +** more specific [SQLITE_ERROR | result codes] are returned directly +** by sqlite3_step(). The use of the "v2" interface is recommended. +*/ +int sqlite3_step(sqlite3_stmt*); + +/* +** CAPI3REF: +** +** Return the number of values in the current row of the result set. +** +** After a call to [sqlite3_step()] that returns [SQLITE_ROW], this routine +** will return the same value as the [sqlite3_column_count()] function. +** After [sqlite3_step()] has returned an [SQLITE_DONE], [SQLITE_BUSY], or +** a [SQLITE_ERROR | error code], or before [sqlite3_step()] has been +** called on the [sqlite3_stmt | prepared statement] for the first time, +** this routine returns zero. +*/ +int sqlite3_data_count(sqlite3_stmt *pStmt); + +/* +** CAPI3REF: Fundamental Datatypes +** +** Every value in SQLite has one of five fundamental datatypes: +** +** <ul> +** <li> 64-bit signed integer +** <li> 64-bit IEEE floating point number +** <li> string +** <li> BLOB +** <li> NULL +** </ul> +** +** These constants are codes for each of those types. +** +** Note that the SQLITE_TEXT constant was also used in SQLite version 2 +** for a completely different meaning. Software that links against both +** SQLite version 2 and SQLite version 3 should use SQLITE3_TEXT not +** SQLITE_TEXT. +*/ +#define SQLITE_INTEGER 1 +#define SQLITE_FLOAT 2 +#define SQLITE_BLOB 4 +#define SQLITE_NULL 5 +#ifdef SQLITE_TEXT +# undef SQLITE_TEXT +#else +# define SQLITE_TEXT 3 +#endif +#define SQLITE3_TEXT 3 + +/* +** CAPI3REF: Results Values From A Query +** +** These routines return information about +** a single column of the current result row of a query. In every +** case the first argument is a pointer to the +** [sqlite3_stmt | SQL statement] that is being +** evaluated (the [sqlite3_stmt*] that was returned from +** [sqlite3_prepare_v2()] or one of its variants) and +** the second argument is the index of the column for which information +** should be returned. The left-most column of the result set +** has an index of 0. +** +** If the SQL statement is not currently point to a valid row, or if the +** the column index is out of range, the result is undefined. +** These routines may only be called when the most recent call to +** [sqlite3_step()] has returned [SQLITE_ROW] and neither +** [sqlite3_reset()] nor [sqlite3_finalize()] has been call subsequently. +** If any of these routines are called after [sqlite3_reset()] or +** [sqlite3_finalize()] or after [sqlite3_step()] has returned +** something other than [SQLITE_ROW], the results are undefined. +** If [sqlite3_step()] or [sqlite3_reset()] or [sqlite3_finalize()] +** are called from a different thread while any of these routines +** are pending, then the results are undefined. +** +** The sqlite3_column_type() routine returns +** [SQLITE_INTEGER | datatype code] for the initial data type +** of the result column. The returned value is one of [SQLITE_INTEGER], +** [SQLITE_FLOAT], [SQLITE_TEXT], [SQLITE_BLOB], or [SQLITE_NULL]. The value +** returned by sqlite3_column_type() is only meaningful if no type +** conversions have occurred as described below. After a type conversion, +** the value returned by sqlite3_column_type() is undefined. Future +** versions of SQLite may change the behavior of sqlite3_column_type() +** following a type conversion. +** +** If the result is a BLOB or UTF-8 string then the sqlite3_column_bytes() +** routine returns the number of bytes in that BLOB or string. +** If the result is a UTF-16 string, then sqlite3_column_bytes() converts +** the string to UTF-8 and then returns the number of bytes. +** If the result is a numeric value then sqlite3_column_bytes() uses +** [sqlite3_snprintf()] to convert that value to a UTF-8 string and returns +** the number of bytes in that string. +** The value returned does not include the zero terminator at the end +** of the string. For clarity: the value returned is the number of +** bytes in the string, not the number of characters. +** +** Strings returned by sqlite3_column_text() and sqlite3_column_text16(), +** even zero-length strings, are always zero terminated. The return +** value from sqlite3_column_blob() for a zero-length blob is an arbitrary +** pointer, possibly even a NULL pointer. +** +** The sqlite3_column_bytes16() routine is similar to sqlite3_column_bytes() +** but leaves the result in UTF-16 instead of UTF-8. +** The zero terminator is not included in this count. +** +** These routines attempt to convert the value where appropriate. For +** example, if the internal representation is FLOAT and a text result +** is requested, [sqlite3_snprintf()] is used internally to do the conversion +** automatically. The following table details the conversions that +** are applied: +** +** <blockquote> +** <table border="1"> +** <tr><th> Internal<br>Type <th> Requested<br>Type <th> Conversion +** +** <tr><td> NULL <td> INTEGER <td> Result is 0 +** <tr><td> NULL <td> FLOAT <td> Result is 0.0 +** <tr><td> NULL <td> TEXT <td> Result is NULL pointer +** <tr><td> NULL <td> BLOB <td> Result is NULL pointer +** <tr><td> INTEGER <td> FLOAT <td> Convert from integer to float +** <tr><td> INTEGER <td> TEXT <td> ASCII rendering of the integer +** <tr><td> INTEGER <td> BLOB <td> Same as for INTEGER->TEXT +** <tr><td> FLOAT <td> INTEGER <td> Convert from float to integer +** <tr><td> FLOAT <td> TEXT <td> ASCII rendering of the float +** <tr><td> FLOAT <td> BLOB <td> Same as FLOAT->TEXT +** <tr><td> TEXT <td> INTEGER <td> Use atoi() +** <tr><td> TEXT <td> FLOAT <td> Use atof() +** <tr><td> TEXT <td> BLOB <td> No change +** <tr><td> BLOB <td> INTEGER <td> Convert to TEXT then use atoi() +** <tr><td> BLOB <td> FLOAT <td> Convert to TEXT then use atof() +** <tr><td> BLOB <td> TEXT <td> Add a zero terminator if needed +** </table> +** </blockquote> +** +** The table above makes reference to standard C library functions atoi() +** and atof(). SQLite does not really use these functions. It has its +** on equavalent internal routines. The atoi() and atof() names are +** used in the table for brevity and because they are familiar to most +** C programmers. +** +** Note that when type conversions occur, pointers returned by prior +** calls to sqlite3_column_blob(), sqlite3_column_text(), and/or +** sqlite3_column_text16() may be invalidated. +** Type conversions and pointer invalidations might occur +** in the following cases: +** +** <ul> +** <li><p> The initial content is a BLOB and sqlite3_column_text() +** or sqlite3_column_text16() is called. A zero-terminator might +** need to be added to the string.</p></li> +** +** <li><p> The initial content is UTF-8 text and sqlite3_column_bytes16() or +** sqlite3_column_text16() is called. The content must be converted +** to UTF-16.</p></li> +** +** <li><p> The initial content is UTF-16 text and sqlite3_column_bytes() or +** sqlite3_column_text() is called. The content must be converted +** to UTF-8.</p></li> +** </ul> +** +** Conversions between UTF-16be and UTF-16le are always done in place and do +** not invalidate a prior pointer, though of course the content of the buffer +** that the prior pointer points to will have been modified. Other kinds +** of conversion are done in place when it is possible, but sometime it is +** not possible and in those cases prior pointers are invalidated. +** +** The safest and easiest to remember policy is to invoke these routines +** in one of the following ways: +** +** <ul> +** <li>sqlite3_column_text() followed by sqlite3_column_bytes()</li> +** <li>sqlite3_column_blob() followed by sqlite3_column_bytes()</li> +** <li>sqlite3_column_text16() followed by sqlite3_column_bytes16()</li> +** </ul> +** +** In other words, you should call sqlite3_column_text(), sqlite3_column_blob(), +** or sqlite3_column_text16() first to force the result into the desired +** format, then invoke sqlite3_column_bytes() or sqlite3_column_bytes16() to +** find the size of the result. Do not mix call to sqlite3_column_text() or +** sqlite3_column_blob() with calls to sqlite3_column_bytes16(). And do not +** mix calls to sqlite3_column_text16() with calls to sqlite3_column_bytes(). +** +** The pointers returned are valid until a type conversion occurs as +** described above, or until [sqlite3_step()] or [sqlite3_reset()] or +** [sqlite3_finalize()] is called. The memory space used to hold strings +** and blobs is freed automatically. Do <b>not</b> pass the pointers returned +** [sqlite3_column_blob()], [sqlite3_column_text()], etc. into +** [sqlite3_free()]. +** +** If a memory allocation error occurs during the evaluation of any +** of these routines, a default value is returned. The default value +** is either the integer 0, the floating point number 0.0, or a NULL +** pointer. Subsequent calls to [sqlite3_errcode()] will return +** [SQLITE_NOMEM]. +*/ +const void *sqlite3_column_blob(sqlite3_stmt*, int iCol); +int sqlite3_column_bytes(sqlite3_stmt*, int iCol); +int sqlite3_column_bytes16(sqlite3_stmt*, int iCol); +double sqlite3_column_double(sqlite3_stmt*, int iCol); +int sqlite3_column_int(sqlite3_stmt*, int iCol); +sqlite3_int64 sqlite3_column_int64(sqlite3_stmt*, int iCol); +const unsigned char *sqlite3_column_text(sqlite3_stmt*, int iCol); +const void *sqlite3_column_text16(sqlite3_stmt*, int iCol); +int sqlite3_column_type(sqlite3_stmt*, int iCol); +sqlite3_value *sqlite3_column_value(sqlite3_stmt*, int iCol); + +/* +** CAPI3REF: Destroy A Prepared Statement Object +** +** The sqlite3_finalize() function is called to delete a +** [sqlite3_stmt | compiled SQL statement]. If the statement was +** executed successfully, or not executed at all, then SQLITE_OK is returned. +** If execution of the statement failed then an +** [SQLITE_ERROR | error code] or [SQLITE_IOERR_READ | extended error code] +** is returned. +** +** This routine can be called at any point during the execution of the +** [sqlite3_stmt | virtual machine]. If the virtual machine has not +** completed execution when this routine is called, that is like +** encountering an error or an interrupt. (See [sqlite3_interrupt()].) +** Incomplete updates may be rolled back and transactions cancelled, +** depending on the circumstances, and the +** [SQLITE_ERROR | result code] returned will be [SQLITE_ABORT]. +*/ +int sqlite3_finalize(sqlite3_stmt *pStmt); + +/* +** CAPI3REF: Reset A Prepared Statement Object +** +** The sqlite3_reset() function is called to reset a +** [sqlite3_stmt | compiled SQL statement] object. +** back to it's initial state, ready to be re-executed. +** Any SQL statement variables that had values bound to them using +** the [sqlite3_bind_blob | sqlite3_bind_*() API] retain their values. +** Use [sqlite3_clear_bindings()] to reset the bindings. +*/ +int sqlite3_reset(sqlite3_stmt *pStmt); + +/* +** CAPI3REF: Create Or Redefine SQL Functions +** +** The following two functions are used to add SQL functions or aggregates +** or to redefine the behavior of existing SQL functions or aggregates. The +** difference only between the two is that the second parameter, the +** name of the (scalar) function or aggregate, is encoded in UTF-8 for +** sqlite3_create_function() and UTF-16 for sqlite3_create_function16(). +** +** The first argument is the [sqlite3 | database handle] that holds the +** SQL function or aggregate is to be added or redefined. If a single +** program uses more than one database handle internally, then SQL +** functions or aggregates must be added individually to each database +** handle with which they will be used. +** +** The second parameter is the name of the SQL function to be created +** or redefined. +** The length of the name is limited to 255 bytes, exclusive of the +** zero-terminator. Note that the name length limit is in bytes, not +** characters. Any attempt to create a function with a longer name +** will result in an SQLITE_ERROR error. +** +** The third parameter is the number of arguments that the SQL function or +** aggregate takes. If this parameter is negative, then the SQL function or +** aggregate may take any number of arguments. +** +** The fourth parameter, eTextRep, specifies what +** [SQLITE_UTF8 | text encoding] this SQL function prefers for +** its parameters. Any SQL function implementation should be able to work +** work with UTF-8, UTF-16le, or UTF-16be. But some implementations may be +** more efficient with one encoding than another. It is allowed to +** invoke sqlite3_create_function() or sqlite3_create_function16() multiple +** times with the same function but with different values of eTextRep. +** When multiple implementations of the same function are available, SQLite +** will pick the one that involves the least amount of data conversion. +** If there is only a single implementation which does not care what +** text encoding is used, then the fourth argument should be +** [SQLITE_ANY]. +** +** The fifth parameter is an arbitrary pointer. The implementation +** of the function can gain access to this pointer using +** [sqlite3_user_data()]. +** +** The seventh, eighth and ninth parameters, xFunc, xStep and xFinal, are +** pointers to C-language functions that implement the SQL +** function or aggregate. A scalar SQL function requires an implementation of +** the xFunc callback only, NULL pointers should be passed as the xStep +** and xFinal parameters. An aggregate SQL function requires an implementation +** of xStep and xFinal and NULL should be passed for xFunc. To delete an +** existing SQL function or aggregate, pass NULL for all three function +** callback. +** +** It is permitted to register multiple implementations of the same +** functions with the same name but with either differing numbers of +** arguments or differing perferred text encodings. SQLite will use +** the implementation most closely matches the way in which the +** SQL function is used. +*/ +int sqlite3_create_function( + sqlite3 *, + const char *zFunctionName, + int nArg, + int eTextRep, + void*, + void (*xFunc)(sqlite3_context*,int,sqlite3_value**), + void (*xStep)(sqlite3_context*,int,sqlite3_value**), + void (*xFinal)(sqlite3_context*) +); +int sqlite3_create_function16( + sqlite3*, + const void *zFunctionName, + int nArg, + int eTextRep, + void*, + void (*xFunc)(sqlite3_context*,int,sqlite3_value**), + void (*xStep)(sqlite3_context*,int,sqlite3_value**), + void (*xFinal)(sqlite3_context*) +); + +/* +** CAPI3REF: Text Encodings +** +** These constant define integer codes that represent the various +** text encodings supported by SQLite. +*/ +#define SQLITE_UTF8 1 +#define SQLITE_UTF16LE 2 +#define SQLITE_UTF16BE 3 +#define SQLITE_UTF16 4 /* Use native byte order */ +#define SQLITE_ANY 5 /* sqlite3_create_function only */ +#define SQLITE_UTF16_ALIGNED 8 /* sqlite3_create_collation only */ + +/* +** CAPI3REF: Obsolete Functions +** +** These functions are all now obsolete. In order to maintain +** backwards compatibility with older code, we continue to support +** these functions. However, new development projects should avoid +** the use of these functions. To help encourage people to avoid +** using these functions, we are not going to tell you want they do. +*/ +int sqlite3_aggregate_count(sqlite3_context*); +int sqlite3_expired(sqlite3_stmt*); +int sqlite3_transfer_bindings(sqlite3_stmt*, sqlite3_stmt*); +int sqlite3_global_recover(void); +void sqlite3_thread_cleanup(void); +int sqlite3_memory_alarm(void(*)(void*,sqlite3_int64,int),void*,sqlite3_int64); + +/* +** CAPI3REF: Obtaining SQL Function Parameter Values +** +** The C-language implementation of SQL functions and aggregates uses +** this set of interface routines to access the parameter values on +** the function or aggregate. +** +** The xFunc (for scalar functions) or xStep (for aggregates) parameters +** to [sqlite3_create_function()] and [sqlite3_create_function16()] +** define callbacks that implement the SQL functions and aggregates. +** The 4th parameter to these callbacks is an array of pointers to +** [sqlite3_value] objects. There is one [sqlite3_value] object for +** each parameter to the SQL function. These routines are used to +** extract values from the [sqlite3_value] objects. +** +** These routines work just like the corresponding +** [sqlite3_column_blob | sqlite3_column_* routines] except that +** these routines take a single [sqlite3_value*] pointer instead +** of an [sqlite3_stmt*] pointer and an integer column number. +** +** The sqlite3_value_text16() interface extracts a UTF16 string +** in the native byte-order of the host machine. The +** sqlite3_value_text16be() and sqlite3_value_text16le() interfaces +** extract UTF16 strings as big-endian and little-endian respectively. +** +** The sqlite3_value_numeric_type() interface attempts to apply +** numeric affinity to the value. This means that an attempt is +** made to convert the value to an integer or floating point. If +** such a conversion is possible without loss of information (in order +** words if the value is original a string that looks like a number) +** then it is done. Otherwise no conversion occurs. The +** [SQLITE_INTEGER | datatype] after conversion is returned. +** +** Please pay particular attention to the fact that the pointer that +** is returned from [sqlite3_value_blob()], [sqlite3_value_text()], or +** [sqlite3_value_text16()] can be invalidated by a subsequent call to +** [sqlite3_value_bytes()], [sqlite3_value_bytes16()], [sqlite3_value_text()], +** or [sqlite3_value_text16()]. +** +** These routines must be called from the same thread as +** the SQL function that supplied the sqlite3_value* parameters. +** Or, if the sqlite3_value* argument comes from the [sqlite3_column_value()] +** interface, then these routines should be called from the same thread +** that ran [sqlite3_column_value()]. +*/ +const void *sqlite3_value_blob(sqlite3_value*); +int sqlite3_value_bytes(sqlite3_value*); +int sqlite3_value_bytes16(sqlite3_value*); +double sqlite3_value_double(sqlite3_value*); +int sqlite3_value_int(sqlite3_value*); +sqlite3_int64 sqlite3_value_int64(sqlite3_value*); +const unsigned char *sqlite3_value_text(sqlite3_value*); +const void *sqlite3_value_text16(sqlite3_value*); +const void *sqlite3_value_text16le(sqlite3_value*); +const void *sqlite3_value_text16be(sqlite3_value*); +int sqlite3_value_type(sqlite3_value*); +int sqlite3_value_numeric_type(sqlite3_value*); + +/* +** CAPI3REF: Obtain Aggregate Function Context +** +** The implementation of aggregate SQL functions use this routine to allocate +** a structure for storing their state. The first time this routine +** is called for a particular aggregate, a new structure of size nBytes +** is allocated, zeroed, and returned. On subsequent calls (for the +** same aggregate instance) the same buffer is returned. The implementation +** of the aggregate can use the returned buffer to accumulate data. +** +** The buffer allocated is freed automatically by SQLite whan the aggregate +** query concludes. +** +** The first parameter should be a copy of the +** [sqlite3_context | SQL function context] that is the first +** parameter to the callback routine that implements the aggregate +** function. +** +** This routine must be called from the same thread in which +** the aggregate SQL function is running. +*/ +void *sqlite3_aggregate_context(sqlite3_context*, int nBytes); + +/* +** CAPI3REF: User Data For Functions +** +** The pUserData parameter to the [sqlite3_create_function()] +** and [sqlite3_create_function16()] routines +** used to register user functions is available to +** the implementation of the function using this call. +** +** This routine must be called from the same thread in which +** the SQL function is running. +*/ +void *sqlite3_user_data(sqlite3_context*); + +/* +** CAPI3REF: Function Auxiliary Data +** +** The following two functions may be used by scalar SQL functions to +** associate meta-data with argument values. If the same value is passed to +** multiple invocations of the same SQL function during query execution, under +** some circumstances the associated meta-data may be preserved. This may +** be used, for example, to add a regular-expression matching scalar +** function. The compiled version of the regular expression is stored as +** meta-data associated with the SQL value passed as the regular expression +** pattern. The compiled regular expression can be reused on multiple +** invocations of the same function so that the original pattern string +** does not need to be recompiled on each invocation. +** +** The sqlite3_get_auxdata() interface returns a pointer to the meta-data +** associated with the Nth argument value to the current SQL function +** call, where N is the second parameter. If no meta-data has been set for +** that value, then a NULL pointer is returned. +** +** The sqlite3_set_auxdata() is used to associate meta-data with an SQL +** function argument. The third parameter is a pointer to the meta-data +** to be associated with the Nth user function argument value. The fourth +** parameter specifies a destructor that will be called on the meta- +** data pointer to release it when it is no longer required. If the +** destructor is NULL, it is not invoked. +** +** In practice, meta-data is preserved between function calls for +** expressions that are constant at compile time. This includes literal +** values and SQL variables. +** +** These routines must be called from the same thread in which +** the SQL function is running. +*/ +void *sqlite3_get_auxdata(sqlite3_context*, int); +void sqlite3_set_auxdata(sqlite3_context*, int, void*, void (*)(void*)); + + +/* +** CAPI3REF: Constants Defining Special Destructor Behavior +** +** These are special value for the destructor that is passed in as the +** final argument to routines like [sqlite3_result_blob()]. If the destructor +** argument is SQLITE_STATIC, it means that the content pointer is constant +** and will never change. It does not need to be destroyed. The +** SQLITE_TRANSIENT value means that the content will likely change in +** the near future and that SQLite should make its own private copy of +** the content before returning. +** +** The typedef is necessary to work around problems in certain +** C++ compilers. See ticket #2191. +*/ +typedef void (*sqlite3_destructor_type)(void*); +#define SQLITE_STATIC ((sqlite3_destructor_type)0) +#define SQLITE_TRANSIENT ((sqlite3_destructor_type)-1) + +/* +** CAPI3REF: Setting The Result Of An SQL Function +** +** These routines are used by the xFunc or xFinal callbacks that +** implement SQL functions and aggregates. See +** [sqlite3_create_function()] and [sqlite3_create_function16()] +** for additional information. +** +** These functions work very much like the +** [sqlite3_bind_blob | sqlite3_bind_*] family of functions used +** to bind values to host parameters in prepared statements. +** Refer to the +** [sqlite3_bind_blob | sqlite3_bind_* documentation] for +** additional information. +** +** The sqlite3_result_error() and sqlite3_result_error16() functions +** cause the implemented SQL function to throw an exception. The +** parameter to sqlite3_result_error() or sqlite3_result_error16() +** is the text of an error message. +** +** The sqlite3_result_toobig() cause the function implementation +** to throw and error indicating that a string or BLOB is to long +** to represent. +** +** These routines must be called from within the same thread as +** the SQL function associated with the [sqlite3_context] pointer. +*/ +void sqlite3_result_blob(sqlite3_context*, const void*, int, void(*)(void*)); +void sqlite3_result_double(sqlite3_context*, double); +void sqlite3_result_error(sqlite3_context*, const char*, int); +void sqlite3_result_error16(sqlite3_context*, const void*, int); +void sqlite3_result_error_toobig(sqlite3_context*); +void sqlite3_result_error_nomem(sqlite3_context*); +void sqlite3_result_int(sqlite3_context*, int); +void sqlite3_result_int64(sqlite3_context*, sqlite3_int64); +void sqlite3_result_null(sqlite3_context*); +void sqlite3_result_text(sqlite3_context*, const char*, int, void(*)(void*)); +void sqlite3_result_text16(sqlite3_context*, const void*, int, void(*)(void*)); +void sqlite3_result_text16le(sqlite3_context*, const void*, int,void(*)(void*)); +void sqlite3_result_text16be(sqlite3_context*, const void*, int,void(*)(void*)); +void sqlite3_result_value(sqlite3_context*, sqlite3_value*); +void sqlite3_result_zeroblob(sqlite3_context*, int n); + +/* +** CAPI3REF: Define New Collating Sequences +** +** These functions are used to add new collation sequences to the +** [sqlite3*] handle specified as the first argument. +** +** The name of the new collation sequence is specified as a UTF-8 string +** for sqlite3_create_collation() and sqlite3_create_collation_v2() +** and a UTF-16 string for sqlite3_create_collation16(). In all cases +** the name is passed as the second function argument. +** +** The third argument may be one of the constants [SQLITE_UTF8], +** [SQLITE_UTF16LE] or [SQLITE_UTF16BE], indicating that the user-supplied +** routine expects to be passed pointers to strings encoded using UTF-8, +** UTF-16 little-endian or UTF-16 big-endian respectively. The +** third argument might also be [SQLITE_UTF16_ALIGNED] to indicate that +** the routine expects pointers to 16-bit word aligned strings +** of UTF16 in the native byte order of the host computer. +** +** A pointer to the user supplied routine must be passed as the fifth +** argument. If it is NULL, this is the same as deleting the collation +** sequence (so that SQLite cannot call it anymore). Each time the user +** supplied function is invoked, it is passed a copy of the void* passed as +** the fourth argument to sqlite3_create_collation() or +** sqlite3_create_collation16() as its first parameter. +** +** The remaining arguments to the user-supplied routine are two strings, +** each represented by a [length, data] pair and encoded in the encoding +** that was passed as the third argument when the collation sequence was +** registered. The user routine should return negative, zero or positive if +** the first string is less than, equal to, or greater than the second +** string. i.e. (STRING1 - STRING2). +** +** The sqlite3_create_collation_v2() works like sqlite3_create_collation() +** excapt that it takes an extra argument which is a destructor for +** the collation. The destructor is called when the collation is +** destroyed and is passed a copy of the fourth parameter void* pointer +** of the sqlite3_create_collation_v2(). Collations are destroyed when +** they are overridden by later calls to the collation creation functions +** or when the [sqlite3*] database handle is closed using [sqlite3_close()]. +** +** The sqlite3_create_collation_v2() interface is experimental and +** subject to change in future releases. The other collation creation +** functions are stable. +*/ +int sqlite3_create_collation( + sqlite3*, + const char *zName, + int eTextRep, + void*, + int(*xCompare)(void*,int,const void*,int,const void*) +); +int sqlite3_create_collation_v2( + sqlite3*, + const char *zName, + int eTextRep, + void*, + int(*xCompare)(void*,int,const void*,int,const void*), + void(*xDestroy)(void*) +); +int sqlite3_create_collation16( + sqlite3*, + const char *zName, + int eTextRep, + void*, + int(*xCompare)(void*,int,const void*,int,const void*) +); + +/* +** CAPI3REF: 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 handle to be called whenever an undefined collation sequence is +** required. +** +** If the function is registered using the sqlite3_collation_needed() API, +** then it is passed the names of undefined collation sequences as strings +** encoded in UTF-8. If sqlite3_collation_needed16() is used, the names +** are passed as UTF-16 in machine native byte order. A call to either +** function replaces any existing callback. +** +** When the callback is invoked, the first argument passed is a copy +** of the second argument to sqlite3_collation_needed() or +** sqlite3_collation_needed16(). The second argument is the database +** handle. The third argument is one of [SQLITE_UTF8], [SQLITE_UTF16BE], or +** [SQLITE_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 +** [sqlite3_create_collation()], [sqlite3_create_collation16()], or +** [sqlite3_create_collation_v2()]. +*/ +int sqlite3_collation_needed( + sqlite3*, + void*, + void(*)(void*,sqlite3*,int eTextRep,const char*) +); +int sqlite3_collation_needed16( + sqlite3*, + void*, + void(*)(void*,sqlite3*,int eTextRep,const void*) +); + +/* +** Specify the key for an encrypted database. This routine should be +** called right after sqlite3_open(). +** +** The code to implement this API is not available in the public release +** of SQLite. +*/ +int sqlite3_key( + sqlite3 *db, /* Database to be rekeyed */ + const void *pKey, int nKey /* The key */ +); + +/* +** Change the key on an open database. If the current database is not +** encrypted, this routine will encrypt it. If pNew==0 or nNew==0, the +** database is decrypted. +** +** The code to implement this API is not available in the public release +** of SQLite. +*/ +int sqlite3_rekey( + sqlite3 *db, /* Database to be rekeyed */ + const void *pKey, int nKey /* The new key */ +); + +/* +** CAPI3REF: Suspend Execution For A Short Time +** +** This function causes the current thread to suspend execution +** a number of milliseconds specified in its parameter. +** +** If the operating system does not support sleep requests with +** millisecond time resolution, then the time will be rounded up to +** the nearest second. The number of milliseconds of sleep actually +** requested from the operating system is returned. +** +** SQLite implements this interface by calling the xSleep() +** method of the default [sqlite3_vfs] object. +*/ +int sqlite3_sleep(int); + +/* +** CAPI3REF: Name Of The Folder Holding Temporary Files +** +** If this global variable is made to point to a string which is +** the name of a folder (a.ka. directory), then all temporary files +** created by SQLite will be placed in that directory. If this variable +** is NULL pointer, then SQLite does a search for an appropriate temporary +** file directory. +** +** It is not safe to modify this variable once a database connection +** has been opened. It is intended that this variable be set once +** as part of process initialization and before any SQLite interface +** routines have been call and remain unchanged thereafter. +*/ +SQLITE_EXTERN char *sqlite3_temp_directory; + +/* +** CAPI3REF: Test To See If The Database Is In Auto-Commit Mode +** +** Test to see whether or not the database connection is in autocommit +** mode. Return TRUE if it is and FALSE if not. Autocommit mode is on +** by default. Autocommit is disabled by a BEGIN statement and reenabled +** by the next COMMIT or ROLLBACK. +** +** If certain kinds of errors occur on a statement within a multi-statement +** transactions (errors including [SQLITE_FULL], [SQLITE_IOERR], +** [SQLITE_NOMEM], [SQLITE_BUSY], and [SQLITE_INTERRUPT]) then the +** transaction might be rolled back automatically. The only way to +** find out if SQLite automatically rolled back the transaction after +** an error is to use this function. +** +** If another thread changes the autocommit status of the database +** connection while this routine is running, then the return value +** is undefined. +*/ +int sqlite3_get_autocommit(sqlite3*); + +/* +** CAPI3REF: Find The Database Handle Associated With A Prepared Statement +** +** Return the [sqlite3*] database handle to which a +** [sqlite3_stmt | prepared statement] belongs. +** This is the same database handle that was +** the first argument to the [sqlite3_prepare_v2()] or its variants +** that was used to create the statement in the first place. +*/ +sqlite3 *sqlite3_db_handle(sqlite3_stmt*); + + +/* +** CAPI3REF: Commit And Rollback Notification Callbacks +** +** These routines +** register callback functions to be invoked whenever a transaction +** is committed or rolled back. The pArg argument is passed through +** to the callback. If the callback on a commit hook function +** returns non-zero, then the commit is converted into a rollback. +** +** If another function was previously registered, its pArg value is returned. +** Otherwise NULL is returned. +** +** Registering a NULL function disables the callback. +** +** For the purposes of this API, a transaction is said to have been +** rolled back if an explicit "ROLLBACK" statement is executed, or +** an error or constraint causes an implicit rollback to occur. The +** callback is not invoked if a transaction is automatically rolled +** back because the database connection is closed. +** +** These are experimental interfaces and are subject to change. +*/ +void *sqlite3_commit_hook(sqlite3*, int(*)(void*), void*); +void *sqlite3_rollback_hook(sqlite3*, void(*)(void *), void*); + +/* +** CAPI3REF: Data Change Notification Callbacks +** +** Register a callback function with the database connection identified by the +** first argument to be invoked whenever a row is updated, inserted or deleted. +** Any callback set by a previous call to this function for the same +** database connection is overridden. +** +** The second argument is a pointer to the function to invoke when a +** row is updated, inserted or deleted. The first argument to the callback is +** a copy of the third argument to sqlite3_update_hook(). The second callback +** argument is one of SQLITE_INSERT, SQLITE_DELETE or SQLITE_UPDATE, depending +** on the operation that caused the callback to be invoked. The third and +** fourth arguments to the callback contain pointers to the database and +** table name containing the affected row. The final callback parameter is +** the rowid of the row. In the case of an update, this is the rowid after +** the update takes place. +** +** The update hook is not invoked when internal system tables are +** modified (i.e. sqlite_master and sqlite_sequence). +** +** If another function was previously registered, its pArg value is returned. +** Otherwise NULL is returned. +*/ +void *sqlite3_update_hook( + sqlite3*, + void(*)(void *,int ,char const *,char const *,sqlite3_int64), + void* +); + +/* +** CAPI3REF: Enable Or Disable Shared Pager Cache +** +** This routine enables or disables the sharing of the database cache +** and schema data structures between connections to the same database. +** Sharing is enabled if the argument is true and disabled if the argument +** is false. +** +** Beginning in SQLite version 3.5.0, cache sharing is enabled and disabled +** for an entire process. In prior versions of SQLite, sharing was +** enabled or disabled for each thread separately. +** +** The cache sharing mode set by this interface effects all subsequent +** calls to [sqlite3_open()], [sqlite3_open_v2()], and [sqlite3_open16()]. +** Existing database connections continue use the sharing mode that was +** in effect at the time they were opened. +** +** Virtual tables cannot be used with a shared cache. When shared +** cache is enabled, the [sqlite3_create_module()] API used to register +** virtual tables will always return an error. +** +** This routine returns [SQLITE_OK] if shared cache was +** enabled or disabled successfully. An [SQLITE_ERROR | error code] +** is returned otherwise. +** +** Shared cache is disabled by default. But this might change in +** future releases of SQLite. Applications that care about shared +** cache setting should set it explicitly. +*/ +int sqlite3_enable_shared_cache(int); + +/* +** CAPI3REF: Attempt To Free Heap Memory +** +** Attempt to free N bytes of heap memory by deallocating non-essential +** memory allocations held by the database library (example: memory +** used to cache database pages to improve performance). +*/ +int sqlite3_release_memory(int); + +/* +** CAPI3REF: Impose A Limit On Heap Size +** +** Place a "soft" limit on the amount of heap memory that may be allocated +** by SQLite. If an internal allocation is requested +** that would exceed the specified limit, [sqlite3_release_memory()] is +** invoked one or more times to free up some space before the allocation +** is made. +** +** The limit is called "soft", because if [sqlite3_release_memory()] cannot +** free sufficient memory to prevent the limit from being exceeded, +** the memory is allocated anyway and the current operation proceeds. +** +** A negative or zero value for N means that there is no soft heap limit and +** [sqlite3_release_memory()] will only be called when memory is exhausted. +** The default value for the soft heap limit is zero. +** +** SQLite makes a best effort to honor the soft heap limit. But if it +** is unable to reduce memory usage below the soft limit, execution will +** continue without error or notification. This is why the limit is +** called a "soft" limit. It is advisory only. +** +** Prior to SQLite version 3.5.0, this routine only constrained the memory +** allocated by a single thread - the same thread in which this routine +** runs. Beginning with SQLite version 3.5.0, the soft heap limit is +** applied to all threads. The value specified for the soft heap limit +** is an upper bound on the total memory allocation for all threads. In +** version 3.5.0 there is no mechanism for limiting the heap usage for +** individual threads. +*/ +void sqlite3_soft_heap_limit(int); + +/* +** CAPI3REF: Extract Metadata About A Column Of A Table +** +** This routine +** returns meta-data about a specific column of a specific database +** table accessible using the connection handle passed as the first function +** argument. +** +** The column is identified by the second, third and fourth parameters to +** this function. The second parameter is either the name of the database +** (i.e. "main", "temp" or an attached database) containing the specified +** table or NULL. If it is NULL, then all attached databases are searched +** for the table using the same algorithm as the database engine uses to +** resolve unqualified table references. +** +** The third and fourth parameters to this function are the table and column +** name of the desired column, respectively. Neither of these parameters +** may be NULL. +** +** Meta information is returned by writing to the memory locations passed as +** the 5th and subsequent parameters to this function. Any of these +** arguments may be NULL, in which case the corresponding element of meta +** information is ommitted. +** +** <pre> +** Parameter Output Type Description +** ----------------------------------- +** +** 5th const char* Data type +** 6th const char* Name of the default collation sequence +** 7th int True if the column has a NOT NULL constraint +** 8th int True if the column is part of the PRIMARY KEY +** 9th int True if the column is AUTOINCREMENT +** </pre> +** +** +** The memory pointed to by the character pointers returned for the +** declaration type and collation sequence is valid only until the next +** call to any sqlite API function. +** +** If the specified table is actually a view, then an error is returned. +** +** If the specified column is "rowid", "oid" or "_rowid_" and an +** INTEGER PRIMARY KEY column has been explicitly declared, then the output +** parameters are set for the explicitly declared column. If there is no +** explicitly declared IPK column, then the output parameters are set as +** follows: +** +** <pre> +** data type: "INTEGER" +** collation sequence: "BINARY" +** not null: 0 +** primary key: 1 +** auto increment: 0 +** </pre> +** +** This function may load one or more schemas from database files. If an +** error occurs during this process, or if the requested table or column +** cannot be found, an SQLITE error code is returned and an error message +** left in the database handle (to be retrieved using sqlite3_errmsg()). +** +** This API is only available if the library was compiled with the +** SQLITE_ENABLE_COLUMN_METADATA preprocessor symbol defined. +*/ +int sqlite3_table_column_metadata( + sqlite3 *db, /* Connection handle */ + const char *zDbName, /* Database name or NULL */ + const char *zTableName, /* Table name */ + const char *zColumnName, /* Column name */ + char const **pzDataType, /* OUTPUT: Declared data type */ + char const **pzCollSeq, /* OUTPUT: Collation sequence name */ + int *pNotNull, /* OUTPUT: True if NOT NULL constraint exists */ + int *pPrimaryKey, /* OUTPUT: True if column part of PK */ + int *pAutoinc /* OUTPUT: True if column is auto-increment */ +); + +/* +** CAPI3REF: Load An Extension +** +** Attempt to load an SQLite extension library contained in the file +** zFile. The entry point is zProc. zProc may be 0 in which case the +** name of the entry point defaults to "sqlite3_extension_init". +** +** Return [SQLITE_OK] on success and [SQLITE_ERROR] if something goes wrong. +** +** If an error occurs and pzErrMsg is not 0, then fill *pzErrMsg with +** error message text. The calling function should free this memory +** by calling [sqlite3_free()]. +** +** Extension loading must be enabled using [sqlite3_enable_load_extension()] +** prior to calling this API or an error will be returned. +*/ +int sqlite3_load_extension( + sqlite3 *db, /* Load the extension into this database connection */ + const char *zFile, /* Name of the shared library containing extension */ + const char *zProc, /* Entry point. Derived from zFile if 0 */ + char **pzErrMsg /* Put error message here if not 0 */ +); + +/* +** CAPI3REF: Enable Or Disable Extension Loading +** +** So as not to open security holes in older applications that are +** unprepared to deal with extension loading, and as a means of disabling +** extension loading while evaluating user-entered SQL, the following +** API is provided to turn the [sqlite3_load_extension()] mechanism on and +** off. It is off by default. See ticket #1863. +** +** Call this routine with onoff==1 to turn extension loading on +** and call it with onoff==0 to turn it back off again. +*/ +int sqlite3_enable_load_extension(sqlite3 *db, int onoff); + +/* +** CAPI3REF: Make Arrangements To Automatically Load An Extension +** +** Register an extension entry point that is automatically invoked +** whenever a new database connection is opened using +** [sqlite3_open()], [sqlite3_open16()], or [sqlite3_open_v2()]. +** +** This API can be invoked at program startup in order to register +** one or more statically linked extensions that will be available +** to all new database connections. +** +** Duplicate extensions are detected so calling this routine multiple +** times with the same extension is harmless. +** +** This routine stores a pointer to the extension in an array +** that is obtained from malloc(). If you run a memory leak +** checker on your program and it reports a leak because of this +** array, then invoke [sqlite3_reset_auto_extension()] prior +** to shutdown to free the memory. +** +** Automatic extensions apply across all threads. +** +** This interface is experimental and is subject to change or +** removal in future releases of SQLite. +*/ +int sqlite3_auto_extension(void *xEntryPoint); + + +/* +** CAPI3REF: Reset Automatic Extension Loading +** +** Disable all previously registered automatic extensions. This +** routine undoes the effect of all prior [sqlite3_automatic_extension()] +** calls. +** +** This call disabled automatic extensions in all threads. +** +** This interface is experimental and is subject to change or +** removal in future releases of SQLite. +*/ +void sqlite3_reset_auto_extension(void); + + +/* +****** EXPERIMENTAL - subject to change without notice ************** +** +** The interface to the virtual-table mechanism is currently considered +** to be experimental. The interface might change in incompatible ways. +** If this is a problem for you, do not use the interface at this time. +** +** When the virtual-table mechanism stablizes, we will declare the +** interface fixed, support it indefinitely, and remove this comment. +*/ + +/* +** Structures used by the virtual table interface +*/ +typedef struct sqlite3_vtab sqlite3_vtab; +typedef struct sqlite3_index_info sqlite3_index_info; +typedef struct sqlite3_vtab_cursor sqlite3_vtab_cursor; +typedef struct sqlite3_module sqlite3_module; + +/* +** A module is a class of virtual tables. Each module is defined +** by an instance of the following structure. This structure consists +** mostly of methods for the module. +*/ +struct sqlite3_module { + int iVersion; + int (*xCreate)(sqlite3*, void *pAux, + int argc, const char *const*argv, + sqlite3_vtab **ppVTab, char**); + int (*xConnect)(sqlite3*, void *pAux, + int argc, const char *const*argv, + sqlite3_vtab **ppVTab, char**); + int (*xBestIndex)(sqlite3_vtab *pVTab, sqlite3_index_info*); + int (*xDisconnect)(sqlite3_vtab *pVTab); + int (*xDestroy)(sqlite3_vtab *pVTab); + int (*xOpen)(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor); + int (*xClose)(sqlite3_vtab_cursor*); + int (*xFilter)(sqlite3_vtab_cursor*, int idxNum, const char *idxStr, + int argc, sqlite3_value **argv); + int (*xNext)(sqlite3_vtab_cursor*); + int (*xEof)(sqlite3_vtab_cursor*); + int (*xColumn)(sqlite3_vtab_cursor*, sqlite3_context*, int); + int (*xRowid)(sqlite3_vtab_cursor*, sqlite3_int64 *pRowid); + int (*xUpdate)(sqlite3_vtab *, int, sqlite3_value **, sqlite3_int64 *); + int (*xBegin)(sqlite3_vtab *pVTab); + int (*xSync)(sqlite3_vtab *pVTab); + int (*xCommit)(sqlite3_vtab *pVTab); + int (*xRollback)(sqlite3_vtab *pVTab); + int (*xFindFunction)(sqlite3_vtab *pVtab, int nArg, const char *zName, + void (**pxFunc)(sqlite3_context*,int,sqlite3_value**), + void **ppArg); + + int (*xRename)(sqlite3_vtab *pVtab, const char *zNew); +}; + +/* +** The sqlite3_index_info structure and its substructures is used to +** pass information into and receive the reply from the xBestIndex +** method of an sqlite3_module. The fields under **Inputs** are the +** inputs to xBestIndex and are read-only. xBestIndex inserts its +** results into the **Outputs** fields. +** +** The aConstraint[] array records WHERE clause constraints of the +** form: +** +** column OP expr +** +** Where OP is =, <, <=, >, or >=. The particular operator is stored +** in aConstraint[].op. The index of the column is stored in +** aConstraint[].iColumn. aConstraint[].usable is TRUE if the +** expr on the right-hand side can be evaluated (and thus the constraint +** is usable) and false if it cannot. +** +** The optimizer automatically inverts terms of the form "expr OP column" +** and makes other simplifications to the WHERE clause in an attempt to +** get as many WHERE clause terms into the form shown above as possible. +** The aConstraint[] array only reports WHERE clause terms in the correct +** form that refer to the particular virtual table being queried. +** +** Information about the ORDER BY clause is stored in aOrderBy[]. +** Each term of aOrderBy records a column of the ORDER BY clause. +** +** The xBestIndex method must fill aConstraintUsage[] with information +** about what parameters to pass to xFilter. If argvIndex>0 then +** the right-hand side of the corresponding aConstraint[] is evaluated +** and becomes the argvIndex-th entry in argv. If aConstraintUsage[].omit +** is true, then the constraint is assumed to be fully handled by the +** virtual table and is not checked again by SQLite. +** +** The idxNum and idxPtr values are recorded and passed into xFilter. +** sqlite3_free() is used to free idxPtr if needToFreeIdxPtr is true. +** +** The orderByConsumed means that output from xFilter will occur in +** the correct order to satisfy the ORDER BY clause so that no separate +** sorting step is required. +** +** The estimatedCost value is an estimate of the cost of doing the +** particular lookup. A full scan of a table with N entries should have +** a cost of N. A binary search of a table of N entries should have a +** cost of approximately log(N). +*/ +struct sqlite3_index_info { + /* Inputs */ + int nConstraint; /* Number of entries in aConstraint */ + struct sqlite3_index_constraint { + int iColumn; /* Column on left-hand side of constraint */ + unsigned char op; /* Constraint operator */ + unsigned char usable; /* True if this constraint is usable */ + int iTermOffset; /* Used internally - xBestIndex should ignore */ + } *aConstraint; /* Table of WHERE clause constraints */ + int nOrderBy; /* Number of terms in the ORDER BY clause */ + struct sqlite3_index_orderby { + int iColumn; /* Column number */ + unsigned char desc; /* True for DESC. False for ASC. */ + } *aOrderBy; /* The ORDER BY clause */ + + /* Outputs */ + struct sqlite3_index_constraint_usage { + int argvIndex; /* if >0, constraint is part of argv to xFilter */ + unsigned char omit; /* Do not code a test for this constraint */ + } *aConstraintUsage; + int idxNum; /* Number used to identify the index */ + char *idxStr; /* String, possibly obtained from sqlite3_malloc */ + int needToFreeIdxStr; /* Free idxStr using sqlite3_free() if true */ + int orderByConsumed; /* True if output is already ordered */ + double estimatedCost; /* Estimated cost of using this index */ +}; +#define SQLITE_INDEX_CONSTRAINT_EQ 2 +#define SQLITE_INDEX_CONSTRAINT_GT 4 +#define SQLITE_INDEX_CONSTRAINT_LE 8 +#define SQLITE_INDEX_CONSTRAINT_LT 16 +#define SQLITE_INDEX_CONSTRAINT_GE 32 +#define SQLITE_INDEX_CONSTRAINT_MATCH 64 + +/* +** This routine is used to register a new module name with an SQLite +** connection. Module names must be registered before creating new +** virtual tables on the module, or before using preexisting virtual +** tables of the module. +*/ +int sqlite3_create_module( + sqlite3 *db, /* SQLite connection to register module with */ + const char *zName, /* Name of the module */ + const sqlite3_module *, /* Methods for the module */ + void * /* Client data for xCreate/xConnect */ +); + +/* +** This routine is identical to the sqlite3_create_module() method above, +** except that it allows a destructor function to be specified. It is +** even more experimental than the rest of the virtual tables API. +*/ +int sqlite3_create_module_v2( + sqlite3 *db, /* SQLite connection to register module with */ + const char *zName, /* Name of the module */ + const sqlite3_module *, /* Methods for the module */ + void *, /* Client data for xCreate/xConnect */ + void(*xDestroy)(void*) /* Module destructor function */ +); + +/* +** Every module implementation uses a subclass of the following structure +** to describe a particular instance of the module. Each subclass will +** be tailored to the specific needs of the module implementation. The +** purpose of this superclass is to define certain fields that are common +** to all module implementations. +** +** Virtual tables methods can set an error message by assigning a +** string obtained from sqlite3_mprintf() to zErrMsg. The method should +** take care that any prior string is freed by a call to sqlite3_free() +** prior to assigning a new string to zErrMsg. After the error message +** is delivered up to the client application, the string will be automatically +** freed by sqlite3_free() and the zErrMsg field will be zeroed. Note +** that sqlite3_mprintf() and sqlite3_free() are used on the zErrMsg field +** since virtual tables are commonly implemented in loadable extensions which +** do not have access to sqlite3MPrintf() or sqlite3Free(). +*/ +struct sqlite3_vtab { + const sqlite3_module *pModule; /* The module for this virtual table */ + int nRef; /* Used internally */ + char *zErrMsg; /* Error message from sqlite3_mprintf() */ + /* Virtual table implementations will typically add additional fields */ +}; + +/* Every module implementation uses a subclass of the following structure +** to describe cursors that point into the virtual table and are used +** to loop through the virtual table. Cursors are created using the +** xOpen method of the module. Each module implementation will define +** the content of a cursor structure to suit its own needs. +** +** This superclass exists in order to define fields of the cursor that +** are common to all implementations. +*/ +struct sqlite3_vtab_cursor { + sqlite3_vtab *pVtab; /* Virtual table of this cursor */ + /* Virtual table implementations will typically add additional fields */ +}; + +/* +** The xCreate and xConnect methods of a module use the following API +** to declare the format (the names and datatypes of the columns) of +** the virtual tables they implement. +*/ +int sqlite3_declare_vtab(sqlite3*, const char *zCreateTable); + +/* +** Virtual tables can provide alternative implementations of functions +** using the xFindFunction method. But global versions of those functions +** must exist in order to be overloaded. +** +** This API makes sure a global version of a function with a particular +** name and number of parameters exists. If no such function exists +** before this API is called, a new function is created. The implementation +** of the new function always causes an exception to be thrown. So +** the new function is not good for anything by itself. Its only +** purpose is to be a place-holder function that can be overloaded +** by virtual tables. +** +** This API should be considered part of the virtual table interface, +** which is experimental and subject to change. +*/ +int sqlite3_overload_function(sqlite3*, const char *zFuncName, int nArg); + +/* +** The interface to the virtual-table mechanism defined above (back up +** to a comment remarkably similar to this one) is currently considered +** to be experimental. The interface might change in incompatible ways. +** If this is a problem for you, do not use the interface at this time. +** +** When the virtual-table mechanism stabilizes, we will declare the +** interface fixed, support it indefinitely, and remove this comment. +** +****** EXPERIMENTAL - subject to change without notice ************** +*/ + +/* +** CAPI3REF: A Handle To An Open BLOB +** +** An instance of the following opaque structure is used to +** represent an blob-handle. A blob-handle is created by +** [sqlite3_blob_open()] and destroyed by [sqlite3_blob_close()]. +** The [sqlite3_blob_read()] and [sqlite3_blob_write()] interfaces +** can be used to read or write small subsections of the blob. +** The [sqlite3_blob_bytes()] interface returns the size of the +** blob in bytes. +*/ +typedef struct sqlite3_blob sqlite3_blob; + +/* +** CAPI3REF: Open A BLOB For Incremental I/O +** +** Open a handle to the blob located in row iRow,, column zColumn, +** table zTable in database zDb. i.e. the same blob that would +** be selected by: +** +** <pre> +** SELECT zColumn FROM zDb.zTable WHERE rowid = iRow; +** </pre> +** +** If the flags parameter is non-zero, the blob is opened for +** read and write access. If it is zero, the blob is opened for read +** access. +** +** On success, [SQLITE_OK] is returned and the new +** [sqlite3_blob | blob handle] is written to *ppBlob. +** Otherwise an error code is returned and +** any value written to *ppBlob should not be used by the caller. +** This function sets the database-handle error code and message +** accessible via [sqlite3_errcode()] and [sqlite3_errmsg()]. +*/ +int sqlite3_blob_open( + sqlite3*, + const char *zDb, + const char *zTable, + const char *zColumn, + sqlite3_int64 iRow, + int flags, + sqlite3_blob **ppBlob +); + +/* +** CAPI3REF: Close A BLOB Handle +** +** Close an open [sqlite3_blob | blob handle]. +*/ +int sqlite3_blob_close(sqlite3_blob *); + +/* +** CAPI3REF: Return The Size Of An Open BLOB +** +** Return the size in bytes of the blob accessible via the open +** [sqlite3_blob | blob-handle] passed as an argument. +*/ +int sqlite3_blob_bytes(sqlite3_blob *); + +/* +** CAPI3REF: Read Data From A BLOB Incrementally +** +** This function is used to read data from an open +** [sqlite3_blob | blob-handle] into a caller supplied buffer. +** n bytes of data are copied into buffer +** z from the open blob, starting at offset iOffset. +** +** On success, SQLITE_OK is returned. Otherwise, an +** [SQLITE_ERROR | SQLite error code] or an +** [SQLITE_IOERR_READ | extended error code] is returned. +*/ +int sqlite3_blob_read(sqlite3_blob *, void *z, int n, int iOffset); + +/* +** CAPI3REF: Write Data Into A BLOB Incrementally +** +** This function is used to write data into an open +** [sqlite3_blob | blob-handle] from a user supplied buffer. +** n bytes of data are copied from the buffer +** pointed to by z into the open blob, starting at offset iOffset. +** +** If the [sqlite3_blob | blob-handle] passed as the first argument +** was not opened for writing (the flags parameter to [sqlite3_blob_open()] +*** was zero), this function returns [SQLITE_READONLY]. +** +** This function may only modify the contents of the blob, it is +** not possible to increase the size of a blob using this API. If +** offset iOffset is less than n bytes from the end of the blob, +** [SQLITE_ERROR] is returned and no data is written. +** +** On success, SQLITE_OK is returned. Otherwise, an +** [SQLITE_ERROR | SQLite error code] or an +** [SQLITE_IOERR_READ | extended error code] is returned. +*/ +int sqlite3_blob_write(sqlite3_blob *, const void *z, int n, int iOffset); + +/* +** CAPI3REF: Virtual File System Objects +** +** A virtual filesystem (VFS) is an [sqlite3_vfs] object +** that SQLite uses to interact +** with the underlying operating system. Most builds come with a +** single default VFS that is appropriate for the host computer. +** New VFSes can be registered and existing VFSes can be unregistered. +** The following interfaces are provided. +** +** The sqlite3_vfs_find() interface returns a pointer to a VFS given its +** name. Names are case sensitive. If there is no match, a NULL +** pointer is returned. If zVfsName is NULL then the default +** VFS is returned. +** +** New VFSes are registered with sqlite3_vfs_register(). Each +** new VFS becomes the default VFS if the makeDflt flag is set. +** The same VFS can be registered multiple times without injury. +** To make an existing VFS into the default VFS, register it again +** with the makeDflt flag set. If two different VFSes with the +** same name are registered, the behavior is undefined. If a +** VFS is registered with a name that is NULL or an empty string, +** then the behavior is undefined. +** +** Unregister a VFS with the sqlite3_vfs_unregister() interface. +** If the default VFS is unregistered, another VFS is chosen as +** the default. The choice for the new VFS is arbitrary. +*/ +sqlite3_vfs *sqlite3_vfs_find(const char *zVfsName); +int sqlite3_vfs_register(sqlite3_vfs*, int makeDflt); +int sqlite3_vfs_unregister(sqlite3_vfs*); + +/* +** CAPI3REF: Mutexes +** +** The SQLite core uses these routines for thread +** synchronization. Though they are intended for internal +** use by SQLite, code that links against SQLite is +** permitted to use any of these routines. +** +** The SQLite source code contains multiple implementations +** of these mutex routines. An appropriate implementation +** is selected automatically at compile-time. The following +** implementations are available in the SQLite core: +** +** <ul> +** <li> SQLITE_MUTEX_OS2 +** <li> SQLITE_MUTEX_PTHREAD +** <li> SQLITE_MUTEX_W32 +** <li> SQLITE_MUTEX_NOOP +** </ul> +** +** The SQLITE_MUTEX_NOOP implementation is a set of routines +** that does no real locking and is appropriate for use in +** a single-threaded application. The SQLITE_MUTEX_OS2, +** SQLITE_MUTEX_PTHREAD, and SQLITE_MUTEX_W32 implementations +** are appropriate for use on os/2, unix, and windows. +** +** If SQLite is compiled with the SQLITE_MUTEX_APPDEF preprocessor +** macro defined (with "-DSQLITE_MUTEX_APPDEF=1"), then no mutex +** implementation is included with the library. The +** mutex interface routines defined here become external +** references in the SQLite library for which implementations +** must be provided by the application. This facility allows an +** application that links against SQLite to provide its own mutex +** implementation without having to modify the SQLite core. +** +** The sqlite3_mutex_alloc() routine allocates a new +** mutex and returns a pointer to it. If it returns NULL +** that means that a mutex could not be allocated. SQLite +** will unwind its stack and return an error. The argument +** to sqlite3_mutex_alloc() is one of these integer constants: +** +** <ul> +** <li> SQLITE_MUTEX_FAST +** <li> SQLITE_MUTEX_RECURSIVE +** <li> SQLITE_MUTEX_STATIC_MASTER +** <li> SQLITE_MUTEX_STATIC_MEM +** <li> SQLITE_MUTEX_STATIC_MEM2 +** <li> SQLITE_MUTEX_STATIC_PRNG +** <li> SQLITE_MUTEX_STATIC_LRU +** </ul> +** +** The first two constants cause sqlite3_mutex_alloc() to create +** a new mutex. The new mutex is recursive when SQLITE_MUTEX_RECURSIVE +** is used but not necessarily so when SQLITE_MUTEX_FAST is used. +** The mutex implementation does not need to make a distinction +** between SQLITE_MUTEX_RECURSIVE and SQLITE_MUTEX_FAST if it does +** not want to. But SQLite will only request a recursive mutex in +** cases where it really needs one. If a faster non-recursive mutex +** implementation is available on the host platform, the mutex subsystem +** might return such a mutex in response to SQLITE_MUTEX_FAST. +** +** The other allowed parameters to sqlite3_mutex_alloc() each return +** a pointer to a static preexisting mutex. Four static mutexes are +** used by the current version of SQLite. Future versions of SQLite +** may add additional static mutexes. Static mutexes are for internal +** use by SQLite only. Applications that use SQLite mutexes should +** use only the dynamic mutexes returned by SQLITE_MUTEX_FAST or +** SQLITE_MUTEX_RECURSIVE. +** +** Note that if one of the dynamic mutex parameters (SQLITE_MUTEX_FAST +** or SQLITE_MUTEX_RECURSIVE) is used then sqlite3_mutex_alloc() +** returns a different mutex on every call. But for the static +** mutex types, the same mutex is returned on every call that has +** the same type number. +** +** The sqlite3_mutex_free() routine deallocates a previously +** allocated dynamic mutex. SQLite is careful to deallocate every +** dynamic mutex that it allocates. The dynamic mutexes must not be in +** use when they are deallocated. Attempting to deallocate a static +** mutex results in undefined behavior. SQLite never deallocates +** a static mutex. +** +** The sqlite3_mutex_enter() and sqlite3_mutex_try() routines attempt +** to enter a mutex. If another thread is already within the mutex, +** sqlite3_mutex_enter() will block and sqlite3_mutex_try() will return +** SQLITE_BUSY. The sqlite3_mutex_try() interface returns SQLITE_OK +** upon successful entry. Mutexes created using SQLITE_MUTEX_RECURSIVE can +** be entered multiple times by the same thread. In such cases the, +** mutex must be exited an equal number of times before another thread +** can enter. If the same thread tries to enter any other kind of mutex +** more than once, the behavior is undefined. SQLite will never exhibit +** such behavior in its own use of mutexes. +** +** Some systems (ex: windows95) do not the operation implemented by +** sqlite3_mutex_try(). On those systems, sqlite3_mutex_try() will +** always return SQLITE_BUSY. The SQLite core only ever uses +** sqlite3_mutex_try() as an optimization so this is acceptable behavior. +** +** The sqlite3_mutex_leave() routine exits a mutex that was +** previously entered by the same thread. The behavior +** is undefined if the mutex is not currently entered by the +** calling thread or is not currently allocated. SQLite will +** never do either. +** +** See also: [sqlite3_mutex_held()] and [sqlite3_mutex_notheld()]. +*/ +sqlite3_mutex *sqlite3_mutex_alloc(int); +void sqlite3_mutex_free(sqlite3_mutex*); +void sqlite3_mutex_enter(sqlite3_mutex*); +int sqlite3_mutex_try(sqlite3_mutex*); +void sqlite3_mutex_leave(sqlite3_mutex*); + +/* +** CAPI3REF: Mutex Verifcation Routines +** +** The sqlite3_mutex_held() and sqlite3_mutex_notheld() routines +** are intended for use inside assert() statements. The SQLite core +** never uses these routines except inside an assert() and applications +** are advised to follow the lead of the core. The core only +** provides implementations for these routines when it is compiled +** with the SQLITE_DEBUG flag. External mutex implementations +** are only required to provide these routines if SQLITE_DEBUG is +** defined and if NDEBUG is not defined. +** +** These routines should return true if the mutex in their argument +** is held or not held, respectively, by the calling thread. +** +** The implementation is not required to provided versions of these +** routines that actually work. +** If the implementation does not provide working +** versions of these routines, it should at least provide stubs +** that always return true so that one does not get spurious +** assertion failures. +** +** If the argument to sqlite3_mutex_held() is a NULL pointer then +** the routine should return 1. This seems counter-intuitive since +** clearly the mutex cannot be held if it does not exist. But the +** the reason the mutex does not exist is because the build is not +** using mutexes. And we do not want the assert() containing the +** call to sqlite3_mutex_held() to fail, so a non-zero return is +** the appropriate thing to do. The sqlite3_mutex_notheld() +** interface should also return 1 when given a NULL pointer. +*/ +int sqlite3_mutex_held(sqlite3_mutex*); +int sqlite3_mutex_notheld(sqlite3_mutex*); + +/* +** CAPI3REF: Mutex Types +** +** The [sqlite3_mutex_alloc()] interface takes a single argument +** which is one of these integer constants. +*/ +#define SQLITE_MUTEX_FAST 0 +#define SQLITE_MUTEX_RECURSIVE 1 +#define SQLITE_MUTEX_STATIC_MASTER 2 +#define SQLITE_MUTEX_STATIC_MEM 3 /* sqlite3_malloc() */ +#define SQLITE_MUTEX_STATIC_MEM2 4 /* sqlite3_release_memory() */ +#define SQLITE_MUTEX_STATIC_PRNG 5 /* sqlite3_random() */ +#define SQLITE_MUTEX_STATIC_LRU 6 /* lru page list */ + +/* +** CAPI3REF: Low-Level Control Of Database Files +** +** The [sqlite3_file_control()] interface makes a direct call to the +** xFileControl method for the [sqlite3_io_methods] object associated +** with a particular database identified by the second argument. The +** name of the database is the name assigned to the database by the +** <a href="lang_attach.html">ATTACH</a> SQL command that opened the +** database. To control the main database file, use the name "main" +** or a NULL pointer. The third and fourth parameters to this routine +** are passed directly through to the second and third parameters of +** the xFileControl method. The return value of the xFileControl +** method becomes the return value of this routine. +** +** If the second parameter (zDbName) does not match the name of any +** open database file, then SQLITE_ERROR is returned. This error +** code is not remembered and will not be recalled by [sqlite3_errcode()] +** or [sqlite3_errmsg()]. The underlying xFileControl method might +** also return SQLITE_ERROR. There is no way to distinguish between +** an incorrect zDbName and an SQLITE_ERROR return from the underlying +** xFileControl method. +** +** See also: [SQLITE_FCNTL_LOCKSTATE] +*/ +int sqlite3_file_control(sqlite3*, const char *zDbName, int op, void*); + +/* +** Undo the hack that converts floating point types to integer for +** builds on processors without floating point support. +*/ +#ifdef SQLITE_OMIT_FLOATING_POINT +# undef double +#endif + +#if 0 +} /* End of the 'extern "C"' block */ +#endif +#endif + +/************** End of sqlite3.h *********************************************/ +/************** Continuing where we left off in fts3_tokenizer.h *************/ + +/* +** Structures used by the tokenizer interface. When a new tokenizer +** implementation is registered, the caller provides a pointer to +** an sqlite3_tokenizer_module containing pointers to the callback +** functions that make up an implementation. +** +** When an fts3 table is created, it passes any arguments passed to +** the tokenizer clause of the CREATE VIRTUAL TABLE statement to the +** sqlite3_tokenizer_module.xCreate() function of the requested tokenizer +** implementation. The xCreate() function in turn returns an +** sqlite3_tokenizer structure representing the specific tokenizer to +** be used for the fts3 table (customized by the tokenizer clause arguments). +** +** To tokenize an input buffer, the sqlite3_tokenizer_module.xOpen() +** method is called. It returns an sqlite3_tokenizer_cursor object +** that may be used to tokenize a specific input buffer based on +** the tokenization rules supplied by a specific sqlite3_tokenizer +** object. +*/ +typedef struct sqlite3_tokenizer_module sqlite3_tokenizer_module; +typedef struct sqlite3_tokenizer sqlite3_tokenizer; +typedef struct sqlite3_tokenizer_cursor sqlite3_tokenizer_cursor; + +struct sqlite3_tokenizer_module { + + /* + ** Structure version. Should always be set to 0. + */ + int iVersion; + + /* + ** Create a new tokenizer. The values in the argv[] array are the + ** arguments passed to the "tokenizer" clause of the CREATE VIRTUAL + ** TABLE statement that created the fts3 table. For example, if + ** the following SQL is executed: + ** + ** CREATE .. USING fts3( ... , tokenizer <tokenizer-name> arg1 arg2) + ** + ** then argc is set to 2, and the argv[] array contains pointers + ** to the strings "arg1" and "arg2". + ** + ** This method should return either SQLITE_OK (0), or an SQLite error + ** code. If SQLITE_OK is returned, then *ppTokenizer should be set + ** to point at the newly created tokenizer structure. The generic + ** sqlite3_tokenizer.pModule variable should not be initialised by + ** this callback. The caller will do so. + */ + int (*xCreate)( + int argc, /* Size of argv array */ + const char *const*argv, /* Tokenizer argument strings */ + sqlite3_tokenizer **ppTokenizer /* OUT: Created tokenizer */ + ); + + /* + ** Destroy an existing tokenizer. The fts3 module calls this method + ** exactly once for each successful call to xCreate(). + */ + int (*xDestroy)(sqlite3_tokenizer *pTokenizer); + + /* + ** Create a tokenizer cursor to tokenize an input buffer. The caller + ** is responsible for ensuring that the input buffer remains valid + ** until the cursor is closed (using the xClose() method). + */ + int (*xOpen)( + sqlite3_tokenizer *pTokenizer, /* Tokenizer object */ + const char *pInput, int nBytes, /* Input buffer */ + sqlite3_tokenizer_cursor **ppCursor /* OUT: Created tokenizer cursor */ + ); + + /* + ** Destroy an existing tokenizer cursor. The fts3 module calls this + ** method exactly once for each successful call to xOpen(). + */ + int (*xClose)(sqlite3_tokenizer_cursor *pCursor); + + /* + ** Retrieve the next token from the tokenizer cursor pCursor. This + ** method should either return SQLITE_OK and set the values of the + ** "OUT" variables identified below, or SQLITE_DONE to indicate that + ** the end of the buffer has been reached, or an SQLite error code. + ** + ** *ppToken should be set to point at a buffer containing the + ** normalized version of the token (i.e. after any case-folding and/or + ** stemming has been performed). *pnBytes should be set to the length + ** of this buffer in bytes. The input text that generated the token is + ** identified by the byte offsets returned in *piStartOffset and + ** *piEndOffset. + ** + ** The buffer *ppToken is set to point at is managed by the tokenizer + ** implementation. It is only required to be valid until the next call + ** to xNext() or xClose(). + */ + /* TODO(shess) current implementation requires pInput to be + ** nul-terminated. This should either be fixed, or pInput/nBytes + ** should be converted to zInput. + */ + int (*xNext)( + sqlite3_tokenizer_cursor *pCursor, /* Tokenizer cursor */ + const char **ppToken, int *pnBytes, /* OUT: Normalized text for token */ + int *piStartOffset, /* OUT: Byte offset of token in input buffer */ + int *piEndOffset, /* OUT: Byte offset of end of token in input buffer */ + int *piPosition /* OUT: Number of tokens returned before this one */ + ); +}; + +struct sqlite3_tokenizer { + const sqlite3_tokenizer_module *pModule; /* The module for this tokenizer */ + /* Tokenizer implementations will typically add additional fields */ +}; + +struct sqlite3_tokenizer_cursor { + sqlite3_tokenizer *pTokenizer; /* Tokenizer for this cursor. */ + /* Tokenizer implementations will typically add additional fields */ +}; + +#endif /* _FTS3_TOKENIZER_H_ */ + +/************** End of fts3_tokenizer.h **************************************/ +/************** Continuing where we left off in fts3.c ***********************/ +#ifndef SQLITE_CORE + #include "sqlite3ext.h" + SQLITE_EXTENSION_INIT1 +#endif + + +/* TODO(shess) MAN, this thing needs some refactoring. At minimum, it +** would be nice to order the file better, perhaps something along the +** lines of: +** +** - utility functions +** - table setup functions +** - table update functions +** - table query functions +** +** Put the query functions last because they're likely to reference +** typedefs or functions from the table update section. +*/ + +#if 0 +# define FTSTRACE(A) printf A; fflush(stdout) +#else +# define FTSTRACE(A) +#endif + +/* +** Default span for NEAR operators. +*/ +#define SQLITE_FTS3_DEFAULT_NEAR_PARAM 10 + +/* It is not safe to call isspace(), tolower(), or isalnum() on +** hi-bit-set characters. This is the same solution used in the +** tokenizer. +*/ +/* TODO(shess) The snippet-generation code should be using the +** tokenizer-generated tokens rather than doing its own local +** tokenization. +*/ +/* TODO(shess) Is __isascii() a portable version of (c&0x80)==0? */ +static int safe_isspace(char c){ + return (c&0x80)==0 ? isspace(c) : 0; +} +static int safe_tolower(char c){ + return (c&0x80)==0 ? tolower(c) : c; +} +static int safe_isalnum(char c){ + return (c&0x80)==0 ? isalnum(c) : 0; +} + +typedef enum DocListType { + DL_DOCIDS, /* docids only */ + DL_POSITIONS, /* docids + positions */ + DL_POSITIONS_OFFSETS /* docids + positions + offsets */ +} DocListType; + +/* +** By default, only positions and not offsets are stored in the doclists. +** To change this so that offsets are stored too, compile with +** +** -DDL_DEFAULT=DL_POSITIONS_OFFSETS +** +** If DL_DEFAULT is set to DL_DOCIDS, your table can only be inserted +** into (no deletes or updates). +*/ +#ifndef DL_DEFAULT +# define DL_DEFAULT DL_POSITIONS +#endif + +enum { + POS_END = 0, /* end of this position list */ + POS_COLUMN, /* followed by new column number */ + POS_BASE +}; + +/* MERGE_COUNT controls how often we merge segments (see comment at +** top of file). +*/ +#define MERGE_COUNT 16 + +/* utility functions */ + +/* CLEAR() and SCRAMBLE() abstract memset() on a pointer to a single +** record to prevent errors of the form: +** +** my_function(SomeType *b){ +** memset(b, '\0', sizeof(b)); // sizeof(b)!=sizeof(*b) +** } +*/ +/* TODO(shess) Obvious candidates for a header file. */ +#define CLEAR(b) memset(b, '\0', sizeof(*(b))) + +#ifndef NDEBUG +# define SCRAMBLE(b) memset(b, 0x55, sizeof(*(b))) +#else +# define SCRAMBLE(b) +#endif + +/* We may need up to VARINT_MAX bytes to store an encoded 64-bit integer. */ +#define VARINT_MAX 10 + +/* Write a 64-bit variable-length integer to memory starting at p[0]. + * The length of data written will be between 1 and VARINT_MAX bytes. + * The number of bytes written is returned. */ +static int fts3PutVarint(char *p, sqlite_int64 v){ + unsigned char *q = (unsigned char *) p; + sqlite_uint64 vu = v; + do{ + *q++ = (unsigned char) ((vu & 0x7f) | 0x80); + vu >>= 7; + }while( vu!=0 ); + q[-1] &= 0x7f; /* turn off high bit in final byte */ + assert( q - (unsigned char *)p <= VARINT_MAX ); + return (int) (q - (unsigned char *)p); +} + +/* Read a 64-bit variable-length integer from memory starting at p[0]. + * Return the number of bytes read, or 0 on error. + * The value is stored in *v. */ +static int fts3GetVarint(const char *p, sqlite_int64 *v){ + const unsigned char *q = (const unsigned char *) p; + sqlite_uint64 x = 0, y = 1; + while( (*q & 0x80) == 0x80 ){ + x += y * (*q++ & 0x7f); + y <<= 7; + if( q - (unsigned char *)p >= VARINT_MAX ){ /* bad data */ + assert( 0 ); + return 0; + } + } + x += y * (*q++); + *v = (sqlite_int64) x; + return (int) (q - (unsigned char *)p); +} + +static int fts3GetVarint32(const char *p, int *pi){ + sqlite_int64 i; + int ret = fts3GetVarint(p, &i); + *pi = (int) i; + assert( *pi==i ); + return ret; +} + +/*******************************************************************/ +/* DataBuffer is used to collect data into a buffer in piecemeal +** fashion. It implements the usual distinction between amount of +** data currently stored (nData) and buffer capacity (nCapacity). +** +** dataBufferInit - create a buffer with given initial capacity. +** dataBufferReset - forget buffer's data, retaining capacity. +** dataBufferDestroy - free buffer's data. +** dataBufferExpand - expand capacity without adding data. +** dataBufferAppend - append data. +** dataBufferAppend2 - append two pieces of data at once. +** dataBufferReplace - replace buffer's data. +*/ +typedef struct DataBuffer { + char *pData; /* Pointer to malloc'ed buffer. */ + int nCapacity; /* Size of pData buffer. */ + int nData; /* End of data loaded into pData. */ +} DataBuffer; + +static void dataBufferInit(DataBuffer *pBuffer, int nCapacity){ + assert( nCapacity>=0 ); + pBuffer->nData = 0; + pBuffer->nCapacity = nCapacity; + pBuffer->pData = nCapacity==0 ? NULL : sqlite3_malloc(nCapacity); +} +static void dataBufferReset(DataBuffer *pBuffer){ + pBuffer->nData = 0; +} +static void dataBufferDestroy(DataBuffer *pBuffer){ + if( pBuffer->pData!=NULL ) sqlite3_free(pBuffer->pData); + SCRAMBLE(pBuffer); +} +static void dataBufferExpand(DataBuffer *pBuffer, int nAddCapacity){ + assert( nAddCapacity>0 ); + /* TODO(shess) Consider expanding more aggressively. Note that the + ** underlying malloc implementation may take care of such things for + ** us already. + */ + if( pBuffer->nData+nAddCapacity>pBuffer->nCapacity ){ + pBuffer->nCapacity = pBuffer->nData+nAddCapacity; + pBuffer->pData = sqlite3_realloc(pBuffer->pData, pBuffer->nCapacity); + } +} +static void dataBufferAppend(DataBuffer *pBuffer, + const char *pSource, int nSource){ + assert( nSource>0 && pSource!=NULL ); + dataBufferExpand(pBuffer, nSource); + memcpy(pBuffer->pData+pBuffer->nData, pSource, nSource); + pBuffer->nData += nSource; +} +static void dataBufferAppend2(DataBuffer *pBuffer, + const char *pSource1, int nSource1, + const char *pSource2, int nSource2){ + assert( nSource1>0 && pSource1!=NULL ); + assert( nSource2>0 && pSource2!=NULL ); + dataBufferExpand(pBuffer, nSource1+nSource2); + memcpy(pBuffer->pData+pBuffer->nData, pSource1, nSource1); + memcpy(pBuffer->pData+pBuffer->nData+nSource1, pSource2, nSource2); + pBuffer->nData += nSource1+nSource2; +} +static void dataBufferReplace(DataBuffer *pBuffer, + const char *pSource, int nSource){ + dataBufferReset(pBuffer); + dataBufferAppend(pBuffer, pSource, nSource); +} + +/* StringBuffer is a null-terminated version of DataBuffer. */ +typedef struct StringBuffer { + DataBuffer b; /* Includes null terminator. */ +} StringBuffer; + +static void initStringBuffer(StringBuffer *sb){ + dataBufferInit(&sb->b, 100); + dataBufferReplace(&sb->b, "", 1); +} +static int stringBufferLength(StringBuffer *sb){ + return sb->b.nData-1; +} +static char *stringBufferData(StringBuffer *sb){ + return sb->b.pData; +} +static void stringBufferDestroy(StringBuffer *sb){ + dataBufferDestroy(&sb->b); +} + +static void nappend(StringBuffer *sb, const char *zFrom, int nFrom){ + assert( sb->b.nData>0 ); + if( nFrom>0 ){ + sb->b.nData--; + dataBufferAppend2(&sb->b, zFrom, nFrom, "", 1); + } +} +static void append(StringBuffer *sb, const char *zFrom){ + nappend(sb, zFrom, strlen(zFrom)); +} + +/* Append a list of strings separated by commas. */ +static void appendList(StringBuffer *sb, int nString, char **azString){ + int i; + for(i=0; i<nString; ++i){ + if( i>0 ) append(sb, ", "); + append(sb, azString[i]); + } +} + +static int endsInWhiteSpace(StringBuffer *p){ + return stringBufferLength(p)>0 && + safe_isspace(stringBufferData(p)[stringBufferLength(p)-1]); +} + +/* If the StringBuffer ends in something other than white space, add a +** single space character to the end. +*/ +static void appendWhiteSpace(StringBuffer *p){ + if( stringBufferLength(p)==0 ) return; + if( !endsInWhiteSpace(p) ) append(p, " "); +} + +/* Remove white space from the end of the StringBuffer */ +static void trimWhiteSpace(StringBuffer *p){ + while( endsInWhiteSpace(p) ){ + p->b.pData[--p->b.nData-1] = '\0'; + } +} + +/*******************************************************************/ +/* DLReader is used to read document elements from a doclist. The +** current docid is cached, so dlrDocid() is fast. DLReader does not +** own the doclist buffer. +** +** dlrAtEnd - true if there's no more data to read. +** dlrDocid - docid of current document. +** dlrDocData - doclist data for current document (including docid). +** dlrDocDataBytes - length of same. +** dlrAllDataBytes - length of all remaining data. +** dlrPosData - position data for current document. +** dlrPosDataLen - length of pos data for current document (incl POS_END). +** dlrStep - step to current document. +** dlrInit - initial for doclist of given type against given data. +** dlrDestroy - clean up. +** +** Expected usage is something like: +** +** DLReader reader; +** dlrInit(&reader, pData, nData); +** while( !dlrAtEnd(&reader) ){ +** // calls to dlrDocid() and kin. +** dlrStep(&reader); +** } +** dlrDestroy(&reader); +*/ +typedef struct DLReader { + DocListType iType; + const char *pData; + int nData; + + sqlite_int64 iDocid; + int nElement; +} DLReader; + +static int dlrAtEnd(DLReader *pReader){ + assert( pReader->nData>=0 ); + return pReader->nData==0; +} +static sqlite_int64 dlrDocid(DLReader *pReader){ + assert( !dlrAtEnd(pReader) ); + return pReader->iDocid; +} +static const char *dlrDocData(DLReader *pReader){ + assert( !dlrAtEnd(pReader) ); + return pReader->pData; +} +static int dlrDocDataBytes(DLReader *pReader){ + assert( !dlrAtEnd(pReader) ); + return pReader->nElement; +} +static int dlrAllDataBytes(DLReader *pReader){ + assert( !dlrAtEnd(pReader) ); + return pReader->nData; +} +/* TODO(shess) Consider adding a field to track iDocid varint length +** to make these two functions faster. This might matter (a tiny bit) +** for queries. +*/ +static const char *dlrPosData(DLReader *pReader){ + sqlite_int64 iDummy; + int n = fts3GetVarint(pReader->pData, &iDummy); + assert( !dlrAtEnd(pReader) ); + return pReader->pData+n; +} +static int dlrPosDataLen(DLReader *pReader){ + sqlite_int64 iDummy; + int n = fts3GetVarint(pReader->pData, &iDummy); + assert( !dlrAtEnd(pReader) ); + return pReader->nElement-n; +} +static void dlrStep(DLReader *pReader){ + assert( !dlrAtEnd(pReader) ); + + /* Skip past current doclist element. */ + assert( pReader->nElement<=pReader->nData ); + pReader->pData += pReader->nElement; + pReader->nData -= pReader->nElement; + + /* If there is more data, read the next doclist element. */ + if( pReader->nData!=0 ){ + sqlite_int64 iDocidDelta; + int iDummy, n = fts3GetVarint(pReader->pData, &iDocidDelta); + pReader->iDocid += iDocidDelta; + if( pReader->iType>=DL_POSITIONS ){ + assert( n<pReader->nData ); + while( 1 ){ + n += fts3GetVarint32(pReader->pData+n, &iDummy); + assert( n<=pReader->nData ); + if( iDummy==POS_END ) break; + if( iDummy==POS_COLUMN ){ + n += fts3GetVarint32(pReader->pData+n, &iDummy); + assert( n<pReader->nData ); + }else if( pReader->iType==DL_POSITIONS_OFFSETS ){ + n += fts3GetVarint32(pReader->pData+n, &iDummy); + n += fts3GetVarint32(pReader->pData+n, &iDummy); + assert( n<pReader->nData ); + } + } + } + pReader->nElement = n; + assert( pReader->nElement<=pReader->nData ); + } +} +static void dlrInit(DLReader *pReader, DocListType iType, + const char *pData, int nData){ + assert( pData!=NULL && nData!=0 ); + pReader->iType = iType; + pReader->pData = pData; + pReader->nData = nData; + pReader->nElement = 0; + pReader->iDocid = 0; + + /* Load the first element's data. There must be a first element. */ + dlrStep(pReader); +} +static void dlrDestroy(DLReader *pReader){ + SCRAMBLE(pReader); +} + +#ifndef NDEBUG +/* Verify that the doclist can be validly decoded. Also returns the +** last docid found because it's convenient in other assertions for +** DLWriter. +*/ +static void docListValidate(DocListType iType, const char *pData, int nData, + sqlite_int64 *pLastDocid){ + sqlite_int64 iPrevDocid = 0; + assert( nData>0 ); + assert( pData!=0 ); + assert( pData+nData>pData ); + while( nData!=0 ){ + sqlite_int64 iDocidDelta; + int n = fts3GetVarint(pData, &iDocidDelta); + iPrevDocid += iDocidDelta; + if( iType>DL_DOCIDS ){ + int iDummy; + while( 1 ){ + n += fts3GetVarint32(pData+n, &iDummy); + if( iDummy==POS_END ) break; + if( iDummy==POS_COLUMN ){ + n += fts3GetVarint32(pData+n, &iDummy); + }else if( iType>DL_POSITIONS ){ + n += fts3GetVarint32(pData+n, &iDummy); + n += fts3GetVarint32(pData+n, &iDummy); + } + assert( n<=nData ); + } + } + assert( n<=nData ); + pData += n; + nData -= n; + } + if( pLastDocid ) *pLastDocid = iPrevDocid; +} +#define ASSERT_VALID_DOCLIST(i, p, n, o) docListValidate(i, p, n, o) +#else +#define ASSERT_VALID_DOCLIST(i, p, n, o) assert( 1 ) +#endif + +/*******************************************************************/ +/* DLWriter is used to write doclist data to a DataBuffer. DLWriter +** always appends to the buffer and does not own it. +** +** dlwInit - initialize to write a given type doclistto a buffer. +** dlwDestroy - clear the writer's memory. Does not free buffer. +** dlwAppend - append raw doclist data to buffer. +** dlwCopy - copy next doclist from reader to writer. +** dlwAdd - construct doclist element and append to buffer. +** Only apply dlwAdd() to DL_DOCIDS doclists (else use PLWriter). +*/ +typedef struct DLWriter { + DocListType iType; + DataBuffer *b; + sqlite_int64 iPrevDocid; +#ifndef NDEBUG + int has_iPrevDocid; +#endif +} DLWriter; + +static void dlwInit(DLWriter *pWriter, DocListType iType, DataBuffer *b){ + pWriter->b = b; + pWriter->iType = iType; + pWriter->iPrevDocid = 0; +#ifndef NDEBUG + pWriter->has_iPrevDocid = 0; +#endif +} +static void dlwDestroy(DLWriter *pWriter){ + SCRAMBLE(pWriter); +} +/* iFirstDocid is the first docid in the doclist in pData. It is +** needed because pData may point within a larger doclist, in which +** case the first item would be delta-encoded. +** +** iLastDocid is the final docid in the doclist in pData. It is +** needed to create the new iPrevDocid for future delta-encoding. The +** code could decode the passed doclist to recreate iLastDocid, but +** the only current user (docListMerge) already has decoded this +** information. +*/ +/* TODO(shess) This has become just a helper for docListMerge. +** Consider a refactor to make this cleaner. +*/ +static void dlwAppend(DLWriter *pWriter, + const char *pData, int nData, + sqlite_int64 iFirstDocid, sqlite_int64 iLastDocid){ + sqlite_int64 iDocid = 0; + char c[VARINT_MAX]; + int nFirstOld, nFirstNew; /* Old and new varint len of first docid. */ +#ifndef NDEBUG + sqlite_int64 iLastDocidDelta; +#endif + + /* Recode the initial docid as delta from iPrevDocid. */ + nFirstOld = fts3GetVarint(pData, &iDocid); + assert( nFirstOld<nData || (nFirstOld==nData && pWriter->iType==DL_DOCIDS) ); + nFirstNew = fts3PutVarint(c, iFirstDocid-pWriter->iPrevDocid); + + /* Verify that the incoming doclist is valid AND that it ends with + ** the expected docid. This is essential because we'll trust this + ** docid in future delta-encoding. + */ + ASSERT_VALID_DOCLIST(pWriter->iType, pData, nData, &iLastDocidDelta); + assert( iLastDocid==iFirstDocid-iDocid+iLastDocidDelta ); + + /* Append recoded initial docid and everything else. Rest of docids + ** should have been delta-encoded from previous initial docid. + */ + if( nFirstOld<nData ){ + dataBufferAppend2(pWriter->b, c, nFirstNew, + pData+nFirstOld, nData-nFirstOld); + }else{ + dataBufferAppend(pWriter->b, c, nFirstNew); + } + pWriter->iPrevDocid = iLastDocid; +} +static void dlwCopy(DLWriter *pWriter, DLReader *pReader){ + dlwAppend(pWriter, dlrDocData(pReader), dlrDocDataBytes(pReader), + dlrDocid(pReader), dlrDocid(pReader)); +} +static void dlwAdd(DLWriter *pWriter, sqlite_int64 iDocid){ + char c[VARINT_MAX]; + int n = fts3PutVarint(c, iDocid-pWriter->iPrevDocid); + + /* Docids must ascend. */ + assert( !pWriter->has_iPrevDocid || iDocid>pWriter->iPrevDocid ); + assert( pWriter->iType==DL_DOCIDS ); + + dataBufferAppend(pWriter->b, c, n); + pWriter->iPrevDocid = iDocid; +#ifndef NDEBUG + pWriter->has_iPrevDocid = 1; +#endif +} + +/*******************************************************************/ +/* PLReader is used to read data from a document's position list. As +** the caller steps through the list, data is cached so that varints +** only need to be decoded once. +** +** plrInit, plrDestroy - create/destroy a reader. +** plrColumn, plrPosition, plrStartOffset, plrEndOffset - accessors +** plrAtEnd - at end of stream, only call plrDestroy once true. +** plrStep - step to the next element. +*/ +typedef struct PLReader { + /* These refer to the next position's data. nData will reach 0 when + ** reading the last position, so plrStep() signals EOF by setting + ** pData to NULL. + */ + const char *pData; + int nData; + + DocListType iType; + int iColumn; /* the last column read */ + int iPosition; /* the last position read */ + int iStartOffset; /* the last start offset read */ + int iEndOffset; /* the last end offset read */ +} PLReader; + +static int plrAtEnd(PLReader *pReader){ + return pReader->pData==NULL; +} +static int plrColumn(PLReader *pReader){ + assert( !plrAtEnd(pReader) ); + return pReader->iColumn; +} +static int plrPosition(PLReader *pReader){ + assert( !plrAtEnd(pReader) ); + return pReader->iPosition; +} +static int plrStartOffset(PLReader *pReader){ + assert( !plrAtEnd(pReader) ); + return pReader->iStartOffset; +} +static int plrEndOffset(PLReader *pReader){ + assert( !plrAtEnd(pReader) ); + return pReader->iEndOffset; +} +static void plrStep(PLReader *pReader){ + int i, n; + + assert( !plrAtEnd(pReader) ); + + if( pReader->nData==0 ){ + pReader->pData = NULL; + return; + } + + n = fts3GetVarint32(pReader->pData, &i); + if( i==POS_COLUMN ){ + n += fts3GetVarint32(pReader->pData+n, &pReader->iColumn); + pReader->iPosition = 0; + pReader->iStartOffset = 0; + n += fts3GetVarint32(pReader->pData+n, &i); + } + /* Should never see adjacent column changes. */ + assert( i!=POS_COLUMN ); + + if( i==POS_END ){ + pReader->nData = 0; + pReader->pData = NULL; + return; + } + + pReader->iPosition += i-POS_BASE; + if( pReader->iType==DL_POSITIONS_OFFSETS ){ + n += fts3GetVarint32(pReader->pData+n, &i); + pReader->iStartOffset += i; + n += fts3GetVarint32(pReader->pData+n, &i); + pReader->iEndOffset = pReader->iStartOffset+i; + } + assert( n<=pReader->nData ); + pReader->pData += n; + pReader->nData -= n; +} + +static void plrInit(PLReader *pReader, DLReader *pDLReader){ + pReader->pData = dlrPosData(pDLReader); + pReader->nData = dlrPosDataLen(pDLReader); + pReader->iType = pDLReader->iType; + pReader->iColumn = 0; + pReader->iPosition = 0; + pReader->iStartOffset = 0; + pReader->iEndOffset = 0; + plrStep(pReader); +} +static void plrDestroy(PLReader *pReader){ + SCRAMBLE(pReader); +} + +/*******************************************************************/ +/* PLWriter is used in constructing a document's position list. As a +** convenience, if iType is DL_DOCIDS, PLWriter becomes a no-op. +** PLWriter writes to the associated DLWriter's buffer. +** +** plwInit - init for writing a document's poslist. +** plwDestroy - clear a writer. +** plwAdd - append position and offset information. +** plwCopy - copy next position's data from reader to writer. +** plwTerminate - add any necessary doclist terminator. +** +** Calling plwAdd() after plwTerminate() may result in a corrupt +** doclist. +*/ +/* TODO(shess) Until we've written the second item, we can cache the +** first item's information. Then we'd have three states: +** +** - initialized with docid, no positions. +** - docid and one position. +** - docid and multiple positions. +** +** Only the last state needs to actually write to dlw->b, which would +** be an improvement in the DLCollector case. +*/ +typedef struct PLWriter { + DLWriter *dlw; + + int iColumn; /* the last column written */ + int iPos; /* the last position written */ + int iOffset; /* the last start offset written */ +} PLWriter; + +/* TODO(shess) In the case where the parent is reading these values +** from a PLReader, we could optimize to a copy if that PLReader has +** the same type as pWriter. +*/ +static void plwAdd(PLWriter *pWriter, int iColumn, int iPos, + int iStartOffset, int iEndOffset){ + /* Worst-case space for POS_COLUMN, iColumn, iPosDelta, + ** iStartOffsetDelta, and iEndOffsetDelta. + */ + char c[5*VARINT_MAX]; + int n = 0; + + /* Ban plwAdd() after plwTerminate(). */ + assert( pWriter->iPos!=-1 ); + + if( pWriter->dlw->iType==DL_DOCIDS ) return; + + if( iColumn!=pWriter->iColumn ){ + n += fts3PutVarint(c+n, POS_COLUMN); + n += fts3PutVarint(c+n, iColumn); + pWriter->iColumn = iColumn; + pWriter->iPos = 0; + pWriter->iOffset = 0; + } + assert( iPos>=pWriter->iPos ); + n += fts3PutVarint(c+n, POS_BASE+(iPos-pWriter->iPos)); + pWriter->iPos = iPos; + if( pWriter->dlw->iType==DL_POSITIONS_OFFSETS ){ + assert( iStartOffset>=pWriter->iOffset ); + n += fts3PutVarint(c+n, iStartOffset-pWriter->iOffset); + pWriter->iOffset = iStartOffset; + assert( iEndOffset>=iStartOffset ); + n += fts3PutVarint(c+n, iEndOffset-iStartOffset); + } + dataBufferAppend(pWriter->dlw->b, c, n); +} +static void plwCopy(PLWriter *pWriter, PLReader *pReader){ + plwAdd(pWriter, plrColumn(pReader), plrPosition(pReader), + plrStartOffset(pReader), plrEndOffset(pReader)); +} +static void plwInit(PLWriter *pWriter, DLWriter *dlw, sqlite_int64 iDocid){ + char c[VARINT_MAX]; + int n; + + pWriter->dlw = dlw; + + /* Docids must ascend. */ + assert( !pWriter->dlw->has_iPrevDocid || iDocid>pWriter->dlw->iPrevDocid ); + n = fts3PutVarint(c, iDocid-pWriter->dlw->iPrevDocid); + dataBufferAppend(pWriter->dlw->b, c, n); + pWriter->dlw->iPrevDocid = iDocid; +#ifndef NDEBUG + pWriter->dlw->has_iPrevDocid = 1; +#endif + + pWriter->iColumn = 0; + pWriter->iPos = 0; + pWriter->iOffset = 0; +} +/* TODO(shess) Should plwDestroy() also terminate the doclist? But +** then plwDestroy() would no longer be just a destructor, it would +** also be doing work, which isn't consistent with the overall idiom. +** Another option would be for plwAdd() to always append any necessary +** terminator, so that the output is always correct. But that would +** add incremental work to the common case with the only benefit being +** API elegance. Punt for now. +*/ +static void plwTerminate(PLWriter *pWriter){ + if( pWriter->dlw->iType>DL_DOCIDS ){ + char c[VARINT_MAX]; + int n = fts3PutVarint(c, POS_END); + dataBufferAppend(pWriter->dlw->b, c, n); + } +#ifndef NDEBUG + /* Mark as terminated for assert in plwAdd(). */ + pWriter->iPos = -1; +#endif +} +static void plwDestroy(PLWriter *pWriter){ + SCRAMBLE(pWriter); +} + +/*******************************************************************/ +/* DLCollector wraps PLWriter and DLWriter to provide a +** dynamically-allocated doclist area to use during tokenization. +** +** dlcNew - malloc up and initialize a collector. +** dlcDelete - destroy a collector and all contained items. +** dlcAddPos - append position and offset information. +** dlcAddDoclist - add the collected doclist to the given buffer. +** dlcNext - terminate the current document and open another. +*/ +typedef struct DLCollector { + DataBuffer b; + DLWriter dlw; + PLWriter plw; +} DLCollector; + +/* TODO(shess) This could also be done by calling plwTerminate() and +** dataBufferAppend(). I tried that, expecting nominal performance +** differences, but it seemed to pretty reliably be worth 1% to code +** it this way. I suspect it's the incremental malloc overhead (some +** percentage of the plwTerminate() calls will cause a realloc), so +** this might be worth revisiting if the DataBuffer implementation +** changes. +*/ +static void dlcAddDoclist(DLCollector *pCollector, DataBuffer *b){ + if( pCollector->dlw.iType>DL_DOCIDS ){ + char c[VARINT_MAX]; + int n = fts3PutVarint(c, POS_END); + dataBufferAppend2(b, pCollector->b.pData, pCollector->b.nData, c, n); + }else{ + dataBufferAppend(b, pCollector->b.pData, pCollector->b.nData); + } +} +static void dlcNext(DLCollector *pCollector, sqlite_int64 iDocid){ + plwTerminate(&pCollector->plw); + plwDestroy(&pCollector->plw); + plwInit(&pCollector->plw, &pCollector->dlw, iDocid); +} +static void dlcAddPos(DLCollector *pCollector, int iColumn, int iPos, + int iStartOffset, int iEndOffset){ + plwAdd(&pCollector->plw, iColumn, iPos, iStartOffset, iEndOffset); +} + +static DLCollector *dlcNew(sqlite_int64 iDocid, DocListType iType){ + DLCollector *pCollector = sqlite3_malloc(sizeof(DLCollector)); + dataBufferInit(&pCollector->b, 0); + dlwInit(&pCollector->dlw, iType, &pCollector->b); + plwInit(&pCollector->plw, &pCollector->dlw, iDocid); + return pCollector; +} +static void dlcDelete(DLCollector *pCollector){ + plwDestroy(&pCollector->plw); + dlwDestroy(&pCollector->dlw); + dataBufferDestroy(&pCollector->b); + SCRAMBLE(pCollector); + sqlite3_free(pCollector); +} + + +/* Copy the doclist data of iType in pData/nData into *out, trimming +** unnecessary data as we go. Only columns matching iColumn are +** copied, all columns copied if iColumn is -1. Elements with no +** matching columns are dropped. The output is an iOutType doclist. +*/ +/* NOTE(shess) This code is only valid after all doclists are merged. +** If this is run before merges, then doclist items which represent +** deletion will be trimmed, and will thus not effect a deletion +** during the merge. +*/ +static void docListTrim(DocListType iType, const char *pData, int nData, + int iColumn, DocListType iOutType, DataBuffer *out){ + DLReader dlReader; + DLWriter dlWriter; + + assert( iOutType<=iType ); + + dlrInit(&dlReader, iType, pData, nData); + dlwInit(&dlWriter, iOutType, out); + + while( !dlrAtEnd(&dlReader) ){ + PLReader plReader; + PLWriter plWriter; + int match = 0; + + plrInit(&plReader, &dlReader); + + while( !plrAtEnd(&plReader) ){ + if( iColumn==-1 || plrColumn(&plReader)==iColumn ){ + if( !match ){ + plwInit(&plWriter, &dlWriter, dlrDocid(&dlReader)); + match = 1; + } + plwAdd(&plWriter, plrColumn(&plReader), plrPosition(&plReader), + plrStartOffset(&plReader), plrEndOffset(&plReader)); + } + plrStep(&plReader); + } + if( match ){ + plwTerminate(&plWriter); + plwDestroy(&plWriter); + } + + plrDestroy(&plReader); + dlrStep(&dlReader); + } + dlwDestroy(&dlWriter); + dlrDestroy(&dlReader); +} + +/* Used by docListMerge() to keep doclists in the ascending order by +** docid, then ascending order by age (so the newest comes first). +*/ +typedef struct OrderedDLReader { + DLReader *pReader; + + /* TODO(shess) If we assume that docListMerge pReaders is ordered by + ** age (which we do), then we could use pReader comparisons to break + ** ties. + */ + int idx; +} OrderedDLReader; + +/* Order eof to end, then by docid asc, idx desc. */ +static int orderedDLReaderCmp(OrderedDLReader *r1, OrderedDLReader *r2){ + if( dlrAtEnd(r1->pReader) ){ + if( dlrAtEnd(r2->pReader) ) return 0; /* Both atEnd(). */ + return 1; /* Only r1 atEnd(). */ + } + if( dlrAtEnd(r2->pReader) ) return -1; /* Only r2 atEnd(). */ + + if( dlrDocid(r1->pReader)<dlrDocid(r2->pReader) ) return -1; + if( dlrDocid(r1->pReader)>dlrDocid(r2->pReader) ) return 1; + + /* Descending on idx. */ + return r2->idx-r1->idx; +} + +/* Bubble p[0] to appropriate place in p[1..n-1]. Assumes that +** p[1..n-1] is already sorted. +*/ +/* TODO(shess) Is this frequent enough to warrant a binary search? +** Before implementing that, instrument the code to check. In most +** current usage, I expect that p[0] will be less than p[1] a very +** high proportion of the time. +*/ +static void orderedDLReaderReorder(OrderedDLReader *p, int n){ + while( n>1 && orderedDLReaderCmp(p, p+1)>0 ){ + OrderedDLReader tmp = p[0]; + p[0] = p[1]; + p[1] = tmp; + n--; + p++; + } +} + +/* Given an array of doclist readers, merge their doclist elements +** into out in sorted order (by docid), dropping elements from older +** readers when there is a duplicate docid. pReaders is assumed to be +** ordered by age, oldest first. +*/ +/* TODO(shess) nReaders must be <= MERGE_COUNT. This should probably +** be fixed. +*/ +static void docListMerge(DataBuffer *out, + DLReader *pReaders, int nReaders){ + OrderedDLReader readers[MERGE_COUNT]; + DLWriter writer; + int i, n; + const char *pStart = 0; + int nStart = 0; + sqlite_int64 iFirstDocid = 0, iLastDocid = 0; + + assert( nReaders>0 ); + if( nReaders==1 ){ + dataBufferAppend(out, dlrDocData(pReaders), dlrAllDataBytes(pReaders)); + return; + } + + assert( nReaders<=MERGE_COUNT ); + n = 0; + for(i=0; i<nReaders; i++){ + assert( pReaders[i].iType==pReaders[0].iType ); + readers[i].pReader = pReaders+i; + readers[i].idx = i; + n += dlrAllDataBytes(&pReaders[i]); + } + /* Conservatively size output to sum of inputs. Output should end + ** up strictly smaller than input. + */ + dataBufferExpand(out, n); + + /* Get the readers into sorted order. */ + while( i-->0 ){ + orderedDLReaderReorder(readers+i, nReaders-i); + } + + dlwInit(&writer, pReaders[0].iType, out); + while( !dlrAtEnd(readers[0].pReader) ){ + sqlite_int64 iDocid = dlrDocid(readers[0].pReader); + + /* If this is a continuation of the current buffer to copy, extend + ** that buffer. memcpy() seems to be more efficient if it has a + ** lots of data to copy. + */ + if( dlrDocData(readers[0].pReader)==pStart+nStart ){ + nStart += dlrDocDataBytes(readers[0].pReader); + }else{ + if( pStart!=0 ){ + dlwAppend(&writer, pStart, nStart, iFirstDocid, iLastDocid); + } + pStart = dlrDocData(readers[0].pReader); + nStart = dlrDocDataBytes(readers[0].pReader); + iFirstDocid = iDocid; + } + iLastDocid = iDocid; + dlrStep(readers[0].pReader); + + /* Drop all of the older elements with the same docid. */ + for(i=1; i<nReaders && + !dlrAtEnd(readers[i].pReader) && + dlrDocid(readers[i].pReader)==iDocid; i++){ + dlrStep(readers[i].pReader); + } + + /* Get the readers back into order. */ + while( i-->0 ){ + orderedDLReaderReorder(readers+i, nReaders-i); + } + } + + /* Copy over any remaining elements. */ + if( nStart>0 ) dlwAppend(&writer, pStart, nStart, iFirstDocid, iLastDocid); + dlwDestroy(&writer); +} + +/* Helper function for posListUnion(). Compares the current position +** between left and right, returning as standard C idiom of <0 if +** left<right, >0 if left>right, and 0 if left==right. "End" always +** compares greater. +*/ +static int posListCmp(PLReader *pLeft, PLReader *pRight){ + assert( pLeft->iType==pRight->iType ); + if( pLeft->iType==DL_DOCIDS ) return 0; + + if( plrAtEnd(pLeft) ) return plrAtEnd(pRight) ? 0 : 1; + if( plrAtEnd(pRight) ) return -1; + + if( plrColumn(pLeft)<plrColumn(pRight) ) return -1; + if( plrColumn(pLeft)>plrColumn(pRight) ) return 1; + + if( plrPosition(pLeft)<plrPosition(pRight) ) return -1; + if( plrPosition(pLeft)>plrPosition(pRight) ) return 1; + if( pLeft->iType==DL_POSITIONS ) return 0; + + if( plrStartOffset(pLeft)<plrStartOffset(pRight) ) return -1; + if( plrStartOffset(pLeft)>plrStartOffset(pRight) ) return 1; + + if( plrEndOffset(pLeft)<plrEndOffset(pRight) ) return -1; + if( plrEndOffset(pLeft)>plrEndOffset(pRight) ) return 1; + + return 0; +} + +/* Write the union of position lists in pLeft and pRight to pOut. +** "Union" in this case meaning "All unique position tuples". Should +** work with any doclist type, though both inputs and the output +** should be the same type. +*/ +static void posListUnion(DLReader *pLeft, DLReader *pRight, DLWriter *pOut){ + PLReader left, right; + PLWriter writer; + + assert( dlrDocid(pLeft)==dlrDocid(pRight) ); + assert( pLeft->iType==pRight->iType ); + assert( pLeft->iType==pOut->iType ); + + plrInit(&left, pLeft); + plrInit(&right, pRight); + plwInit(&writer, pOut, dlrDocid(pLeft)); + + while( !plrAtEnd(&left) || !plrAtEnd(&right) ){ + int c = posListCmp(&left, &right); + if( c<0 ){ + plwCopy(&writer, &left); + plrStep(&left); + }else if( c>0 ){ + plwCopy(&writer, &right); + plrStep(&right); + }else{ + plwCopy(&writer, &left); + plrStep(&left); + plrStep(&right); + } + } + + plwTerminate(&writer); + plwDestroy(&writer); + plrDestroy(&left); + plrDestroy(&right); +} + +/* Write the union of doclists in pLeft and pRight to pOut. For +** docids in common between the inputs, the union of the position +** lists is written. Inputs and outputs are always type DL_DEFAULT. +*/ +static void docListUnion( + const char *pLeft, int nLeft, + const char *pRight, int nRight, + DataBuffer *pOut /* Write the combined doclist here */ +){ + DLReader left, right; + DLWriter writer; + + if( nLeft==0 ){ + if( nRight!=0) dataBufferAppend(pOut, pRight, nRight); + return; + } + if( nRight==0 ){ + dataBufferAppend(pOut, pLeft, nLeft); + return; + } + + dlrInit(&left, DL_DEFAULT, pLeft, nLeft); + dlrInit(&right, DL_DEFAULT, pRight, nRight); + dlwInit(&writer, DL_DEFAULT, pOut); + + while( !dlrAtEnd(&left) || !dlrAtEnd(&right) ){ + if( dlrAtEnd(&right) ){ + dlwCopy(&writer, &left); + dlrStep(&left); + }else if( dlrAtEnd(&left) ){ + dlwCopy(&writer, &right); + dlrStep(&right); + }else if( dlrDocid(&left)<dlrDocid(&right) ){ + dlwCopy(&writer, &left); + dlrStep(&left); + }else if( dlrDocid(&left)>dlrDocid(&right) ){ + dlwCopy(&writer, &right); + dlrStep(&right); + }else{ + posListUnion(&left, &right, &writer); + dlrStep(&left); + dlrStep(&right); + } + } + + dlrDestroy(&left); + dlrDestroy(&right); + dlwDestroy(&writer); +} + +/* +** This function is used as part of the implementation of phrase and +** NEAR matching. +** +** pLeft and pRight are DLReaders positioned to the same docid in +** lists of type DL_POSITION. This function writes an entry to the +** DLWriter pOut for each position in pRight that is less than +** (nNear+1) greater (but not equal to or smaller) than a position +** in pLeft. For example, if nNear is 0, and the positions contained +** by pLeft and pRight are: +** +** pLeft: 5 10 15 20 +** pRight: 6 9 17 21 +** +** then the docid is added to pOut. If pOut is of type DL_POSITIONS, +** then a positionids "6" and "21" are also added to pOut. +** +** If boolean argument isSaveLeft is true, then positionids are copied +** from pLeft instead of pRight. In the example above, the positions "5" +** and "20" would be added instead of "6" and "21". +*/ +static void posListPhraseMerge( + DLReader *pLeft, + DLReader *pRight, + int nNear, + int isSaveLeft, + DLWriter *pOut +){ + PLReader left, right; + PLWriter writer; + int match = 0; + + assert( dlrDocid(pLeft)==dlrDocid(pRight) ); + assert( pOut->iType!=DL_POSITIONS_OFFSETS ); + + plrInit(&left, pLeft); + plrInit(&right, pRight); + + while( !plrAtEnd(&left) && !plrAtEnd(&right) ){ + if( plrColumn(&left)<plrColumn(&right) ){ + plrStep(&left); + }else if( plrColumn(&left)>plrColumn(&right) ){ + plrStep(&right); + }else if( plrPosition(&left)>=plrPosition(&right) ){ + plrStep(&right); + }else{ + if( (plrPosition(&right)-plrPosition(&left))<=(nNear+1) ){ + if( !match ){ + plwInit(&writer, pOut, dlrDocid(pLeft)); + match = 1; + } + if( !isSaveLeft ){ + plwAdd(&writer, plrColumn(&right), plrPosition(&right), 0, 0); + }else{ + plwAdd(&writer, plrColumn(&left), plrPosition(&left), 0, 0); + } + plrStep(&right); + }else{ + plrStep(&left); + } + } + } + + if( match ){ + plwTerminate(&writer); + plwDestroy(&writer); + } + + plrDestroy(&left); + plrDestroy(&right); +} + +/* +** Compare the values pointed to by the PLReaders passed as arguments. +** Return -1 if the value pointed to by pLeft is considered less than +** the value pointed to by pRight, +1 if it is considered greater +** than it, or 0 if it is equal. i.e. +** +** (*pLeft - *pRight) +** +** A PLReader that is in the EOF condition is considered greater than +** any other. If neither argument is in EOF state, the return value of +** plrColumn() is used. If the plrColumn() values are equal, the +** comparison is on the basis of plrPosition(). +*/ +static int plrCompare(PLReader *pLeft, PLReader *pRight){ + assert(!plrAtEnd(pLeft) || !plrAtEnd(pRight)); + + if( plrAtEnd(pRight) || plrAtEnd(pLeft) ){ + return (plrAtEnd(pRight) ? -1 : 1); + } + if( plrColumn(pLeft)!=plrColumn(pRight) ){ + return ((plrColumn(pLeft)<plrColumn(pRight)) ? -1 : 1); + } + if( plrPosition(pLeft)!=plrPosition(pRight) ){ + return ((plrPosition(pLeft)<plrPosition(pRight)) ? -1 : 1); + } + return 0; +} + +/* We have two doclists with positions: pLeft and pRight. Depending +** on the value of the nNear parameter, perform either a phrase +** intersection (if nNear==0) or a NEAR intersection (if nNear>0) +** and write the results into pOut. +** +** A phrase intersection means that two documents only match +** if pLeft.iPos+1==pRight.iPos. +** +** A NEAR intersection means that two documents only match if +** (abs(pLeft.iPos-pRight.iPos)<nNear). +** +** If a NEAR intersection is requested, then the nPhrase argument should +** be passed the number of tokens in the two operands to the NEAR operator +** combined. For example: +** +** Query syntax nPhrase +** ------------------------------------ +** "A B C" NEAR "D E" 5 +** A NEAR B 2 +** +** iType controls the type of data written to pOut. If iType is +** DL_POSITIONS, the positions are those from pRight. +*/ +static void docListPhraseMerge( + const char *pLeft, int nLeft, + const char *pRight, int nRight, + int nNear, /* 0 for a phrase merge, non-zero for a NEAR merge */ + int nPhrase, /* Number of tokens in left+right operands to NEAR */ + DocListType iType, /* Type of doclist to write to pOut */ + DataBuffer *pOut /* Write the combined doclist here */ +){ + DLReader left, right; + DLWriter writer; + + if( nLeft==0 || nRight==0 ) return; + + assert( iType!=DL_POSITIONS_OFFSETS ); + + dlrInit(&left, DL_POSITIONS, pLeft, nLeft); + dlrInit(&right, DL_POSITIONS, pRight, nRight); + dlwInit(&writer, iType, pOut); + + while( !dlrAtEnd(&left) && !dlrAtEnd(&right) ){ + if( dlrDocid(&left)<dlrDocid(&right) ){ + dlrStep(&left); + }else if( dlrDocid(&right)<dlrDocid(&left) ){ + dlrStep(&right); + }else{ + if( nNear==0 ){ + posListPhraseMerge(&left, &right, 0, 0, &writer); + }else{ + /* This case occurs when two terms (simple terms or phrases) are + * connected by a NEAR operator, span (nNear+1). i.e. + * + * '"terrible company" NEAR widget' + */ + DataBuffer one = {0, 0, 0}; + DataBuffer two = {0, 0, 0}; + + DLWriter dlwriter2; + DLReader dr1 = {0, 0, 0, 0, 0}; + DLReader dr2 = {0, 0, 0, 0, 0}; + + dlwInit(&dlwriter2, iType, &one); + posListPhraseMerge(&right, &left, nNear-3+nPhrase, 1, &dlwriter2); + dlwInit(&dlwriter2, iType, &two); + posListPhraseMerge(&left, &right, nNear-1, 0, &dlwriter2); + + if( one.nData) dlrInit(&dr1, iType, one.pData, one.nData); + if( two.nData) dlrInit(&dr2, iType, two.pData, two.nData); + + if( !dlrAtEnd(&dr1) || !dlrAtEnd(&dr2) ){ + PLReader pr1 = {0}; + PLReader pr2 = {0}; + + PLWriter plwriter; + plwInit(&plwriter, &writer, dlrDocid(dlrAtEnd(&dr1)?&dr2:&dr1)); + + if( one.nData ) plrInit(&pr1, &dr1); + if( two.nData ) plrInit(&pr2, &dr2); + while( !plrAtEnd(&pr1) || !plrAtEnd(&pr2) ){ + int iCompare = plrCompare(&pr1, &pr2); + switch( iCompare ){ + case -1: + plwCopy(&plwriter, &pr1); + plrStep(&pr1); + break; + case 1: + plwCopy(&plwriter, &pr2); + plrStep(&pr2); + break; + case 0: + plwCopy(&plwriter, &pr1); + plrStep(&pr1); + plrStep(&pr2); + break; + } + } + plwTerminate(&plwriter); + } + dataBufferDestroy(&one); + dataBufferDestroy(&two); + } + dlrStep(&left); + dlrStep(&right); + } + } + + dlrDestroy(&left); + dlrDestroy(&right); + dlwDestroy(&writer); +} + +/* We have two DL_DOCIDS doclists: pLeft and pRight. +** Write the intersection of these two doclists into pOut as a +** DL_DOCIDS doclist. +*/ +static void docListAndMerge( + const char *pLeft, int nLeft, + const char *pRight, int nRight, + DataBuffer *pOut /* Write the combined doclist here */ +){ + DLReader left, right; + DLWriter writer; + + if( nLeft==0 || nRight==0 ) return; + + dlrInit(&left, DL_DOCIDS, pLeft, nLeft); + dlrInit(&right, DL_DOCIDS, pRight, nRight); + dlwInit(&writer, DL_DOCIDS, pOut); + + while( !dlrAtEnd(&left) && !dlrAtEnd(&right) ){ + if( dlrDocid(&left)<dlrDocid(&right) ){ + dlrStep(&left); + }else if( dlrDocid(&right)<dlrDocid(&left) ){ + dlrStep(&right); + }else{ + dlwAdd(&writer, dlrDocid(&left)); + dlrStep(&left); + dlrStep(&right); + } + } + + dlrDestroy(&left); + dlrDestroy(&right); + dlwDestroy(&writer); +} + +/* We have two DL_DOCIDS doclists: pLeft and pRight. +** Write the union of these two doclists into pOut as a +** DL_DOCIDS doclist. +*/ +static void docListOrMerge( + const char *pLeft, int nLeft, + const char *pRight, int nRight, + DataBuffer *pOut /* Write the combined doclist here */ +){ + DLReader left, right; + DLWriter writer; + + if( nLeft==0 ){ + if( nRight!=0 ) dataBufferAppend(pOut, pRight, nRight); + return; + } + if( nRight==0 ){ + dataBufferAppend(pOut, pLeft, nLeft); + return; + } + + dlrInit(&left, DL_DOCIDS, pLeft, nLeft); + dlrInit(&right, DL_DOCIDS, pRight, nRight); + dlwInit(&writer, DL_DOCIDS, pOut); + + while( !dlrAtEnd(&left) || !dlrAtEnd(&right) ){ + if( dlrAtEnd(&right) ){ + dlwAdd(&writer, dlrDocid(&left)); + dlrStep(&left); + }else if( dlrAtEnd(&left) ){ + dlwAdd(&writer, dlrDocid(&right)); + dlrStep(&right); + }else if( dlrDocid(&left)<dlrDocid(&right) ){ + dlwAdd(&writer, dlrDocid(&left)); + dlrStep(&left); + }else if( dlrDocid(&right)<dlrDocid(&left) ){ + dlwAdd(&writer, dlrDocid(&right)); + dlrStep(&right); + }else{ + dlwAdd(&writer, dlrDocid(&left)); + dlrStep(&left); + dlrStep(&right); + } + } + + dlrDestroy(&left); + dlrDestroy(&right); + dlwDestroy(&writer); +} + +/* We have two DL_DOCIDS doclists: pLeft and pRight. +** Write into pOut as DL_DOCIDS doclist containing all documents that +** occur in pLeft but not in pRight. +*/ +static void docListExceptMerge( + const char *pLeft, int nLeft, + const char *pRight, int nRight, + DataBuffer *pOut /* Write the combined doclist here */ +){ + DLReader left, right; + DLWriter writer; + + if( nLeft==0 ) return; + if( nRight==0 ){ + dataBufferAppend(pOut, pLeft, nLeft); + return; + } + + dlrInit(&left, DL_DOCIDS, pLeft, nLeft); + dlrInit(&right, DL_DOCIDS, pRight, nRight); + dlwInit(&writer, DL_DOCIDS, pOut); + + while( !dlrAtEnd(&left) ){ + while( !dlrAtEnd(&right) && dlrDocid(&right)<dlrDocid(&left) ){ + dlrStep(&right); + } + if( dlrAtEnd(&right) || dlrDocid(&left)<dlrDocid(&right) ){ + dlwAdd(&writer, dlrDocid(&left)); + } + dlrStep(&left); + } + + dlrDestroy(&left); + dlrDestroy(&right); + dlwDestroy(&writer); +} + +static char *string_dup_n(const char *s, int n){ + char *str = sqlite3_malloc(n + 1); + memcpy(str, s, n); + str[n] = '\0'; + return str; +} + +/* Duplicate a string; the caller must free() the returned string. + * (We don't use strdup() since it's not part of the standard C library and + * may not be available everywhere.) */ +static char *string_dup(const char *s){ + return string_dup_n(s, strlen(s)); +} + +/* Format a string, replacing each occurrence of the % character with + * zDb.zName. This may be more convenient than sqlite_mprintf() + * when one string is used repeatedly in a format string. + * The caller must free() the returned string. */ +static char *string_format(const char *zFormat, + const char *zDb, const char *zName){ + const char *p; + size_t len = 0; + size_t nDb = strlen(zDb); + size_t nName = strlen(zName); + size_t nFullTableName = nDb+1+nName; + char *result; + char *r; + + /* first compute length needed */ + for(p = zFormat ; *p ; ++p){ + len += (*p=='%' ? nFullTableName : 1); + } + len += 1; /* for null terminator */ + + r = result = sqlite3_malloc(len); + for(p = zFormat; *p; ++p){ + if( *p=='%' ){ + memcpy(r, zDb, nDb); + r += nDb; + *r++ = '.'; + memcpy(r, zName, nName); + r += nName; + } else { + *r++ = *p; + } + } + *r++ = '\0'; + assert( r == result + len ); + return result; +} + +static int sql_exec(sqlite3 *db, const char *zDb, const char *zName, + const char *zFormat){ + char *zCommand = string_format(zFormat, zDb, zName); + int rc; + FTSTRACE(("FTS3 sql: %s\n", zCommand)); + rc = sqlite3_exec(db, zCommand, NULL, 0, NULL); + sqlite3_free(zCommand); + return rc; +} + +static int sql_prepare(sqlite3 *db, const char *zDb, const char *zName, + sqlite3_stmt **ppStmt, const char *zFormat){ + char *zCommand = string_format(zFormat, zDb, zName); + int rc; + FTSTRACE(("FTS3 prepare: %s\n", zCommand)); + rc = sqlite3_prepare_v2(db, zCommand, -1, ppStmt, NULL); + sqlite3_free(zCommand); + return rc; +} + +/* end utility functions */ + +/* Forward reference */ +typedef struct fulltext_vtab fulltext_vtab; + +/* A single term in a query is represented by an instances of +** the following structure. Each word which may match against +** document content is a term. Operators, like NEAR or OR, are +** not terms. Query terms are organized as a flat list stored +** in the Query.pTerms array. +** +** If the QueryTerm.nPhrase variable is non-zero, then the QueryTerm +** is the first in a contiguous string of terms that are either part +** of the same phrase, or connected by the NEAR operator. +** +** If the QueryTerm.nNear variable is non-zero, then the token is followed +** by a NEAR operator with span set to (nNear-1). For example, the +** following query: +** +** The QueryTerm.iPhrase variable stores the index of the token within +** it's phrase, indexed starting at 1, or 1 if the token is not part +** of any phrase. +** +** For example, the data structure used to represent the following query: +** +** ... MATCH 'sqlite NEAR/5 google NEAR/2 "search engine"' +** +** is: +** +** {nPhrase=4, iPhrase=1, nNear=6, pTerm="sqlite"}, +** {nPhrase=0, iPhrase=1, nNear=3, pTerm="google"}, +** {nPhrase=0, iPhrase=1, nNear=0, pTerm="search"}, +** {nPhrase=0, iPhrase=2, nNear=0, pTerm="engine"}, +** +** compiling the FTS3 syntax to Query structures is done by the parseQuery() +** function. +*/ +typedef struct QueryTerm { + short int nPhrase; /* How many following terms are part of the same phrase */ + short int iPhrase; /* This is the i-th term of a phrase. */ + short int iColumn; /* Column of the index that must match this term */ + signed char nNear; /* term followed by a NEAR operator with span=(nNear-1) */ + signed char isOr; /* this term is preceded by "OR" */ + signed char isNot; /* this term is preceded by "-" */ + signed char isPrefix; /* this term is followed by "*" */ + char *pTerm; /* text of the term. '\000' terminated. malloced */ + int nTerm; /* Number of bytes in pTerm[] */ +} QueryTerm; + + +/* A query string is parsed into a Query structure. + * + * We could, in theory, allow query strings to be complicated + * nested expressions with precedence determined by parentheses. + * But none of the major search engines do this. (Perhaps the + * feeling is that an parenthesized expression is two complex of + * an idea for the average user to grasp.) Taking our lead from + * the major search engines, we will allow queries to be a list + * of terms (with an implied AND operator) or phrases in double-quotes, + * with a single optional "-" before each non-phrase term to designate + * negation and an optional OR connector. + * + * OR binds more tightly than the implied AND, which is what the + * major search engines seem to do. So, for example: + * + * [one two OR three] ==> one AND (two OR three) + * [one OR two three] ==> (one OR two) AND three + * + * A "-" before a term matches all entries that lack that term. + * The "-" must occur immediately before the term with in intervening + * space. This is how the search engines do it. + * + * A NOT term cannot be the right-hand operand of an OR. If this + * occurs in the query string, the NOT is ignored: + * + * [one OR -two] ==> one OR two + * + */ +typedef struct Query { + fulltext_vtab *pFts; /* The full text index */ + int nTerms; /* Number of terms in the query */ + QueryTerm *pTerms; /* Array of terms. Space obtained from malloc() */ + int nextIsOr; /* Set the isOr flag on the next inserted term */ + int nextIsNear; /* Set the isOr flag on the next inserted term */ + int nextColumn; /* Next word parsed must be in this column */ + int dfltColumn; /* The default column */ +} Query; + + +/* +** An instance of the following structure keeps track of generated +** matching-word offset information and snippets. +*/ +typedef struct Snippet { + int nMatch; /* Total number of matches */ + int nAlloc; /* Space allocated for aMatch[] */ + struct snippetMatch { /* One entry for each matching term */ + char snStatus; /* Status flag for use while constructing snippets */ + short int iCol; /* The column that contains the match */ + short int iTerm; /* The index in Query.pTerms[] of the matching term */ + int iToken; /* The index of the matching document token */ + short int nByte; /* Number of bytes in the term */ + int iStart; /* The offset to the first character of the term */ + } *aMatch; /* Points to space obtained from malloc */ + char *zOffset; /* Text rendering of aMatch[] */ + int nOffset; /* strlen(zOffset) */ + char *zSnippet; /* Snippet text */ + int nSnippet; /* strlen(zSnippet) */ +} Snippet; + + +typedef enum QueryType { + QUERY_GENERIC, /* table scan */ + QUERY_DOCID, /* lookup by docid */ + QUERY_FULLTEXT /* QUERY_FULLTEXT + [i] is a full-text search for column i*/ +} QueryType; + +typedef enum fulltext_statement { + CONTENT_INSERT_STMT, + CONTENT_SELECT_STMT, + CONTENT_UPDATE_STMT, + CONTENT_DELETE_STMT, + + BLOCK_INSERT_STMT, + BLOCK_SELECT_STMT, + BLOCK_DELETE_STMT, + + SEGDIR_MAX_INDEX_STMT, + SEGDIR_SET_STMT, + SEGDIR_SELECT_STMT, + SEGDIR_SPAN_STMT, + SEGDIR_DELETE_STMT, + SEGDIR_SELECT_ALL_STMT, + + MAX_STMT /* Always at end! */ +} fulltext_statement; + +/* These must exactly match the enum above. */ +/* TODO(shess): Is there some risk that a statement will be used in two +** cursors at once, e.g. if a query joins a virtual table to itself? +** If so perhaps we should move some of these to the cursor object. +*/ +static const char *const fulltext_zStatement[MAX_STMT] = { + /* CONTENT_INSERT */ NULL, /* generated in contentInsertStatement() */ + /* CONTENT_SELECT */ NULL, /* generated in contentSelectStatement() */ + /* CONTENT_UPDATE */ NULL, /* generated in contentUpdateStatement() */ + /* CONTENT_DELETE */ "delete from %_content where docid = ?", + + /* BLOCK_INSERT */ + "insert into %_segments (blockid, block) values (null, ?)", + /* BLOCK_SELECT */ "select block from %_segments where blockid = ?", + /* BLOCK_DELETE */ "delete from %_segments where blockid between ? and ?", + + /* SEGDIR_MAX_INDEX */ "select max(idx) from %_segdir where level = ?", + /* SEGDIR_SET */ "insert into %_segdir values (?, ?, ?, ?, ?, ?)", + /* SEGDIR_SELECT */ + "select start_block, leaves_end_block, root from %_segdir " + " where level = ? order by idx", + /* SEGDIR_SPAN */ + "select min(start_block), max(end_block) from %_segdir " + " where level = ? and start_block <> 0", + /* SEGDIR_DELETE */ "delete from %_segdir where level = ?", + /* SEGDIR_SELECT_ALL */ + "select root, leaves_end_block from %_segdir order by level desc, idx", +}; + +/* +** A connection to a fulltext index is an instance of the following +** structure. The xCreate and xConnect methods create an instance +** of this structure and xDestroy and xDisconnect free that instance. +** All other methods receive a pointer to the structure as one of their +** arguments. +*/ +struct fulltext_vtab { + sqlite3_vtab base; /* Base class used by SQLite core */ + sqlite3 *db; /* The database connection */ + const char *zDb; /* logical database name */ + const char *zName; /* virtual table name */ + int nColumn; /* number of columns in virtual table */ + char **azColumn; /* column names. malloced */ + char **azContentColumn; /* column names in content table; malloced */ + sqlite3_tokenizer *pTokenizer; /* tokenizer for inserts and queries */ + + /* Precompiled statements which we keep as long as the table is + ** open. + */ + sqlite3_stmt *pFulltextStatements[MAX_STMT]; + + /* Precompiled statements used for segment merges. We run a + ** separate select across the leaf level of each tree being merged. + */ + sqlite3_stmt *pLeafSelectStmts[MERGE_COUNT]; + /* The statement used to prepare pLeafSelectStmts. */ +#define LEAF_SELECT \ + "select block from %_segments where blockid between ? and ? order by blockid" + + /* These buffer pending index updates during transactions. + ** nPendingData estimates the memory size of the pending data. It + ** doesn't include the hash-bucket overhead, nor any malloc + ** overhead. When nPendingData exceeds kPendingThreshold, the + ** buffer is flushed even before the transaction closes. + ** pendingTerms stores the data, and is only valid when nPendingData + ** is >=0 (nPendingData<0 means pendingTerms has not been + ** initialized). iPrevDocid is the last docid written, used to make + ** certain we're inserting in sorted order. + */ + int nPendingData; +#define kPendingThreshold (1*1024*1024) + sqlite_int64 iPrevDocid; + fts3Hash pendingTerms; +}; + +/* +** When the core wants to do a query, it create a cursor using a +** call to xOpen. This structure is an instance of a cursor. It +** is destroyed by xClose. +*/ +typedef struct fulltext_cursor { + sqlite3_vtab_cursor base; /* Base class used by SQLite core */ + QueryType iCursorType; /* Copy of sqlite3_index_info.idxNum */ + sqlite3_stmt *pStmt; /* Prepared statement in use by the cursor */ + int eof; /* True if at End Of Results */ + Query q; /* Parsed query string */ + Snippet snippet; /* Cached snippet for the current row */ + int iColumn; /* Column being searched */ + DataBuffer result; /* Doclist results from fulltextQuery */ + DLReader reader; /* Result reader if result not empty */ +} fulltext_cursor; + +static struct fulltext_vtab *cursor_vtab(fulltext_cursor *c){ + return (fulltext_vtab *) c->base.pVtab; +} + +static const sqlite3_module fts3Module; /* forward declaration */ + +/* Return a dynamically generated statement of the form + * insert into %_content (docid, ...) values (?, ...) + */ +static const char *contentInsertStatement(fulltext_vtab *v){ + StringBuffer sb; + int i; + + initStringBuffer(&sb); + append(&sb, "insert into %_content (docid, "); + appendList(&sb, v->nColumn, v->azContentColumn); + append(&sb, ") values (?"); + for(i=0; i<v->nColumn; ++i) + append(&sb, ", ?"); + append(&sb, ")"); + return stringBufferData(&sb); +} + +/* Return a dynamically generated statement of the form + * select <content columns> from %_content where docid = ? + */ +static const char *contentSelectStatement(fulltext_vtab *v){ + StringBuffer sb; + initStringBuffer(&sb); + append(&sb, "SELECT "); + appendList(&sb, v->nColumn, v->azContentColumn); + append(&sb, " FROM %_content WHERE docid = ?"); + return stringBufferData(&sb); +} + +/* Return a dynamically generated statement of the form + * update %_content set [col_0] = ?, [col_1] = ?, ... + * where docid = ? + */ +static const char *contentUpdateStatement(fulltext_vtab *v){ + StringBuffer sb; + int i; + + initStringBuffer(&sb); + append(&sb, "update %_content set "); + for(i=0; i<v->nColumn; ++i) { + if( i>0 ){ + append(&sb, ", "); + } + append(&sb, v->azContentColumn[i]); + append(&sb, " = ?"); + } + append(&sb, " where docid = ?"); + return stringBufferData(&sb); +} + +/* Puts a freshly-prepared statement determined by iStmt in *ppStmt. +** If the indicated statement has never been prepared, it is prepared +** and cached, otherwise the cached version is reset. +*/ +static int sql_get_statement(fulltext_vtab *v, fulltext_statement iStmt, + sqlite3_stmt **ppStmt){ + assert( iStmt<MAX_STMT ); + if( v->pFulltextStatements[iStmt]==NULL ){ + const char *zStmt; + int rc; + switch( iStmt ){ + case CONTENT_INSERT_STMT: + zStmt = contentInsertStatement(v); break; + case CONTENT_SELECT_STMT: + zStmt = contentSelectStatement(v); break; + case CONTENT_UPDATE_STMT: + zStmt = contentUpdateStatement(v); break; + default: + zStmt = fulltext_zStatement[iStmt]; + } + rc = sql_prepare(v->db, v->zDb, v->zName, &v->pFulltextStatements[iStmt], + zStmt); + if( zStmt != fulltext_zStatement[iStmt]) sqlite3_free((void *) zStmt); + if( rc!=SQLITE_OK ) return rc; + } else { + int rc = sqlite3_reset(v->pFulltextStatements[iStmt]); + if( rc!=SQLITE_OK ) return rc; + } + + *ppStmt = v->pFulltextStatements[iStmt]; + return SQLITE_OK; +} + +/* Like sqlite3_step(), but convert SQLITE_DONE to SQLITE_OK and +** SQLITE_ROW to SQLITE_ERROR. Useful for statements like UPDATE, +** where we expect no results. +*/ +static int sql_single_step(sqlite3_stmt *s){ + int rc = sqlite3_step(s); + return (rc==SQLITE_DONE) ? SQLITE_OK : rc; +} + +/* Like sql_get_statement(), but for special replicated LEAF_SELECT +** statements. +*/ +/* TODO(shess) Write version for generic statements and then share +** that between the cached-statement functions. +*/ +static int sql_get_leaf_statement(fulltext_vtab *v, int idx, + sqlite3_stmt **ppStmt){ + assert( idx>=0 && idx<MERGE_COUNT ); + if( v->pLeafSelectStmts[idx]==NULL ){ + int rc = sql_prepare(v->db, v->zDb, v->zName, &v->pLeafSelectStmts[idx], + LEAF_SELECT); + if( rc!=SQLITE_OK ) return rc; + }else{ + int rc = sqlite3_reset(v->pLeafSelectStmts[idx]); + if( rc!=SQLITE_OK ) return rc; + } + + *ppStmt = v->pLeafSelectStmts[idx]; + return SQLITE_OK; +} + +/* insert into %_content (docid, ...) values ([docid], [pValues]) +** If the docid contains SQL NULL, then a unique docid will be +** generated. +*/ +static int content_insert(fulltext_vtab *v, sqlite3_value *docid, + sqlite3_value **pValues){ + sqlite3_stmt *s; + int i; + int rc = sql_get_statement(v, CONTENT_INSERT_STMT, &s); + if( rc!=SQLITE_OK ) return rc; + + rc = sqlite3_bind_value(s, 1, docid); + if( rc!=SQLITE_OK ) return rc; + + for(i=0; i<v->nColumn; ++i){ + rc = sqlite3_bind_value(s, 2+i, pValues[i]); + if( rc!=SQLITE_OK ) return rc; + } + + return sql_single_step(s); +} + +/* update %_content set col0 = pValues[0], col1 = pValues[1], ... + * where docid = [iDocid] */ +static int content_update(fulltext_vtab *v, sqlite3_value **pValues, + sqlite_int64 iDocid){ + sqlite3_stmt *s; + int i; + int rc = sql_get_statement(v, CONTENT_UPDATE_STMT, &s); + if( rc!=SQLITE_OK ) return rc; + + for(i=0; i<v->nColumn; ++i){ + rc = sqlite3_bind_value(s, 1+i, pValues[i]); + if( rc!=SQLITE_OK ) return rc; + } + + rc = sqlite3_bind_int64(s, 1+v->nColumn, iDocid); + if( rc!=SQLITE_OK ) return rc; + + return sql_single_step(s); +} + +static void freeStringArray(int nString, const char **pString){ + int i; + + for (i=0 ; i < nString ; ++i) { + if( pString[i]!=NULL ) sqlite3_free((void *) pString[i]); + } + sqlite3_free((void *) pString); +} + +/* select * from %_content where docid = [iDocid] + * The caller must delete the returned array and all strings in it. + * null fields will be NULL in the returned array. + * + * TODO: Perhaps we should return pointer/length strings here for consistency + * with other code which uses pointer/length. */ +static int content_select(fulltext_vtab *v, sqlite_int64 iDocid, + const char ***pValues){ + sqlite3_stmt *s; + const char **values; + int i; + int rc; + + *pValues = NULL; + + rc = sql_get_statement(v, CONTENT_SELECT_STMT, &s); + if( rc!=SQLITE_OK ) return rc; + + rc = sqlite3_bind_int64(s, 1, iDocid); + if( rc!=SQLITE_OK ) return rc; + + rc = sqlite3_step(s); + if( rc!=SQLITE_ROW ) return rc; + + values = (const char **) sqlite3_malloc(v->nColumn * sizeof(const char *)); + for(i=0; i<v->nColumn; ++i){ + if( sqlite3_column_type(s, i)==SQLITE_NULL ){ + values[i] = NULL; + }else{ + values[i] = string_dup((char*)sqlite3_column_text(s, i)); + } + } + + /* We expect only one row. We must execute another sqlite3_step() + * to complete the iteration; otherwise the table will remain locked. */ + rc = sqlite3_step(s); + if( rc==SQLITE_DONE ){ + *pValues = values; + return SQLITE_OK; + } + + freeStringArray(v->nColumn, values); + return rc; +} + +/* delete from %_content where docid = [iDocid ] */ +static int content_delete(fulltext_vtab *v, sqlite_int64 iDocid){ + sqlite3_stmt *s; + int rc = sql_get_statement(v, CONTENT_DELETE_STMT, &s); + if( rc!=SQLITE_OK ) return rc; + + rc = sqlite3_bind_int64(s, 1, iDocid); + if( rc!=SQLITE_OK ) return rc; + + return sql_single_step(s); +} + +/* insert into %_segments values ([pData]) +** returns assigned blockid in *piBlockid +*/ +static int block_insert(fulltext_vtab *v, const char *pData, int nData, + sqlite_int64 *piBlockid){ + sqlite3_stmt *s; + int rc = sql_get_statement(v, BLOCK_INSERT_STMT, &s); + if( rc!=SQLITE_OK ) return rc; + + rc = sqlite3_bind_blob(s, 1, pData, nData, SQLITE_STATIC); + if( rc!=SQLITE_OK ) return rc; + + rc = sqlite3_step(s); + if( rc==SQLITE_ROW ) return SQLITE_ERROR; + if( rc!=SQLITE_DONE ) return rc; + + /* blockid column is an alias for rowid. */ + *piBlockid = sqlite3_last_insert_rowid(v->db); + return SQLITE_OK; +} + +/* delete from %_segments +** where blockid between [iStartBlockid] and [iEndBlockid] +** +** Deletes the range of blocks, inclusive, used to delete the blocks +** which form a segment. +*/ +static int block_delete(fulltext_vtab *v, + sqlite_int64 iStartBlockid, sqlite_int64 iEndBlockid){ + sqlite3_stmt *s; + int rc = sql_get_statement(v, BLOCK_DELETE_STMT, &s); + if( rc!=SQLITE_OK ) return rc; + + rc = sqlite3_bind_int64(s, 1, iStartBlockid); + if( rc!=SQLITE_OK ) return rc; + + rc = sqlite3_bind_int64(s, 2, iEndBlockid); + if( rc!=SQLITE_OK ) return rc; + + return sql_single_step(s); +} + +/* Returns SQLITE_ROW with *pidx set to the maximum segment idx found +** at iLevel. Returns SQLITE_DONE if there are no segments at +** iLevel. Otherwise returns an error. +*/ +static int segdir_max_index(fulltext_vtab *v, int iLevel, int *pidx){ + sqlite3_stmt *s; + int rc = sql_get_statement(v, SEGDIR_MAX_INDEX_STMT, &s); + if( rc!=SQLITE_OK ) return rc; + + rc = sqlite3_bind_int(s, 1, iLevel); + if( rc!=SQLITE_OK ) return rc; + + rc = sqlite3_step(s); + /* Should always get at least one row due to how max() works. */ + if( rc==SQLITE_DONE ) return SQLITE_DONE; + if( rc!=SQLITE_ROW ) return rc; + + /* NULL means that there were no inputs to max(). */ + if( SQLITE_NULL==sqlite3_column_type(s, 0) ){ + rc = sqlite3_step(s); + if( rc==SQLITE_ROW ) return SQLITE_ERROR; + return rc; + } + + *pidx = sqlite3_column_int(s, 0); + + /* We expect only one row. We must execute another sqlite3_step() + * to complete the iteration; otherwise the table will remain locked. */ + rc = sqlite3_step(s); + if( rc==SQLITE_ROW ) return SQLITE_ERROR; + if( rc!=SQLITE_DONE ) return rc; + return SQLITE_ROW; +} + +/* insert into %_segdir values ( +** [iLevel], [idx], +** [iStartBlockid], [iLeavesEndBlockid], [iEndBlockid], +** [pRootData] +** ) +*/ +static int segdir_set(fulltext_vtab *v, int iLevel, int idx, + sqlite_int64 iStartBlockid, + sqlite_int64 iLeavesEndBlockid, + sqlite_int64 iEndBlockid, + const char *pRootData, int nRootData){ + sqlite3_stmt *s; + int rc = sql_get_statement(v, SEGDIR_SET_STMT, &s); + if( rc!=SQLITE_OK ) return rc; + + rc = sqlite3_bind_int(s, 1, iLevel); + if( rc!=SQLITE_OK ) return rc; + + rc = sqlite3_bind_int(s, 2, idx); + if( rc!=SQLITE_OK ) return rc; + + rc = sqlite3_bind_int64(s, 3, iStartBlockid); + if( rc!=SQLITE_OK ) return rc; + + rc = sqlite3_bind_int64(s, 4, iLeavesEndBlockid); + if( rc!=SQLITE_OK ) return rc; + + rc = sqlite3_bind_int64(s, 5, iEndBlockid); + if( rc!=SQLITE_OK ) return rc; + + rc = sqlite3_bind_blob(s, 6, pRootData, nRootData, SQLITE_STATIC); + if( rc!=SQLITE_OK ) return rc; + + return sql_single_step(s); +} + +/* Queries %_segdir for the block span of the segments in level +** iLevel. Returns SQLITE_DONE if there are no blocks for iLevel, +** SQLITE_ROW if there are blocks, else an error. +*/ +static int segdir_span(fulltext_vtab *v, int iLevel, + sqlite_int64 *piStartBlockid, + sqlite_int64 *piEndBlockid){ + sqlite3_stmt *s; + int rc = sql_get_statement(v, SEGDIR_SPAN_STMT, &s); + if( rc!=SQLITE_OK ) return rc; + + rc = sqlite3_bind_int(s, 1, iLevel); + if( rc!=SQLITE_OK ) return rc; + + rc = sqlite3_step(s); + if( rc==SQLITE_DONE ) return SQLITE_DONE; /* Should never happen */ + if( rc!=SQLITE_ROW ) return rc; + + /* This happens if all segments at this level are entirely inline. */ + if( SQLITE_NULL==sqlite3_column_type(s, 0) ){ + /* We expect only one row. We must execute another sqlite3_step() + * to complete the iteration; otherwise the table will remain locked. */ + int rc2 = sqlite3_step(s); + if( rc2==SQLITE_ROW ) return SQLITE_ERROR; + return rc2; + } + + *piStartBlockid = sqlite3_column_int64(s, 0); + *piEndBlockid = sqlite3_column_int64(s, 1); + + /* We expect only one row. We must execute another sqlite3_step() + * to complete the iteration; otherwise the table will remain locked. */ + rc = sqlite3_step(s); + if( rc==SQLITE_ROW ) return SQLITE_ERROR; + if( rc!=SQLITE_DONE ) return rc; + return SQLITE_ROW; +} + +/* Delete the segment blocks and segment directory records for all +** segments at iLevel. +*/ +static int segdir_delete(fulltext_vtab *v, int iLevel){ + sqlite3_stmt *s; + sqlite_int64 iStartBlockid, iEndBlockid; + int rc = segdir_span(v, iLevel, &iStartBlockid, &iEndBlockid); + if( rc!=SQLITE_ROW && rc!=SQLITE_DONE ) return rc; + + if( rc==SQLITE_ROW ){ + rc = block_delete(v, iStartBlockid, iEndBlockid); + if( rc!=SQLITE_OK ) return rc; + } + + /* Delete the segment directory itself. */ + rc = sql_get_statement(v, SEGDIR_DELETE_STMT, &s); + if( rc!=SQLITE_OK ) return rc; + + rc = sqlite3_bind_int64(s, 1, iLevel); + if( rc!=SQLITE_OK ) return rc; + + return sql_single_step(s); +} + +/* TODO(shess) clearPendingTerms() is far down the file because +** writeZeroSegment() is far down the file because LeafWriter is far +** down the file. Consider refactoring the code to move the non-vtab +** code above the vtab code so that we don't need this forward +** reference. +*/ +static int clearPendingTerms(fulltext_vtab *v); + +/* +** Free the memory used to contain a fulltext_vtab structure. +*/ +static void fulltext_vtab_destroy(fulltext_vtab *v){ + int iStmt, i; + + FTSTRACE(("FTS3 Destroy %p\n", v)); + for( iStmt=0; iStmt<MAX_STMT; iStmt++ ){ + if( v->pFulltextStatements[iStmt]!=NULL ){ + sqlite3_finalize(v->pFulltextStatements[iStmt]); + v->pFulltextStatements[iStmt] = NULL; + } + } + + for( i=0; i<MERGE_COUNT; i++ ){ + if( v->pLeafSelectStmts[i]!=NULL ){ + sqlite3_finalize(v->pLeafSelectStmts[i]); + v->pLeafSelectStmts[i] = NULL; + } + } + + if( v->pTokenizer!=NULL ){ + v->pTokenizer->pModule->xDestroy(v->pTokenizer); + v->pTokenizer = NULL; + } + + clearPendingTerms(v); + + sqlite3_free(v->azColumn); + for(i = 0; i < v->nColumn; ++i) { + sqlite3_free(v->azContentColumn[i]); + } + sqlite3_free(v->azContentColumn); + sqlite3_free(v); +} + +/* +** Token types for parsing the arguments to xConnect or xCreate. +*/ +#define TOKEN_EOF 0 /* End of file */ +#define TOKEN_SPACE 1 /* Any kind of whitespace */ +#define TOKEN_ID 2 /* An identifier */ +#define TOKEN_STRING 3 /* A string literal */ +#define TOKEN_PUNCT 4 /* A single punctuation character */ + +/* +** If X is a character that can be used in an identifier then +** ftsIdChar(X) will be true. Otherwise it is false. +** +** For ASCII, any character with the high-order bit set is +** allowed in an identifier. For 7-bit characters, +** isFtsIdChar[X] must be 1. +** +** Ticket #1066. the SQL standard does not allow '$' in the +** middle of identfiers. But many SQL implementations do. +** SQLite will allow '$' in identifiers for compatibility. +** But the feature is undocumented. +*/ +static const char isFtsIdChar[] = { +/* x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xA xB xC xD xE xF */ + 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 2x */ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, /* 3x */ + 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 4x */ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, /* 5x */ + 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 6x */ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, /* 7x */ +}; +#define ftsIdChar(C) (((c=C)&0x80)!=0 || (c>0x1f && isFtsIdChar[c-0x20])) + + +/* +** Return the length of the token that begins at z[0]. +** Store the token type in *tokenType before returning. +*/ +static int ftsGetToken(const char *z, int *tokenType){ + int i, c; + switch( *z ){ + case 0: { + *tokenType = TOKEN_EOF; + return 0; + } + case ' ': case '\t': case '\n': case '\f': case '\r': { + for(i=1; safe_isspace(z[i]); i++){} + *tokenType = TOKEN_SPACE; + return i; + } + case '`': + case '\'': + case '"': { + int delim = z[0]; + for(i=1; (c=z[i])!=0; i++){ + if( c==delim ){ + if( z[i+1]==delim ){ + i++; + }else{ + break; + } + } + } + *tokenType = TOKEN_STRING; + return i + (c!=0); + } + case '[': { + for(i=1, c=z[0]; c!=']' && (c=z[i])!=0; i++){} + *tokenType = TOKEN_ID; + return i; + } + default: { + if( !ftsIdChar(*z) ){ + break; + } + for(i=1; ftsIdChar(z[i]); i++){} + *tokenType = TOKEN_ID; + return i; + } + } + *tokenType = TOKEN_PUNCT; + return 1; +} + +/* +** A token extracted from a string is an instance of the following +** structure. +*/ +typedef struct FtsToken { + const char *z; /* Pointer to token text. Not '\000' terminated */ + short int n; /* Length of the token text in bytes. */ +} FtsToken; + +/* +** Given a input string (which is really one of the argv[] parameters +** passed into xConnect or xCreate) split the string up into tokens. +** Return an array of pointers to '\000' terminated strings, one string +** for each non-whitespace token. +** +** The returned array is terminated by a single NULL pointer. +** +** Space to hold the returned array is obtained from a single +** malloc and should be freed by passing the return value to free(). +** The individual strings within the token list are all a part of +** the single memory allocation and will all be freed at once. +*/ +static char **tokenizeString(const char *z, int *pnToken){ + int nToken = 0; + FtsToken *aToken = sqlite3_malloc( strlen(z) * sizeof(aToken[0]) ); + int n = 1; + int e, i; + int totalSize = 0; + char **azToken; + char *zCopy; + while( n>0 ){ + n = ftsGetToken(z, &e); + if( e!=TOKEN_SPACE ){ + aToken[nToken].z = z; + aToken[nToken].n = n; + nToken++; + totalSize += n+1; + } + z += n; + } + azToken = (char**)sqlite3_malloc( nToken*sizeof(char*) + totalSize ); + zCopy = (char*)&azToken[nToken]; + nToken--; + for(i=0; i<nToken; i++){ + azToken[i] = zCopy; + n = aToken[i].n; + memcpy(zCopy, aToken[i].z, n); + zCopy[n] = 0; + zCopy += n+1; + } + azToken[nToken] = 0; + sqlite3_free(aToken); + *pnToken = nToken; + return azToken; +} + +/* +** Convert an SQL-style quoted string into a normal string by removing +** the quote characters. The conversion is done in-place. If the +** input does not begin with a quote character, then this routine +** is a no-op. +** +** Examples: +** +** "abc" becomes abc +** 'xyz' becomes xyz +** [pqr] becomes pqr +** `mno` becomes mno +*/ +static void dequoteString(char *z){ + int quote; + int i, j; + if( z==0 ) return; + quote = z[0]; + switch( quote ){ + case '\'': break; + case '"': break; + case '`': break; /* For MySQL compatibility */ + case '[': quote = ']'; break; /* For MS SqlServer compatibility */ + default: return; + } + for(i=1, j=0; z[i]; i++){ + if( z[i]==quote ){ + if( z[i+1]==quote ){ + z[j++] = quote; + i++; + }else{ + z[j++] = 0; + break; + } + }else{ + z[j++] = z[i]; + } + } +} + +/* +** The input azIn is a NULL-terminated list of tokens. Remove the first +** token and all punctuation tokens. Remove the quotes from +** around string literal tokens. +** +** Example: +** +** input: tokenize chinese ( 'simplifed' , 'mixed' ) +** output: chinese simplifed mixed +** +** Another example: +** +** input: delimiters ( '[' , ']' , '...' ) +** output: [ ] ... +*/ +static void tokenListToIdList(char **azIn){ + int i, j; + if( azIn ){ + for(i=0, j=-1; azIn[i]; i++){ + if( safe_isalnum(azIn[i][0]) || azIn[i][1] ){ + dequoteString(azIn[i]); + if( j>=0 ){ + azIn[j] = azIn[i]; + } + j++; + } + } + azIn[j] = 0; + } +} + + +/* +** Find the first alphanumeric token in the string zIn. Null-terminate +** this token. Remove any quotation marks. And return a pointer to +** the result. +*/ +static char *firstToken(char *zIn, char **pzTail){ + int n, ttype; + while(1){ + n = ftsGetToken(zIn, &ttype); + if( ttype==TOKEN_SPACE ){ + zIn += n; + }else if( ttype==TOKEN_EOF ){ + *pzTail = zIn; + return 0; + }else{ + zIn[n] = 0; + *pzTail = &zIn[1]; + dequoteString(zIn); + return zIn; + } + } + /*NOTREACHED*/ +} + +/* Return true if... +** +** * s begins with the string t, ignoring case +** * s is longer than t +** * The first character of s beyond t is not a alphanumeric +** +** Ignore leading space in *s. +** +** To put it another way, return true if the first token of +** s[] is t[]. +*/ +static int startsWith(const char *s, const char *t){ + while( safe_isspace(*s) ){ s++; } + while( *t ){ + if( safe_tolower(*s++)!=safe_tolower(*t++) ) return 0; + } + return *s!='_' && !safe_isalnum(*s); +} + +/* +** An instance of this structure defines the "spec" of a +** full text index. This structure is populated by parseSpec +** and use by fulltextConnect and fulltextCreate. +*/ +typedef struct TableSpec { + const char *zDb; /* Logical database name */ + const char *zName; /* Name of the full-text index */ + int nColumn; /* Number of columns to be indexed */ + char **azColumn; /* Original names of columns to be indexed */ + char **azContentColumn; /* Column names for %_content */ + char **azTokenizer; /* Name of tokenizer and its arguments */ +} TableSpec; + +/* +** Reclaim all of the memory used by a TableSpec +*/ +static void clearTableSpec(TableSpec *p) { + sqlite3_free(p->azColumn); + sqlite3_free(p->azContentColumn); + sqlite3_free(p->azTokenizer); +} + +/* Parse a CREATE VIRTUAL TABLE statement, which looks like this: + * + * CREATE VIRTUAL TABLE email + * USING fts3(subject, body, tokenize mytokenizer(myarg)) + * + * We return parsed information in a TableSpec structure. + * + */ +static int parseSpec(TableSpec *pSpec, int argc, const char *const*argv, + char**pzErr){ + int i, n; + char *z, *zDummy; + char **azArg; + const char *zTokenizer = 0; /* argv[] entry describing the tokenizer */ + + assert( argc>=3 ); + /* Current interface: + ** argv[0] - module name + ** argv[1] - database name + ** argv[2] - table name + ** argv[3..] - columns, optionally followed by tokenizer specification + ** and snippet delimiters specification. + */ + + /* Make a copy of the complete argv[][] array in a single allocation. + ** The argv[][] array is read-only and transient. We can write to the + ** copy in order to modify things and the copy is persistent. + */ + CLEAR(pSpec); + for(i=n=0; i<argc; i++){ + n += strlen(argv[i]) + 1; + } + azArg = sqlite3_malloc( sizeof(char*)*argc + n ); + if( azArg==0 ){ + return SQLITE_NOMEM; + } + z = (char*)&azArg[argc]; + for(i=0; i<argc; i++){ + azArg[i] = z; + strcpy(z, argv[i]); + z += strlen(z)+1; + } + + /* Identify the column names and the tokenizer and delimiter arguments + ** in the argv[][] array. + */ + pSpec->zDb = azArg[1]; + pSpec->zName = azArg[2]; + pSpec->nColumn = 0; + pSpec->azColumn = azArg; + zTokenizer = "tokenize simple"; + for(i=3; i<argc; ++i){ + if( startsWith(azArg[i],"tokenize") ){ + zTokenizer = azArg[i]; + }else{ + z = azArg[pSpec->nColumn] = firstToken(azArg[i], &zDummy); + pSpec->nColumn++; + } + } + if( pSpec->nColumn==0 ){ + azArg[0] = "content"; + pSpec->nColumn = 1; + } + + /* + ** Construct the list of content column names. + ** + ** Each content column name will be of the form cNNAAAA + ** where NN is the column number and AAAA is the sanitized + ** column name. "sanitized" means that special characters are + ** converted to "_". The cNN prefix guarantees that all column + ** names are unique. + ** + ** The AAAA suffix is not strictly necessary. It is included + ** for the convenience of people who might examine the generated + ** %_content table and wonder what the columns are used for. + */ + pSpec->azContentColumn = sqlite3_malloc( pSpec->nColumn * sizeof(char *) ); + if( pSpec->azContentColumn==0 ){ + clearTableSpec(pSpec); + return SQLITE_NOMEM; + } + for(i=0; i<pSpec->nColumn; i++){ + char *p; + pSpec->azContentColumn[i] = sqlite3_mprintf("c%d%s", i, azArg[i]); + for (p = pSpec->azContentColumn[i]; *p ; ++p) { + if( !safe_isalnum(*p) ) *p = '_'; + } + } + + /* + ** Parse the tokenizer specification string. + */ + pSpec->azTokenizer = tokenizeString(zTokenizer, &n); + tokenListToIdList(pSpec->azTokenizer); + + return SQLITE_OK; +} + +/* +** Generate a CREATE TABLE statement that describes the schema of +** the virtual table. Return a pointer to this schema string. +** +** Space is obtained from sqlite3_mprintf() and should be freed +** using sqlite3_free(). +*/ +static char *fulltextSchema( + int nColumn, /* Number of columns */ + const char *const* azColumn, /* List of columns */ + const char *zTableName /* Name of the table */ +){ + int i; + char *zSchema, *zNext; + const char *zSep = "("; + zSchema = sqlite3_mprintf("CREATE TABLE x"); + for(i=0; i<nColumn; i++){ + zNext = sqlite3_mprintf("%s%s%Q", zSchema, zSep, azColumn[i]); + sqlite3_free(zSchema); + zSchema = zNext; + zSep = ","; + } + zNext = sqlite3_mprintf("%s,%Q HIDDEN", zSchema, zTableName); + sqlite3_free(zSchema); + zSchema = zNext; + zNext = sqlite3_mprintf("%s,docid HIDDEN)", zSchema); + sqlite3_free(zSchema); + return zNext; +} + +/* +** Build a new sqlite3_vtab structure that will describe the +** fulltext index defined by spec. +*/ +static int constructVtab( + sqlite3 *db, /* The SQLite database connection */ + fts3Hash *pHash, /* Hash table containing tokenizers */ + TableSpec *spec, /* Parsed spec information from parseSpec() */ + sqlite3_vtab **ppVTab, /* Write the resulting vtab structure here */ + char **pzErr /* Write any error message here */ +){ + int rc; + int n; + fulltext_vtab *v = 0; + const sqlite3_tokenizer_module *m = NULL; + char *schema; + + char const *zTok; /* Name of tokenizer to use for this fts table */ + int nTok; /* Length of zTok, including nul terminator */ + + v = (fulltext_vtab *) sqlite3_malloc(sizeof(fulltext_vtab)); + if( v==0 ) return SQLITE_NOMEM; + CLEAR(v); + /* sqlite will initialize v->base */ + v->db = db; + v->zDb = spec->zDb; /* Freed when azColumn is freed */ + v->zName = spec->zName; /* Freed when azColumn is freed */ + v->nColumn = spec->nColumn; + v->azContentColumn = spec->azContentColumn; + spec->azContentColumn = 0; + v->azColumn = spec->azColumn; + spec->azColumn = 0; + + if( spec->azTokenizer==0 ){ + return SQLITE_NOMEM; + } + + zTok = spec->azTokenizer[0]; + if( !zTok ){ + zTok = "simple"; + } + nTok = strlen(zTok)+1; + + m = (sqlite3_tokenizer_module *)sqlite3Fts3HashFind(pHash, zTok, nTok); + if( !m ){ + *pzErr = sqlite3_mprintf("unknown tokenizer: %s", spec->azTokenizer[0]); + rc = SQLITE_ERROR; + goto err; + } + + for(n=0; spec->azTokenizer[n]; n++){} + if( n ){ + rc = m->xCreate(n-1, (const char*const*)&spec->azTokenizer[1], + &v->pTokenizer); + }else{ + rc = m->xCreate(0, 0, &v->pTokenizer); + } + if( rc!=SQLITE_OK ) goto err; + v->pTokenizer->pModule = m; + + /* TODO: verify the existence of backing tables foo_content, foo_term */ + + schema = fulltextSchema(v->nColumn, (const char*const*)v->azColumn, + spec->zName); + rc = sqlite3_declare_vtab(db, schema); + sqlite3_free(schema); + if( rc!=SQLITE_OK ) goto err; + + memset(v->pFulltextStatements, 0, sizeof(v->pFulltextStatements)); + + /* Indicate that the buffer is not live. */ + v->nPendingData = -1; + + *ppVTab = &v->base; + FTSTRACE(("FTS3 Connect %p\n", v)); + + return rc; + +err: + fulltext_vtab_destroy(v); + return rc; +} + +static int fulltextConnect( + sqlite3 *db, + void *pAux, + int argc, const char *const*argv, + sqlite3_vtab **ppVTab, + char **pzErr +){ + TableSpec spec; + int rc = parseSpec(&spec, argc, argv, pzErr); + if( rc!=SQLITE_OK ) return rc; + + rc = constructVtab(db, (fts3Hash *)pAux, &spec, ppVTab, pzErr); + clearTableSpec(&spec); + return rc; +} + +/* The %_content table holds the text of each document, with +** the docid column exposed as the SQLite rowid for the table. +*/ +/* TODO(shess) This comment needs elaboration to match the updated +** code. Work it into the top-of-file comment at that time. +*/ +static int fulltextCreate(sqlite3 *db, void *pAux, + int argc, const char * const *argv, + sqlite3_vtab **ppVTab, char **pzErr){ + int rc; + TableSpec spec; + StringBuffer schema; + FTSTRACE(("FTS3 Create\n")); + + rc = parseSpec(&spec, argc, argv, pzErr); + if( rc!=SQLITE_OK ) return rc; + + initStringBuffer(&schema); + append(&schema, "CREATE TABLE %_content("); + append(&schema, " docid INTEGER PRIMARY KEY,"); + appendList(&schema, spec.nColumn, spec.azContentColumn); + append(&schema, ")"); + rc = sql_exec(db, spec.zDb, spec.zName, stringBufferData(&schema)); + stringBufferDestroy(&schema); + if( rc!=SQLITE_OK ) goto out; + + rc = sql_exec(db, spec.zDb, spec.zName, + "create table %_segments(" + " blockid INTEGER PRIMARY KEY," + " block blob" + ");" + ); + if( rc!=SQLITE_OK ) goto out; + + rc = sql_exec(db, spec.zDb, spec.zName, + "create table %_segdir(" + " level integer," + " idx integer," + " start_block integer," + " leaves_end_block integer," + " end_block integer," + " root blob," + " primary key(level, idx)" + ");"); + if( rc!=SQLITE_OK ) goto out; + + rc = constructVtab(db, (fts3Hash *)pAux, &spec, ppVTab, pzErr); + +out: + clearTableSpec(&spec); + return rc; +} + +/* Decide how to handle an SQL query. */ +static int fulltextBestIndex(sqlite3_vtab *pVTab, sqlite3_index_info *pInfo){ + fulltext_vtab *v = (fulltext_vtab *)pVTab; + int i; + FTSTRACE(("FTS3 BestIndex\n")); + + for(i=0; i<pInfo->nConstraint; ++i){ + const struct sqlite3_index_constraint *pConstraint; + pConstraint = &pInfo->aConstraint[i]; + if( pConstraint->usable ) { + if( (pConstraint->iColumn==-1 || pConstraint->iColumn==v->nColumn+1) && + pConstraint->op==SQLITE_INDEX_CONSTRAINT_EQ ){ + pInfo->idxNum = QUERY_DOCID; /* lookup by docid */ + FTSTRACE(("FTS3 QUERY_DOCID\n")); + } else if( pConstraint->iColumn>=0 && pConstraint->iColumn<=v->nColumn && + pConstraint->op==SQLITE_INDEX_CONSTRAINT_MATCH ){ + /* full-text search */ + pInfo->idxNum = QUERY_FULLTEXT + pConstraint->iColumn; + FTSTRACE(("FTS3 QUERY_FULLTEXT %d\n", pConstraint->iColumn)); + } else continue; + + pInfo->aConstraintUsage[i].argvIndex = 1; + pInfo->aConstraintUsage[i].omit = 1; + + /* An arbitrary value for now. + * TODO: Perhaps docid matches should be considered cheaper than + * full-text searches. */ + pInfo->estimatedCost = 1.0; + + return SQLITE_OK; + } + } + pInfo->idxNum = QUERY_GENERIC; + return SQLITE_OK; +} + +static int fulltextDisconnect(sqlite3_vtab *pVTab){ + FTSTRACE(("FTS3 Disconnect %p\n", pVTab)); + fulltext_vtab_destroy((fulltext_vtab *)pVTab); + return SQLITE_OK; +} + +static int fulltextDestroy(sqlite3_vtab *pVTab){ + fulltext_vtab *v = (fulltext_vtab *)pVTab; + int rc; + + FTSTRACE(("FTS3 Destroy %p\n", pVTab)); + rc = sql_exec(v->db, v->zDb, v->zName, + "drop table if exists %_content;" + "drop table if exists %_segments;" + "drop table if exists %_segdir;" + ); + if( rc!=SQLITE_OK ) return rc; + + fulltext_vtab_destroy((fulltext_vtab *)pVTab); + return SQLITE_OK; +} + +static int fulltextOpen(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor){ + fulltext_cursor *c; + + c = (fulltext_cursor *) sqlite3_malloc(sizeof(fulltext_cursor)); + if( c ){ + memset(c, 0, sizeof(fulltext_cursor)); + /* sqlite will initialize c->base */ + *ppCursor = &c->base; + FTSTRACE(("FTS3 Open %p: %p\n", pVTab, c)); + return SQLITE_OK; + }else{ + return SQLITE_NOMEM; + } +} + + +/* Free all of the dynamically allocated memory held by *q +*/ +static void queryClear(Query *q){ + int i; + for(i = 0; i < q->nTerms; ++i){ + sqlite3_free(q->pTerms[i].pTerm); + } + sqlite3_free(q->pTerms); + CLEAR(q); +} + +/* Free all of the dynamically allocated memory held by the +** Snippet +*/ +static void snippetClear(Snippet *p){ + sqlite3_free(p->aMatch); + sqlite3_free(p->zOffset); + sqlite3_free(p->zSnippet); + CLEAR(p); +} +/* +** Append a single entry to the p->aMatch[] log. +*/ +static void snippetAppendMatch( + Snippet *p, /* Append the entry to this snippet */ + int iCol, int iTerm, /* The column and query term */ + int iToken, /* Matching token in document */ + int iStart, int nByte /* Offset and size of the match */ +){ + int i; + struct snippetMatch *pMatch; + if( p->nMatch+1>=p->nAlloc ){ + p->nAlloc = p->nAlloc*2 + 10; + p->aMatch = sqlite3_realloc(p->aMatch, p->nAlloc*sizeof(p->aMatch[0]) ); + if( p->aMatch==0 ){ + p->nMatch = 0; + p->nAlloc = 0; + return; + } + } + i = p->nMatch++; + pMatch = &p->aMatch[i]; + pMatch->iCol = iCol; + pMatch->iTerm = iTerm; + pMatch->iToken = iToken; + pMatch->iStart = iStart; + pMatch->nByte = nByte; +} + +/* +** Sizing information for the circular buffer used in snippetOffsetsOfColumn() +*/ +#define FTS3_ROTOR_SZ (32) +#define FTS3_ROTOR_MASK (FTS3_ROTOR_SZ-1) + +/* +** Add entries to pSnippet->aMatch[] for every match that occurs against +** document zDoc[0..nDoc-1] which is stored in column iColumn. +*/ +static void snippetOffsetsOfColumn( + Query *pQuery, + Snippet *pSnippet, + int iColumn, + const char *zDoc, + int nDoc +){ + const sqlite3_tokenizer_module *pTModule; /* The tokenizer module */ + sqlite3_tokenizer *pTokenizer; /* The specific tokenizer */ + sqlite3_tokenizer_cursor *pTCursor; /* Tokenizer cursor */ + fulltext_vtab *pVtab; /* The full text index */ + int nColumn; /* Number of columns in the index */ + const QueryTerm *aTerm; /* Query string terms */ + int nTerm; /* Number of query string terms */ + int i, j; /* Loop counters */ + int rc; /* Return code */ + unsigned int match, prevMatch; /* Phrase search bitmasks */ + const char *zToken; /* Next token from the tokenizer */ + int nToken; /* Size of zToken */ + int iBegin, iEnd, iPos; /* Offsets of beginning and end */ + + /* The following variables keep a circular buffer of the last + ** few tokens */ + unsigned int iRotor = 0; /* Index of current token */ + int iRotorBegin[FTS3_ROTOR_SZ]; /* Beginning offset of token */ + int iRotorLen[FTS3_ROTOR_SZ]; /* Length of token */ + + pVtab = pQuery->pFts; + nColumn = pVtab->nColumn; + pTokenizer = pVtab->pTokenizer; + pTModule = pTokenizer->pModule; + rc = pTModule->xOpen(pTokenizer, zDoc, nDoc, &pTCursor); + if( rc ) return; + pTCursor->pTokenizer = pTokenizer; + aTerm = pQuery->pTerms; + nTerm = pQuery->nTerms; + if( nTerm>=FTS3_ROTOR_SZ ){ + nTerm = FTS3_ROTOR_SZ - 1; + } + prevMatch = 0; + while(1){ + rc = pTModule->xNext(pTCursor, &zToken, &nToken, &iBegin, &iEnd, &iPos); + if( rc ) break; + iRotorBegin[iRotor&FTS3_ROTOR_MASK] = iBegin; + iRotorLen[iRotor&FTS3_ROTOR_MASK] = iEnd-iBegin; + match = 0; + for(i=0; i<nTerm; i++){ + int iCol; + iCol = aTerm[i].iColumn; + if( iCol>=0 && iCol<nColumn && iCol!=iColumn ) continue; + if( aTerm[i].nTerm>nToken ) continue; + if( !aTerm[i].isPrefix && aTerm[i].nTerm<nToken ) continue; + assert( aTerm[i].nTerm<=nToken ); + if( memcmp(aTerm[i].pTerm, zToken, aTerm[i].nTerm) ) continue; + if( aTerm[i].iPhrase>1 && (prevMatch & (1<<i))==0 ) continue; + match |= 1<<i; + if( i==nTerm-1 || aTerm[i+1].iPhrase==1 ){ + for(j=aTerm[i].iPhrase-1; j>=0; j--){ + int k = (iRotor-j) & FTS3_ROTOR_MASK; + snippetAppendMatch(pSnippet, iColumn, i-j, iPos-j, + iRotorBegin[k], iRotorLen[k]); + } + } + } + prevMatch = match<<1; + iRotor++; + } + pTModule->xClose(pTCursor); +} + +/* +** Remove entries from the pSnippet structure to account for the NEAR +** operator. When this is called, pSnippet contains the list of token +** offsets produced by treating all NEAR operators as AND operators. +** This function removes any entries that should not be present after +** accounting for the NEAR restriction. For example, if the queried +** document is: +** +** "A B C D E A" +** +** and the query is: +** +** A NEAR/0 E +** +** then when this function is called the Snippet contains token offsets +** 0, 4 and 5. This function removes the "0" entry (because the first A +** is not near enough to an E). +*/ +static void trimSnippetOffsetsForNear(Query *pQuery, Snippet *pSnippet){ + int ii; + int iDir = 1; + + while(iDir>-2) { + assert( iDir==1 || iDir==-1 ); + for(ii=0; ii<pSnippet->nMatch; ii++){ + int jj; + int nNear; + struct snippetMatch *pMatch = &pSnippet->aMatch[ii]; + QueryTerm *pQueryTerm = &pQuery->pTerms[pMatch->iTerm]; + + if( (pMatch->iTerm+iDir)<0 + || (pMatch->iTerm+iDir)>=pQuery->nTerms + ){ + continue; + } + + nNear = pQueryTerm->nNear; + if( iDir<0 ){ + nNear = pQueryTerm[-1].nNear; + } + + if( pMatch->iTerm>=0 && nNear ){ + int isOk = 0; + int iNextTerm = pMatch->iTerm+iDir; + int iPrevTerm = iNextTerm; + + int iEndToken; + int iStartToken; + + if( iDir<0 ){ + int nPhrase = 1; + iStartToken = pMatch->iToken; + while( (pMatch->iTerm+nPhrase)<pQuery->nTerms + && pQuery->pTerms[pMatch->iTerm+nPhrase].iPhrase>1 + ){ + nPhrase++; + } + iEndToken = iStartToken + nPhrase - 1; + }else{ + iEndToken = pMatch->iToken; + iStartToken = pMatch->iToken+1-pQueryTerm->iPhrase; + } + + while( pQuery->pTerms[iNextTerm].iPhrase>1 ){ + iNextTerm--; + } + while( (iPrevTerm+1)<pQuery->nTerms && + pQuery->pTerms[iPrevTerm+1].iPhrase>1 + ){ + iPrevTerm++; + } + + for(jj=0; isOk==0 && jj<pSnippet->nMatch; jj++){ + struct snippetMatch *p = &pSnippet->aMatch[jj]; + if( p->iCol==pMatch->iCol && (( + p->iTerm==iNextTerm && + p->iToken>iEndToken && + p->iToken<=iEndToken+nNear + ) || ( + p->iTerm==iPrevTerm && + p->iToken<iStartToken && + p->iToken>=iStartToken-nNear + ))){ + isOk = 1; + } + } + if( !isOk ){ + for(jj=1-pQueryTerm->iPhrase; jj<=0; jj++){ + pMatch[jj].iTerm = -1; + } + ii = -1; + iDir = 1; + } + } + } + iDir -= 2; + } +} + +/* +** Compute all offsets for the current row of the query. +** If the offsets have already been computed, this routine is a no-op. +*/ +static void snippetAllOffsets(fulltext_cursor *p){ + int nColumn; + int iColumn, i; + int iFirst, iLast; + fulltext_vtab *pFts; + + if( p->snippet.nMatch ) return; + if( p->q.nTerms==0 ) return; + pFts = p->q.pFts; + nColumn = pFts->nColumn; + iColumn = (p->iCursorType - QUERY_FULLTEXT); + if( iColumn<0 || iColumn>=nColumn ){ + iFirst = 0; + iLast = nColumn-1; + }else{ + iFirst = iColumn; + iLast = iColumn; + } + for(i=iFirst; i<=iLast; i++){ + const char *zDoc; + int nDoc; + zDoc = (const char*)sqlite3_column_text(p->pStmt, i+1); + nDoc = sqlite3_column_bytes(p->pStmt, i+1); + snippetOffsetsOfColumn(&p->q, &p->snippet, i, zDoc, nDoc); + } + + trimSnippetOffsetsForNear(&p->q, &p->snippet); +} + +/* +** Convert the information in the aMatch[] array of the snippet +** into the string zOffset[0..nOffset-1]. +*/ +static void snippetOffsetText(Snippet *p){ + int i; + int cnt = 0; + StringBuffer sb; + char zBuf[200]; + if( p->zOffset ) return; + initStringBuffer(&sb); + for(i=0; i<p->nMatch; i++){ + struct snippetMatch *pMatch = &p->aMatch[i]; + if( pMatch->iTerm>=0 ){ + /* If snippetMatch.iTerm is less than 0, then the match was + ** discarded as part of processing the NEAR operator (see the + ** trimSnippetOffsetsForNear() function for details). Ignore + ** it in this case + */ + zBuf[0] = ' '; + sprintf(&zBuf[cnt>0], "%d %d %d %d", pMatch->iCol, + pMatch->iTerm, pMatch->iStart, pMatch->nByte); + append(&sb, zBuf); + cnt++; + } + } + p->zOffset = stringBufferData(&sb); + p->nOffset = stringBufferLength(&sb); +} + +/* +** zDoc[0..nDoc-1] is phrase of text. aMatch[0..nMatch-1] are a set +** of matching words some of which might be in zDoc. zDoc is column +** number iCol. +** +** iBreak is suggested spot in zDoc where we could begin or end an +** excerpt. Return a value similar to iBreak but possibly adjusted +** to be a little left or right so that the break point is better. +*/ +static int wordBoundary( + int iBreak, /* The suggested break point */ + const char *zDoc, /* Document text */ + int nDoc, /* Number of bytes in zDoc[] */ + struct snippetMatch *aMatch, /* Matching words */ + int nMatch, /* Number of entries in aMatch[] */ + int iCol /* The column number for zDoc[] */ +){ + int i; + if( iBreak<=10 ){ + return 0; + } + if( iBreak>=nDoc-10 ){ + return nDoc; + } + for(i=0; i<nMatch && aMatch[i].iCol<iCol; i++){} + while( i<nMatch && aMatch[i].iStart+aMatch[i].nByte<iBreak ){ i++; } + if( i<nMatch ){ + if( aMatch[i].iStart<iBreak+10 ){ + return aMatch[i].iStart; + } + if( i>0 && aMatch[i-1].iStart+aMatch[i-1].nByte>=iBreak ){ + return aMatch[i-1].iStart; + } + } + for(i=1; i<=10; i++){ + if( safe_isspace(zDoc[iBreak-i]) ){ + return iBreak - i + 1; + } + if( safe_isspace(zDoc[iBreak+i]) ){ + return iBreak + i + 1; + } + } + return iBreak; +} + + + +/* +** Allowed values for Snippet.aMatch[].snStatus +*/ +#define SNIPPET_IGNORE 0 /* It is ok to omit this match from the snippet */ +#define SNIPPET_DESIRED 1 /* We want to include this match in the snippet */ + +/* +** Generate the text of a snippet. +*/ +static void snippetText( + fulltext_cursor *pCursor, /* The cursor we need the snippet for */ + const char *zStartMark, /* Markup to appear before each match */ + const char *zEndMark, /* Markup to appear after each match */ + const char *zEllipsis /* Ellipsis mark */ +){ + int i, j; + struct snippetMatch *aMatch; + int nMatch; + int nDesired; + StringBuffer sb; + int tailCol; + int tailOffset; + int iCol; + int nDoc; + const char *zDoc; + int iStart, iEnd; + int tailEllipsis = 0; + int iMatch; + + + sqlite3_free(pCursor->snippet.zSnippet); + pCursor->snippet.zSnippet = 0; + aMatch = pCursor->snippet.aMatch; + nMatch = pCursor->snippet.nMatch; + initStringBuffer(&sb); + + for(i=0; i<nMatch; i++){ + aMatch[i].snStatus = SNIPPET_IGNORE; + } + nDesired = 0; + for(i=0; i<pCursor->q.nTerms; i++){ + for(j=0; j<nMatch; j++){ + if( aMatch[j].iTerm==i ){ + aMatch[j].snStatus = SNIPPET_DESIRED; + nDesired++; + break; + } + } + } + + iMatch = 0; + tailCol = -1; + tailOffset = 0; + for(i=0; i<nMatch && nDesired>0; i++){ + if( aMatch[i].snStatus!=SNIPPET_DESIRED ) continue; + nDesired--; + iCol = aMatch[i].iCol; + zDoc = (const char*)sqlite3_column_text(pCursor->pStmt, iCol+1); + nDoc = sqlite3_column_bytes(pCursor->pStmt, iCol+1); + iStart = aMatch[i].iStart - 40; + iStart = wordBoundary(iStart, zDoc, nDoc, aMatch, nMatch, iCol); + if( iStart<=10 ){ + iStart = 0; + } + if( iCol==tailCol && iStart<=tailOffset+20 ){ + iStart = tailOffset; + } + if( (iCol!=tailCol && tailCol>=0) || iStart!=tailOffset ){ + trimWhiteSpace(&sb); + appendWhiteSpace(&sb); + append(&sb, zEllipsis); + appendWhiteSpace(&sb); + } + iEnd = aMatch[i].iStart + aMatch[i].nByte + 40; + iEnd = wordBoundary(iEnd, zDoc, nDoc, aMatch, nMatch, iCol); + if( iEnd>=nDoc-10 ){ + iEnd = nDoc; + tailEllipsis = 0; + }else{ + tailEllipsis = 1; + } + while( iMatch<nMatch && aMatch[iMatch].iCol<iCol ){ iMatch++; } + while( iStart<iEnd ){ + while( iMatch<nMatch && aMatch[iMatch].iStart<iStart + && aMatch[iMatch].iCol<=iCol ){ + iMatch++; + } + if( iMatch<nMatch && aMatch[iMatch].iStart<iEnd + && aMatch[iMatch].iCol==iCol ){ + nappend(&sb, &zDoc[iStart], aMatch[iMatch].iStart - iStart); + iStart = aMatch[iMatch].iStart; + append(&sb, zStartMark); + nappend(&sb, &zDoc[iStart], aMatch[iMatch].nByte); + append(&sb, zEndMark); + iStart += aMatch[iMatch].nByte; + for(j=iMatch+1; j<nMatch; j++){ + if( aMatch[j].iTerm==aMatch[iMatch].iTerm + && aMatch[j].snStatus==SNIPPET_DESIRED ){ + nDesired--; + aMatch[j].snStatus = SNIPPET_IGNORE; + } + } + }else{ + nappend(&sb, &zDoc[iStart], iEnd - iStart); + iStart = iEnd; + } + } + tailCol = iCol; + tailOffset = iEnd; + } + trimWhiteSpace(&sb); + if( tailEllipsis ){ + appendWhiteSpace(&sb); + append(&sb, zEllipsis); + } + pCursor->snippet.zSnippet = stringBufferData(&sb); + pCursor->snippet.nSnippet = stringBufferLength(&sb); +} + + +/* +** Close the cursor. For additional information see the documentation +** on the xClose method of the virtual table interface. +*/ +static int fulltextClose(sqlite3_vtab_cursor *pCursor){ + fulltext_cursor *c = (fulltext_cursor *) pCursor; + FTSTRACE(("FTS3 Close %p\n", c)); + sqlite3_finalize(c->pStmt); + queryClear(&c->q); + snippetClear(&c->snippet); + if( c->result.nData!=0 ) dlrDestroy(&c->reader); + dataBufferDestroy(&c->result); + sqlite3_free(c); + return SQLITE_OK; +} + +static int fulltextNext(sqlite3_vtab_cursor *pCursor){ + fulltext_cursor *c = (fulltext_cursor *) pCursor; + int rc; + + FTSTRACE(("FTS3 Next %p\n", pCursor)); + snippetClear(&c->snippet); + if( c->iCursorType < QUERY_FULLTEXT ){ + /* TODO(shess) Handle SQLITE_SCHEMA AND SQLITE_BUSY. */ + rc = sqlite3_step(c->pStmt); + switch( rc ){ + case SQLITE_ROW: + c->eof = 0; + return SQLITE_OK; + case SQLITE_DONE: + c->eof = 1; + return SQLITE_OK; + default: + c->eof = 1; + return rc; + } + } else { /* full-text query */ + rc = sqlite3_reset(c->pStmt); + if( rc!=SQLITE_OK ) return rc; + + if( c->result.nData==0 || dlrAtEnd(&c->reader) ){ + c->eof = 1; + return SQLITE_OK; + } + rc = sqlite3_bind_int64(c->pStmt, 1, dlrDocid(&c->reader)); + dlrStep(&c->reader); + if( rc!=SQLITE_OK ) return rc; + /* TODO(shess) Handle SQLITE_SCHEMA AND SQLITE_BUSY. */ + rc = sqlite3_step(c->pStmt); + if( rc==SQLITE_ROW ){ /* the case we expect */ + c->eof = 0; + return SQLITE_OK; + } + /* an error occurred; abort */ + return rc==SQLITE_DONE ? SQLITE_ERROR : rc; + } +} + + +/* TODO(shess) If we pushed LeafReader to the top of the file, or to +** another file, term_select() could be pushed above +** docListOfTerm(). +*/ +static int termSelect(fulltext_vtab *v, int iColumn, + const char *pTerm, int nTerm, int isPrefix, + DocListType iType, DataBuffer *out); + +/* Return a DocList corresponding to the query term *pTerm. If *pTerm +** is the first term of a phrase query, go ahead and evaluate the phrase +** query and return the doclist for the entire phrase query. +** +** The resulting DL_DOCIDS doclist is stored in pResult, which is +** overwritten. +*/ +static int docListOfTerm( + fulltext_vtab *v, /* The full text index */ + int iColumn, /* column to restrict to. No restriction if >=nColumn */ + QueryTerm *pQTerm, /* Term we are looking for, or 1st term of a phrase */ + DataBuffer *pResult /* Write the result here */ +){ + DataBuffer left, right, new; + int i, rc; + + /* No phrase search if no position info. */ + assert( pQTerm->nPhrase==0 || DL_DEFAULT!=DL_DOCIDS ); + + /* This code should never be called with buffered updates. */ + assert( v->nPendingData<0 ); + + dataBufferInit(&left, 0); + rc = termSelect(v, iColumn, pQTerm->pTerm, pQTerm->nTerm, pQTerm->isPrefix, + (0<pQTerm->nPhrase ? DL_POSITIONS : DL_DOCIDS), &left); + if( rc ) return rc; + for(i=1; i<=pQTerm->nPhrase && left.nData>0; i++){ + /* If this token is connected to the next by a NEAR operator, and + ** the next token is the start of a phrase, then set nPhraseRight + ** to the number of tokens in the phrase. Otherwise leave it at 1. + */ + int nPhraseRight = 1; + while( (i+nPhraseRight)<=pQTerm->nPhrase + && pQTerm[i+nPhraseRight].nNear==0 + ){ + nPhraseRight++; + } + + dataBufferInit(&right, 0); + rc = termSelect(v, iColumn, pQTerm[i].pTerm, pQTerm[i].nTerm, + pQTerm[i].isPrefix, DL_POSITIONS, &right); + if( rc ){ + dataBufferDestroy(&left); + return rc; + } + dataBufferInit(&new, 0); + docListPhraseMerge(left.pData, left.nData, right.pData, right.nData, + pQTerm[i-1].nNear, pQTerm[i-1].iPhrase + nPhraseRight, + ((i<pQTerm->nPhrase) ? DL_POSITIONS : DL_DOCIDS), + &new); + dataBufferDestroy(&left); + dataBufferDestroy(&right); + left = new; + } + *pResult = left; + return SQLITE_OK; +} + +/* Add a new term pTerm[0..nTerm-1] to the query *q. +*/ +static void queryAdd(Query *q, const char *pTerm, int nTerm){ + QueryTerm *t; + ++q->nTerms; + q->pTerms = sqlite3_realloc(q->pTerms, q->nTerms * sizeof(q->pTerms[0])); + if( q->pTerms==0 ){ + q->nTerms = 0; + return; + } + t = &q->pTerms[q->nTerms - 1]; + CLEAR(t); + t->pTerm = sqlite3_malloc(nTerm+1); + memcpy(t->pTerm, pTerm, nTerm); + t->pTerm[nTerm] = 0; + t->nTerm = nTerm; + t->isOr = q->nextIsOr; + t->isPrefix = 0; + q->nextIsOr = 0; + t->iColumn = q->nextColumn; + q->nextColumn = q->dfltColumn; +} + +/* +** Check to see if the string zToken[0...nToken-1] matches any +** column name in the virtual table. If it does, +** return the zero-indexed column number. If not, return -1. +*/ +static int checkColumnSpecifier( + fulltext_vtab *pVtab, /* The virtual table */ + const char *zToken, /* Text of the token */ + int nToken /* Number of characters in the token */ +){ + int i; + for(i=0; i<pVtab->nColumn; i++){ + if( memcmp(pVtab->azColumn[i], zToken, nToken)==0 + && pVtab->azColumn[i][nToken]==0 ){ + return i; + } + } + return -1; +} + +/* +** Parse the text at pSegment[0..nSegment-1]. Add additional terms +** to the query being assemblied in pQuery. +** +** inPhrase is true if pSegment[0..nSegement-1] is contained within +** double-quotes. If inPhrase is true, then the first term +** is marked with the number of terms in the phrase less one and +** OR and "-" syntax is ignored. If inPhrase is false, then every +** term found is marked with nPhrase=0 and OR and "-" syntax is significant. +*/ +static int tokenizeSegment( + sqlite3_tokenizer *pTokenizer, /* The tokenizer to use */ + const char *pSegment, int nSegment, /* Query expression being parsed */ + int inPhrase, /* True if within "..." */ + Query *pQuery /* Append results here */ +){ + const sqlite3_tokenizer_module *pModule = pTokenizer->pModule; + sqlite3_tokenizer_cursor *pCursor; + int firstIndex = pQuery->nTerms; + int iCol; + int nTerm = 1; + + int rc = pModule->xOpen(pTokenizer, pSegment, nSegment, &pCursor); + if( rc!=SQLITE_OK ) return rc; + pCursor->pTokenizer = pTokenizer; + + while( 1 ){ + const char *pToken; + int nToken, iBegin, iEnd, iPos; + + rc = pModule->xNext(pCursor, + &pToken, &nToken, + &iBegin, &iEnd, &iPos); + if( rc!=SQLITE_OK ) break; + if( !inPhrase && + pSegment[iEnd]==':' && + (iCol = checkColumnSpecifier(pQuery->pFts, pToken, nToken))>=0 ){ + pQuery->nextColumn = iCol; + continue; + } + if( !inPhrase && pQuery->nTerms>0 && nToken==2 + && pSegment[iBegin+0]=='O' + && pSegment[iBegin+1]=='R' + ){ + pQuery->nextIsOr = 1; + continue; + } + if( !inPhrase && pQuery->nTerms>0 && !pQuery->nextIsOr && nToken==4 + && pSegment[iBegin+0]=='N' + && pSegment[iBegin+1]=='E' + && pSegment[iBegin+2]=='A' + && pSegment[iBegin+3]=='R' + ){ + QueryTerm *pTerm = &pQuery->pTerms[pQuery->nTerms-1]; + if( (iBegin+6)<nSegment + && pSegment[iBegin+4] == '/' + && pSegment[iBegin+5]>='0' && pSegment[iBegin+5]<='9' + ){ + pTerm->nNear = (pSegment[iBegin+5] - '0'); + nToken += 2; + if( pSegment[iBegin+6]>='0' && pSegment[iBegin+6]<=9 ){ + pTerm->nNear = pTerm->nNear * 10 + (pSegment[iBegin+6] - '0'); + iEnd++; + } + pModule->xNext(pCursor, &pToken, &nToken, &iBegin, &iEnd, &iPos); + } else { + pTerm->nNear = SQLITE_FTS3_DEFAULT_NEAR_PARAM; + } + pTerm->nNear++; + continue; + } + + queryAdd(pQuery, pToken, nToken); + if( !inPhrase && iBegin>0 && pSegment[iBegin-1]=='-' ){ + pQuery->pTerms[pQuery->nTerms-1].isNot = 1; + } + if( iEnd<nSegment && pSegment[iEnd]=='*' ){ + pQuery->pTerms[pQuery->nTerms-1].isPrefix = 1; + } + pQuery->pTerms[pQuery->nTerms-1].iPhrase = nTerm; + if( inPhrase ){ + nTerm++; + } + } + + if( inPhrase && pQuery->nTerms>firstIndex ){ + pQuery->pTerms[firstIndex].nPhrase = pQuery->nTerms - firstIndex - 1; + } + + return pModule->xClose(pCursor); +} + +/* Parse a query string, yielding a Query object pQuery. +** +** The calling function will need to queryClear() to clean up +** the dynamically allocated memory held by pQuery. +*/ +static int parseQuery( + fulltext_vtab *v, /* The fulltext index */ + const char *zInput, /* Input text of the query string */ + int nInput, /* Size of the input text */ + int dfltColumn, /* Default column of the index to match against */ + Query *pQuery /* Write the parse results here. */ +){ + int iInput, inPhrase = 0; + int ii; + QueryTerm *aTerm; + + if( zInput==0 ) nInput = 0; + if( nInput<0 ) nInput = strlen(zInput); + pQuery->nTerms = 0; + pQuery->pTerms = NULL; + pQuery->nextIsOr = 0; + pQuery->nextColumn = dfltColumn; + pQuery->dfltColumn = dfltColumn; + pQuery->pFts = v; + + for(iInput=0; iInput<nInput; ++iInput){ + int i; + for(i=iInput; i<nInput && zInput[i]!='"'; ++i){} + if( i>iInput ){ + tokenizeSegment(v->pTokenizer, zInput+iInput, i-iInput, inPhrase, + pQuery); + } + iInput = i; + if( i<nInput ){ + assert( zInput[i]=='"' ); + inPhrase = !inPhrase; + } + } + + if( inPhrase ){ + /* unmatched quote */ + queryClear(pQuery); + return SQLITE_ERROR; + } + + /* Modify the values of the QueryTerm.nPhrase variables to account for + ** the NEAR operator. For the purposes of QueryTerm.nPhrase, phrases + ** and tokens connected by the NEAR operator are handled as a single + ** phrase. See comments above the QueryTerm structure for details. + */ + aTerm = pQuery->pTerms; + for(ii=0; ii<pQuery->nTerms; ii++){ + if( aTerm[ii].nNear || aTerm[ii].nPhrase ){ + while (aTerm[ii+aTerm[ii].nPhrase].nNear) { + aTerm[ii].nPhrase += (1 + aTerm[ii+aTerm[ii].nPhrase+1].nPhrase); + } + } + } + + return SQLITE_OK; +} + +/* TODO(shess) Refactor the code to remove this forward decl. */ +static int flushPendingTerms(fulltext_vtab *v); + +/* Perform a full-text query using the search expression in +** zInput[0..nInput-1]. Return a list of matching documents +** in pResult. +** +** Queries must match column iColumn. Or if iColumn>=nColumn +** they are allowed to match against any column. +*/ +static int fulltextQuery( + fulltext_vtab *v, /* The full text index */ + int iColumn, /* Match against this column by default */ + const char *zInput, /* The query string */ + int nInput, /* Number of bytes in zInput[] */ + DataBuffer *pResult, /* Write the result doclist here */ + Query *pQuery /* Put parsed query string here */ +){ + int i, iNext, rc; + DataBuffer left, right, or, new; + int nNot = 0; + QueryTerm *aTerm; + + /* TODO(shess) Instead of flushing pendingTerms, we could query for + ** the relevant term and merge the doclist into what we receive from + ** the database. Wait and see if this is a common issue, first. + ** + ** A good reason not to flush is to not generate update-related + ** error codes from here. + */ + + /* Flush any buffered updates before executing the query. */ + rc = flushPendingTerms(v); + if( rc!=SQLITE_OK ) return rc; + + /* TODO(shess) I think that the queryClear() calls below are not + ** necessary, because fulltextClose() already clears the query. + */ + rc = parseQuery(v, zInput, nInput, iColumn, pQuery); + if( rc!=SQLITE_OK ) return rc; + + /* Empty or NULL queries return no results. */ + if( pQuery->nTerms==0 ){ + dataBufferInit(pResult, 0); + return SQLITE_OK; + } + + /* Merge AND terms. */ + /* TODO(shess) I think we can early-exit if( i>nNot && left.nData==0 ). */ + aTerm = pQuery->pTerms; + for(i = 0; i<pQuery->nTerms; i=iNext){ + if( aTerm[i].isNot ){ + /* Handle all NOT terms in a separate pass */ + nNot++; + iNext = i + aTerm[i].nPhrase+1; + continue; + } + iNext = i + aTerm[i].nPhrase + 1; + rc = docListOfTerm(v, aTerm[i].iColumn, &aTerm[i], &right); + if( rc ){ + if( i!=nNot ) dataBufferDestroy(&left); + queryClear(pQuery); + return rc; + } + while( iNext<pQuery->nTerms && aTerm[iNext].isOr ){ + rc = docListOfTerm(v, aTerm[iNext].iColumn, &aTerm[iNext], &or); + iNext += aTerm[iNext].nPhrase + 1; + if( rc ){ + if( i!=nNot ) dataBufferDestroy(&left); + dataBufferDestroy(&right); + queryClear(pQuery); + return rc; + } + dataBufferInit(&new, 0); + docListOrMerge(right.pData, right.nData, or.pData, or.nData, &new); + dataBufferDestroy(&right); + dataBufferDestroy(&or); + right = new; + } + if( i==nNot ){ /* first term processed. */ + left = right; + }else{ + dataBufferInit(&new, 0); + docListAndMerge(left.pData, left.nData, right.pData, right.nData, &new); + dataBufferDestroy(&right); + dataBufferDestroy(&left); + left = new; + } + } + + if( nNot==pQuery->nTerms ){ + /* We do not yet know how to handle a query of only NOT terms */ + return SQLITE_ERROR; + } + + /* Do the EXCEPT terms */ + for(i=0; i<pQuery->nTerms; i += aTerm[i].nPhrase + 1){ + if( !aTerm[i].isNot ) continue; + rc = docListOfTerm(v, aTerm[i].iColumn, &aTerm[i], &right); + if( rc ){ + queryClear(pQuery); + dataBufferDestroy(&left); + return rc; + } + dataBufferInit(&new, 0); + docListExceptMerge(left.pData, left.nData, right.pData, right.nData, &new); + dataBufferDestroy(&right); + dataBufferDestroy(&left); + left = new; + } + + *pResult = left; + return rc; +} + +/* +** This is the xFilter interface for the virtual table. See +** the virtual table xFilter method documentation for additional +** information. +** +** If idxNum==QUERY_GENERIC then do a full table scan against +** the %_content table. +** +** If idxNum==QUERY_DOCID then do a docid lookup for a single entry +** in the %_content table. +** +** If idxNum>=QUERY_FULLTEXT then use the full text index. The +** column on the left-hand side of the MATCH operator is column +** number idxNum-QUERY_FULLTEXT, 0 indexed. argv[0] is the right-hand +** side of the MATCH operator. +*/ +/* TODO(shess) Upgrade the cursor initialization and destruction to +** account for fulltextFilter() being called multiple times on the +** same cursor. The current solution is very fragile. Apply fix to +** fts3 as appropriate. +*/ +static int fulltextFilter( + sqlite3_vtab_cursor *pCursor, /* The cursor used for this query */ + int idxNum, const char *idxStr, /* Which indexing scheme to use */ + int argc, sqlite3_value **argv /* Arguments for the indexing scheme */ +){ + fulltext_cursor *c = (fulltext_cursor *) pCursor; + fulltext_vtab *v = cursor_vtab(c); + int rc; + StringBuffer sb; + + FTSTRACE(("FTS3 Filter %p\n",pCursor)); + + initStringBuffer(&sb); + append(&sb, "SELECT docid, "); + appendList(&sb, v->nColumn, v->azContentColumn); + append(&sb, " FROM %_content"); + if( idxNum!=QUERY_GENERIC ) append(&sb, " WHERE docid = ?"); + sqlite3_finalize(c->pStmt); + rc = sql_prepare(v->db, v->zDb, v->zName, &c->pStmt, stringBufferData(&sb)); + stringBufferDestroy(&sb); + if( rc!=SQLITE_OK ) return rc; + + c->iCursorType = idxNum; + switch( idxNum ){ + case QUERY_GENERIC: + break; + + case QUERY_DOCID: + rc = sqlite3_bind_int64(c->pStmt, 1, sqlite3_value_int64(argv[0])); + if( rc!=SQLITE_OK ) return rc; + break; + + default: /* full-text search */ + { + const char *zQuery = (const char *)sqlite3_value_text(argv[0]); + assert( idxNum<=QUERY_FULLTEXT+v->nColumn); + assert( argc==1 ); + queryClear(&c->q); + if( c->result.nData!=0 ){ + /* This case happens if the same cursor is used repeatedly. */ + dlrDestroy(&c->reader); + dataBufferReset(&c->result); + }else{ + dataBufferInit(&c->result, 0); + } + rc = fulltextQuery(v, idxNum-QUERY_FULLTEXT, zQuery, -1, &c->result, &c->q); + if( rc!=SQLITE_OK ) return rc; + if( c->result.nData!=0 ){ + dlrInit(&c->reader, DL_DOCIDS, c->result.pData, c->result.nData); + } + break; + } + } + + return fulltextNext(pCursor); +} + +/* This is the xEof method of the virtual table. The SQLite core +** calls this routine to find out if it has reached the end of +** a query's results set. +*/ +static int fulltextEof(sqlite3_vtab_cursor *pCursor){ + fulltext_cursor *c = (fulltext_cursor *) pCursor; + return c->eof; +} + +/* This is the xColumn method of the virtual table. The SQLite +** core calls this method during a query when it needs the value +** of a column from the virtual table. This method needs to use +** one of the sqlite3_result_*() routines to store the requested +** value back in the pContext. +*/ +static int fulltextColumn(sqlite3_vtab_cursor *pCursor, + sqlite3_context *pContext, int idxCol){ + fulltext_cursor *c = (fulltext_cursor *) pCursor; + fulltext_vtab *v = cursor_vtab(c); + + if( idxCol<v->nColumn ){ + sqlite3_value *pVal = sqlite3_column_value(c->pStmt, idxCol+1); + sqlite3_result_value(pContext, pVal); + }else if( idxCol==v->nColumn ){ + /* The extra column whose name is the same as the table. + ** Return a blob which is a pointer to the cursor + */ + sqlite3_result_blob(pContext, &c, sizeof(c), SQLITE_TRANSIENT); + }else if( idxCol==v->nColumn+1 ){ + /* The docid column, which is an alias for rowid. */ + sqlite3_value *pVal = sqlite3_column_value(c->pStmt, 0); + sqlite3_result_value(pContext, pVal); + } + return SQLITE_OK; +} + +/* This is the xRowid method. The SQLite core calls this routine to +** retrieve the rowid for the current row of the result set. fts3 +** exposes %_content.docid as the rowid for the virtual table. The +** rowid should be written to *pRowid. +*/ +static int fulltextRowid(sqlite3_vtab_cursor *pCursor, sqlite_int64 *pRowid){ + fulltext_cursor *c = (fulltext_cursor *) pCursor; + + *pRowid = sqlite3_column_int64(c->pStmt, 0); + return SQLITE_OK; +} + +/* Add all terms in [zText] to pendingTerms table. If [iColumn] > 0, +** we also store positions and offsets in the hash table using that +** column number. +*/ +static int buildTerms(fulltext_vtab *v, sqlite_int64 iDocid, + const char *zText, int iColumn){ + sqlite3_tokenizer *pTokenizer = v->pTokenizer; + sqlite3_tokenizer_cursor *pCursor; + const char *pToken; + int nTokenBytes; + int iStartOffset, iEndOffset, iPosition; + int rc; + + rc = pTokenizer->pModule->xOpen(pTokenizer, zText, -1, &pCursor); + if( rc!=SQLITE_OK ) return rc; + + pCursor->pTokenizer = pTokenizer; + while( SQLITE_OK==(rc=pTokenizer->pModule->xNext(pCursor, + &pToken, &nTokenBytes, + &iStartOffset, &iEndOffset, + &iPosition)) ){ + DLCollector *p; + int nData; /* Size of doclist before our update. */ + + /* Positions can't be negative; we use -1 as a terminator + * internally. Token can't be NULL or empty. */ + if( iPosition<0 || pToken == NULL || nTokenBytes == 0 ){ + rc = SQLITE_ERROR; + break; + } + + p = fts3HashFind(&v->pendingTerms, pToken, nTokenBytes); + if( p==NULL ){ + nData = 0; + p = dlcNew(iDocid, DL_DEFAULT); + fts3HashInsert(&v->pendingTerms, pToken, nTokenBytes, p); + + /* Overhead for our hash table entry, the key, and the value. */ + v->nPendingData += sizeof(struct fts3HashElem)+sizeof(*p)+nTokenBytes; + }else{ + nData = p->b.nData; + if( p->dlw.iPrevDocid!=iDocid ) dlcNext(p, iDocid); + } + if( iColumn>=0 ){ + dlcAddPos(p, iColumn, iPosition, iStartOffset, iEndOffset); + } + + /* Accumulate data added by dlcNew or dlcNext, and dlcAddPos. */ + v->nPendingData += p->b.nData-nData; + } + + /* TODO(shess) Check return? Should this be able to cause errors at + ** this point? Actually, same question about sqlite3_finalize(), + ** though one could argue that failure there means that the data is + ** not durable. *ponder* + */ + pTokenizer->pModule->xClose(pCursor); + if( SQLITE_DONE == rc ) return SQLITE_OK; + return rc; +} + +/* Add doclists for all terms in [pValues] to pendingTerms table. */ +static int insertTerms(fulltext_vtab *v, sqlite_int64 iDocid, + sqlite3_value **pValues){ + int i; + for(i = 0; i < v->nColumn ; ++i){ + char *zText = (char*)sqlite3_value_text(pValues[i]); + int rc = buildTerms(v, iDocid, zText, i); + if( rc!=SQLITE_OK ) return rc; + } + return SQLITE_OK; +} + +/* Add empty doclists for all terms in the given row's content to +** pendingTerms. +*/ +static int deleteTerms(fulltext_vtab *v, sqlite_int64 iDocid){ + const char **pValues; + int i, rc; + + /* TODO(shess) Should we allow such tables at all? */ + if( DL_DEFAULT==DL_DOCIDS ) return SQLITE_ERROR; + + rc = content_select(v, iDocid, &pValues); + if( rc!=SQLITE_OK ) return rc; + + for(i = 0 ; i < v->nColumn; ++i) { + rc = buildTerms(v, iDocid, pValues[i], -1); + if( rc!=SQLITE_OK ) break; + } + + freeStringArray(v->nColumn, pValues); + return SQLITE_OK; +} + +/* TODO(shess) Refactor the code to remove this forward decl. */ +static int initPendingTerms(fulltext_vtab *v, sqlite_int64 iDocid); + +/* Insert a row into the %_content table; set *piDocid to be the ID of the +** new row. Add doclists for terms to pendingTerms. +*/ +static int index_insert(fulltext_vtab *v, sqlite3_value *pRequestDocid, + sqlite3_value **pValues, sqlite_int64 *piDocid){ + int rc; + + rc = content_insert(v, pRequestDocid, pValues); /* execute an SQL INSERT */ + if( rc!=SQLITE_OK ) return rc; + + /* docid column is an alias for rowid. */ + *piDocid = sqlite3_last_insert_rowid(v->db); + rc = initPendingTerms(v, *piDocid); + if( rc!=SQLITE_OK ) return rc; + + return insertTerms(v, *piDocid, pValues); +} + +/* Delete a row from the %_content table; add empty doclists for terms +** to pendingTerms. +*/ +static int index_delete(fulltext_vtab *v, sqlite_int64 iRow){ + int rc = initPendingTerms(v, iRow); + if( rc!=SQLITE_OK ) return rc; + + rc = deleteTerms(v, iRow); + if( rc!=SQLITE_OK ) return rc; + + return content_delete(v, iRow); /* execute an SQL DELETE */ +} + +/* Update a row in the %_content table; add delete doclists to +** pendingTerms for old terms not in the new data, add insert doclists +** to pendingTerms for terms in the new data. +*/ +static int index_update(fulltext_vtab *v, sqlite_int64 iRow, + sqlite3_value **pValues){ + int rc = initPendingTerms(v, iRow); + if( rc!=SQLITE_OK ) return rc; + + /* Generate an empty doclist for each term that previously appeared in this + * row. */ + rc = deleteTerms(v, iRow); + if( rc!=SQLITE_OK ) return rc; + + rc = content_update(v, pValues, iRow); /* execute an SQL UPDATE */ + if( rc!=SQLITE_OK ) return rc; + + /* Now add positions for terms which appear in the updated row. */ + return insertTerms(v, iRow, pValues); +} + +/*******************************************************************/ +/* InteriorWriter is used to collect terms and block references into +** interior nodes in %_segments. See commentary at top of file for +** format. +*/ + +/* How large interior nodes can grow. */ +#define INTERIOR_MAX 2048 + +/* Minimum number of terms per interior node (except the root). This +** prevents large terms from making the tree too skinny - must be >0 +** so that the tree always makes progress. Note that the min tree +** fanout will be INTERIOR_MIN_TERMS+1. +*/ +#define INTERIOR_MIN_TERMS 7 +#if INTERIOR_MIN_TERMS<1 +# error INTERIOR_MIN_TERMS must be greater than 0. +#endif + +/* ROOT_MAX controls how much data is stored inline in the segment +** directory. +*/ +/* TODO(shess) Push ROOT_MAX down to whoever is writing things. It's +** only here so that interiorWriterRootInfo() and leafWriterRootInfo() +** can both see it, but if the caller passed it in, we wouldn't even +** need a define. +*/ +#define ROOT_MAX 1024 +#if ROOT_MAX<VARINT_MAX*2 +# error ROOT_MAX must have enough space for a header. +#endif + +/* InteriorBlock stores a linked-list of interior blocks while a lower +** layer is being constructed. +*/ +typedef struct InteriorBlock { + DataBuffer term; /* Leftmost term in block's subtree. */ + DataBuffer data; /* Accumulated data for the block. */ + struct InteriorBlock *next; +} InteriorBlock; + +static InteriorBlock *interiorBlockNew(int iHeight, sqlite_int64 iChildBlock, + const char *pTerm, int nTerm){ + InteriorBlock *block = sqlite3_malloc(sizeof(InteriorBlock)); + char c[VARINT_MAX+VARINT_MAX]; + int n; + + if( block ){ + memset(block, 0, sizeof(*block)); + dataBufferInit(&block->term, 0); + dataBufferReplace(&block->term, pTerm, nTerm); + + n = fts3PutVarint(c, iHeight); + n += fts3PutVarint(c+n, iChildBlock); + dataBufferInit(&block->data, INTERIOR_MAX); + dataBufferReplace(&block->data, c, n); + } + return block; +} + +#ifndef NDEBUG +/* Verify that the data is readable as an interior node. */ +static void interiorBlockValidate(InteriorBlock *pBlock){ + const char *pData = pBlock->data.pData; + int nData = pBlock->data.nData; + int n, iDummy; + sqlite_int64 iBlockid; + + assert( nData>0 ); + assert( pData!=0 ); + assert( pData+nData>pData ); + + /* Must lead with height of node as a varint(n), n>0 */ + n = fts3GetVarint32(pData, &iDummy); + assert( n>0 ); + assert( iDummy>0 ); + assert( n<nData ); + pData += n; + nData -= n; + + /* Must contain iBlockid. */ + n = fts3GetVarint(pData, &iBlockid); + assert( n>0 ); + assert( n<=nData ); + pData += n; + nData -= n; + + /* Zero or more terms of positive length */ + if( nData!=0 ){ + /* First term is not delta-encoded. */ + n = fts3GetVarint32(pData, &iDummy); + assert( n>0 ); + assert( iDummy>0 ); + assert( n+iDummy>0); + assert( n+iDummy<=nData ); + pData += n+iDummy; + nData -= n+iDummy; + + /* Following terms delta-encoded. */ + while( nData!=0 ){ + /* Length of shared prefix. */ + n = fts3GetVarint32(pData, &iDummy); + assert( n>0 ); + assert( iDummy>=0 ); + assert( n<nData ); + pData += n; + nData -= n; + + /* Length and data of distinct suffix. */ + n = fts3GetVarint32(pData, &iDummy); + assert( n>0 ); + assert( iDummy>0 ); + assert( n+iDummy>0); + assert( n+iDummy<=nData ); + pData += n+iDummy; + nData -= n+iDummy; + } + } +} +#define ASSERT_VALID_INTERIOR_BLOCK(x) interiorBlockValidate(x) +#else +#define ASSERT_VALID_INTERIOR_BLOCK(x) assert( 1 ) +#endif + +typedef struct InteriorWriter { + int iHeight; /* from 0 at leaves. */ + InteriorBlock *first, *last; + struct InteriorWriter *parentWriter; + + DataBuffer term; /* Last term written to block "last". */ + sqlite_int64 iOpeningChildBlock; /* First child block in block "last". */ +#ifndef NDEBUG + sqlite_int64 iLastChildBlock; /* for consistency checks. */ +#endif +} InteriorWriter; + +/* Initialize an interior node where pTerm[nTerm] marks the leftmost +** term in the tree. iChildBlock is the leftmost child block at the +** next level down the tree. +*/ +static void interiorWriterInit(int iHeight, const char *pTerm, int nTerm, + sqlite_int64 iChildBlock, + InteriorWriter *pWriter){ + InteriorBlock *block; + assert( iHeight>0 ); + CLEAR(pWriter); + + pWriter->iHeight = iHeight; + pWriter->iOpeningChildBlock = iChildBlock; +#ifndef NDEBUG + pWriter->iLastChildBlock = iChildBlock; +#endif + block = interiorBlockNew(iHeight, iChildBlock, pTerm, nTerm); + pWriter->last = pWriter->first = block; + ASSERT_VALID_INTERIOR_BLOCK(pWriter->last); + dataBufferInit(&pWriter->term, 0); +} + +/* Append the child node rooted at iChildBlock to the interior node, +** with pTerm[nTerm] as the leftmost term in iChildBlock's subtree. +*/ +static void interiorWriterAppend(InteriorWriter *pWriter, + const char *pTerm, int nTerm, + sqlite_int64 iChildBlock){ + char c[VARINT_MAX+VARINT_MAX]; + int n, nPrefix = 0; + + ASSERT_VALID_INTERIOR_BLOCK(pWriter->last); + + /* The first term written into an interior node is actually + ** associated with the second child added (the first child was added + ** in interiorWriterInit, or in the if clause at the bottom of this + ** function). That term gets encoded straight up, with nPrefix left + ** at 0. + */ + if( pWriter->term.nData==0 ){ + n = fts3PutVarint(c, nTerm); + }else{ + while( nPrefix<pWriter->term.nData && + pTerm[nPrefix]==pWriter->term.pData[nPrefix] ){ + nPrefix++; + } + + n = fts3PutVarint(c, nPrefix); + n += fts3PutVarint(c+n, nTerm-nPrefix); + } + +#ifndef NDEBUG + pWriter->iLastChildBlock++; +#endif + assert( pWriter->iLastChildBlock==iChildBlock ); + + /* Overflow to a new block if the new term makes the current block + ** too big, and the current block already has enough terms. + */ + if( pWriter->last->data.nData+n+nTerm-nPrefix>INTERIOR_MAX && + iChildBlock-pWriter->iOpeningChildBlock>INTERIOR_MIN_TERMS ){ + pWriter->last->next = interiorBlockNew(pWriter->iHeight, iChildBlock, + pTerm, nTerm); + pWriter->last = pWriter->last->next; + pWriter->iOpeningChildBlock = iChildBlock; + dataBufferReset(&pWriter->term); + }else{ + dataBufferAppend2(&pWriter->last->data, c, n, + pTerm+nPrefix, nTerm-nPrefix); + dataBufferReplace(&pWriter->term, pTerm, nTerm); + } + ASSERT_VALID_INTERIOR_BLOCK(pWriter->last); +} + +/* Free the space used by pWriter, including the linked-list of +** InteriorBlocks, and parentWriter, if present. +*/ +static int interiorWriterDestroy(InteriorWriter *pWriter){ + InteriorBlock *block = pWriter->first; + + while( block!=NULL ){ + InteriorBlock *b = block; + block = block->next; + dataBufferDestroy(&b->term); + dataBufferDestroy(&b->data); + sqlite3_free(b); + } + if( pWriter->parentWriter!=NULL ){ + interiorWriterDestroy(pWriter->parentWriter); + sqlite3_free(pWriter->parentWriter); + } + dataBufferDestroy(&pWriter->term); + SCRAMBLE(pWriter); + return SQLITE_OK; +} + +/* If pWriter can fit entirely in ROOT_MAX, return it as the root info +** directly, leaving *piEndBlockid unchanged. Otherwise, flush +** pWriter to %_segments, building a new layer of interior nodes, and +** recursively ask for their root into. +*/ +static int interiorWriterRootInfo(fulltext_vtab *v, InteriorWriter *pWriter, + char **ppRootInfo, int *pnRootInfo, + sqlite_int64 *piEndBlockid){ + InteriorBlock *block = pWriter->first; + sqlite_int64 iBlockid = 0; + int rc; + + /* If we can fit the segment inline */ + if( block==pWriter->last && block->data.nData<ROOT_MAX ){ + *ppRootInfo = block->data.pData; + *pnRootInfo = block->data.nData; + return SQLITE_OK; + } + + /* Flush the first block to %_segments, and create a new level of + ** interior node. + */ + ASSERT_VALID_INTERIOR_BLOCK(block); + rc = block_insert(v, block->data.pData, block->data.nData, &iBlockid); + if( rc!=SQLITE_OK ) return rc; + *piEndBlockid = iBlockid; + + pWriter->parentWriter = sqlite3_malloc(sizeof(*pWriter->parentWriter)); + interiorWriterInit(pWriter->iHeight+1, + block->term.pData, block->term.nData, + iBlockid, pWriter->parentWriter); + + /* Flush additional blocks and append to the higher interior + ** node. + */ + for(block=block->next; block!=NULL; block=block->next){ + ASSERT_VALID_INTERIOR_BLOCK(block); + rc = block_insert(v, block->data.pData, block->data.nData, &iBlockid); + if( rc!=SQLITE_OK ) return rc; + *piEndBlockid = iBlockid; + + interiorWriterAppend(pWriter->parentWriter, + block->term.pData, block->term.nData, iBlockid); + } + + /* Parent node gets the chance to be the root. */ + return interiorWriterRootInfo(v, pWriter->parentWriter, + ppRootInfo, pnRootInfo, piEndBlockid); +} + +/****************************************************************/ +/* InteriorReader is used to read off the data from an interior node +** (see comment at top of file for the format). +*/ +typedef struct InteriorReader { + const char *pData; + int nData; + + DataBuffer term; /* previous term, for decoding term delta. */ + + sqlite_int64 iBlockid; +} InteriorReader; + +static void interiorReaderDestroy(InteriorReader *pReader){ + dataBufferDestroy(&pReader->term); + SCRAMBLE(pReader); +} + +/* TODO(shess) The assertions are great, but what if we're in NDEBUG +** and the blob is empty or otherwise contains suspect data? +*/ +static void interiorReaderInit(const char *pData, int nData, + InteriorReader *pReader){ + int n, nTerm; + + /* Require at least the leading flag byte */ + assert( nData>0 ); + assert( pData[0]!='\0' ); + + CLEAR(pReader); + + /* Decode the base blockid, and set the cursor to the first term. */ + n = fts3GetVarint(pData+1, &pReader->iBlockid); + assert( 1+n<=nData ); + pReader->pData = pData+1+n; + pReader->nData = nData-(1+n); + + /* A single-child interior node (such as when a leaf node was too + ** large for the segment directory) won't have any terms. + ** Otherwise, decode the first term. + */ + if( pReader->nData==0 ){ + dataBufferInit(&pReader->term, 0); + }else{ + n = fts3GetVarint32(pReader->pData, &nTerm); + dataBufferInit(&pReader->term, nTerm); + dataBufferReplace(&pReader->term, pReader->pData+n, nTerm); + assert( n+nTerm<=pReader->nData ); + pReader->pData += n+nTerm; + pReader->nData -= n+nTerm; + } +} + +static int interiorReaderAtEnd(InteriorReader *pReader){ + return pReader->term.nData==0; +} + +static sqlite_int64 interiorReaderCurrentBlockid(InteriorReader *pReader){ + return pReader->iBlockid; +} + +static int interiorReaderTermBytes(InteriorReader *pReader){ + assert( !interiorReaderAtEnd(pReader) ); + return pReader->term.nData; +} +static const char *interiorReaderTerm(InteriorReader *pReader){ + assert( !interiorReaderAtEnd(pReader) ); + return pReader->term.pData; +} + +/* Step forward to the next term in the node. */ +static void interiorReaderStep(InteriorReader *pReader){ + assert( !interiorReaderAtEnd(pReader) ); + + /* If the last term has been read, signal eof, else construct the + ** next term. + */ + if( pReader->nData==0 ){ + dataBufferReset(&pReader->term); + }else{ + int n, nPrefix, nSuffix; + + n = fts3GetVarint32(pReader->pData, &nPrefix); + n += fts3GetVarint32(pReader->pData+n, &nSuffix); + + /* Truncate the current term and append suffix data. */ + pReader->term.nData = nPrefix; + dataBufferAppend(&pReader->term, pReader->pData+n, nSuffix); + + assert( n+nSuffix<=pReader->nData ); + pReader->pData += n+nSuffix; + pReader->nData -= n+nSuffix; + } + pReader->iBlockid++; +} + +/* Compare the current term to pTerm[nTerm], returning strcmp-style +** results. If isPrefix, equality means equal through nTerm bytes. +*/ +static int interiorReaderTermCmp(InteriorReader *pReader, + const char *pTerm, int nTerm, int isPrefix){ + const char *pReaderTerm = interiorReaderTerm(pReader); + int nReaderTerm = interiorReaderTermBytes(pReader); + int c, n = nReaderTerm<nTerm ? nReaderTerm : nTerm; + + if( n==0 ){ + if( nReaderTerm>0 ) return -1; + if( nTerm>0 ) return 1; + return 0; + } + + c = memcmp(pReaderTerm, pTerm, n); + if( c!=0 ) return c; + if( isPrefix && n==nTerm ) return 0; + return nReaderTerm - nTerm; +} + +/****************************************************************/ +/* LeafWriter is used to collect terms and associated doclist data +** into leaf blocks in %_segments (see top of file for format info). +** Expected usage is: +** +** LeafWriter writer; +** leafWriterInit(0, 0, &writer); +** while( sorted_terms_left_to_process ){ +** // data is doclist data for that term. +** rc = leafWriterStep(v, &writer, pTerm, nTerm, pData, nData); +** if( rc!=SQLITE_OK ) goto err; +** } +** rc = leafWriterFinalize(v, &writer); +**err: +** leafWriterDestroy(&writer); +** return rc; +** +** leafWriterStep() may write a collected leaf out to %_segments. +** leafWriterFinalize() finishes writing any buffered data and stores +** a root node in %_segdir. leafWriterDestroy() frees all buffers and +** InteriorWriters allocated as part of writing this segment. +** +** TODO(shess) Document leafWriterStepMerge(). +*/ + +/* Put terms with data this big in their own block. */ +#define STANDALONE_MIN 1024 + +/* Keep leaf blocks below this size. */ +#define LEAF_MAX 2048 + +typedef struct LeafWriter { + int iLevel; + int idx; + sqlite_int64 iStartBlockid; /* needed to create the root info */ + sqlite_int64 iEndBlockid; /* when we're done writing. */ + + DataBuffer term; /* previous encoded term */ + DataBuffer data; /* encoding buffer */ + + /* bytes of first term in the current node which distinguishes that + ** term from the last term of the previous node. + */ + int nTermDistinct; + + InteriorWriter parentWriter; /* if we overflow */ + int has_parent; +} LeafWriter; + +static void leafWriterInit(int iLevel, int idx, LeafWriter *pWriter){ + CLEAR(pWriter); + pWriter->iLevel = iLevel; + pWriter->idx = idx; + + dataBufferInit(&pWriter->term, 32); + + /* Start out with a reasonably sized block, though it can grow. */ + dataBufferInit(&pWriter->data, LEAF_MAX); +} + +#ifndef NDEBUG +/* Verify that the data is readable as a leaf node. */ +static void leafNodeValidate(const char *pData, int nData){ + int n, iDummy; + + if( nData==0 ) return; + assert( nData>0 ); + assert( pData!=0 ); + assert( pData+nData>pData ); + + /* Must lead with a varint(0) */ + n = fts3GetVarint32(pData, &iDummy); + assert( iDummy==0 ); + assert( n>0 ); + assert( n<nData ); + pData += n; + nData -= n; + + /* Leading term length and data must fit in buffer. */ + n = fts3GetVarint32(pData, &iDummy); + assert( n>0 ); + assert( iDummy>0 ); + assert( n+iDummy>0 ); + assert( n+iDummy<nData ); + pData += n+iDummy; + nData -= n+iDummy; + + /* Leading term's doclist length and data must fit. */ + n = fts3GetVarint32(pData, &iDummy); + assert( n>0 ); + assert( iDummy>0 ); + assert( n+iDummy>0 ); + assert( n+iDummy<=nData ); + ASSERT_VALID_DOCLIST(DL_DEFAULT, pData+n, iDummy, NULL); + pData += n+iDummy; + nData -= n+iDummy; + + /* Verify that trailing terms and doclists also are readable. */ + while( nData!=0 ){ + n = fts3GetVarint32(pData, &iDummy); + assert( n>0 ); + assert( iDummy>=0 ); + assert( n<nData ); + pData += n; + nData -= n; + n = fts3GetVarint32(pData, &iDummy); + assert( n>0 ); + assert( iDummy>0 ); + assert( n+iDummy>0 ); + assert( n+iDummy<nData ); + pData += n+iDummy; + nData -= n+iDummy; + + n = fts3GetVarint32(pData, &iDummy); + assert( n>0 ); + assert( iDummy>0 ); + assert( n+iDummy>0 ); + assert( n+iDummy<=nData ); + ASSERT_VALID_DOCLIST(DL_DEFAULT, pData+n, iDummy, NULL); + pData += n+iDummy; + nData -= n+iDummy; + } +} +#define ASSERT_VALID_LEAF_NODE(p, n) leafNodeValidate(p, n) +#else +#define ASSERT_VALID_LEAF_NODE(p, n) assert( 1 ) +#endif + +/* Flush the current leaf node to %_segments, and adding the resulting +** blockid and the starting term to the interior node which will +** contain it. +*/ +static int leafWriterInternalFlush(fulltext_vtab *v, LeafWriter *pWriter, + int iData, int nData){ + sqlite_int64 iBlockid = 0; + const char *pStartingTerm; + int nStartingTerm, rc, n; + + /* Must have the leading varint(0) flag, plus at least some + ** valid-looking data. + */ + assert( nData>2 ); + assert( iData>=0 ); + assert( iData+nData<=pWriter->data.nData ); + ASSERT_VALID_LEAF_NODE(pWriter->data.pData+iData, nData); + + rc = block_insert(v, pWriter->data.pData+iData, nData, &iBlockid); + if( rc!=SQLITE_OK ) return rc; + assert( iBlockid!=0 ); + + /* Reconstruct the first term in the leaf for purposes of building + ** the interior node. + */ + n = fts3GetVarint32(pWriter->data.pData+iData+1, &nStartingTerm); + pStartingTerm = pWriter->data.pData+iData+1+n; + assert( pWriter->data.nData>iData+1+n+nStartingTerm ); + assert( pWriter->nTermDistinct>0 ); + assert( pWriter->nTermDistinct<=nStartingTerm ); + nStartingTerm = pWriter->nTermDistinct; + + if( pWriter->has_parent ){ + interiorWriterAppend(&pWriter->parentWriter, + pStartingTerm, nStartingTerm, iBlockid); + }else{ + interiorWriterInit(1, pStartingTerm, nStartingTerm, iBlockid, + &pWriter->parentWriter); + pWriter->has_parent = 1; + } + + /* Track the span of this segment's leaf nodes. */ + if( pWriter->iEndBlockid==0 ){ + pWriter->iEndBlockid = pWriter->iStartBlockid = iBlockid; + }else{ + pWriter->iEndBlockid++; + assert( iBlockid==pWriter->iEndBlockid ); + } + + return SQLITE_OK; +} +static int leafWriterFlush(fulltext_vtab *v, LeafWriter *pWriter){ + int rc = leafWriterInternalFlush(v, pWriter, 0, pWriter->data.nData); + if( rc!=SQLITE_OK ) return rc; + + /* Re-initialize the output buffer. */ + dataBufferReset(&pWriter->data); + + return SQLITE_OK; +} + +/* Fetch the root info for the segment. If the entire leaf fits +** within ROOT_MAX, then it will be returned directly, otherwise it +** will be flushed and the root info will be returned from the +** interior node. *piEndBlockid is set to the blockid of the last +** interior or leaf node written to disk (0 if none are written at +** all). +*/ +static int leafWriterRootInfo(fulltext_vtab *v, LeafWriter *pWriter, + char **ppRootInfo, int *pnRootInfo, + sqlite_int64 *piEndBlockid){ + /* we can fit the segment entirely inline */ + if( !pWriter->has_parent && pWriter->data.nData<ROOT_MAX ){ + *ppRootInfo = pWriter->data.pData; + *pnRootInfo = pWriter->data.nData; + *piEndBlockid = 0; + return SQLITE_OK; + } + + /* Flush remaining leaf data. */ + if( pWriter->data.nData>0 ){ + int rc = leafWriterFlush(v, pWriter); + if( rc!=SQLITE_OK ) return rc; + } + + /* We must have flushed a leaf at some point. */ + assert( pWriter->has_parent ); + + /* Tenatively set the end leaf blockid as the end blockid. If the + ** interior node can be returned inline, this will be the final + ** blockid, otherwise it will be overwritten by + ** interiorWriterRootInfo(). + */ + *piEndBlockid = pWriter->iEndBlockid; + + return interiorWriterRootInfo(v, &pWriter->parentWriter, + ppRootInfo, pnRootInfo, piEndBlockid); +} + +/* Collect the rootInfo data and store it into the segment directory. +** This has the effect of flushing the segment's leaf data to +** %_segments, and also flushing any interior nodes to %_segments. +*/ +static int leafWriterFinalize(fulltext_vtab *v, LeafWriter *pWriter){ + sqlite_int64 iEndBlockid; + char *pRootInfo; + int rc, nRootInfo; + + rc = leafWriterRootInfo(v, pWriter, &pRootInfo, &nRootInfo, &iEndBlockid); + if( rc!=SQLITE_OK ) return rc; + + /* Don't bother storing an entirely empty segment. */ + if( iEndBlockid==0 && nRootInfo==0 ) return SQLITE_OK; + + return segdir_set(v, pWriter->iLevel, pWriter->idx, + pWriter->iStartBlockid, pWriter->iEndBlockid, + iEndBlockid, pRootInfo, nRootInfo); +} + +static void leafWriterDestroy(LeafWriter *pWriter){ + if( pWriter->has_parent ) interiorWriterDestroy(&pWriter->parentWriter); + dataBufferDestroy(&pWriter->term); + dataBufferDestroy(&pWriter->data); +} + +/* Encode a term into the leafWriter, delta-encoding as appropriate. +** Returns the length of the new term which distinguishes it from the +** previous term, which can be used to set nTermDistinct when a node +** boundary is crossed. +*/ +static int leafWriterEncodeTerm(LeafWriter *pWriter, + const char *pTerm, int nTerm){ + char c[VARINT_MAX+VARINT_MAX]; + int n, nPrefix = 0; + + assert( nTerm>0 ); + while( nPrefix<pWriter->term.nData && + pTerm[nPrefix]==pWriter->term.pData[nPrefix] ){ + nPrefix++; + /* Failing this implies that the terms weren't in order. */ + assert( nPrefix<nTerm ); + } + + if( pWriter->data.nData==0 ){ + /* Encode the node header and leading term as: + ** varint(0) + ** varint(nTerm) + ** char pTerm[nTerm] + */ + n = fts3PutVarint(c, '\0'); + n += fts3PutVarint(c+n, nTerm); + dataBufferAppend2(&pWriter->data, c, n, pTerm, nTerm); + }else{ + /* Delta-encode the term as: + ** varint(nPrefix) + ** varint(nSuffix) + ** char pTermSuffix[nSuffix] + */ + n = fts3PutVarint(c, nPrefix); + n += fts3PutVarint(c+n, nTerm-nPrefix); + dataBufferAppend2(&pWriter->data, c, n, pTerm+nPrefix, nTerm-nPrefix); + } + dataBufferReplace(&pWriter->term, pTerm, nTerm); + + return nPrefix+1; +} + +/* Used to avoid a memmove when a large amount of doclist data is in +** the buffer. This constructs a node and term header before +** iDoclistData and flushes the resulting complete node using +** leafWriterInternalFlush(). +*/ +static int leafWriterInlineFlush(fulltext_vtab *v, LeafWriter *pWriter, + const char *pTerm, int nTerm, + int iDoclistData){ + char c[VARINT_MAX+VARINT_MAX]; + int iData, n = fts3PutVarint(c, 0); + n += fts3PutVarint(c+n, nTerm); + + /* There should always be room for the header. Even if pTerm shared + ** a substantial prefix with the previous term, the entire prefix + ** could be constructed from earlier data in the doclist, so there + ** should be room. + */ + assert( iDoclistData>=n+nTerm ); + + iData = iDoclistData-(n+nTerm); + memcpy(pWriter->data.pData+iData, c, n); + memcpy(pWriter->data.pData+iData+n, pTerm, nTerm); + + return leafWriterInternalFlush(v, pWriter, iData, pWriter->data.nData-iData); +} + +/* Push pTerm[nTerm] along with the doclist data to the leaf layer of +** %_segments. +*/ +static int leafWriterStepMerge(fulltext_vtab *v, LeafWriter *pWriter, + const char *pTerm, int nTerm, + DLReader *pReaders, int nReaders){ + char c[VARINT_MAX+VARINT_MAX]; + int iTermData = pWriter->data.nData, iDoclistData; + int i, nData, n, nActualData, nActual, rc, nTermDistinct; + + ASSERT_VALID_LEAF_NODE(pWriter->data.pData, pWriter->data.nData); + nTermDistinct = leafWriterEncodeTerm(pWriter, pTerm, nTerm); + + /* Remember nTermDistinct if opening a new node. */ + if( iTermData==0 ) pWriter->nTermDistinct = nTermDistinct; + + iDoclistData = pWriter->data.nData; + + /* Estimate the length of the merged doclist so we can leave space + ** to encode it. + */ + for(i=0, nData=0; i<nReaders; i++){ + nData += dlrAllDataBytes(&pReaders[i]); + } + n = fts3PutVarint(c, nData); + dataBufferAppend(&pWriter->data, c, n); + + docListMerge(&pWriter->data, pReaders, nReaders); + ASSERT_VALID_DOCLIST(DL_DEFAULT, + pWriter->data.pData+iDoclistData+n, + pWriter->data.nData-iDoclistData-n, NULL); + + /* The actual amount of doclist data at this point could be smaller + ** than the length we encoded. Additionally, the space required to + ** encode this length could be smaller. For small doclists, this is + ** not a big deal, we can just use memmove() to adjust things. + */ + nActualData = pWriter->data.nData-(iDoclistData+n); + nActual = fts3PutVarint(c, nActualData); + assert( nActualData<=nData ); + assert( nActual<=n ); + + /* If the new doclist is big enough for force a standalone leaf + ** node, we can immediately flush it inline without doing the + ** memmove(). + */ + /* TODO(shess) This test matches leafWriterStep(), which does this + ** test before it knows the cost to varint-encode the term and + ** doclist lengths. At some point, change to + ** pWriter->data.nData-iTermData>STANDALONE_MIN. + */ + if( nTerm+nActualData>STANDALONE_MIN ){ + /* Push leaf node from before this term. */ + if( iTermData>0 ){ + rc = leafWriterInternalFlush(v, pWriter, 0, iTermData); + if( rc!=SQLITE_OK ) return rc; + + pWriter->nTermDistinct = nTermDistinct; + } + + /* Fix the encoded doclist length. */ + iDoclistData += n - nActual; + memcpy(pWriter->data.pData+iDoclistData, c, nActual); + + /* Push the standalone leaf node. */ + rc = leafWriterInlineFlush(v, pWriter, pTerm, nTerm, iDoclistData); + if( rc!=SQLITE_OK ) return rc; + + /* Leave the node empty. */ + dataBufferReset(&pWriter->data); + + return rc; + } + + /* At this point, we know that the doclist was small, so do the + ** memmove if indicated. + */ + if( nActual<n ){ + memmove(pWriter->data.pData+iDoclistData+nActual, + pWriter->data.pData+iDoclistData+n, + pWriter->data.nData-(iDoclistData+n)); + pWriter->data.nData -= n-nActual; + } + + /* Replace written length with actual length. */ + memcpy(pWriter->data.pData+iDoclistData, c, nActual); + + /* If the node is too large, break things up. */ + /* TODO(shess) This test matches leafWriterStep(), which does this + ** test before it knows the cost to varint-encode the term and + ** doclist lengths. At some point, change to + ** pWriter->data.nData>LEAF_MAX. + */ + if( iTermData+nTerm+nActualData>LEAF_MAX ){ + /* Flush out the leading data as a node */ + rc = leafWriterInternalFlush(v, pWriter, 0, iTermData); + if( rc!=SQLITE_OK ) return rc; + + pWriter->nTermDistinct = nTermDistinct; + + /* Rebuild header using the current term */ + n = fts3PutVarint(pWriter->data.pData, 0); + n += fts3PutVarint(pWriter->data.pData+n, nTerm); + memcpy(pWriter->data.pData+n, pTerm, nTerm); + n += nTerm; + + /* There should always be room, because the previous encoding + ** included all data necessary to construct the term. + */ + assert( n<iDoclistData ); + /* So long as STANDALONE_MIN is half or less of LEAF_MAX, the + ** following memcpy() is safe (as opposed to needing a memmove). + */ + assert( 2*STANDALONE_MIN<=LEAF_MAX ); + assert( n+pWriter->data.nData-iDoclistData<iDoclistData ); + memcpy(pWriter->data.pData+n, + pWriter->data.pData+iDoclistData, + pWriter->data.nData-iDoclistData); + pWriter->data.nData -= iDoclistData-n; + } + ASSERT_VALID_LEAF_NODE(pWriter->data.pData, pWriter->data.nData); + + return SQLITE_OK; +} + +/* Push pTerm[nTerm] along with the doclist data to the leaf layer of +** %_segments. +*/ +/* TODO(shess) Revise writeZeroSegment() so that doclists are +** constructed directly in pWriter->data. +*/ +static int leafWriterStep(fulltext_vtab *v, LeafWriter *pWriter, + const char *pTerm, int nTerm, + const char *pData, int nData){ + int rc; + DLReader reader; + + dlrInit(&reader, DL_DEFAULT, pData, nData); + rc = leafWriterStepMerge(v, pWriter, pTerm, nTerm, &reader, 1); + dlrDestroy(&reader); + + return rc; +} + + +/****************************************************************/ +/* LeafReader is used to iterate over an individual leaf node. */ +typedef struct LeafReader { + DataBuffer term; /* copy of current term. */ + + const char *pData; /* data for current term. */ + int nData; +} LeafReader; + +static void leafReaderDestroy(LeafReader *pReader){ + dataBufferDestroy(&pReader->term); + SCRAMBLE(pReader); +} + +static int leafReaderAtEnd(LeafReader *pReader){ + return pReader->nData<=0; +} + +/* Access the current term. */ +static int leafReaderTermBytes(LeafReader *pReader){ + return pReader->term.nData; +} +static const char *leafReaderTerm(LeafReader *pReader){ + assert( pReader->term.nData>0 ); + return pReader->term.pData; +} + +/* Access the doclist data for the current term. */ +static int leafReaderDataBytes(LeafReader *pReader){ + int nData; + assert( pReader->term.nData>0 ); + fts3GetVarint32(pReader->pData, &nData); + return nData; +} +static const char *leafReaderData(LeafReader *pReader){ + int n, nData; + assert( pReader->term.nData>0 ); + n = fts3GetVarint32(pReader->pData, &nData); + return pReader->pData+n; +} + +static void leafReaderInit(const char *pData, int nData, + LeafReader *pReader){ + int nTerm, n; + + assert( nData>0 ); + assert( pData[0]=='\0' ); + + CLEAR(pReader); + + /* Read the first term, skipping the header byte. */ + n = fts3GetVarint32(pData+1, &nTerm); + dataBufferInit(&pReader->term, nTerm); + dataBufferReplace(&pReader->term, pData+1+n, nTerm); + + /* Position after the first term. */ + assert( 1+n+nTerm<nData ); + pReader->pData = pData+1+n+nTerm; + pReader->nData = nData-1-n-nTerm; +} + +/* Step the reader forward to the next term. */ +static void leafReaderStep(LeafReader *pReader){ + int n, nData, nPrefix, nSuffix; + assert( !leafReaderAtEnd(pReader) ); + + /* Skip previous entry's data block. */ + n = fts3GetVarint32(pReader->pData, &nData); + assert( n+nData<=pReader->nData ); + pReader->pData += n+nData; + pReader->nData -= n+nData; + + if( !leafReaderAtEnd(pReader) ){ + /* Construct the new term using a prefix from the old term plus a + ** suffix from the leaf data. + */ + n = fts3GetVarint32(pReader->pData, &nPrefix); + n += fts3GetVarint32(pReader->pData+n, &nSuffix); + assert( n+nSuffix<pReader->nData ); + pReader->term.nData = nPrefix; + dataBufferAppend(&pReader->term, pReader->pData+n, nSuffix); + + pReader->pData += n+nSuffix; + pReader->nData -= n+nSuffix; + } +} + +/* strcmp-style comparison of pReader's current term against pTerm. +** If isPrefix, equality means equal through nTerm bytes. +*/ +static int leafReaderTermCmp(LeafReader *pReader, + const char *pTerm, int nTerm, int isPrefix){ + int c, n = pReader->term.nData<nTerm ? pReader->term.nData : nTerm; + if( n==0 ){ + if( pReader->term.nData>0 ) return -1; + if(nTerm>0 ) return 1; + return 0; + } + + c = memcmp(pReader->term.pData, pTerm, n); + if( c!=0 ) return c; + if( isPrefix && n==nTerm ) return 0; + return pReader->term.nData - nTerm; +} + + +/****************************************************************/ +/* LeavesReader wraps LeafReader to allow iterating over the entire +** leaf layer of the tree. +*/ +typedef struct LeavesReader { + int idx; /* Index within the segment. */ + + sqlite3_stmt *pStmt; /* Statement we're streaming leaves from. */ + int eof; /* we've seen SQLITE_DONE from pStmt. */ + + LeafReader leafReader; /* reader for the current leaf. */ + DataBuffer rootData; /* root data for inline. */ +} LeavesReader; + +/* Access the current term. */ +static int leavesReaderTermBytes(LeavesReader *pReader){ + assert( !pReader->eof ); + return leafReaderTermBytes(&pReader->leafReader); +} +static const char *leavesReaderTerm(LeavesReader *pReader){ + assert( !pReader->eof ); + return leafReaderTerm(&pReader->leafReader); +} + +/* Access the doclist data for the current term. */ +static int leavesReaderDataBytes(LeavesReader *pReader){ + assert( !pReader->eof ); + return leafReaderDataBytes(&pReader->leafReader); +} +static const char *leavesReaderData(LeavesReader *pReader){ + assert( !pReader->eof ); + return leafReaderData(&pReader->leafReader); +} + +static int leavesReaderAtEnd(LeavesReader *pReader){ + return pReader->eof; +} + +/* loadSegmentLeaves() may not read all the way to SQLITE_DONE, thus +** leaving the statement handle open, which locks the table. +*/ +/* TODO(shess) This "solution" is not satisfactory. Really, there +** should be check-in function for all statement handles which +** arranges to call sqlite3_reset(). This most likely will require +** modification to control flow all over the place, though, so for now +** just punt. +** +** Note the the current system assumes that segment merges will run to +** completion, which is why this particular probably hasn't arisen in +** this case. Probably a brittle assumption. +*/ +static int leavesReaderReset(LeavesReader *pReader){ + return sqlite3_reset(pReader->pStmt); +} + +static void leavesReaderDestroy(LeavesReader *pReader){ + leafReaderDestroy(&pReader->leafReader); + dataBufferDestroy(&pReader->rootData); + SCRAMBLE(pReader); +} + +/* Initialize pReader with the given root data (if iStartBlockid==0 +** the leaf data was entirely contained in the root), or from the +** stream of blocks between iStartBlockid and iEndBlockid, inclusive. +*/ +static int leavesReaderInit(fulltext_vtab *v, + int idx, + sqlite_int64 iStartBlockid, + sqlite_int64 iEndBlockid, + const char *pRootData, int nRootData, + LeavesReader *pReader){ + CLEAR(pReader); + pReader->idx = idx; + + dataBufferInit(&pReader->rootData, 0); + if( iStartBlockid==0 ){ + /* Entire leaf level fit in root data. */ + dataBufferReplace(&pReader->rootData, pRootData, nRootData); + leafReaderInit(pReader->rootData.pData, pReader->rootData.nData, + &pReader->leafReader); + }else{ + sqlite3_stmt *s; + int rc = sql_get_leaf_statement(v, idx, &s); + if( rc!=SQLITE_OK ) return rc; + + rc = sqlite3_bind_int64(s, 1, iStartBlockid); + if( rc!=SQLITE_OK ) return rc; + + rc = sqlite3_bind_int64(s, 2, iEndBlockid); + if( rc!=SQLITE_OK ) return rc; + + rc = sqlite3_step(s); + if( rc==SQLITE_DONE ){ + pReader->eof = 1; + return SQLITE_OK; + } + if( rc!=SQLITE_ROW ) return rc; + + pReader->pStmt = s; + leafReaderInit(sqlite3_column_blob(pReader->pStmt, 0), + sqlite3_column_bytes(pReader->pStmt, 0), + &pReader->leafReader); + } + return SQLITE_OK; +} + +/* Step the current leaf forward to the next term. If we reach the +** end of the current leaf, step forward to the next leaf block. +*/ +static int leavesReaderStep(fulltext_vtab *v, LeavesReader *pReader){ + assert( !leavesReaderAtEnd(pReader) ); + leafReaderStep(&pReader->leafReader); + + if( leafReaderAtEnd(&pReader->leafReader) ){ + int rc; + if( pReader->rootData.pData ){ + pReader->eof = 1; + return SQLITE_OK; + } + rc = sqlite3_step(pReader->pStmt); + if( rc!=SQLITE_ROW ){ + pReader->eof = 1; + return rc==SQLITE_DONE ? SQLITE_OK : rc; + } + leafReaderDestroy(&pReader->leafReader); + leafReaderInit(sqlite3_column_blob(pReader->pStmt, 0), + sqlite3_column_bytes(pReader->pStmt, 0), + &pReader->leafReader); + } + return SQLITE_OK; +} + +/* Order LeavesReaders by their term, ignoring idx. Readers at eof +** always sort to the end. +*/ +static int leavesReaderTermCmp(LeavesReader *lr1, LeavesReader *lr2){ + if( leavesReaderAtEnd(lr1) ){ + if( leavesReaderAtEnd(lr2) ) return 0; + return 1; + } + if( leavesReaderAtEnd(lr2) ) return -1; + + return leafReaderTermCmp(&lr1->leafReader, + leavesReaderTerm(lr2), leavesReaderTermBytes(lr2), + 0); +} + +/* Similar to leavesReaderTermCmp(), with additional ordering by idx +** so that older segments sort before newer segments. +*/ +static int leavesReaderCmp(LeavesReader *lr1, LeavesReader *lr2){ + int c = leavesReaderTermCmp(lr1, lr2); + if( c!=0 ) return c; + return lr1->idx-lr2->idx; +} + +/* Assume that pLr[1]..pLr[nLr] are sorted. Bubble pLr[0] into its +** sorted position. +*/ +static void leavesReaderReorder(LeavesReader *pLr, int nLr){ + while( nLr>1 && leavesReaderCmp(pLr, pLr+1)>0 ){ + LeavesReader tmp = pLr[0]; + pLr[0] = pLr[1]; + pLr[1] = tmp; + nLr--; + pLr++; + } +} + +/* Initializes pReaders with the segments from level iLevel, returning +** the number of segments in *piReaders. Leaves pReaders in sorted +** order. +*/ +static int leavesReadersInit(fulltext_vtab *v, int iLevel, + LeavesReader *pReaders, int *piReaders){ + sqlite3_stmt *s; + int i, rc = sql_get_statement(v, SEGDIR_SELECT_STMT, &s); + if( rc!=SQLITE_OK ) return rc; + + rc = sqlite3_bind_int(s, 1, iLevel); + if( rc!=SQLITE_OK ) return rc; + + i = 0; + while( (rc = sqlite3_step(s))==SQLITE_ROW ){ + sqlite_int64 iStart = sqlite3_column_int64(s, 0); + sqlite_int64 iEnd = sqlite3_column_int64(s, 1); + const char *pRootData = sqlite3_column_blob(s, 2); + int nRootData = sqlite3_column_bytes(s, 2); + + assert( i<MERGE_COUNT ); + rc = leavesReaderInit(v, i, iStart, iEnd, pRootData, nRootData, + &pReaders[i]); + if( rc!=SQLITE_OK ) break; + + i++; + } + if( rc!=SQLITE_DONE ){ + while( i-->0 ){ + leavesReaderDestroy(&pReaders[i]); + } + return rc; + } + + *piReaders = i; + + /* Leave our results sorted by term, then age. */ + while( i-- ){ + leavesReaderReorder(pReaders+i, *piReaders-i); + } + return SQLITE_OK; +} + +/* Merge doclists from pReaders[nReaders] into a single doclist, which +** is written to pWriter. Assumes pReaders is ordered oldest to +** newest. +*/ +/* TODO(shess) Consider putting this inline in segmentMerge(). */ +static int leavesReadersMerge(fulltext_vtab *v, + LeavesReader *pReaders, int nReaders, + LeafWriter *pWriter){ + DLReader dlReaders[MERGE_COUNT]; + const char *pTerm = leavesReaderTerm(pReaders); + int i, nTerm = leavesReaderTermBytes(pReaders); + + assert( nReaders<=MERGE_COUNT ); + + for(i=0; i<nReaders; i++){ + dlrInit(&dlReaders[i], DL_DEFAULT, + leavesReaderData(pReaders+i), + leavesReaderDataBytes(pReaders+i)); + } + + return leafWriterStepMerge(v, pWriter, pTerm, nTerm, dlReaders, nReaders); +} + +/* Forward ref due to mutual recursion with segdirNextIndex(). */ +static int segmentMerge(fulltext_vtab *v, int iLevel); + +/* Put the next available index at iLevel into *pidx. If iLevel +** already has MERGE_COUNT segments, they are merged to a higher +** level to make room. +*/ +static int segdirNextIndex(fulltext_vtab *v, int iLevel, int *pidx){ + int rc = segdir_max_index(v, iLevel, pidx); + if( rc==SQLITE_DONE ){ /* No segments at iLevel. */ + *pidx = 0; + }else if( rc==SQLITE_ROW ){ + if( *pidx==(MERGE_COUNT-1) ){ + rc = segmentMerge(v, iLevel); + if( rc!=SQLITE_OK ) return rc; + *pidx = 0; + }else{ + (*pidx)++; + } + }else{ + return rc; + } + return SQLITE_OK; +} + +/* Merge MERGE_COUNT segments at iLevel into a new segment at +** iLevel+1. If iLevel+1 is already full of segments, those will be +** merged to make room. +*/ +static int segmentMerge(fulltext_vtab *v, int iLevel){ + LeafWriter writer; + LeavesReader lrs[MERGE_COUNT]; + int i, rc, idx = 0; + + /* Determine the next available segment index at the next level, + ** merging as necessary. + */ + rc = segdirNextIndex(v, iLevel+1, &idx); + if( rc!=SQLITE_OK ) return rc; + + /* TODO(shess) This assumes that we'll always see exactly + ** MERGE_COUNT segments to merge at a given level. That will be + ** broken if we allow the developer to request preemptive or + ** deferred merging. + */ + memset(&lrs, '\0', sizeof(lrs)); + rc = leavesReadersInit(v, iLevel, lrs, &i); + if( rc!=SQLITE_OK ) return rc; + assert( i==MERGE_COUNT ); + + leafWriterInit(iLevel+1, idx, &writer); + + /* Since leavesReaderReorder() pushes readers at eof to the end, + ** when the first reader is empty, all will be empty. + */ + while( !leavesReaderAtEnd(lrs) ){ + /* Figure out how many readers share their next term. */ + for(i=1; i<MERGE_COUNT && !leavesReaderAtEnd(lrs+i); i++){ + if( 0!=leavesReaderTermCmp(lrs, lrs+i) ) break; + } + + rc = leavesReadersMerge(v, lrs, i, &writer); + if( rc!=SQLITE_OK ) goto err; + + /* Step forward those that were merged. */ + while( i-->0 ){ + rc = leavesReaderStep(v, lrs+i); + if( rc!=SQLITE_OK ) goto err; + + /* Reorder by term, then by age. */ + leavesReaderReorder(lrs+i, MERGE_COUNT-i); + } + } + + for(i=0; i<MERGE_COUNT; i++){ + leavesReaderDestroy(&lrs[i]); + } + + rc = leafWriterFinalize(v, &writer); + leafWriterDestroy(&writer); + if( rc!=SQLITE_OK ) return rc; + + /* Delete the merged segment data. */ + return segdir_delete(v, iLevel); + + err: + for(i=0; i<MERGE_COUNT; i++){ + leavesReaderDestroy(&lrs[i]); + } + leafWriterDestroy(&writer); + return rc; +} + +/* Scan pReader for pTerm/nTerm, and merge the term's doclist over +** *out (any doclists with duplicate docids overwrite those in *out). +** Internal function for loadSegmentLeaf(). +*/ +static int loadSegmentLeavesInt(fulltext_vtab *v, LeavesReader *pReader, + const char *pTerm, int nTerm, int isPrefix, + DataBuffer *out){ + assert( nTerm>0 ); + + /* Process while the prefix matches. */ + while( !leavesReaderAtEnd(pReader) ){ + /* TODO(shess) Really want leavesReaderTermCmp(), but that name is + ** already taken to compare the terms of two LeavesReaders. Think + ** on a better name. [Meanwhile, break encapsulation rather than + ** use a confusing name.] + */ + int rc; + int c = leafReaderTermCmp(&pReader->leafReader, pTerm, nTerm, isPrefix); + if( c==0 ){ + const char *pData = leavesReaderData(pReader); + int nData = leavesReaderDataBytes(pReader); + if( out->nData==0 ){ + dataBufferReplace(out, pData, nData); + }else{ + DataBuffer result; + dataBufferInit(&result, out->nData+nData); + docListUnion(out->pData, out->nData, pData, nData, &result); + dataBufferDestroy(out); + *out = result; + /* TODO(shess) Rather than destroy out, we could retain it for + ** later reuse. + */ + } + } + if( c>0 ) break; /* Past any possible matches. */ + + rc = leavesReaderStep(v, pReader); + if( rc!=SQLITE_OK ) return rc; + } + return SQLITE_OK; +} + +/* Call loadSegmentLeavesInt() with pData/nData as input. */ +static int loadSegmentLeaf(fulltext_vtab *v, const char *pData, int nData, + const char *pTerm, int nTerm, int isPrefix, + DataBuffer *out){ + LeavesReader reader; + int rc; + + assert( nData>1 ); + assert( *pData=='\0' ); + rc = leavesReaderInit(v, 0, 0, 0, pData, nData, &reader); + if( rc!=SQLITE_OK ) return rc; + + rc = loadSegmentLeavesInt(v, &reader, pTerm, nTerm, isPrefix, out); + leavesReaderReset(&reader); + leavesReaderDestroy(&reader); + return rc; +} + +/* Call loadSegmentLeavesInt() with the leaf nodes from iStartLeaf to +** iEndLeaf (inclusive) as input, and merge the resulting doclist into +** out. +*/ +static int loadSegmentLeaves(fulltext_vtab *v, + sqlite_int64 iStartLeaf, sqlite_int64 iEndLeaf, + const char *pTerm, int nTerm, int isPrefix, + DataBuffer *out){ + int rc; + LeavesReader reader; + + assert( iStartLeaf<=iEndLeaf ); + rc = leavesReaderInit(v, 0, iStartLeaf, iEndLeaf, NULL, 0, &reader); + if( rc!=SQLITE_OK ) return rc; + + rc = loadSegmentLeavesInt(v, &reader, pTerm, nTerm, isPrefix, out); + leavesReaderReset(&reader); + leavesReaderDestroy(&reader); + return rc; +} + +/* Taking pData/nData as an interior node, find the sequence of child +** nodes which could include pTerm/nTerm/isPrefix. Note that the +** interior node terms logically come between the blocks, so there is +** one more blockid than there are terms (that block contains terms >= +** the last interior-node term). +*/ +/* TODO(shess) The calling code may already know that the end child is +** not worth calculating, because the end may be in a later sibling +** node. Consider whether breaking symmetry is worthwhile. I suspect +** it's not worthwhile. +*/ +static void getChildrenContaining(const char *pData, int nData, + const char *pTerm, int nTerm, int isPrefix, + sqlite_int64 *piStartChild, + sqlite_int64 *piEndChild){ + InteriorReader reader; + + assert( nData>1 ); + assert( *pData!='\0' ); + interiorReaderInit(pData, nData, &reader); + + /* Scan for the first child which could contain pTerm/nTerm. */ + while( !interiorReaderAtEnd(&reader) ){ + if( interiorReaderTermCmp(&reader, pTerm, nTerm, 0)>0 ) break; + interiorReaderStep(&reader); + } + *piStartChild = interiorReaderCurrentBlockid(&reader); + + /* Keep scanning to find a term greater than our term, using prefix + ** comparison if indicated. If isPrefix is false, this will be the + ** same blockid as the starting block. + */ + while( !interiorReaderAtEnd(&reader) ){ + if( interiorReaderTermCmp(&reader, pTerm, nTerm, isPrefix)>0 ) break; + interiorReaderStep(&reader); + } + *piEndChild = interiorReaderCurrentBlockid(&reader); + + interiorReaderDestroy(&reader); + + /* Children must ascend, and if !prefix, both must be the same. */ + assert( *piEndChild>=*piStartChild ); + assert( isPrefix || *piStartChild==*piEndChild ); +} + +/* Read block at iBlockid and pass it with other params to +** getChildrenContaining(). +*/ +static int loadAndGetChildrenContaining( + fulltext_vtab *v, + sqlite_int64 iBlockid, + const char *pTerm, int nTerm, int isPrefix, + sqlite_int64 *piStartChild, sqlite_int64 *piEndChild +){ + sqlite3_stmt *s = NULL; + int rc; + + assert( iBlockid!=0 ); + assert( pTerm!=NULL ); + assert( nTerm!=0 ); /* TODO(shess) Why not allow this? */ + assert( piStartChild!=NULL ); + assert( piEndChild!=NULL ); + + rc = sql_get_statement(v, BLOCK_SELECT_STMT, &s); + if( rc!=SQLITE_OK ) return rc; + + rc = sqlite3_bind_int64(s, 1, iBlockid); + if( rc!=SQLITE_OK ) return rc; + + rc = sqlite3_step(s); + if( rc==SQLITE_DONE ) return SQLITE_ERROR; + if( rc!=SQLITE_ROW ) return rc; + + getChildrenContaining(sqlite3_column_blob(s, 0), sqlite3_column_bytes(s, 0), + pTerm, nTerm, isPrefix, piStartChild, piEndChild); + + /* We expect only one row. We must execute another sqlite3_step() + * to complete the iteration; otherwise the table will remain + * locked. */ + rc = sqlite3_step(s); + if( rc==SQLITE_ROW ) return SQLITE_ERROR; + if( rc!=SQLITE_DONE ) return rc; + + return SQLITE_OK; +} + +/* Traverse the tree represented by pData[nData] looking for +** pTerm[nTerm], placing its doclist into *out. This is internal to +** loadSegment() to make error-handling cleaner. +*/ +static int loadSegmentInt(fulltext_vtab *v, const char *pData, int nData, + sqlite_int64 iLeavesEnd, + const char *pTerm, int nTerm, int isPrefix, + DataBuffer *out){ + /* Special case where root is a leaf. */ + if( *pData=='\0' ){ + return loadSegmentLeaf(v, pData, nData, pTerm, nTerm, isPrefix, out); + }else{ + int rc; + sqlite_int64 iStartChild, iEndChild; + + /* Process pData as an interior node, then loop down the tree + ** until we find the set of leaf nodes to scan for the term. + */ + getChildrenContaining(pData, nData, pTerm, nTerm, isPrefix, + &iStartChild, &iEndChild); + while( iStartChild>iLeavesEnd ){ + sqlite_int64 iNextStart, iNextEnd; + rc = loadAndGetChildrenContaining(v, iStartChild, pTerm, nTerm, isPrefix, + &iNextStart, &iNextEnd); + if( rc!=SQLITE_OK ) return rc; + + /* If we've branched, follow the end branch, too. */ + if( iStartChild!=iEndChild ){ + sqlite_int64 iDummy; + rc = loadAndGetChildrenContaining(v, iEndChild, pTerm, nTerm, isPrefix, + &iDummy, &iNextEnd); + if( rc!=SQLITE_OK ) return rc; + } + + assert( iNextStart<=iNextEnd ); + iStartChild = iNextStart; + iEndChild = iNextEnd; + } + assert( iStartChild<=iLeavesEnd ); + assert( iEndChild<=iLeavesEnd ); + + /* Scan through the leaf segments for doclists. */ + return loadSegmentLeaves(v, iStartChild, iEndChild, + pTerm, nTerm, isPrefix, out); + } +} + +/* Call loadSegmentInt() to collect the doclist for pTerm/nTerm, then +** merge its doclist over *out (any duplicate doclists read from the +** segment rooted at pData will overwrite those in *out). +*/ +/* TODO(shess) Consider changing this to determine the depth of the +** leaves using either the first characters of interior nodes (when +** ==1, we're one level above the leaves), or the first character of +** the root (which will describe the height of the tree directly). +** Either feels somewhat tricky to me. +*/ +/* TODO(shess) The current merge is likely to be slow for large +** doclists (though it should process from newest/smallest to +** oldest/largest, so it may not be that bad). It might be useful to +** modify things to allow for N-way merging. This could either be +** within a segment, with pairwise merges across segments, or across +** all segments at once. +*/ +static int loadSegment(fulltext_vtab *v, const char *pData, int nData, + sqlite_int64 iLeavesEnd, + const char *pTerm, int nTerm, int isPrefix, + DataBuffer *out){ + DataBuffer result; + int rc; + + assert( nData>1 ); + + /* This code should never be called with buffered updates. */ + assert( v->nPendingData<0 ); + + dataBufferInit(&result, 0); + rc = loadSegmentInt(v, pData, nData, iLeavesEnd, + pTerm, nTerm, isPrefix, &result); + if( rc==SQLITE_OK && result.nData>0 ){ + if( out->nData==0 ){ + DataBuffer tmp = *out; + *out = result; + result = tmp; + }else{ + DataBuffer merged; + DLReader readers[2]; + + dlrInit(&readers[0], DL_DEFAULT, out->pData, out->nData); + dlrInit(&readers[1], DL_DEFAULT, result.pData, result.nData); + dataBufferInit(&merged, out->nData+result.nData); + docListMerge(&merged, readers, 2); + dataBufferDestroy(out); + *out = merged; + dlrDestroy(&readers[0]); + dlrDestroy(&readers[1]); + } + } + dataBufferDestroy(&result); + return rc; +} + +/* Scan the database and merge together the posting lists for the term +** into *out. +*/ +static int termSelect(fulltext_vtab *v, int iColumn, + const char *pTerm, int nTerm, int isPrefix, + DocListType iType, DataBuffer *out){ + DataBuffer doclist; + sqlite3_stmt *s; + int rc = sql_get_statement(v, SEGDIR_SELECT_ALL_STMT, &s); + if( rc!=SQLITE_OK ) return rc; + + /* This code should never be called with buffered updates. */ + assert( v->nPendingData<0 ); + + dataBufferInit(&doclist, 0); + + /* Traverse the segments from oldest to newest so that newer doclist + ** elements for given docids overwrite older elements. + */ + while( (rc = sqlite3_step(s))==SQLITE_ROW ){ + const char *pData = sqlite3_column_blob(s, 0); + const int nData = sqlite3_column_bytes(s, 0); + const sqlite_int64 iLeavesEnd = sqlite3_column_int64(s, 1); + rc = loadSegment(v, pData, nData, iLeavesEnd, pTerm, nTerm, isPrefix, + &doclist); + if( rc!=SQLITE_OK ) goto err; + } + if( rc==SQLITE_DONE ){ + if( doclist.nData!=0 ){ + /* TODO(shess) The old term_select_all() code applied the column + ** restrict as we merged segments, leading to smaller buffers. + ** This is probably worthwhile to bring back, once the new storage + ** system is checked in. + */ + if( iColumn==v->nColumn) iColumn = -1; + docListTrim(DL_DEFAULT, doclist.pData, doclist.nData, + iColumn, iType, out); + } + rc = SQLITE_OK; + } + + err: + dataBufferDestroy(&doclist); + return rc; +} + +/****************************************************************/ +/* Used to hold hashtable data for sorting. */ +typedef struct TermData { + const char *pTerm; + int nTerm; + DLCollector *pCollector; +} TermData; + +/* Orders TermData elements in strcmp fashion ( <0 for less-than, 0 +** for equal, >0 for greater-than). +*/ +static int termDataCmp(const void *av, const void *bv){ + const TermData *a = (const TermData *)av; + const TermData *b = (const TermData *)bv; + int n = a->nTerm<b->nTerm ? a->nTerm : b->nTerm; + int c = memcmp(a->pTerm, b->pTerm, n); + if( c!=0 ) return c; + return a->nTerm-b->nTerm; +} + +/* Order pTerms data by term, then write a new level 0 segment using +** LeafWriter. +*/ +static int writeZeroSegment(fulltext_vtab *v, fts3Hash *pTerms){ + fts3HashElem *e; + int idx, rc, i, n; + TermData *pData; + LeafWriter writer; + DataBuffer dl; + + /* Determine the next index at level 0, merging as necessary. */ + rc = segdirNextIndex(v, 0, &idx); + if( rc!=SQLITE_OK ) return rc; + + n = fts3HashCount(pTerms); + pData = sqlite3_malloc(n*sizeof(TermData)); + + for(i = 0, e = fts3HashFirst(pTerms); e; i++, e = fts3HashNext(e)){ + assert( i<n ); + pData[i].pTerm = fts3HashKey(e); + pData[i].nTerm = fts3HashKeysize(e); + pData[i].pCollector = fts3HashData(e); + } + assert( i==n ); + + /* TODO(shess) Should we allow user-defined collation sequences, + ** here? I think we only need that once we support prefix searches. + */ + if( n>1 ) qsort(pData, n, sizeof(*pData), termDataCmp); + + /* TODO(shess) Refactor so that we can write directly to the segment + ** DataBuffer, as happens for segment merges. + */ + leafWriterInit(0, idx, &writer); + dataBufferInit(&dl, 0); + for(i=0; i<n; i++){ + dataBufferReset(&dl); + dlcAddDoclist(pData[i].pCollector, &dl); + rc = leafWriterStep(v, &writer, + pData[i].pTerm, pData[i].nTerm, dl.pData, dl.nData); + if( rc!=SQLITE_OK ) goto err; + } + rc = leafWriterFinalize(v, &writer); + + err: + dataBufferDestroy(&dl); + sqlite3_free(pData); + leafWriterDestroy(&writer); + return rc; +} + +/* If pendingTerms has data, free it. */ +static int clearPendingTerms(fulltext_vtab *v){ + if( v->nPendingData>=0 ){ + fts3HashElem *e; + for(e=fts3HashFirst(&v->pendingTerms); e; e=fts3HashNext(e)){ + dlcDelete(fts3HashData(e)); + } + fts3HashClear(&v->pendingTerms); + v->nPendingData = -1; + } + return SQLITE_OK; +} + +/* If pendingTerms has data, flush it to a level-zero segment, and +** free it. +*/ +static int flushPendingTerms(fulltext_vtab *v){ + if( v->nPendingData>=0 ){ + int rc = writeZeroSegment(v, &v->pendingTerms); + if( rc==SQLITE_OK ) clearPendingTerms(v); + return rc; + } + return SQLITE_OK; +} + +/* If pendingTerms is "too big", or docid is out of order, flush it. +** Regardless, be certain that pendingTerms is initialized for use. +*/ +static int initPendingTerms(fulltext_vtab *v, sqlite_int64 iDocid){ + /* TODO(shess) Explore whether partially flushing the buffer on + ** forced-flush would provide better performance. I suspect that if + ** we ordered the doclists by size and flushed the largest until the + ** buffer was half empty, that would let the less frequent terms + ** generate longer doclists. + */ + if( iDocid<=v->iPrevDocid || v->nPendingData>kPendingThreshold ){ + int rc = flushPendingTerms(v); + if( rc!=SQLITE_OK ) return rc; + } + if( v->nPendingData<0 ){ + fts3HashInit(&v->pendingTerms, FTS3_HASH_STRING, 1); + v->nPendingData = 0; + } + v->iPrevDocid = iDocid; + return SQLITE_OK; +} + +/* This function implements the xUpdate callback; it's the top-level entry + * point for inserting, deleting or updating a row in a full-text table. */ +static int fulltextUpdate(sqlite3_vtab *pVtab, int nArg, sqlite3_value **ppArg, + sqlite_int64 *pRowid){ + fulltext_vtab *v = (fulltext_vtab *) pVtab; + int rc; + + FTSTRACE(("FTS3 Update %p\n", pVtab)); + + if( nArg<2 ){ + rc = index_delete(v, sqlite3_value_int64(ppArg[0])); + } else if( sqlite3_value_type(ppArg[0]) != SQLITE_NULL ){ + /* An update: + * ppArg[0] = old rowid + * ppArg[1] = new rowid + * ppArg[2..2+v->nColumn-1] = values + * ppArg[2+v->nColumn] = value for magic column (we ignore this) + * ppArg[2+v->nColumn+1] = value for docid + */ + sqlite_int64 rowid = sqlite3_value_int64(ppArg[0]); + if( sqlite3_value_type(ppArg[1]) != SQLITE_INTEGER || + sqlite3_value_int64(ppArg[1]) != rowid ){ + rc = SQLITE_ERROR; /* we don't allow changing the rowid */ + }else if( sqlite3_value_type(ppArg[2+v->nColumn+1]) != SQLITE_INTEGER || + sqlite3_value_int64(ppArg[2+v->nColumn+1]) != rowid ){ + rc = SQLITE_ERROR; /* we don't allow changing the docid */ + }else{ + assert( nArg==2+v->nColumn+2); + rc = index_update(v, rowid, &ppArg[2]); + } + } else { + /* An insert: + * ppArg[1] = requested rowid + * ppArg[2..2+v->nColumn-1] = values + * ppArg[2+v->nColumn] = value for magic column (we ignore this) + * ppArg[2+v->nColumn+1] = value for docid + */ + sqlite3_value *pRequestDocid = ppArg[2+v->nColumn+1]; + assert( nArg==2+v->nColumn+2); + if( SQLITE_NULL != sqlite3_value_type(pRequestDocid) && + SQLITE_NULL != sqlite3_value_type(ppArg[1]) ){ + /* TODO(shess) Consider allowing this to work if the values are + ** identical. I'm inclined to discourage that usage, though, + ** given that both rowid and docid are special columns. Better + ** would be to define one or the other as the default winner, + ** but should it be fts3-centric (docid) or SQLite-centric + ** (rowid)? + */ + rc = SQLITE_ERROR; + }else{ + if( SQLITE_NULL == sqlite3_value_type(pRequestDocid) ){ + pRequestDocid = ppArg[1]; + } + rc = index_insert(v, pRequestDocid, &ppArg[2], pRowid); + } + } + + return rc; +} + +static int fulltextSync(sqlite3_vtab *pVtab){ + FTSTRACE(("FTS3 xSync()\n")); + return flushPendingTerms((fulltext_vtab *)pVtab); +} + +static int fulltextBegin(sqlite3_vtab *pVtab){ + fulltext_vtab *v = (fulltext_vtab *) pVtab; + FTSTRACE(("FTS3 xBegin()\n")); + + /* Any buffered updates should have been cleared by the previous + ** transaction. + */ + assert( v->nPendingData<0 ); + return clearPendingTerms(v); +} + +static int fulltextCommit(sqlite3_vtab *pVtab){ + fulltext_vtab *v = (fulltext_vtab *) pVtab; + FTSTRACE(("FTS3 xCommit()\n")); + + /* Buffered updates should have been cleared by fulltextSync(). */ + assert( v->nPendingData<0 ); + return clearPendingTerms(v); +} + +static int fulltextRollback(sqlite3_vtab *pVtab){ + FTSTRACE(("FTS3 xRollback()\n")); + return clearPendingTerms((fulltext_vtab *)pVtab); +} + +/* +** Implementation of the snippet() function for FTS3 +*/ +static void snippetFunc( + sqlite3_context *pContext, + int argc, + sqlite3_value **argv +){ + fulltext_cursor *pCursor; + if( argc<1 ) return; + if( sqlite3_value_type(argv[0])!=SQLITE_BLOB || + sqlite3_value_bytes(argv[0])!=sizeof(pCursor) ){ + sqlite3_result_error(pContext, "illegal first argument to html_snippet",-1); + }else{ + const char *zStart = "<b>"; + const char *zEnd = "</b>"; + const char *zEllipsis = "<b>...</b>"; + memcpy(&pCursor, sqlite3_value_blob(argv[0]), sizeof(pCursor)); + if( argc>=2 ){ + zStart = (const char*)sqlite3_value_text(argv[1]); + if( argc>=3 ){ + zEnd = (const char*)sqlite3_value_text(argv[2]); + if( argc>=4 ){ + zEllipsis = (const char*)sqlite3_value_text(argv[3]); + } + } + } + snippetAllOffsets(pCursor); + snippetText(pCursor, zStart, zEnd, zEllipsis); + sqlite3_result_text(pContext, pCursor->snippet.zSnippet, + pCursor->snippet.nSnippet, SQLITE_STATIC); + } +} + +/* +** Implementation of the offsets() function for FTS3 +*/ +static void snippetOffsetsFunc( + sqlite3_context *pContext, + int argc, + sqlite3_value **argv +){ + fulltext_cursor *pCursor; + if( argc<1 ) return; + if( sqlite3_value_type(argv[0])!=SQLITE_BLOB || + sqlite3_value_bytes(argv[0])!=sizeof(pCursor) ){ + sqlite3_result_error(pContext, "illegal first argument to offsets",-1); + }else{ + memcpy(&pCursor, sqlite3_value_blob(argv[0]), sizeof(pCursor)); + snippetAllOffsets(pCursor); + snippetOffsetText(&pCursor->snippet); + sqlite3_result_text(pContext, + pCursor->snippet.zOffset, pCursor->snippet.nOffset, + SQLITE_STATIC); + } +} + +/* +** This routine implements the xFindFunction method for the FTS3 +** virtual table. +*/ +static int fulltextFindFunction( + sqlite3_vtab *pVtab, + int nArg, + const char *zName, + void (**pxFunc)(sqlite3_context*,int,sqlite3_value**), + void **ppArg +){ + if( strcmp(zName,"snippet")==0 ){ + *pxFunc = snippetFunc; + return 1; + }else if( strcmp(zName,"offsets")==0 ){ + *pxFunc = snippetOffsetsFunc; + return 1; + } + return 0; +} + +/* +** Rename an fts3 table. +*/ +static int fulltextRename( + sqlite3_vtab *pVtab, + const char *zName +){ + fulltext_vtab *p = (fulltext_vtab *)pVtab; + int rc = SQLITE_NOMEM; + char *zSql = sqlite3_mprintf( + "ALTER TABLE %Q.'%q_content' RENAME TO '%q_content';" + "ALTER TABLE %Q.'%q_segments' RENAME TO '%q_segments';" + "ALTER TABLE %Q.'%q_segdir' RENAME TO '%q_segdir';" + , p->zDb, p->zName, zName + , p->zDb, p->zName, zName + , p->zDb, p->zName, zName + ); + if( zSql ){ + rc = sqlite3_exec(p->db, zSql, 0, 0, 0); + sqlite3_free(zSql); + } + return rc; +} + +static const sqlite3_module fts3Module = { + /* iVersion */ 0, + /* xCreate */ fulltextCreate, + /* xConnect */ fulltextConnect, + /* xBestIndex */ fulltextBestIndex, + /* xDisconnect */ fulltextDisconnect, + /* xDestroy */ fulltextDestroy, + /* xOpen */ fulltextOpen, + /* xClose */ fulltextClose, + /* xFilter */ fulltextFilter, + /* xNext */ fulltextNext, + /* xEof */ fulltextEof, + /* xColumn */ fulltextColumn, + /* xRowid */ fulltextRowid, + /* xUpdate */ fulltextUpdate, + /* xBegin */ fulltextBegin, + /* xSync */ fulltextSync, + /* xCommit */ fulltextCommit, + /* xRollback */ fulltextRollback, + /* xFindFunction */ fulltextFindFunction, + /* xRename */ fulltextRename, +}; + +static void hashDestroy(void *p){ + fts3Hash *pHash = (fts3Hash *)p; + sqlite3Fts3HashClear(pHash); + sqlite3_free(pHash); +} + +/* +** The fts3 built-in tokenizers - "simple" and "porter" - are implemented +** in files fts3_tokenizer1.c and fts3_porter.c respectively. The following +** two forward declarations are for functions declared in these files +** used to retrieve the respective implementations. +** +** Calling sqlite3Fts3SimpleTokenizerModule() sets the value pointed +** to by the argument to point a the "simple" tokenizer implementation. +** Function ...PorterTokenizerModule() sets *pModule to point to the +** porter tokenizer/stemmer implementation. +*/ +void sqlite3Fts3SimpleTokenizerModule(sqlite3_tokenizer_module const**ppModule); +void sqlite3Fts3PorterTokenizerModule(sqlite3_tokenizer_module const**ppModule); +void sqlite3Fts3IcuTokenizerModule(sqlite3_tokenizer_module const**ppModule); + +int sqlite3Fts3InitHashTable(sqlite3 *, fts3Hash *, const char *); + +/* +** Initialise the fts3 extension. If this extension is built as part +** of the sqlite library, then this function is called directly by +** SQLite. If fts3 is built as a dynamically loadable extension, this +** function is called by the sqlite3_extension_init() entry point. +*/ +int sqlite3Fts3Init(sqlite3 *db){ + int rc = SQLITE_OK; + fts3Hash *pHash = 0; + const sqlite3_tokenizer_module *pSimple = 0; + const sqlite3_tokenizer_module *pPorter = 0; + const sqlite3_tokenizer_module *pIcu = 0; + + sqlite3Fts3SimpleTokenizerModule(&pSimple); + sqlite3Fts3PorterTokenizerModule(&pPorter); +#ifdef SQLITE_ENABLE_ICU + sqlite3Fts3IcuTokenizerModule(&pIcu); +#endif + + /* Allocate and initialise the hash-table used to store tokenizers. */ + pHash = sqlite3_malloc(sizeof(fts3Hash)); + if( !pHash ){ + rc = SQLITE_NOMEM; + }else{ + sqlite3Fts3HashInit(pHash, FTS3_HASH_STRING, 1); + } + + /* Load the built-in tokenizers into the hash table */ + if( rc==SQLITE_OK ){ + if( sqlite3Fts3HashInsert(pHash, "simple", 7, (void *)pSimple) + || sqlite3Fts3HashInsert(pHash, "porter", 7, (void *)pPorter) + || (pIcu && sqlite3Fts3HashInsert(pHash, "icu", 4, (void *)pIcu)) + ){ + rc = SQLITE_NOMEM; + } + } + + /* Create the virtual table wrapper around the hash-table and overload + ** the two scalar functions. If this is successful, register the + ** module with sqlite. + */ + if( SQLITE_OK==rc + && SQLITE_OK==(rc = sqlite3Fts3InitHashTable(db, pHash, "fts3_tokenizer")) + && SQLITE_OK==(rc = sqlite3_overload_function(db, "snippet", -1)) + && SQLITE_OK==(rc = sqlite3_overload_function(db, "offsets", -1)) + ){ + return sqlite3_create_module_v2( + db, "fts3", &fts3Module, (void *)pHash, hashDestroy + ); + } + + /* An error has occured. Delete the hash table and return the error code. */ + assert( rc!=SQLITE_OK ); + if( pHash ){ + sqlite3Fts3HashClear(pHash); + sqlite3_free(pHash); + } + return rc; +} + +#if !SQLITE_CORE +int sqlite3_extension_init( + sqlite3 *db, + char **pzErrMsg, + const sqlite3_api_routines *pApi +){ + SQLITE_EXTENSION_INIT2(pApi) + return sqlite3Fts3Init(db); +} +#endif + +#endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) */ + +/************** End of fts3.c ************************************************/ +/************** Begin file fts3_hash.c ***************************************/ +/* +** 2001 September 22 +** +** 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 is the implementation of generic hash-tables used in SQLite. +** We've modified it slightly to serve as a standalone hash table +** implementation for the full-text indexing module. +*/ + +/* +** The code in this file is only compiled if: +** +** * The FTS3 module is being built as an extension +** (in which case SQLITE_CORE is not defined), or +** +** * The FTS3 module is being built into the core of +** SQLite (in which case SQLITE_ENABLE_FTS3 is defined). +*/ +#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) + + +/************** Include sqlite3.h in the middle of fts3_hash.c ***************/ +/************** Begin file sqlite3.h *****************************************/ +/* +** 2001 September 15 +** +** 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 header file defines the interface that the SQLite library +** presents to client programs. If a C-function, structure, datatype, +** or constant definition does not appear in this file, then it is +** not a published API of SQLite, is subject to change without +** notice, and should not be referenced by programs that use SQLite. +** +** Some of the definitions that are in this file are marked as +** "experimental". Experimental interfaces are normally new +** features recently added to SQLite. We do not anticipate changes +** to experimental interfaces but reserve to make minor changes if +** experience from use "in the wild" suggest such changes are prudent. +** +** The official C-language API documentation for SQLite is derived +** from comments in this file. This file is the authoritative source +** on how SQLite interfaces are suppose to operate. +** +** The name of this file under configuration management is "sqlite.h.in". +** The makefile makes some minor changes to this file (such as inserting +** the version number) and changes its name to "sqlite3.h" as +** part of the build process. +** +** @(#) $Id: sqlite.h.in,v 1.271 2007/11/21 15:24:01 drh Exp $ +*/ +#ifndef _SQLITE3_H_ +#define _SQLITE3_H_ + +/* +** Make sure we can call this stuff from C++. +*/ +#if 0 +extern "C" { +#endif + + +/* +** Add the ability to override 'extern' +*/ +#ifndef SQLITE_EXTERN +# define SQLITE_EXTERN extern +#endif + +/* +** Make sure these symbols where not defined by some previous header +** file. +*/ +#ifdef SQLITE_VERSION +# undef SQLITE_VERSION +#endif +#ifdef SQLITE_VERSION_NUMBER +# undef SQLITE_VERSION_NUMBER +#endif + +/* +** CAPI3REF: Compile-Time Library Version Numbers +** +** The version of the SQLite library is contained in the sqlite3.h +** header file in a #define named SQLITE_VERSION. The SQLITE_VERSION +** macro resolves to a string constant. +** +** The format of the version string is "X.Y.Z", where +** X is the major version number, Y is the minor version number and Z +** is the release number. The X.Y.Z might be followed by "alpha" or "beta". +** For example "3.1.1beta". +** +** The X value is always 3 in SQLite. The X value only changes when +** backwards compatibility is broken and we intend to never break +** backwards compatibility. The Y value only changes when +** there are major feature enhancements that are forwards compatible +** but not backwards compatible. The Z value is incremented with +** each release but resets back to 0 when Y is incremented. +** +** The SQLITE_VERSION_NUMBER is an integer with the value +** (X*1000000 + Y*1000 + Z). For example, for version "3.1.1beta", +** SQLITE_VERSION_NUMBER is set to 3001001. To detect if they are using +** version 3.1.1 or greater at compile time, programs may use the test +** (SQLITE_VERSION_NUMBER>=3001001). +** +** See also: [sqlite3_libversion()] and [sqlite3_libversion_number()]. +*/ +#define SQLITE_VERSION "3.5.2" +#define SQLITE_VERSION_NUMBER 3005002 + +/* +** CAPI3REF: Run-Time Library Version Numbers +** +** These routines return values equivalent to the header constants +** [SQLITE_VERSION] and [SQLITE_VERSION_NUMBER]. The values returned +** by this routines should only be different from the header values +** if you compile your program using an sqlite3.h header from a +** different version of SQLite that the version of the library you +** link against. +** +** The sqlite3_version[] string constant contains the text of the +** [SQLITE_VERSION] string. The sqlite3_libversion() function returns +** a poiner to the sqlite3_version[] string constant. The function +** is provided for DLL users who can only access functions and not +** constants within the DLL. +*/ +SQLITE_EXTERN const char sqlite3_version[]; +const char *sqlite3_libversion(void); +int sqlite3_libversion_number(void); + +/* +** CAPI3REF: Test To See If The Library Is Threadsafe +** +** This routine returns TRUE (nonzero) if SQLite was compiled with +** all of its mutexes enabled and is thus threadsafe. It returns +** zero if the particular build is for single-threaded operation +** only. +** +** Really all this routine does is return true if SQLite was compiled +** with the -DSQLITE_THREADSAFE=1 option and false if +** compiled with -DSQLITE_THREADSAFE=0. If SQLite uses an +** application-defined mutex subsystem, malloc subsystem, collating +** sequence, VFS, SQL function, progress callback, commit hook, +** extension, or other accessories and these add-ons are not +** threadsafe, then clearly the combination will not be threadsafe +** either. Hence, this routine never reports that the library +** is guaranteed to be threadsafe, only when it is guaranteed not +** to be. +** +** This is an experimental API and may go away or change in future +** releases. +*/ +int sqlite3_threadsafe(void); + +/* +** CAPI3REF: Database Connection Handle +** +** Each open SQLite database is represented by pointer to an instance of the +** opaque structure named "sqlite3". It is useful to think of an sqlite3 +** pointer as an object. The [sqlite3_open()], [sqlite3_open16()], and +** [sqlite3_open_v2()] interfaces are its constructors +** and [sqlite3_close()] is its destructor. There are many other interfaces +** (such as [sqlite3_prepare_v2()], [sqlite3_create_function()], and +** [sqlite3_busy_timeout()] to name but three) that are methods on this +** object. +*/ +typedef struct sqlite3 sqlite3; + + +/* +** CAPI3REF: 64-Bit Integer Types +** +** Some compilers do not support the "long long" datatype. So we have +** to do compiler-specific typedefs for 64-bit signed and unsigned integers. +** +** Many SQLite interface functions require a 64-bit integer arguments. +** Those interfaces are declared using this typedef. +*/ +#ifdef SQLITE_INT64_TYPE + typedef SQLITE_INT64_TYPE sqlite_int64; + typedef unsigned SQLITE_INT64_TYPE sqlite_uint64; +#elif defined(_MSC_VER) || defined(__BORLANDC__) + typedef __int64 sqlite_int64; + typedef unsigned __int64 sqlite_uint64; +#else + typedef long long int sqlite_int64; + typedef unsigned long long int sqlite_uint64; +#endif +typedef sqlite_int64 sqlite3_int64; +typedef sqlite_uint64 sqlite3_uint64; + +/* +** If compiling for a processor that lacks floating point support, +** substitute integer for floating-point +*/ +#ifdef SQLITE_OMIT_FLOATING_POINT +# define double sqlite3_int64 +#endif + +/* +** CAPI3REF: Closing A Database Connection +** +** Call this function with a pointer to a structure that was previously +** returned from [sqlite3_open()], [sqlite3_open16()], or +** [sqlite3_open_v2()] and the corresponding database will by +** closed. +** +** All SQL statements prepared using [sqlite3_prepare_v2()] or +** [sqlite3_prepare16_v2()] must be destroyed using [sqlite3_finalize()] +** before this routine is called. Otherwise, SQLITE_BUSY is returned and the +** database connection remains open. +** +** Passing this routine a database connection that has already been +** closed results in undefined behavior. If other interfaces that +** reference the same database connection are pending (either in the +** same thread or in different threads) when this routine is called, +** then the behavior is undefined and is almost certainly undesirable. +*/ +int sqlite3_close(sqlite3 *); + +/* +** The type for a callback function. +** This is legacy and deprecated. It is included for historical +** compatibility and is not documented. +*/ +typedef int (*sqlite3_callback)(void*,int,char**, char**); + +/* +** CAPI3REF: One-Step Query Execution Interface +** +** This interface is used to do a one-time evaluatation of zero +** or more SQL statements. UTF-8 text of the SQL statements to +** be evaluted is passed in as the second parameter. The statements +** are prepared one by one using [sqlite3_prepare()], evaluated +** using [sqlite3_step()], then destroyed using [sqlite3_finalize()]. +** +** If one or more of the SQL statements are queries, then +** the callback function specified by the 3rd parameter is +** invoked once for each row of the query result. This callback +** should normally return 0. If the callback returns a non-zero +** value then the query is aborted, all subsequent SQL statements +** are skipped and the sqlite3_exec() function returns the [SQLITE_ABORT]. +** +** The 4th parameter to this interface is an arbitrary pointer that is +** passed through to the callback function as its first parameter. +** +** The 2nd parameter to the callback function is the number of +** columns in the query result. The 3rd parameter to the callback +** is an array of strings holding the values for each column +** as extracted using [sqlite3_column_text()]. +** The 4th parameter to the callback is an array of strings +** obtained using [sqlite3_column_name()] and holding +** the names of each column. +** +** The callback function may be NULL, even for queries. A NULL +** callback is not an error. It just means that no callback +** will be invoked. +** +** If an error occurs while parsing or evaluating the SQL (but +** not while executing the callback) then an appropriate error +** message is written into memory obtained from [sqlite3_malloc()] and +** *errmsg is made to point to that message. The calling function +** is responsible for freeing the memory using [sqlite3_free()]. +** If errmsg==NULL, then no error message is ever written. +** +** The return value is is SQLITE_OK if there are no errors and +** some other [SQLITE_OK | return code] if there is an error. +** The particular return value depends on the type of error. +** +*/ +int sqlite3_exec( + sqlite3*, /* An open database */ + const char *sql, /* SQL to be evaluted */ + int (*callback)(void*,int,char**,char**), /* Callback function */ + void *, /* 1st argument to callback */ + char **errmsg /* Error msg written here */ +); + +/* +** CAPI3REF: Result Codes +** KEYWORDS: SQLITE_OK +** +** Many SQLite functions return an integer result code from the set shown +** above in order to indicates success or failure. +** +** The result codes above are the only ones returned by SQLite in its +** default configuration. However, the [sqlite3_extended_result_codes()] +** API can be used to set a database connectoin to return more detailed +** result codes. +** +** See also: [SQLITE_IOERR_READ | extended result codes] +** +*/ +#define SQLITE_OK 0 /* Successful result */ +/* beginning-of-error-codes */ +#define SQLITE_ERROR 1 /* SQL error or missing database */ +#define SQLITE_INTERNAL 2 /* NOT USED. Internal logic error in SQLite */ +#define SQLITE_PERM 3 /* Access permission denied */ +#define SQLITE_ABORT 4 /* Callback routine requested an abort */ +#define SQLITE_BUSY 5 /* The database file is locked */ +#define SQLITE_LOCKED 6 /* A table in the database is locked */ +#define SQLITE_NOMEM 7 /* A malloc() failed */ +#define SQLITE_READONLY 8 /* Attempt to write a readonly database */ +#define SQLITE_INTERRUPT 9 /* Operation terminated by sqlite3_interrupt()*/ +#define SQLITE_IOERR 10 /* Some kind of disk I/O error occurred */ +#define SQLITE_CORRUPT 11 /* The database disk image is malformed */ +#define SQLITE_NOTFOUND 12 /* NOT USED. Table or record not found */ +#define SQLITE_FULL 13 /* Insertion failed because database is full */ +#define SQLITE_CANTOPEN 14 /* Unable to open the database file */ +#define SQLITE_PROTOCOL 15 /* NOT USED. Database lock protocol error */ +#define SQLITE_EMPTY 16 /* Database is empty */ +#define SQLITE_SCHEMA 17 /* The database schema changed */ +#define SQLITE_TOOBIG 18 /* String or BLOB exceeds size limit */ +#define SQLITE_CONSTRAINT 19 /* Abort due to constraint violation */ +#define SQLITE_MISMATCH 20 /* Data type mismatch */ +#define SQLITE_MISUSE 21 /* Library used incorrectly */ +#define SQLITE_NOLFS 22 /* Uses OS features not supported on host */ +#define SQLITE_AUTH 23 /* Authorization denied */ +#define SQLITE_FORMAT 24 /* Auxiliary database format error */ +#define SQLITE_RANGE 25 /* 2nd parameter to sqlite3_bind out of range */ +#define SQLITE_NOTADB 26 /* File opened that is not a database file */ +#define SQLITE_ROW 100 /* sqlite3_step() has another row ready */ +#define SQLITE_DONE 101 /* sqlite3_step() has finished executing */ +/* end-of-error-codes */ + +/* +** CAPI3REF: Extended Result Codes +** +** In its default configuration, SQLite API routines return one of 26 integer +** result codes described at result-codes. However, experience has shown that +** many of these result codes are too course-grained. They do not provide as +** much information about problems as users might like. In an effort to +** address this, newer versions of SQLite (version 3.3.8 and later) include +** support for additional result codes that provide more detailed information +** about errors. The extended result codes are enabled (or disabled) for +** each database +** connection using the [sqlite3_extended_result_codes()] API. +** +** Some of the available extended result codes are listed above. +** We expect the number of extended result codes will be expand +** over time. Software that uses extended result codes should expect +** to see new result codes in future releases of SQLite. +** +** The symbolic name for an extended result code always contains a related +** primary result code as a prefix. Primary result codes contain a single +** "_" character. Extended result codes contain two or more "_" characters. +** The numeric value of an extended result code can be converted to its +** corresponding primary result code by masking off the lower 8 bytes. +** +** The SQLITE_OK result code will never be extended. It will always +** be exactly zero. +*/ +#define SQLITE_IOERR_READ (SQLITE_IOERR | (1<<8)) +#define SQLITE_IOERR_SHORT_READ (SQLITE_IOERR | (2<<8)) +#define SQLITE_IOERR_WRITE (SQLITE_IOERR | (3<<8)) +#define SQLITE_IOERR_FSYNC (SQLITE_IOERR | (4<<8)) +#define SQLITE_IOERR_DIR_FSYNC (SQLITE_IOERR | (5<<8)) +#define SQLITE_IOERR_TRUNCATE (SQLITE_IOERR | (6<<8)) +#define SQLITE_IOERR_FSTAT (SQLITE_IOERR | (7<<8)) +#define SQLITE_IOERR_UNLOCK (SQLITE_IOERR | (8<<8)) +#define SQLITE_IOERR_RDLOCK (SQLITE_IOERR | (9<<8)) +#define SQLITE_IOERR_DELETE (SQLITE_IOERR | (10<<8)) +#define SQLITE_IOERR_BLOCKED (SQLITE_IOERR | (11<<8)) +#define SQLITE_IOERR_NOMEM (SQLITE_IOERR | (12<<8)) + +/* +** CAPI3REF: Flags For File Open Operations +** +** Combination of the following bit values are used as the +** third argument to the [sqlite3_open_v2()] interface and +** as fourth argument to the xOpen method of the +** [sqlite3_vfs] object. +** +*/ +#define SQLITE_OPEN_READONLY 0x00000001 +#define SQLITE_OPEN_READWRITE 0x00000002 +#define SQLITE_OPEN_CREATE 0x00000004 +#define SQLITE_OPEN_DELETEONCLOSE 0x00000008 +#define SQLITE_OPEN_EXCLUSIVE 0x00000010 +#define SQLITE_OPEN_MAIN_DB 0x00000100 +#define SQLITE_OPEN_TEMP_DB 0x00000200 +#define SQLITE_OPEN_TRANSIENT_DB 0x00000400 +#define SQLITE_OPEN_MAIN_JOURNAL 0x00000800 +#define SQLITE_OPEN_TEMP_JOURNAL 0x00001000 +#define SQLITE_OPEN_SUBJOURNAL 0x00002000 +#define SQLITE_OPEN_MASTER_JOURNAL 0x00004000 + +/* +** CAPI3REF: Device Characteristics +** +** The xDeviceCapabilities method of the [sqlite3_io_methods] +** object returns an integer which is a vector of the following +** bit values expressing I/O characteristics of the mass storage +** device that holds the file that the [sqlite3_io_methods] +** refers to. +** +** The SQLITE_IOCAP_ATOMIC property means that all writes of +** any size are atomic. The SQLITE_IOCAP_ATOMICnnn values +** mean that writes of blocks that are nnn bytes in size and +** are aligned to an address which is an integer multiple of +** nnn are atomic. The SQLITE_IOCAP_SAFE_APPEND value means +** that when data is appended to a file, the data is appended +** first then the size of the file is extended, never the other +** way around. The SQLITE_IOCAP_SEQUENTIAL property means that +** information is written to disk in the same order as calls +** to xWrite(). +*/ +#define SQLITE_IOCAP_ATOMIC 0x00000001 +#define SQLITE_IOCAP_ATOMIC512 0x00000002 +#define SQLITE_IOCAP_ATOMIC1K 0x00000004 +#define SQLITE_IOCAP_ATOMIC2K 0x00000008 +#define SQLITE_IOCAP_ATOMIC4K 0x00000010 +#define SQLITE_IOCAP_ATOMIC8K 0x00000020 +#define SQLITE_IOCAP_ATOMIC16K 0x00000040 +#define SQLITE_IOCAP_ATOMIC32K 0x00000080 +#define SQLITE_IOCAP_ATOMIC64K 0x00000100 +#define SQLITE_IOCAP_SAFE_APPEND 0x00000200 +#define SQLITE_IOCAP_SEQUENTIAL 0x00000400 + +/* +** CAPI3REF: File Locking Levels +** +** SQLite uses one of the following integer values as the second +** argument to calls it makes to the xLock() and xUnlock() methods +** of an [sqlite3_io_methods] object. +*/ +#define SQLITE_LOCK_NONE 0 +#define SQLITE_LOCK_SHARED 1 +#define SQLITE_LOCK_RESERVED 2 +#define SQLITE_LOCK_PENDING 3 +#define SQLITE_LOCK_EXCLUSIVE 4 + +/* +** CAPI3REF: Synchronization Type Flags +** +** When SQLite invokes the xSync() method of an [sqlite3_io_methods] +** object it uses a combination of the following integer values as +** the second argument. +** +** When the SQLITE_SYNC_DATAONLY flag is used, it means that the +** sync operation only needs to flush data to mass storage. Inode +** information need not be flushed. The SQLITE_SYNC_NORMAL means +** to use normal fsync() semantics. The SQLITE_SYNC_FULL flag means +** to use Mac OS-X style fullsync instead of fsync(). +*/ +#define SQLITE_SYNC_NORMAL 0x00002 +#define SQLITE_SYNC_FULL 0x00003 +#define SQLITE_SYNC_DATAONLY 0x00010 + + +/* +** CAPI3REF: OS Interface Open File Handle +** +** An [sqlite3_file] object represents an open file in the OS +** interface layer. Individual OS interface implementations will +** want to subclass this object by appending additional fields +** for their own use. The pMethods entry is a pointer to an +** [sqlite3_io_methods] object that defines methods for performing +** I/O operations on the open file. +*/ +typedef struct sqlite3_file sqlite3_file; +struct sqlite3_file { + const struct sqlite3_io_methods *pMethods; /* Methods for an open file */ +}; + +/* +** CAPI3REF: OS Interface File Virtual Methods Object +** +** Every file opened by the [sqlite3_vfs] xOpen method contains a pointer to +** an instance of the this object. This object defines the +** methods used to perform various operations against the open file. +** +** The flags argument to xSync may be one of [SQLITE_SYNC_NORMAL] or +** [SQLITE_SYNC_FULL]. The first choice is the normal fsync(). +* The second choice is an +** OS-X style fullsync. The SQLITE_SYNC_DATA flag may be ORed in to +** indicate that only the data of the file and not its inode needs to be +** synced. +** +** The integer values to xLock() and xUnlock() are one of +** <ul> +** <li> [SQLITE_LOCK_NONE], +** <li> [SQLITE_LOCK_SHARED], +** <li> [SQLITE_LOCK_RESERVED], +** <li> [SQLITE_LOCK_PENDING], or +** <li> [SQLITE_LOCK_EXCLUSIVE]. +** </ul> +** xLock() increases the lock. xUnlock() decreases the lock. +** The xCheckReservedLock() method looks +** to see if any database connection, either in this +** process or in some other process, is holding an RESERVED, +** PENDING, or EXCLUSIVE lock on the file. It returns true +** if such a lock exists and false if not. +** +** The xFileControl() method is a generic interface that allows custom +** VFS implementations to directly control an open file using the +** [sqlite3_file_control()] interface. The second "op" argument +** is an integer opcode. The third +** argument is a generic pointer which is intended to be a pointer +** to a structure that may contain arguments or space in which to +** write return values. Potential uses for xFileControl() might be +** functions to enable blocking locks with timeouts, to change the +** locking strategy (for example to use dot-file locks), to inquire +** about the status of a lock, or to break stale locks. The SQLite +** core reserves opcodes less than 100 for its own use. +** A [SQLITE_FCNTL_LOCKSTATE | list of opcodes] less than 100 is available. +** Applications that define a custom xFileControl method should use opcodes +** greater than 100 to avoid conflicts. +** +** The xSectorSize() method returns the sector size of the +** device that underlies the file. The sector size is the +** minimum write that can be performed without disturbing +** other bytes in the file. The xDeviceCharacteristics() +** method returns a bit vector describing behaviors of the +** underlying device: +** +** <ul> +** <li> [SQLITE_IOCAP_ATOMIC] +** <li> [SQLITE_IOCAP_ATOMIC512] +** <li> [SQLITE_IOCAP_ATOMIC1K] +** <li> [SQLITE_IOCAP_ATOMIC2K] +** <li> [SQLITE_IOCAP_ATOMIC4K] +** <li> [SQLITE_IOCAP_ATOMIC8K] +** <li> [SQLITE_IOCAP_ATOMIC16K] +** <li> [SQLITE_IOCAP_ATOMIC32K] +** <li> [SQLITE_IOCAP_ATOMIC64K] +** <li> [SQLITE_IOCAP_SAFE_APPEND] +** <li> [SQLITE_IOCAP_SEQUENTIAL] +** </ul> +** +** The SQLITE_IOCAP_ATOMIC property means that all writes of +** any size are atomic. The SQLITE_IOCAP_ATOMICnnn values +** mean that writes of blocks that are nnn bytes in size and +** are aligned to an address which is an integer multiple of +** nnn are atomic. The SQLITE_IOCAP_SAFE_APPEND value means +** that when data is appended to a file, the data is appended +** first then the size of the file is extended, never the other +** way around. The SQLITE_IOCAP_SEQUENTIAL property means that +** information is written to disk in the same order as calls +** to xWrite(). +*/ +typedef struct sqlite3_io_methods sqlite3_io_methods; +struct sqlite3_io_methods { + int iVersion; + int (*xClose)(sqlite3_file*); + int (*xRead)(sqlite3_file*, void*, int iAmt, sqlite3_int64 iOfst); + int (*xWrite)(sqlite3_file*, const void*, int iAmt, sqlite3_int64 iOfst); + int (*xTruncate)(sqlite3_file*, sqlite3_int64 size); + int (*xSync)(sqlite3_file*, int flags); + int (*xFileSize)(sqlite3_file*, sqlite3_int64 *pSize); + int (*xLock)(sqlite3_file*, int); + int (*xUnlock)(sqlite3_file*, int); + int (*xCheckReservedLock)(sqlite3_file*); + int (*xFileControl)(sqlite3_file*, int op, void *pArg); + int (*xSectorSize)(sqlite3_file*); + int (*xDeviceCharacteristics)(sqlite3_file*); + /* Additional methods may be added in future releases */ +}; + +/* +** CAPI3REF: Standard File Control Opcodes +** +** These integer constants are opcodes for the xFileControl method +** of the [sqlite3_io_methods] object and to the [sqlite3_file_control()] +** interface. +** +** The [SQLITE_FCNTL_LOCKSTATE] opcode is used for debugging. This +** opcode cases the xFileControl method to write the current state of +** the lock (one of [SQLITE_LOCK_NONE], [SQLITE_LOCK_SHARED], +** [SQLITE_LOCK_RESERVED], [SQLITE_LOCK_PENDING], or [SQLITE_LOCK_EXCLUSIVE]) +** into an integer that the pArg argument points to. This capability +** is used during testing and only needs to be supported when SQLITE_TEST +** is defined. +*/ +#define SQLITE_FCNTL_LOCKSTATE 1 + +/* +** CAPI3REF: Mutex Handle +** +** The mutex module within SQLite defines [sqlite3_mutex] to be an +** abstract type for a mutex object. The SQLite core never looks +** at the internal representation of an [sqlite3_mutex]. It only +** deals with pointers to the [sqlite3_mutex] object. +** +** Mutexes are created using [sqlite3_mutex_alloc()]. +*/ +typedef struct sqlite3_mutex sqlite3_mutex; + +/* +** CAPI3REF: OS Interface Object +** +** An instance of this object defines the interface between the +** SQLite core and the underlying operating system. The "vfs" +** in the name of the object stands for "virtual file system". +** +** The iVersion field is initially 1 but may be larger for future +** versions of SQLite. Additional fields may be appended to this +** object when the iVersion value is increased. +** +** The szOsFile field is the size of the subclassed [sqlite3_file] +** structure used by this VFS. mxPathname is the maximum length of +** a pathname in this VFS. +** +** Registered vfs modules are kept on a linked list formed by +** the pNext pointer. The [sqlite3_vfs_register()] +** and [sqlite3_vfs_unregister()] interfaces manage this list +** in a thread-safe way. The [sqlite3_vfs_find()] interface +** searches the list. +** +** The pNext field is the only fields in the sqlite3_vfs +** structure that SQLite will ever modify. SQLite will only access +** or modify this field while holding a particular static mutex. +** The application should never modify anything within the sqlite3_vfs +** object once the object has been registered. +** +** The zName field holds the name of the VFS module. The name must +** be unique across all VFS modules. +** +** SQLite will guarantee that the zFilename string passed to +** xOpen() is a full pathname as generated by xFullPathname() and +** that the string will be valid and unchanged until xClose() is +** called. So the [sqlite3_file] can store a pointer to the +** filename if it needs to remember the filename for some reason. +** +** The flags argument to xOpen() is a copy of the flags argument +** to [sqlite3_open_v2()]. If [sqlite3_open()] or [sqlite3_open16()] +** is used, then flags is [SQLITE_OPEN_READWRITE] | [SQLITE_OPEN_CREATE]. +** If xOpen() opens a file read-only then it sets *pOutFlags to +** include [SQLITE_OPEN_READONLY]. Other bits in *pOutFlags may be +** set. +** +** SQLite will also add one of the following flags to the xOpen() +** call, depending on the object being opened: +** +** <ul> +** <li> [SQLITE_OPEN_MAIN_DB] +** <li> [SQLITE_OPEN_MAIN_JOURNAL] +** <li> [SQLITE_OPEN_TEMP_DB] +** <li> [SQLITE_OPEN_TEMP_JOURNAL] +** <li> [SQLITE_OPEN_TRANSIENT_DB] +** <li> [SQLITE_OPEN_SUBJOURNAL] +** <li> [SQLITE_OPEN_MASTER_JOURNAL] +** </ul> +** +** The file I/O implementation can use the object type flags to +** changes the way it deals with files. For example, an application +** that does not care about crash recovery or rollback, might make +** the open of a journal file a no-op. Writes to this journal are +** also a no-op. Any attempt to read the journal return SQLITE_IOERR. +** Or the implementation might recognize the a database file will +** be doing page-aligned sector reads and writes in a random order +** and set up its I/O subsystem accordingly. +** +** SQLite might also add one of the following flags to the xOpen +** method: +** +** <ul> +** <li> [SQLITE_OPEN_DELETEONCLOSE] +** <li> [SQLITE_OPEN_EXCLUSIVE] +** </ul> +** +** The [SQLITE_OPEN_DELETEONCLOSE] flag means the file should be +** deleted when it is closed. This will always be set for TEMP +** databases and journals and for subjournals. The +** [SQLITE_OPEN_EXCLUSIVE] flag means the file should be opened +** for exclusive access. This flag is set for all files except +** for the main database file. +** +** Space to hold the [sqlite3_file] structure passed as the third +** argument to xOpen is allocated by caller (the SQLite core). +** szOsFile bytes are allocated for this object. The xOpen method +** fills in the allocated space. +** +** The flags argument to xAccess() may be [SQLITE_ACCESS_EXISTS] +** to test for the existance of a file, +** or [SQLITE_ACCESS_READWRITE] to test to see +** if a file is readable and writable, or [SQLITE_ACCESS_READ] +** to test to see if a file is at least readable. The file can be a +** directory. +** +** SQLite will always allocate at least mxPathname+1 byte for +** the output buffers for xGetTempname and xFullPathname. The exact +** size of the output buffer is also passed as a parameter to both +** methods. If the output buffer is not large enough, SQLITE_CANTOPEN +** should be returned. As this is handled as a fatal error by SQLite, +** vfs implementations should endevour to prevent this by setting +** mxPathname to a sufficiently large value. +** +** The xRandomness(), xSleep(), and xCurrentTime() interfaces +** are not strictly a part of the filesystem, but they are +** included in the VFS structure for completeness. +** The xRandomness() function attempts to return nBytes bytes +** of good-quality randomness into zOut. The return value is +** the actual number of bytes of randomness obtained. The +** xSleep() method cause the calling thread to sleep for at +** least the number of microseconds given. The xCurrentTime() +** method returns a Julian Day Number for the current date and +** time. +*/ +typedef struct sqlite3_vfs sqlite3_vfs; +struct sqlite3_vfs { + int iVersion; /* Structure version number */ + int szOsFile; /* Size of subclassed sqlite3_file */ + int mxPathname; /* Maximum file pathname length */ + sqlite3_vfs *pNext; /* Next registered VFS */ + const char *zName; /* Name of this virtual file system */ + void *pAppData; /* Pointer to application-specific data */ + int (*xOpen)(sqlite3_vfs*, const char *zName, sqlite3_file*, + int flags, int *pOutFlags); + int (*xDelete)(sqlite3_vfs*, const char *zName, int syncDir); + int (*xAccess)(sqlite3_vfs*, const char *zName, int flags); + int (*xGetTempname)(sqlite3_vfs*, int nOut, char *zOut); + int (*xFullPathname)(sqlite3_vfs*, const char *zName, int nOut, char *zOut); + void *(*xDlOpen)(sqlite3_vfs*, const char *zFilename); + void (*xDlError)(sqlite3_vfs*, int nByte, char *zErrMsg); + void *(*xDlSym)(sqlite3_vfs*,void*, const char *zSymbol); + void (*xDlClose)(sqlite3_vfs*, void*); + int (*xRandomness)(sqlite3_vfs*, int nByte, char *zOut); + int (*xSleep)(sqlite3_vfs*, int microseconds); + int (*xCurrentTime)(sqlite3_vfs*, double*); + /* New fields may be appended in figure versions. The iVersion + ** value will increment whenever this happens. */ +}; + +/* +** CAPI3REF: Flags for the xAccess VFS method +** +** These integer constants can be used as the third parameter to +** the xAccess method of an [sqlite3_vfs] object. They determine +** the kind of what kind of permissions the xAccess method is +** looking for. With SQLITE_ACCESS_EXISTS, the xAccess method +** simply checks to see if the file exists. With SQLITE_ACCESS_READWRITE, +** the xAccess method checks to see if the file is both readable +** and writable. With SQLITE_ACCESS_READ the xAccess method +** checks to see if the file is readable. +*/ +#define SQLITE_ACCESS_EXISTS 0 +#define SQLITE_ACCESS_READWRITE 1 +#define SQLITE_ACCESS_READ 2 + +/* +** CAPI3REF: Enable Or Disable Extended Result Codes +** +** This routine enables or disables the +** [SQLITE_IOERR_READ | extended result codes] feature. +** By default, SQLite API routines return one of only 26 integer +** [SQLITE_OK | result codes]. When extended result codes +** are enabled by this routine, the repetoire of result codes can be +** much larger and can (hopefully) provide more detailed information +** about the cause of an error. +** +** The second argument is a boolean value that turns extended result +** codes on and off. Extended result codes are off by default for +** backwards compatibility with older versions of SQLite. +*/ +int sqlite3_extended_result_codes(sqlite3*, int onoff); + +/* +** CAPI3REF: Last Insert Rowid +** +** Each entry in an SQLite table has a unique 64-bit signed integer key +** called the "rowid". The rowid is always available as an undeclared +** column named ROWID, OID, or _ROWID_. If the table has a column of +** type INTEGER PRIMARY KEY then that column is another an alias for the +** rowid. +** +** This routine returns the rowid of the most recent successful INSERT into +** the database from the database connection given in the first +** argument. If no successful inserts have ever occurred on this database +** connection, zero is returned. +** +** If an INSERT occurs within a trigger, then the rowid of the +** inserted row is returned by this routine as long as the trigger +** is running. But once the trigger terminates, the value returned +** by this routine reverts to the last value inserted before the +** trigger fired. +** +** An INSERT that fails due to a constraint violation is not a +** successful insert and does not change the value returned by this +** routine. Thus INSERT OR FAIL, INSERT OR IGNORE, INSERT OR ROLLBACK, +** and INSERT OR ABORT make no changes to the return value of this +** routine when their insertion fails. When INSERT OR REPLACE +** encounters a constraint violation, it does not fail. The +** INSERT continues to completion after deleting rows that caused +** the constraint problem so INSERT OR REPLACE will always change +** the return value of this interface. +** +** If another thread does a new insert on the same database connection +** while this routine is running and thus changes the last insert rowid, +** then the return value of this routine is undefined. +*/ +sqlite3_int64 sqlite3_last_insert_rowid(sqlite3*); + +/* +** CAPI3REF: Count The Number Of Rows Modified +** +** This function returns the number of database rows that were changed +** (or inserted or deleted) by the most recent SQL statement. Only +** changes that are directly specified by the INSERT, UPDATE, or +** DELETE statement are counted. Auxiliary changes caused by +** triggers are not counted. Use the [sqlite3_total_changes()] function +** to find the total number of changes including changes caused by triggers. +** +** Within the body of a trigger, the sqlite3_changes() interface can be +** called to find the number of +** changes in the most recently completed INSERT, UPDATE, or DELETE +** statement within the body of the trigger. +** +** All changes are counted, even if they were later undone by a +** ROLLBACK or ABORT. Except, changes associated with creating and +** dropping tables are not counted. +** +** If a callback invokes [sqlite3_exec()] or [sqlite3_step()] recursively, +** then the changes in the inner, recursive call are counted together +** with the changes in the outer call. +** +** SQLite implements the command "DELETE FROM table" without a WHERE clause +** by dropping and recreating the table. (This is much faster than going +** through and deleting individual elements from the table.) Because of +** this optimization, the change count for "DELETE FROM table" will be +** zero regardless of the number of elements that were originally in the +** table. To get an accurate count of the number of rows deleted, use +** "DELETE FROM table WHERE 1" instead. +** +** If another thread makes changes on the same database connection +** while this routine is running then the return value of this routine +** is undefined. +*/ +int sqlite3_changes(sqlite3*); + +/* +** CAPI3REF: Total Number Of Rows Modified +*** +** This function returns the number of database rows that have been +** modified by INSERT, UPDATE or DELETE statements since the database handle +** was opened. This includes UPDATE, INSERT and DELETE statements executed +** as part of trigger programs. All changes are counted as soon as the +** statement that makes them is completed (when the statement handle is +** passed to [sqlite3_reset()] or [sqlite3_finalize()]). +** +** See also the [sqlite3_change()] interface. +** +** SQLite implements the command "DELETE FROM table" without a WHERE clause +** by dropping and recreating the table. (This is much faster than going +** through and deleting individual elements form the table.) Because of +** this optimization, the change count for "DELETE FROM table" will be +** zero regardless of the number of elements that were originally in the +** table. To get an accurate count of the number of rows deleted, use +** "DELETE FROM table WHERE 1" instead. +** +** If another thread makes changes on the same database connection +** while this routine is running then the return value of this routine +** is undefined. +*/ +int sqlite3_total_changes(sqlite3*); + +/* +** CAPI3REF: Interrupt A Long-Running Query +** +** This function causes any pending database operation to abort and +** return at its earliest opportunity. This routine is typically +** called in response to a user action such as pressing "Cancel" +** or Ctrl-C where the user wants a long query operation to halt +** immediately. +** +** It is safe to call this routine from a thread different from the +** thread that is currently running the database operation. But it +** is not safe to call this routine with a database connection that +** is closed or might close before sqlite3_interrupt() returns. +** +** The SQL operation that is interrupted will return [SQLITE_INTERRUPT]. +** If an interrupted operation was an update that is inside an +** explicit transaction, then the entire transaction will be rolled +** back automatically. +*/ +void sqlite3_interrupt(sqlite3*); + +/* +** CAPI3REF: Determine If An SQL Statement Is Complete +** +** These functions return true if the given input string comprises +** one or more complete SQL statements. For the sqlite3_complete() call, +** the parameter must be a nul-terminated UTF-8 string. For +** sqlite3_complete16(), a nul-terminated machine byte order UTF-16 string +** is required. +** +** These routines are useful for command-line input to determine if the +** currently entered text forms one or more complete SQL statements or +** if additional input is needed before sending the statements into +** SQLite for parsing. The algorithm is simple. If the +** last token other than spaces and comments is a semicolon, then return +** true. Actually, the algorithm is a little more complicated than that +** in order to deal with triggers, but the basic idea is the same: the +** statement is not complete unless it ends in a semicolon. +*/ +int sqlite3_complete(const char *sql); +int sqlite3_complete16(const void *sql); + +/* +** CAPI3REF: Register A Callback To Handle SQLITE_BUSY Errors +** +** This routine identifies a callback function that might be invoked +** whenever an attempt is made to open a database table +** that another thread or process has locked. +** If the busy callback is NULL, then [SQLITE_BUSY] +** (or sometimes [SQLITE_IOERR_BLOCKED]) +** is returned immediately upon encountering the lock. +** If the busy callback is not NULL, then the +** callback will be invoked with two arguments. The +** first argument to the handler is a copy of the void* pointer which +** is the third argument to this routine. The second argument to +** the handler is the number of times that the busy handler has +** been invoked for this locking event. If the +** busy callback returns 0, then no additional attempts are made to +** access the database and [SQLITE_BUSY] or [SQLITE_IOERR_BLOCKED] is returned. +** If the callback returns non-zero, then another attempt is made to open the +** database for reading and the cycle repeats. +** +** The presence of a busy handler does not guarantee that +** it will be invoked when there is lock contention. +** If SQLite determines that invoking the busy handler could result in +** a deadlock, it will return [SQLITE_BUSY] instead. +** Consider a scenario where one process is holding a read lock that +** it is trying to promote to a reserved lock and +** a second process is holding a reserved lock that it is trying +** to promote to an exclusive lock. The first process cannot proceed +** because it is blocked by the second and the second process cannot +** proceed because it is blocked by the first. If both processes +** invoke the busy handlers, neither will make any progress. Therefore, +** SQLite returns [SQLITE_BUSY] for the first process, hoping that this +** will induce the first process to release its read lock and allow +** the second process to proceed. +** +** The default busy callback is NULL. +** +** The [SQLITE_BUSY] error is converted to [SQLITE_IOERR_BLOCKED] when +** SQLite is in the middle of a large transaction where all the +** changes will not fit into the in-memory cache. SQLite will +** already hold a RESERVED lock on the database file, but it needs +** to promote this lock to EXCLUSIVE so that it can spill cache +** pages into the database file without harm to concurrent +** readers. If it is unable to promote the lock, then the in-memory +** cache will be left in an inconsistent state and so the error +** code is promoted from the relatively benign [SQLITE_BUSY] to +** the more severe [SQLITE_IOERR_BLOCKED]. This error code promotion +** forces an automatic rollback of the changes. See the +** <a href="http://www.sqlite.org/cvstrac/wiki?p=CorruptionFollowingBusyError"> +** CorruptionFollowingBusyError</a> wiki page for a discussion of why +** this is important. +** +** Sqlite is re-entrant, so the busy handler may start a new query. +** (It is not clear why anyone would every want to do this, but it +** is allowed, in theory.) But the busy handler may not close the +** database. Closing the database from a busy handler will delete +** data structures out from under the executing query and will +** probably result in a segmentation fault or other runtime error. +** +** There can only be a single busy handler defined for each database +** connection. Setting a new busy handler clears any previous one. +** Note that calling [sqlite3_busy_timeout()] will also set or clear +** the busy handler. +** +** When operating in [sqlite3_enable_shared_cache | shared cache mode], +** only a single busy handler can be defined for each database file. +** So if two database connections share a single cache, then changing +** the busy handler on one connection will also change the busy +** handler in the other connection. The busy handler is invoked +** in the thread that was running when the SQLITE_BUSY was hit. +*/ +int sqlite3_busy_handler(sqlite3*, int(*)(void*,int), void*); + +/* +** CAPI3REF: Set A Busy Timeout +** +** This routine sets a busy handler that sleeps for a while when a +** table is locked. The handler will sleep multiple times until +** at least "ms" milliseconds of sleeping have been done. After +** "ms" milliseconds of sleeping, the handler returns 0 which +** causes [sqlite3_step()] to return [SQLITE_BUSY] or [SQLITE_IOERR_BLOCKED]. +** +** Calling this routine with an argument less than or equal to zero +** turns off all busy handlers. +** +** There can only be a single busy handler for a particular database +** connection. If another busy handler was defined +** (using [sqlite3_busy_handler()]) prior to calling +** this routine, that other busy handler is cleared. +*/ +int sqlite3_busy_timeout(sqlite3*, int ms); + +/* +** CAPI3REF: Convenience Routines For Running Queries +** +** This next routine is a convenience wrapper around [sqlite3_exec()]. +** Instead of invoking a user-supplied callback for each row of the +** result, this routine remembers each row of the result in memory +** obtained from [sqlite3_malloc()], then returns all of the result after the +** query has finished. +** +** As an example, suppose the query result where this table: +** +** <blockquote><pre> +** Name | Age +** ----------------------- +** Alice | 43 +** Bob | 28 +** Cindy | 21 +** </pre></blockquote> +** +** If the 3rd argument were &azResult then after the function returns +** azResult will contain the following data: +** +** <blockquote><pre> +** azResult[0] = "Name"; +** azResult[1] = "Age"; +** azResult[2] = "Alice"; +** azResult[3] = "43"; +** azResult[4] = "Bob"; +** azResult[5] = "28"; +** azResult[6] = "Cindy"; +** azResult[7] = "21"; +** </pre></blockquote> +** +** Notice that there is an extra row of data containing the column +** headers. But the *nrow return value is still 3. *ncolumn is +** set to 2. In general, the number of values inserted into azResult +** will be ((*nrow) + 1)*(*ncolumn). +** +** After the calling function has finished using the result, it should +** pass the result data pointer to sqlite3_free_table() in order to +** release the memory that was malloc-ed. Because of the way the +** [sqlite3_malloc()] happens, the calling function must not try to call +** [sqlite3_free()] directly. Only [sqlite3_free_table()] is able to release +** the memory properly and safely. +** +** The return value of this routine is the same as from [sqlite3_exec()]. +*/ +int sqlite3_get_table( + sqlite3*, /* An open database */ + const char *sql, /* SQL to be executed */ + char ***resultp, /* Result written to a char *[] that this points to */ + int *nrow, /* Number of result rows written here */ + int *ncolumn, /* Number of result columns written here */ + char **errmsg /* Error msg written here */ +); +void sqlite3_free_table(char **result); + +/* +** CAPI3REF: Formatted String Printing Functions +** +** These routines are workalikes of the "printf()" family of functions +** from the standard C library. +** +** The sqlite3_mprintf() and sqlite3_vmprintf() routines write their +** results into memory obtained from [sqlite3_malloc()]. +** The strings returned by these two routines should be +** released by [sqlite3_free()]. Both routines return a +** NULL pointer if [sqlite3_malloc()] is unable to allocate enough +** memory to hold the resulting string. +** +** In sqlite3_snprintf() routine is similar to "snprintf()" from +** the standard C library. The result is written into the +** buffer supplied as the second parameter whose size is given by +** the first parameter. Note that the order of the +** first two parameters is reversed from snprintf(). This is an +** historical accident that cannot be fixed without breaking +** backwards compatibility. Note also that sqlite3_snprintf() +** returns a pointer to its buffer instead of the number of +** characters actually written into the buffer. We admit that +** the number of characters written would be a more useful return +** value but we cannot change the implementation of sqlite3_snprintf() +** now without breaking compatibility. +** +** As long as the buffer size is greater than zero, sqlite3_snprintf() +** guarantees that the buffer is always zero-terminated. The first +** parameter "n" is the total size of the buffer, including space for +** the zero terminator. So the longest string that can be completely +** written will be n-1 characters. +** +** These routines all implement some additional formatting +** options that are useful for constructing SQL statements. +** All of the usual printf formatting options apply. In addition, there +** is are "%q", "%Q", and "%z" options. +** +** The %q option works like %s in that it substitutes a null-terminated +** string from the argument list. But %q also doubles every '\'' character. +** %q is designed for use inside a string literal. By doubling each '\'' +** character it escapes that character and allows it to be inserted into +** the string. +** +** For example, so some string variable contains text as follows: +** +** <blockquote><pre> +** char *zText = "It's a happy day!"; +** </pre></blockquote> +** +** One can use this text in an SQL statement as follows: +** +** <blockquote><pre> +** char *zSQL = sqlite3_mprintf("INSERT INTO table VALUES('%q')", zText); +** sqlite3_exec(db, zSQL, 0, 0, 0); +** sqlite3_free(zSQL); +** </pre></blockquote> +** +** Because the %q format string is used, the '\'' character in zText +** is escaped and the SQL generated is as follows: +** +** <blockquote><pre> +** INSERT INTO table1 VALUES('It''s a happy day!') +** </pre></blockquote> +** +** This is correct. Had we used %s instead of %q, the generated SQL +** would have looked like this: +** +** <blockquote><pre> +** INSERT INTO table1 VALUES('It's a happy day!'); +** </pre></blockquote> +** +** This second example is an SQL syntax error. As a general rule you +** should always use %q instead of %s when inserting text into a string +** literal. +** +** The %Q option works like %q except it also adds single quotes around +** the outside of the total string. Or if the parameter in the argument +** list is a NULL pointer, %Q substitutes the text "NULL" (without single +** quotes) in place of the %Q option. So, for example, one could say: +** +** <blockquote><pre> +** char *zSQL = sqlite3_mprintf("INSERT INTO table VALUES(%Q)", zText); +** sqlite3_exec(db, zSQL, 0, 0, 0); +** sqlite3_free(zSQL); +** </pre></blockquote> +** +** The code above will render a correct SQL statement in the zSQL +** variable even if the zText variable is a NULL pointer. +** +** The "%z" formatting option works exactly like "%s" with the +** addition that after the string has been read and copied into +** the result, [sqlite3_free()] is called on the input string. +*/ +char *sqlite3_mprintf(const char*,...); +char *sqlite3_vmprintf(const char*, va_list); +char *sqlite3_snprintf(int,char*,const char*, ...); + +/* +** CAPI3REF: Memory Allocation Subsystem +** +** The SQLite core uses these three routines for all of its own +** internal memory allocation needs. (See the exception below.) +** +** The default implementation +** of the memory allocation subsystem uses the malloc(), realloc() +** and free() provided by the standard C library. However, if +** SQLite is compiled with the following C preprocessor macro +** +** <blockquote> SQLITE_MEMORY_SIZE=<i>NNN</i> </blockquote> +** +** where <i>NNN</i> is an integer, then SQLite create a static +** array of at least <i>NNN</i> bytes in size and use that array +** for all of its dynamic memory allocation needs. +** +** In SQLite version 3.5.0 and 3.5.1, it was possible to define +** the SQLITE_OMIT_MEMORY_ALLOCATION which would cause the built-in +** implementation of these routines to be omitted. That capability +** is no longer provided. Only built-in memory allocators can be +** used. +** +** <b>Exception:</b> The windows OS interface layer calls +** the system malloc() and free() directly when converting +** filenames between the UTF-8 encoding used by SQLite +** and whatever filename encoding is used by the particular windows +** installation. Memory allocation errors are detected, but +** they are reported back as [SQLITE_CANTOPEN] or +** [SQLITE_IOERR] rather than [SQLITE_NOMEM]. +*/ +void *sqlite3_malloc(int); +void *sqlite3_realloc(void*, int); +void sqlite3_free(void*); + +/* +** CAPI3REF: Memory Allocator Statistics +** +** In addition to the basic three allocation routines +** [sqlite3_malloc()], [sqlite3_free()], and [sqlite3_realloc()], +** the memory allocation subsystem included with the SQLite +** sources provides the interfaces shown below. +** +** The first of these two routines returns the amount of memory +** currently outstanding (malloced but not freed). The second +** returns the largest instantaneous amount of outstanding +** memory. The highwater mark is reset if the argument is +** true. +** +** The value returned may or may not include allocation +** overhead, depending on which built-in memory allocator +** implementation is used. +*/ +sqlite3_int64 sqlite3_memory_used(void); +sqlite3_int64 sqlite3_memory_highwater(int resetFlag); + +/* +** CAPI3REF: Compile-Time Authorization Callbacks +*** +** This routine registers a authorizer callback with the SQLite library. +** The authorizer callback is invoked as SQL statements are being compiled +** by [sqlite3_prepare()] or its variants [sqlite3_prepare_v2()], +** [sqlite3_prepare16()] and [sqlite3_prepare16_v2()]. At various +** points during the compilation process, as logic is being created +** to perform various actions, the authorizer callback is invoked to +** see if those actions are allowed. The authorizer callback should +** return SQLITE_OK to allow the action, [SQLITE_IGNORE] to disallow the +** specific action but allow the SQL statement to continue to be +** compiled, or [SQLITE_DENY] to cause the entire SQL statement to be +** rejected with an error. +** +** Depending on the action, the [SQLITE_IGNORE] and [SQLITE_DENY] return +** codes might mean something different or they might mean the same +** thing. If the action is, for example, to perform a delete opertion, +** then [SQLITE_IGNORE] and [SQLITE_DENY] both cause the statement compilation +** to fail with an error. But if the action is to read a specific column +** from a specific table, then [SQLITE_DENY] will cause the entire +** statement to fail but [SQLITE_IGNORE] will cause a NULL value to be +** read instead of the actual column value. +** +** The first parameter to the authorizer callback is a copy of +** the third parameter to the sqlite3_set_authorizer() interface. +** The second parameter to the callback is an integer +** [SQLITE_COPY | action code] that specifies the particular action +** to be authorized. The available action codes are +** [SQLITE_COPY | documented separately]. The third through sixth +** parameters to the callback are strings that contain additional +** details about the action to be authorized. +** +** An authorizer is used when preparing SQL statements from an untrusted +** source, to ensure that the SQL statements do not try to access data +** that they are not allowed to see, or that they do not try to +** execute malicious statements that damage the database. For +** example, an application may allow a user to enter arbitrary +** SQL queries for evaluation by a database. But the application does +** not want the user to be able to make arbitrary changes to the +** database. An authorizer could then be put in place while the +** user-entered SQL is being prepared that disallows everything +** except SELECT statements. +** +** Only a single authorizer can be in place on a database connection +** at a time. Each call to sqlite3_set_authorizer overrides the +** previous call. A NULL authorizer means that no authorization +** callback is invoked. The default authorizer is NULL. +** +** Note that the authorizer callback is invoked only during +** [sqlite3_prepare()] or its variants. Authorization is not +** performed during statement evaluation in [sqlite3_step()]. +*/ +int sqlite3_set_authorizer( + sqlite3*, + int (*xAuth)(void*,int,const char*,const char*,const char*,const char*), + void *pUserData +); + +/* +** CAPI3REF: Authorizer Return Codes +** +** The [sqlite3_set_authorizer | authorizer callback function] must +** return either [SQLITE_OK] or one of these two constants in order +** to signal SQLite whether or not the action is permitted. See the +** [sqlite3_set_authorizer | authorizer documentation] for additional +** information. +*/ +#define SQLITE_DENY 1 /* Abort the SQL statement with an error */ +#define SQLITE_IGNORE 2 /* Don't allow access, but don't generate an error */ + +/* +** CAPI3REF: Authorizer Action Codes +** +** The [sqlite3_set_authorizer()] interface registers a callback function +** that is invoked to authorizer certain SQL statement actions. The +** second parameter to the callback is an integer code that specifies +** what action is being authorized. These are the integer action codes that +** the authorizer callback may be passed. +** +** These action code values signify what kind of operation is to be +** authorized. The 3rd and 4th parameters to the authorization callback +** function will be parameters or NULL depending on which of these +** codes is used as the second parameter. The 5th parameter to the +** authorizer callback is the name of the database ("main", "temp", +** etc.) if applicable. The 6th parameter to the authorizer callback +** is the name of the inner-most trigger or view that is responsible for +** the access attempt or NULL if this access attempt is directly from +** top-level SQL code. +*/ +/******************************************* 3rd ************ 4th ***********/ +#define SQLITE_CREATE_INDEX 1 /* Index Name Table Name */ +#define SQLITE_CREATE_TABLE 2 /* Table Name NULL */ +#define SQLITE_CREATE_TEMP_INDEX 3 /* Index Name Table Name */ +#define SQLITE_CREATE_TEMP_TABLE 4 /* Table Name NULL */ +#define SQLITE_CREATE_TEMP_TRIGGER 5 /* Trigger Name Table Name */ +#define SQLITE_CREATE_TEMP_VIEW 6 /* View Name NULL */ +#define SQLITE_CREATE_TRIGGER 7 /* Trigger Name Table Name */ +#define SQLITE_CREATE_VIEW 8 /* View Name NULL */ +#define SQLITE_DELETE 9 /* Table Name NULL */ +#define SQLITE_DROP_INDEX 10 /* Index Name Table Name */ +#define SQLITE_DROP_TABLE 11 /* Table Name NULL */ +#define SQLITE_DROP_TEMP_INDEX 12 /* Index Name Table Name */ +#define SQLITE_DROP_TEMP_TABLE 13 /* Table Name NULL */ +#define SQLITE_DROP_TEMP_TRIGGER 14 /* Trigger Name Table Name */ +#define SQLITE_DROP_TEMP_VIEW 15 /* View Name NULL */ +#define SQLITE_DROP_TRIGGER 16 /* Trigger Name Table Name */ +#define SQLITE_DROP_VIEW 17 /* View Name NULL */ +#define SQLITE_INSERT 18 /* Table Name NULL */ +#define SQLITE_PRAGMA 19 /* Pragma Name 1st arg or NULL */ +#define SQLITE_READ 20 /* Table Name Column Name */ +#define SQLITE_SELECT 21 /* NULL NULL */ +#define SQLITE_TRANSACTION 22 /* NULL NULL */ +#define SQLITE_UPDATE 23 /* Table Name Column Name */ +#define SQLITE_ATTACH 24 /* Filename NULL */ +#define SQLITE_DETACH 25 /* Database Name NULL */ +#define SQLITE_ALTER_TABLE 26 /* Database Name Table Name */ +#define SQLITE_REINDEX 27 /* Index Name NULL */ +#define SQLITE_ANALYZE 28 /* Table Name NULL */ +#define SQLITE_CREATE_VTABLE 29 /* Table Name Module Name */ +#define SQLITE_DROP_VTABLE 30 /* Table Name Module Name */ +#define SQLITE_FUNCTION 31 /* Function Name NULL */ +#define SQLITE_COPY 0 /* No longer used */ + +/* +** CAPI3REF: Tracing And Profiling Functions +** +** These routines register callback functions that can be used for +** tracing and profiling the execution of SQL statements. +** The callback function registered by sqlite3_trace() is invoked +** at the first [sqlite3_step()] for the evaluation of an SQL statement. +** The callback function registered by sqlite3_profile() is invoked +** as each SQL statement finishes and includes +** information on how long that statement ran. +** +** The sqlite3_profile() API is currently considered experimental and +** is subject to change. +*/ +void *sqlite3_trace(sqlite3*, void(*xTrace)(void*,const char*), void*); +void *sqlite3_profile(sqlite3*, + void(*xProfile)(void*,const char*,sqlite3_uint64), void*); + +/* +** CAPI3REF: Query Progress Callbacks +** +** This routine configures a callback function - the progress callback - that +** is invoked periodically during long running calls to [sqlite3_exec()], +** [sqlite3_step()] and [sqlite3_get_table()]. An example use for this +** interface is to keep a GUI updated during a large query. +** +** The progress callback is invoked once for every N virtual machine opcodes, +** where N is the second argument to this function. The progress callback +** itself is identified by the third argument to this function. The fourth +** argument to this function is a void pointer passed to the progress callback +** function each time it is invoked. +** +** If a call to [sqlite3_exec()], [sqlite3_step()], or [sqlite3_get_table()] +** results in fewer than N opcodes being executed, then the progress +** callback is never invoked. +** +** Only a single progress callback function may be registered for each +** open database connection. Every call to sqlite3_progress_handler() +** overwrites the results of the previous call. +** To remove the progress callback altogether, pass NULL as the third +** argument to this function. +** +** If the progress callback returns a result other than 0, then the current +** query is immediately terminated and any database changes rolled back. +** The containing [sqlite3_exec()], [sqlite3_step()], or +** [sqlite3_get_table()] call returns SQLITE_INTERRUPT. This feature +** can be used, for example, to implement the "Cancel" button on a +** progress dialog box in a GUI. +*/ +void sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*); + +/* +** CAPI3REF: Opening A New Database Connection +** +** Open the sqlite database file "filename". The "filename" is UTF-8 +** encoded for [sqlite3_open()] and [sqlite3_open_v2()] and UTF-16 encoded +** in the native byte order for [sqlite3_open16()]. +** An [sqlite3*] handle is returned in *ppDb, even +** if an error occurs. If the database is opened (or created) successfully, +** then [SQLITE_OK] is returned. Otherwise an error code is returned. The +** [sqlite3_errmsg()] or [sqlite3_errmsg16()] routines can be used to obtain +** an English language description of the error. +** +** The default encoding for the database will be UTF-8 if +** [sqlite3_open()] or [sqlite3_open_v2()] is called and +** UTF-16 if [sqlite3_open16()] is used. +** +** Whether or not an error occurs when it is opened, resources associated +** with the [sqlite3*] handle should be released by passing it to +** [sqlite3_close()] when it is no longer required. +** +** The [sqlite3_open_v2()] interface works like [sqlite3_open()] except that +** provides two additional parameters for additional control over the +** new database connection. The flags parameter can be one of: +** +** <ol> +** <li> [SQLITE_OPEN_READONLY] +** <li> [SQLITE_OPEN_READWRITE] +** <li> [SQLITE_OPEN_READWRITE] | [SQLITE_OPEN_CREATE] +** </ol> +** +** The first value opens the database read-only. If the database does +** not previously exist, an error is returned. The second option opens +** the database for reading and writing if possible, or reading only if +** if the file is write protected. In either case the database must already +** exist or an error is returned. The third option opens the database +** for reading and writing and creates it if it does not already exist. +** The third options is behavior that is always used for [sqlite3_open()] +** and [sqlite3_open16()]. +** +** If the filename is ":memory:", then an private +** in-memory database is created for the connection. This in-memory +** database will vanish when the database connection is closed. Future +** version of SQLite might make use of additional special filenames +** that begin with the ":" character. It is recommended that +** when a database filename really does begin with +** ":" that you prefix the filename with a pathname like "./" to +** avoid ambiguity. +** +** If the filename is an empty string, then a private temporary +** on-disk database will be created. This private database will be +** automatically deleted as soon as the database connection is closed. +** +** The fourth parameter to sqlite3_open_v2() is the name of the +** [sqlite3_vfs] object that defines the operating system +** interface that the new database connection should use. If the +** fourth parameter is a NULL pointer then the default [sqlite3_vfs] +** object is used. +** +** <b>Note to windows users:</b> The encoding used for the filename argument +** of [sqlite3_open()] and [sqlite3_open_v2()] must be UTF-8, not whatever +** codepage is currently defined. Filenames containing international +** characters must be converted to UTF-8 prior to passing them into +** [sqlite3_open()] or [sqlite3_open_v2()]. +*/ +int sqlite3_open( + const char *filename, /* Database filename (UTF-8) */ + sqlite3 **ppDb /* OUT: SQLite db handle */ +); +int sqlite3_open16( + const void *filename, /* Database filename (UTF-16) */ + sqlite3 **ppDb /* OUT: SQLite db handle */ +); +int sqlite3_open_v2( + const char *filename, /* Database filename (UTF-8) */ + sqlite3 **ppDb, /* OUT: SQLite db handle */ + int flags, /* Flags */ + const char *zVfs /* Name of VFS module to use */ +); + +/* +** CAPI3REF: Error Codes And Messages +** +** The sqlite3_errcode() interface returns the numeric +** [SQLITE_OK | result code] or [SQLITE_IOERR_READ | extended result code] +** for the most recent failed sqlite3_* API call associated +** with [sqlite3] handle 'db'. If a prior API call failed but the +** most recent API call succeeded, the return value from sqlite3_errcode() +** is undefined. +** +** The sqlite3_errmsg() and sqlite3_errmsg16() return English-language +** text that describes the error, as either UTF8 or UTF16 respectively. +** Memory to hold the error message string is managed internally. The +** string may be overwritten or deallocated by subsequent calls to SQLite +** interface functions. +** +** Calls to many sqlite3_* functions set the error code and string returned +** by [sqlite3_errcode()], [sqlite3_errmsg()], and [sqlite3_errmsg16()] +** (overwriting the previous values). Note that calls to [sqlite3_errcode()], +** [sqlite3_errmsg()], and [sqlite3_errmsg16()] themselves do not affect the +** results of future invocations. Calls to API routines that do not return +** an error code (example: [sqlite3_data_count()]) do not +** change the error code returned by this routine. Interfaces that are +** not associated with a specific database connection (examples: +** [sqlite3_mprintf()] or [sqlite3_enable_shared_cache()] do not change +** the return code. +** +** Assuming no other intervening sqlite3_* API calls are made, the error +** code returned by this function is associated with the same error as +** the strings returned by [sqlite3_errmsg()] and [sqlite3_errmsg16()]. +*/ +int sqlite3_errcode(sqlite3 *db); +const char *sqlite3_errmsg(sqlite3*); +const void *sqlite3_errmsg16(sqlite3*); + +/* +** CAPI3REF: SQL Statement Object +** +** Instance of this object represent single SQL statements. This +** is variously known as a "prepared statement" or a +** "compiled SQL statement" or simply as a "statement". +** +** The life of a statement object goes something like this: +** +** <ol> +** <li> Create the object using [sqlite3_prepare_v2()] or a related +** function. +** <li> Bind values to host parameters using +** [sqlite3_bind_blob | sqlite3_bind_* interfaces]. +** <li> Run the SQL by calling [sqlite3_step()] one or more times. +** <li> Reset the statement using [sqlite3_reset()] then go back +** to step 2. Do this zero or more times. +** <li> Destroy the object using [sqlite3_finalize()]. +** </ol> +** +** Refer to documentation on individual methods above for additional +** information. +*/ +typedef struct sqlite3_stmt sqlite3_stmt; + +/* +** CAPI3REF: Compiling An SQL Statement +** +** To execute an SQL query, it must first be compiled into a byte-code +** program using one of these routines. +** +** The first argument "db" is an [sqlite3 | SQLite database handle] +** obtained from a prior call to [sqlite3_open()], [sqlite3_open_v2()] +** or [sqlite3_open16()]. +** The second argument "zSql" is the statement to be compiled, encoded +** as either UTF-8 or UTF-16. The sqlite3_prepare() and sqlite3_prepare_v2() +** interfaces uses UTF-8 and sqlite3_prepare16() and sqlite3_prepare16_v2() +** use UTF-16. +** +** If the nByte argument is less +** than zero, then zSql is read up to the first zero terminator. If +** nByte is non-negative, then it is the maximum number of +** bytes read from zSql. When nByte is non-negative, the +** zSql string ends at either the first '\000' character or +** until the nByte-th byte, whichever comes first. +** +** *pzTail is made to point to the first byte past the end of the first +** SQL statement in zSql. This routine only compiles the first statement +** in zSql, so *pzTail is left pointing to what remains uncompiled. +** +** *ppStmt is left pointing to a compiled +** [sqlite3_stmt | SQL statement structure] that can be +** executed using [sqlite3_step()]. Or if there is an error, *ppStmt may be +** set to NULL. If the input text contained no SQL (if the input is and +** empty string or a comment) then *ppStmt is set to NULL. The calling +** procedure is responsible for deleting the compiled SQL statement +** using [sqlite3_finalize()] after it has finished with it. +** +** On success, [SQLITE_OK] is returned. Otherwise an +** [SQLITE_ERROR | error code] is returned. +** +** The sqlite3_prepare_v2() and sqlite3_prepare16_v2() interfaces are +** recommended for all new programs. The two older interfaces are retained +** for backwards compatibility, but their use is discouraged. +** In the "v2" interfaces, the prepared statement +** that is returned (the [sqlite3_stmt] object) contains a copy of the +** original SQL text. This causes the [sqlite3_step()] interface to +** behave a differently in two ways: +** +** <ol> +** <li> +** If the database schema changes, instead of returning [SQLITE_SCHEMA] as it +** always used to do, [sqlite3_step()] will automatically recompile the SQL +** statement and try to run it again. If the schema has changed in a way +** that makes the statement no longer valid, [sqlite3_step()] will still +** return [SQLITE_SCHEMA]. But unlike the legacy behavior, [SQLITE_SCHEMA] is +** now a fatal error. Calling [sqlite3_prepare_v2()] again will not make the +** error go away. Note: use [sqlite3_errmsg()] to find the text of the parsing +** error that results in an [SQLITE_SCHEMA] return. +** </li> +** +** <li> +** When an error occurs, +** [sqlite3_step()] will return one of the detailed +** [SQLITE_ERROR | result codes] or +** [SQLITE_IOERR_READ | extended result codes] such as directly. +** The legacy behavior was that [sqlite3_step()] would only return a generic +** [SQLITE_ERROR] result code and you would have to make a second call to +** [sqlite3_reset()] in order to find the underlying cause of the problem. +** With the "v2" prepare interfaces, the underlying reason for the error is +** returned immediately. +** </li> +** </ol> +*/ +int sqlite3_prepare( + sqlite3 *db, /* Database handle */ + const char *zSql, /* SQL statement, UTF-8 encoded */ + int nByte, /* Maximum length of zSql in bytes. */ + sqlite3_stmt **ppStmt, /* OUT: Statement handle */ + const char **pzTail /* OUT: Pointer to unused portion of zSql */ +); +int sqlite3_prepare_v2( + sqlite3 *db, /* Database handle */ + const char *zSql, /* SQL statement, UTF-8 encoded */ + int nByte, /* Maximum length of zSql in bytes. */ + sqlite3_stmt **ppStmt, /* OUT: Statement handle */ + const char **pzTail /* OUT: Pointer to unused portion of zSql */ +); +int sqlite3_prepare16( + sqlite3 *db, /* Database handle */ + const void *zSql, /* SQL statement, UTF-16 encoded */ + int nByte, /* Maximum length of zSql in bytes. */ + sqlite3_stmt **ppStmt, /* OUT: Statement handle */ + const void **pzTail /* OUT: Pointer to unused portion of zSql */ +); +int sqlite3_prepare16_v2( + sqlite3 *db, /* Database handle */ + const void *zSql, /* SQL statement, UTF-16 encoded */ + int nByte, /* Maximum length of zSql in bytes. */ + sqlite3_stmt **ppStmt, /* OUT: Statement handle */ + const void **pzTail /* OUT: Pointer to unused portion of zSql */ +); + +/* +** Retrieve the original SQL statement associated with a compiled statement +** in UTF-8 encoding. +** +** If the compiled SQL statement passed as an argument was compiled using +** either sqlite3_prepare_v2 or sqlite3_prepare16_v2, then this function +** returns a pointer to a nul-terminated string containing a copy of +** the original SQL statement. The pointer is valid until the statement +** is deleted using sqlite3_finalize(). +** +** If the statement was compiled using either of the legacy interfaces +** sqlite3_prepare() or sqlite3_prepare16(), this function returns NULL. +** +****** EXPERIMENTAL - subject to change without notice ************** +*/ +const char *sqlite3_sql(sqlite3_stmt *pStmt); + +/* +** CAPI3REF: Dynamically Typed Value Object +** +** SQLite uses dynamic typing for the values it stores. Values can +** be integers, floating point values, strings, BLOBs, or NULL. When +** passing around values internally, each value is represented as +** an instance of the sqlite3_value object. +*/ +typedef struct Mem sqlite3_value; + +/* +** CAPI3REF: SQL Function Context Object +** +** The context in which an SQL function executes is stored in an +** sqlite3_context object. A pointer to such an object is the +** first parameter to user-defined SQL functions. +*/ +typedef struct sqlite3_context sqlite3_context; + +/* +** CAPI3REF: Binding Values To Prepared Statements +** +** In the SQL strings input to [sqlite3_prepare_v2()] and its variants, +** one or more literals can be replace by a parameter in one of these +** forms: +** +** <ul> +** <li> ? +** <li> ?NNN +** <li> :AAA +** <li> @AAA +** <li> $VVV +** </ul> +** +** In the parameter forms shown above NNN is an integer literal, +** AAA is an alphanumeric identifier and VVV is a variable name according +** to the syntax rules of the TCL programming language. +** The values of these parameters (also called "host parameter names") +** can be set using the sqlite3_bind_*() routines defined here. +** +** The first argument to the sqlite3_bind_*() routines always is a pointer +** to the [sqlite3_stmt] object returned from [sqlite3_prepare_v2()] or +** its variants. The second +** argument is the index of the parameter to be set. The first parameter has +** an index of 1. When the same named parameter is used more than once, second +** and subsequent +** occurrences have the same index as the first occurrence. The index for +** named parameters can be looked up using the +** [sqlite3_bind_parameter_name()] API if desired. The index for "?NNN" +** parametes is the value of NNN. +** The NNN value must be between 1 and the compile-time +** parameter SQLITE_MAX_VARIABLE_NUMBER (default value: 999). +** See <a href="limits.html">limits.html</a> for additional information. +** +** The third argument is the value to bind to the parameter. +** +** In those +** routines that have a fourth argument, its value is the number of bytes +** in the parameter. To be clear: the value is the number of bytes in the +** string, not the number of characters. The number +** of bytes does not include the zero-terminator at the end of strings. +** If the fourth parameter is negative, the length of the string is +** number of bytes up to the first zero terminator. +** +** The fifth argument to sqlite3_bind_blob(), sqlite3_bind_text(), and +** sqlite3_bind_text16() is a destructor used to dispose of the BLOB or +** text after SQLite has finished with it. If the fifth argument is the +** special value [SQLITE_STATIC], then the library assumes that the information +** is in static, unmanaged space and does not need to be freed. If the +** fifth argument has the value [SQLITE_TRANSIENT], then SQLite makes its +** own private copy of the data immediately, before the sqlite3_bind_*() +** routine returns. +** +** The sqlite3_bind_zeroblob() routine binds a BLOB of length n that +** is filled with zeros. A zeroblob uses a fixed amount of memory +** (just an integer to hold it size) while it is being processed. +** Zeroblobs are intended to serve as place-holders for BLOBs whose +** content is later written using +** [sqlite3_blob_open | increment BLOB I/O] routines. A negative +** value for the zeroblob results in a zero-length BLOB. +** +** The sqlite3_bind_*() routines must be called after +** [sqlite3_prepare_v2()] (and its variants) or [sqlite3_reset()] and +** before [sqlite3_step()]. +** Bindings are not cleared by the [sqlite3_reset()] routine. +** Unbound parameters are interpreted as NULL. +** +** These routines return [SQLITE_OK] on success or an error code if +** anything goes wrong. [SQLITE_RANGE] is returned if the parameter +** index is out of range. [SQLITE_NOMEM] is returned if malloc fails. +** [SQLITE_MISUSE] is returned if these routines are called on a virtual +** machine that is the wrong state or which has already been finalized. +*/ +int sqlite3_bind_blob(sqlite3_stmt*, int, const void*, int n, void(*)(void*)); +int sqlite3_bind_double(sqlite3_stmt*, int, double); +int sqlite3_bind_int(sqlite3_stmt*, int, int); +int sqlite3_bind_int64(sqlite3_stmt*, int, sqlite3_int64); +int sqlite3_bind_null(sqlite3_stmt*, int); +int sqlite3_bind_text(sqlite3_stmt*, int, const char*, int n, void(*)(void*)); +int sqlite3_bind_text16(sqlite3_stmt*, int, const void*, int, void(*)(void*)); +int sqlite3_bind_value(sqlite3_stmt*, int, const sqlite3_value*); +int sqlite3_bind_zeroblob(sqlite3_stmt*, int, int n); + +/* +** CAPI3REF: Number Of Host Parameters +** +** Return the largest host parameter index in the precompiled statement given +** as the argument. When the host parameters are of the forms like ":AAA" +** or "?", then they are assigned sequential increasing numbers beginning +** with one, so the value returned is the number of parameters. However +** if the same host parameter name is used multiple times, each occurrance +** is given the same number, so the value returned in that case is the number +** of unique host parameter names. If host parameters of the form "?NNN" +** are used (where NNN is an integer) then there might be gaps in the +** numbering and the value returned by this interface is the index of the +** host parameter with the largest index value. +** +** The prepared statement must not be [sqlite3_finalize | finalized] +** prior to this routine returnning. Otherwise the results are undefined +** and probably undesirable. +*/ +int sqlite3_bind_parameter_count(sqlite3_stmt*); + +/* +** CAPI3REF: Name Of A Host Parameter +** +** This routine returns a pointer to the name of the n-th parameter in a +** [sqlite3_stmt | prepared statement]. +** Host parameters of the form ":AAA" or "@AAA" or "$VVV" have a name +** which is the string ":AAA" or "@AAA" or "$VVV". +** In other words, the initial ":" or "$" or "@" +** is included as part of the name. +** Parameters of the form "?" or "?NNN" have no name. +** +** The first bound parameter has an index of 1, not 0. +** +** If the value n is out of range or if the n-th parameter is nameless, +** then NULL is returned. The returned string is always in the +** UTF-8 encoding even if the named parameter was originally specified +** as UTF-16 in [sqlite3_prepare16()] or [sqlite3_prepare16_v2()]. +*/ +const char *sqlite3_bind_parameter_name(sqlite3_stmt*, int); + +/* +** CAPI3REF: Index Of A Parameter With A Given Name +** +** This routine returns the index of a host parameter with the given name. +** The name must match exactly. If no parameter with the given name is +** found, return 0. Parameter names must be UTF8. +*/ +int sqlite3_bind_parameter_index(sqlite3_stmt*, const char *zName); + +/* +** CAPI3REF: Reset All Bindings On A Prepared Statement +** +** Contrary to the intuition of many, [sqlite3_reset()] does not +** reset the [sqlite3_bind_blob | bindings] on a +** [sqlite3_stmt | prepared statement]. Use this routine to +** reset all host parameters to NULL. +*/ +int sqlite3_clear_bindings(sqlite3_stmt*); + +/* +** CAPI3REF: Number Of Columns In A Result Set +** +** Return the number of columns in the result set returned by the +** [sqlite3_stmt | compiled SQL statement]. This routine returns 0 +** if pStmt is an SQL statement that does not return data (for +** example an UPDATE). +*/ +int sqlite3_column_count(sqlite3_stmt *pStmt); + +/* +** CAPI3REF: Column Names In A Result Set +** +** These routines return the name assigned to a particular column +** in the result set of a SELECT statement. The sqlite3_column_name() +** interface returns a pointer to a UTF8 string and sqlite3_column_name16() +** returns a pointer to a UTF16 string. The first parameter is the +** [sqlite3_stmt | prepared statement] that implements the SELECT statement. +** The second parameter is the column number. The left-most column is +** number 0. +** +** The returned string pointer is valid until either the +** [sqlite3_stmt | prepared statement] is destroyed by [sqlite3_finalize()] +** or until the next call sqlite3_column_name() or sqlite3_column_name16() +** on the same column. +** +** If sqlite3_malloc() fails during the processing of either routine +** (for example during a conversion from UTF-8 to UTF-16) then a +** NULL pointer is returned. +*/ +const char *sqlite3_column_name(sqlite3_stmt*, int N); +const void *sqlite3_column_name16(sqlite3_stmt*, int N); + +/* +** CAPI3REF: Source Of Data In A Query Result +** +** These routines provide a means to determine what column of what +** table in which database a result of a SELECT statement comes from. +** The name of the database or table or column can be returned as +** either a UTF8 or UTF16 string. The _database_ routines return +** the database name, the _table_ routines return the table name, and +** the origin_ routines return the column name. +** The returned string is valid until +** the [sqlite3_stmt | prepared statement] is destroyed using +** [sqlite3_finalize()] or until the same information is requested +** again in a different encoding. +** +** The names returned are the original un-aliased names of the +** database, table, and column. +** +** The first argument to the following calls is a +** [sqlite3_stmt | compiled SQL statement]. +** These functions return information about the Nth column returned by +** the statement, where N is the second function argument. +** +** If the Nth column returned by the statement is an expression +** or subquery and is not a column value, then all of these functions +** return NULL. Otherwise, they return the +** name of the attached database, table and column that query result +** column was extracted from. +** +** As with all other SQLite APIs, those postfixed with "16" return UTF-16 +** encoded strings, the other functions return UTF-8. +** +** These APIs are only available if the library was compiled with the +** SQLITE_ENABLE_COLUMN_METADATA preprocessor symbol defined. +** +** If two or more threads call one or more of these routines against the same +** prepared statement and column at the same time then the results are +** undefined. +*/ +const char *sqlite3_column_database_name(sqlite3_stmt*,int); +const void *sqlite3_column_database_name16(sqlite3_stmt*,int); +const char *sqlite3_column_table_name(sqlite3_stmt*,int); +const void *sqlite3_column_table_name16(sqlite3_stmt*,int); +const char *sqlite3_column_origin_name(sqlite3_stmt*,int); +const void *sqlite3_column_origin_name16(sqlite3_stmt*,int); + +/* +** CAPI3REF: Declared Datatype Of A Query Result +** +** The first parameter is a [sqlite3_stmt | compiled SQL statement]. +** If this statement is a SELECT statement and the Nth column of the +** returned result set of that SELECT is a table column (not an +** expression or subquery) then the declared type of the table +** column is returned. If the Nth column of the result set is an +** expression or subquery, then a NULL pointer is returned. +** The returned string is always UTF-8 encoded. For example, in +** the database schema: +** +** CREATE TABLE t1(c1 VARIANT); +** +** And the following statement compiled: +** +** SELECT c1 + 1, c1 FROM t1; +** +** Then this routine would return the string "VARIANT" for the second +** result column (i==1), and a NULL pointer for the first result column +** (i==0). +** +** SQLite uses dynamic run-time typing. So just because a column +** is declared to contain a particular type does not mean that the +** data stored in that column is of the declared type. SQLite is +** strongly typed, but the typing is dynamic not static. Type +** is associated with individual values, not with the containers +** used to hold those values. +*/ +const char *sqlite3_column_decltype(sqlite3_stmt *, int i); +const void *sqlite3_column_decltype16(sqlite3_stmt*,int); + +/* +** CAPI3REF: Evaluate An SQL Statement +** +** After an [sqlite3_stmt | SQL statement] has been prepared with a call +** to either [sqlite3_prepare_v2()] or [sqlite3_prepare16_v2()] or to one of +** the legacy interfaces [sqlite3_prepare()] or [sqlite3_prepare16()], +** then this function must be called one or more times to evaluate the +** statement. +** +** The details of the behavior of this sqlite3_step() interface depend +** on whether the statement was prepared using the newer "v2" interface +** [sqlite3_prepare_v2()] and [sqlite3_prepare16_v2()] or the older legacy +** interface [sqlite3_prepare()] and [sqlite3_prepare16()]. The use of the +** new "v2" interface is recommended for new applications but the legacy +** interface will continue to be supported. +** +** In the lagacy interface, the return value will be either [SQLITE_BUSY], +** [SQLITE_DONE], [SQLITE_ROW], [SQLITE_ERROR], or [SQLITE_MISUSE]. +** With the "v2" interface, any of the other [SQLITE_OK | result code] +** or [SQLITE_IOERR_READ | extended result code] might be returned as +** well. +** +** [SQLITE_BUSY] means that the database engine was unable to acquire the +** database locks it needs to do its job. If the statement is a COMMIT +** or occurs outside of an explicit transaction, then you can retry the +** statement. If the statement is not a COMMIT and occurs within a +** explicit transaction then you should rollback the transaction before +** continuing. +** +** [SQLITE_DONE] means that the statement has finished executing +** successfully. sqlite3_step() should not be called again on this virtual +** machine without first calling [sqlite3_reset()] to reset the virtual +** machine back to its initial state. +** +** If the SQL statement being executed returns any data, then +** [SQLITE_ROW] is returned each time a new row of data is ready +** for processing by the caller. The values may be accessed using +** the [sqlite3_column_int | column access functions]. +** sqlite3_step() is called again to retrieve the next row of data. +** +** [SQLITE_ERROR] means that a run-time error (such as a constraint +** violation) has occurred. sqlite3_step() should not be called again on +** the VM. More information may be found by calling [sqlite3_errmsg()]. +** With the legacy interface, a more specific error code (example: +** [SQLITE_INTERRUPT], [SQLITE_SCHEMA], [SQLITE_CORRUPT], and so forth) +** can be obtained by calling [sqlite3_reset()] on the +** [sqlite3_stmt | prepared statement]. In the "v2" interface, +** the more specific error code is returned directly by sqlite3_step(). +** +** [SQLITE_MISUSE] means that the this routine was called inappropriately. +** Perhaps it was called on a [sqlite3_stmt | prepared statement] that has +** already been [sqlite3_finalize | finalized] or on one that had +** previously returned [SQLITE_ERROR] or [SQLITE_DONE]. Or it could +** be the case that the same database connection is being used by two or +** more threads at the same moment in time. +** +** <b>Goofy Interface Alert:</b> +** In the legacy interface, +** the sqlite3_step() API always returns a generic error code, +** [SQLITE_ERROR], following any error other than [SQLITE_BUSY] +** and [SQLITE_MISUSE]. You must call [sqlite3_reset()] or +** [sqlite3_finalize()] in order to find one of the specific +** [SQLITE_ERROR | result codes] that better describes the error. +** We admit that this is a goofy design. The problem has been fixed +** with the "v2" interface. If you prepare all of your SQL statements +** using either [sqlite3_prepare_v2()] or [sqlite3_prepare16_v2()] instead +** of the legacy [sqlite3_prepare()] and [sqlite3_prepare16()], then the +** more specific [SQLITE_ERROR | result codes] are returned directly +** by sqlite3_step(). The use of the "v2" interface is recommended. +*/ +int sqlite3_step(sqlite3_stmt*); + +/* +** CAPI3REF: +** +** Return the number of values in the current row of the result set. +** +** After a call to [sqlite3_step()] that returns [SQLITE_ROW], this routine +** will return the same value as the [sqlite3_column_count()] function. +** After [sqlite3_step()] has returned an [SQLITE_DONE], [SQLITE_BUSY], or +** a [SQLITE_ERROR | error code], or before [sqlite3_step()] has been +** called on the [sqlite3_stmt | prepared statement] for the first time, +** this routine returns zero. +*/ +int sqlite3_data_count(sqlite3_stmt *pStmt); + +/* +** CAPI3REF: Fundamental Datatypes +** +** Every value in SQLite has one of five fundamental datatypes: +** +** <ul> +** <li> 64-bit signed integer +** <li> 64-bit IEEE floating point number +** <li> string +** <li> BLOB +** <li> NULL +** </ul> +** +** These constants are codes for each of those types. +** +** Note that the SQLITE_TEXT constant was also used in SQLite version 2 +** for a completely different meaning. Software that links against both +** SQLite version 2 and SQLite version 3 should use SQLITE3_TEXT not +** SQLITE_TEXT. +*/ +#define SQLITE_INTEGER 1 +#define SQLITE_FLOAT 2 +#define SQLITE_BLOB 4 +#define SQLITE_NULL 5 +#ifdef SQLITE_TEXT +# undef SQLITE_TEXT +#else +# define SQLITE_TEXT 3 +#endif +#define SQLITE3_TEXT 3 + +/* +** CAPI3REF: Results Values From A Query +** +** These routines return information about +** a single column of the current result row of a query. In every +** case the first argument is a pointer to the +** [sqlite3_stmt | SQL statement] that is being +** evaluated (the [sqlite3_stmt*] that was returned from +** [sqlite3_prepare_v2()] or one of its variants) and +** the second argument is the index of the column for which information +** should be returned. The left-most column of the result set +** has an index of 0. +** +** If the SQL statement is not currently point to a valid row, or if the +** the column index is out of range, the result is undefined. +** These routines may only be called when the most recent call to +** [sqlite3_step()] has returned [SQLITE_ROW] and neither +** [sqlite3_reset()] nor [sqlite3_finalize()] has been call subsequently. +** If any of these routines are called after [sqlite3_reset()] or +** [sqlite3_finalize()] or after [sqlite3_step()] has returned +** something other than [SQLITE_ROW], the results are undefined. +** If [sqlite3_step()] or [sqlite3_reset()] or [sqlite3_finalize()] +** are called from a different thread while any of these routines +** are pending, then the results are undefined. +** +** The sqlite3_column_type() routine returns +** [SQLITE_INTEGER | datatype code] for the initial data type +** of the result column. The returned value is one of [SQLITE_INTEGER], +** [SQLITE_FLOAT], [SQLITE_TEXT], [SQLITE_BLOB], or [SQLITE_NULL]. The value +** returned by sqlite3_column_type() is only meaningful if no type +** conversions have occurred as described below. After a type conversion, +** the value returned by sqlite3_column_type() is undefined. Future +** versions of SQLite may change the behavior of sqlite3_column_type() +** following a type conversion. +** +** If the result is a BLOB or UTF-8 string then the sqlite3_column_bytes() +** routine returns the number of bytes in that BLOB or string. +** If the result is a UTF-16 string, then sqlite3_column_bytes() converts +** the string to UTF-8 and then returns the number of bytes. +** If the result is a numeric value then sqlite3_column_bytes() uses +** [sqlite3_snprintf()] to convert that value to a UTF-8 string and returns +** the number of bytes in that string. +** The value returned does not include the zero terminator at the end +** of the string. For clarity: the value returned is the number of +** bytes in the string, not the number of characters. +** +** Strings returned by sqlite3_column_text() and sqlite3_column_text16(), +** even zero-length strings, are always zero terminated. The return +** value from sqlite3_column_blob() for a zero-length blob is an arbitrary +** pointer, possibly even a NULL pointer. +** +** The sqlite3_column_bytes16() routine is similar to sqlite3_column_bytes() +** but leaves the result in UTF-16 instead of UTF-8. +** The zero terminator is not included in this count. +** +** These routines attempt to convert the value where appropriate. For +** example, if the internal representation is FLOAT and a text result +** is requested, [sqlite3_snprintf()] is used internally to do the conversion +** automatically. The following table details the conversions that +** are applied: +** +** <blockquote> +** <table border="1"> +** <tr><th> Internal<br>Type <th> Requested<br>Type <th> Conversion +** +** <tr><td> NULL <td> INTEGER <td> Result is 0 +** <tr><td> NULL <td> FLOAT <td> Result is 0.0 +** <tr><td> NULL <td> TEXT <td> Result is NULL pointer +** <tr><td> NULL <td> BLOB <td> Result is NULL pointer +** <tr><td> INTEGER <td> FLOAT <td> Convert from integer to float +** <tr><td> INTEGER <td> TEXT <td> ASCII rendering of the integer +** <tr><td> INTEGER <td> BLOB <td> Same as for INTEGER->TEXT +** <tr><td> FLOAT <td> INTEGER <td> Convert from float to integer +** <tr><td> FLOAT <td> TEXT <td> ASCII rendering of the float +** <tr><td> FLOAT <td> BLOB <td> Same as FLOAT->TEXT +** <tr><td> TEXT <td> INTEGER <td> Use atoi() +** <tr><td> TEXT <td> FLOAT <td> Use atof() +** <tr><td> TEXT <td> BLOB <td> No change +** <tr><td> BLOB <td> INTEGER <td> Convert to TEXT then use atoi() +** <tr><td> BLOB <td> FLOAT <td> Convert to TEXT then use atof() +** <tr><td> BLOB <td> TEXT <td> Add a zero terminator if needed +** </table> +** </blockquote> +** +** The table above makes reference to standard C library functions atoi() +** and atof(). SQLite does not really use these functions. It has its +** on equavalent internal routines. The atoi() and atof() names are +** used in the table for brevity and because they are familiar to most +** C programmers. +** +** Note that when type conversions occur, pointers returned by prior +** calls to sqlite3_column_blob(), sqlite3_column_text(), and/or +** sqlite3_column_text16() may be invalidated. +** Type conversions and pointer invalidations might occur +** in the following cases: +** +** <ul> +** <li><p> The initial content is a BLOB and sqlite3_column_text() +** or sqlite3_column_text16() is called. A zero-terminator might +** need to be added to the string.</p></li> +** +** <li><p> The initial content is UTF-8 text and sqlite3_column_bytes16() or +** sqlite3_column_text16() is called. The content must be converted +** to UTF-16.</p></li> +** +** <li><p> The initial content is UTF-16 text and sqlite3_column_bytes() or +** sqlite3_column_text() is called. The content must be converted +** to UTF-8.</p></li> +** </ul> +** +** Conversions between UTF-16be and UTF-16le are always done in place and do +** not invalidate a prior pointer, though of course the content of the buffer +** that the prior pointer points to will have been modified. Other kinds +** of conversion are done in place when it is possible, but sometime it is +** not possible and in those cases prior pointers are invalidated. +** +** The safest and easiest to remember policy is to invoke these routines +** in one of the following ways: +** +** <ul> +** <li>sqlite3_column_text() followed by sqlite3_column_bytes()</li> +** <li>sqlite3_column_blob() followed by sqlite3_column_bytes()</li> +** <li>sqlite3_column_text16() followed by sqlite3_column_bytes16()</li> +** </ul> +** +** In other words, you should call sqlite3_column_text(), sqlite3_column_blob(), +** or sqlite3_column_text16() first to force the result into the desired +** format, then invoke sqlite3_column_bytes() or sqlite3_column_bytes16() to +** find the size of the result. Do not mix call to sqlite3_column_text() or +** sqlite3_column_blob() with calls to sqlite3_column_bytes16(). And do not +** mix calls to sqlite3_column_text16() with calls to sqlite3_column_bytes(). +** +** The pointers returned are valid until a type conversion occurs as +** described above, or until [sqlite3_step()] or [sqlite3_reset()] or +** [sqlite3_finalize()] is called. The memory space used to hold strings +** and blobs is freed automatically. Do <b>not</b> pass the pointers returned +** [sqlite3_column_blob()], [sqlite3_column_text()], etc. into +** [sqlite3_free()]. +** +** If a memory allocation error occurs during the evaluation of any +** of these routines, a default value is returned. The default value +** is either the integer 0, the floating point number 0.0, or a NULL +** pointer. Subsequent calls to [sqlite3_errcode()] will return +** [SQLITE_NOMEM]. +*/ +const void *sqlite3_column_blob(sqlite3_stmt*, int iCol); +int sqlite3_column_bytes(sqlite3_stmt*, int iCol); +int sqlite3_column_bytes16(sqlite3_stmt*, int iCol); +double sqlite3_column_double(sqlite3_stmt*, int iCol); +int sqlite3_column_int(sqlite3_stmt*, int iCol); +sqlite3_int64 sqlite3_column_int64(sqlite3_stmt*, int iCol); +const unsigned char *sqlite3_column_text(sqlite3_stmt*, int iCol); +const void *sqlite3_column_text16(sqlite3_stmt*, int iCol); +int sqlite3_column_type(sqlite3_stmt*, int iCol); +sqlite3_value *sqlite3_column_value(sqlite3_stmt*, int iCol); + +/* +** CAPI3REF: Destroy A Prepared Statement Object +** +** The sqlite3_finalize() function is called to delete a +** [sqlite3_stmt | compiled SQL statement]. If the statement was +** executed successfully, or not executed at all, then SQLITE_OK is returned. +** If execution of the statement failed then an +** [SQLITE_ERROR | error code] or [SQLITE_IOERR_READ | extended error code] +** is returned. +** +** This routine can be called at any point during the execution of the +** [sqlite3_stmt | virtual machine]. If the virtual machine has not +** completed execution when this routine is called, that is like +** encountering an error or an interrupt. (See [sqlite3_interrupt()].) +** Incomplete updates may be rolled back and transactions cancelled, +** depending on the circumstances, and the +** [SQLITE_ERROR | result code] returned will be [SQLITE_ABORT]. +*/ +int sqlite3_finalize(sqlite3_stmt *pStmt); + +/* +** CAPI3REF: Reset A Prepared Statement Object +** +** The sqlite3_reset() function is called to reset a +** [sqlite3_stmt | compiled SQL statement] object. +** back to it's initial state, ready to be re-executed. +** Any SQL statement variables that had values bound to them using +** the [sqlite3_bind_blob | sqlite3_bind_*() API] retain their values. +** Use [sqlite3_clear_bindings()] to reset the bindings. +*/ +int sqlite3_reset(sqlite3_stmt *pStmt); + +/* +** CAPI3REF: Create Or Redefine SQL Functions +** +** The following two functions are used to add SQL functions or aggregates +** or to redefine the behavior of existing SQL functions or aggregates. The +** difference only between the two is that the second parameter, the +** name of the (scalar) function or aggregate, is encoded in UTF-8 for +** sqlite3_create_function() and UTF-16 for sqlite3_create_function16(). +** +** The first argument is the [sqlite3 | database handle] that holds the +** SQL function or aggregate is to be added or redefined. If a single +** program uses more than one database handle internally, then SQL +** functions or aggregates must be added individually to each database +** handle with which they will be used. +** +** The second parameter is the name of the SQL function to be created +** or redefined. +** The length of the name is limited to 255 bytes, exclusive of the +** zero-terminator. Note that the name length limit is in bytes, not +** characters. Any attempt to create a function with a longer name +** will result in an SQLITE_ERROR error. +** +** The third parameter is the number of arguments that the SQL function or +** aggregate takes. If this parameter is negative, then the SQL function or +** aggregate may take any number of arguments. +** +** The fourth parameter, eTextRep, specifies what +** [SQLITE_UTF8 | text encoding] this SQL function prefers for +** its parameters. Any SQL function implementation should be able to work +** work with UTF-8, UTF-16le, or UTF-16be. But some implementations may be +** more efficient with one encoding than another. It is allowed to +** invoke sqlite3_create_function() or sqlite3_create_function16() multiple +** times with the same function but with different values of eTextRep. +** When multiple implementations of the same function are available, SQLite +** will pick the one that involves the least amount of data conversion. +** If there is only a single implementation which does not care what +** text encoding is used, then the fourth argument should be +** [SQLITE_ANY]. +** +** The fifth parameter is an arbitrary pointer. The implementation +** of the function can gain access to this pointer using +** [sqlite3_user_data()]. +** +** The seventh, eighth and ninth parameters, xFunc, xStep and xFinal, are +** pointers to C-language functions that implement the SQL +** function or aggregate. A scalar SQL function requires an implementation of +** the xFunc callback only, NULL pointers should be passed as the xStep +** and xFinal parameters. An aggregate SQL function requires an implementation +** of xStep and xFinal and NULL should be passed for xFunc. To delete an +** existing SQL function or aggregate, pass NULL for all three function +** callback. +** +** It is permitted to register multiple implementations of the same +** functions with the same name but with either differing numbers of +** arguments or differing perferred text encodings. SQLite will use +** the implementation most closely matches the way in which the +** SQL function is used. +*/ +int sqlite3_create_function( + sqlite3 *, + const char *zFunctionName, + int nArg, + int eTextRep, + void*, + void (*xFunc)(sqlite3_context*,int,sqlite3_value**), + void (*xStep)(sqlite3_context*,int,sqlite3_value**), + void (*xFinal)(sqlite3_context*) +); +int sqlite3_create_function16( + sqlite3*, + const void *zFunctionName, + int nArg, + int eTextRep, + void*, + void (*xFunc)(sqlite3_context*,int,sqlite3_value**), + void (*xStep)(sqlite3_context*,int,sqlite3_value**), + void (*xFinal)(sqlite3_context*) +); + +/* +** CAPI3REF: Text Encodings +** +** These constant define integer codes that represent the various +** text encodings supported by SQLite. +*/ +#define SQLITE_UTF8 1 +#define SQLITE_UTF16LE 2 +#define SQLITE_UTF16BE 3 +#define SQLITE_UTF16 4 /* Use native byte order */ +#define SQLITE_ANY 5 /* sqlite3_create_function only */ +#define SQLITE_UTF16_ALIGNED 8 /* sqlite3_create_collation only */ + +/* +** CAPI3REF: Obsolete Functions +** +** These functions are all now obsolete. In order to maintain +** backwards compatibility with older code, we continue to support +** these functions. However, new development projects should avoid +** the use of these functions. To help encourage people to avoid +** using these functions, we are not going to tell you want they do. +*/ +int sqlite3_aggregate_count(sqlite3_context*); +int sqlite3_expired(sqlite3_stmt*); +int sqlite3_transfer_bindings(sqlite3_stmt*, sqlite3_stmt*); +int sqlite3_global_recover(void); +void sqlite3_thread_cleanup(void); +int sqlite3_memory_alarm(void(*)(void*,sqlite3_int64,int),void*,sqlite3_int64); + +/* +** CAPI3REF: Obtaining SQL Function Parameter Values +** +** The C-language implementation of SQL functions and aggregates uses +** this set of interface routines to access the parameter values on +** the function or aggregate. +** +** The xFunc (for scalar functions) or xStep (for aggregates) parameters +** to [sqlite3_create_function()] and [sqlite3_create_function16()] +** define callbacks that implement the SQL functions and aggregates. +** The 4th parameter to these callbacks is an array of pointers to +** [sqlite3_value] objects. There is one [sqlite3_value] object for +** each parameter to the SQL function. These routines are used to +** extract values from the [sqlite3_value] objects. +** +** These routines work just like the corresponding +** [sqlite3_column_blob | sqlite3_column_* routines] except that +** these routines take a single [sqlite3_value*] pointer instead +** of an [sqlite3_stmt*] pointer and an integer column number. +** +** The sqlite3_value_text16() interface extracts a UTF16 string +** in the native byte-order of the host machine. The +** sqlite3_value_text16be() and sqlite3_value_text16le() interfaces +** extract UTF16 strings as big-endian and little-endian respectively. +** +** The sqlite3_value_numeric_type() interface attempts to apply +** numeric affinity to the value. This means that an attempt is +** made to convert the value to an integer or floating point. If +** such a conversion is possible without loss of information (in order +** words if the value is original a string that looks like a number) +** then it is done. Otherwise no conversion occurs. The +** [SQLITE_INTEGER | datatype] after conversion is returned. +** +** Please pay particular attention to the fact that the pointer that +** is returned from [sqlite3_value_blob()], [sqlite3_value_text()], or +** [sqlite3_value_text16()] can be invalidated by a subsequent call to +** [sqlite3_value_bytes()], [sqlite3_value_bytes16()], [sqlite3_value_text()], +** or [sqlite3_value_text16()]. +** +** These routines must be called from the same thread as +** the SQL function that supplied the sqlite3_value* parameters. +** Or, if the sqlite3_value* argument comes from the [sqlite3_column_value()] +** interface, then these routines should be called from the same thread +** that ran [sqlite3_column_value()]. +*/ +const void *sqlite3_value_blob(sqlite3_value*); +int sqlite3_value_bytes(sqlite3_value*); +int sqlite3_value_bytes16(sqlite3_value*); +double sqlite3_value_double(sqlite3_value*); +int sqlite3_value_int(sqlite3_value*); +sqlite3_int64 sqlite3_value_int64(sqlite3_value*); +const unsigned char *sqlite3_value_text(sqlite3_value*); +const void *sqlite3_value_text16(sqlite3_value*); +const void *sqlite3_value_text16le(sqlite3_value*); +const void *sqlite3_value_text16be(sqlite3_value*); +int sqlite3_value_type(sqlite3_value*); +int sqlite3_value_numeric_type(sqlite3_value*); + +/* +** CAPI3REF: Obtain Aggregate Function Context +** +** The implementation of aggregate SQL functions use this routine to allocate +** a structure for storing their state. The first time this routine +** is called for a particular aggregate, a new structure of size nBytes +** is allocated, zeroed, and returned. On subsequent calls (for the +** same aggregate instance) the same buffer is returned. The implementation +** of the aggregate can use the returned buffer to accumulate data. +** +** The buffer allocated is freed automatically by SQLite whan the aggregate +** query concludes. +** +** The first parameter should be a copy of the +** [sqlite3_context | SQL function context] that is the first +** parameter to the callback routine that implements the aggregate +** function. +** +** This routine must be called from the same thread in which +** the aggregate SQL function is running. +*/ +void *sqlite3_aggregate_context(sqlite3_context*, int nBytes); + +/* +** CAPI3REF: User Data For Functions +** +** The pUserData parameter to the [sqlite3_create_function()] +** and [sqlite3_create_function16()] routines +** used to register user functions is available to +** the implementation of the function using this call. +** +** This routine must be called from the same thread in which +** the SQL function is running. +*/ +void *sqlite3_user_data(sqlite3_context*); + +/* +** CAPI3REF: Function Auxiliary Data +** +** The following two functions may be used by scalar SQL functions to +** associate meta-data with argument values. If the same value is passed to +** multiple invocations of the same SQL function during query execution, under +** some circumstances the associated meta-data may be preserved. This may +** be used, for example, to add a regular-expression matching scalar +** function. The compiled version of the regular expression is stored as +** meta-data associated with the SQL value passed as the regular expression +** pattern. The compiled regular expression can be reused on multiple +** invocations of the same function so that the original pattern string +** does not need to be recompiled on each invocation. +** +** The sqlite3_get_auxdata() interface returns a pointer to the meta-data +** associated with the Nth argument value to the current SQL function +** call, where N is the second parameter. If no meta-data has been set for +** that value, then a NULL pointer is returned. +** +** The sqlite3_set_auxdata() is used to associate meta-data with an SQL +** function argument. The third parameter is a pointer to the meta-data +** to be associated with the Nth user function argument value. The fourth +** parameter specifies a destructor that will be called on the meta- +** data pointer to release it when it is no longer required. If the +** destructor is NULL, it is not invoked. +** +** In practice, meta-data is preserved between function calls for +** expressions that are constant at compile time. This includes literal +** values and SQL variables. +** +** These routines must be called from the same thread in which +** the SQL function is running. +*/ +void *sqlite3_get_auxdata(sqlite3_context*, int); +void sqlite3_set_auxdata(sqlite3_context*, int, void*, void (*)(void*)); + + +/* +** CAPI3REF: Constants Defining Special Destructor Behavior +** +** These are special value for the destructor that is passed in as the +** final argument to routines like [sqlite3_result_blob()]. If the destructor +** argument is SQLITE_STATIC, it means that the content pointer is constant +** and will never change. It does not need to be destroyed. The +** SQLITE_TRANSIENT value means that the content will likely change in +** the near future and that SQLite should make its own private copy of +** the content before returning. +** +** The typedef is necessary to work around problems in certain +** C++ compilers. See ticket #2191. +*/ +typedef void (*sqlite3_destructor_type)(void*); +#define SQLITE_STATIC ((sqlite3_destructor_type)0) +#define SQLITE_TRANSIENT ((sqlite3_destructor_type)-1) + +/* +** CAPI3REF: Setting The Result Of An SQL Function +** +** These routines are used by the xFunc or xFinal callbacks that +** implement SQL functions and aggregates. See +** [sqlite3_create_function()] and [sqlite3_create_function16()] +** for additional information. +** +** These functions work very much like the +** [sqlite3_bind_blob | sqlite3_bind_*] family of functions used +** to bind values to host parameters in prepared statements. +** Refer to the +** [sqlite3_bind_blob | sqlite3_bind_* documentation] for +** additional information. +** +** The sqlite3_result_error() and sqlite3_result_error16() functions +** cause the implemented SQL function to throw an exception. The +** parameter to sqlite3_result_error() or sqlite3_result_error16() +** is the text of an error message. +** +** The sqlite3_result_toobig() cause the function implementation +** to throw and error indicating that a string or BLOB is to long +** to represent. +** +** These routines must be called from within the same thread as +** the SQL function associated with the [sqlite3_context] pointer. +*/ +void sqlite3_result_blob(sqlite3_context*, const void*, int, void(*)(void*)); +void sqlite3_result_double(sqlite3_context*, double); +void sqlite3_result_error(sqlite3_context*, const char*, int); +void sqlite3_result_error16(sqlite3_context*, const void*, int); +void sqlite3_result_error_toobig(sqlite3_context*); +void sqlite3_result_error_nomem(sqlite3_context*); +void sqlite3_result_int(sqlite3_context*, int); +void sqlite3_result_int64(sqlite3_context*, sqlite3_int64); +void sqlite3_result_null(sqlite3_context*); +void sqlite3_result_text(sqlite3_context*, const char*, int, void(*)(void*)); +void sqlite3_result_text16(sqlite3_context*, const void*, int, void(*)(void*)); +void sqlite3_result_text16le(sqlite3_context*, const void*, int,void(*)(void*)); +void sqlite3_result_text16be(sqlite3_context*, const void*, int,void(*)(void*)); +void sqlite3_result_value(sqlite3_context*, sqlite3_value*); +void sqlite3_result_zeroblob(sqlite3_context*, int n); + +/* +** CAPI3REF: Define New Collating Sequences +** +** These functions are used to add new collation sequences to the +** [sqlite3*] handle specified as the first argument. +** +** The name of the new collation sequence is specified as a UTF-8 string +** for sqlite3_create_collation() and sqlite3_create_collation_v2() +** and a UTF-16 string for sqlite3_create_collation16(). In all cases +** the name is passed as the second function argument. +** +** The third argument may be one of the constants [SQLITE_UTF8], +** [SQLITE_UTF16LE] or [SQLITE_UTF16BE], indicating that the user-supplied +** routine expects to be passed pointers to strings encoded using UTF-8, +** UTF-16 little-endian or UTF-16 big-endian respectively. The +** third argument might also be [SQLITE_UTF16_ALIGNED] to indicate that +** the routine expects pointers to 16-bit word aligned strings +** of UTF16 in the native byte order of the host computer. +** +** A pointer to the user supplied routine must be passed as the fifth +** argument. If it is NULL, this is the same as deleting the collation +** sequence (so that SQLite cannot call it anymore). Each time the user +** supplied function is invoked, it is passed a copy of the void* passed as +** the fourth argument to sqlite3_create_collation() or +** sqlite3_create_collation16() as its first parameter. +** +** The remaining arguments to the user-supplied routine are two strings, +** each represented by a [length, data] pair and encoded in the encoding +** that was passed as the third argument when the collation sequence was +** registered. The user routine should return negative, zero or positive if +** the first string is less than, equal to, or greater than the second +** string. i.e. (STRING1 - STRING2). +** +** The sqlite3_create_collation_v2() works like sqlite3_create_collation() +** excapt that it takes an extra argument which is a destructor for +** the collation. The destructor is called when the collation is +** destroyed and is passed a copy of the fourth parameter void* pointer +** of the sqlite3_create_collation_v2(). Collations are destroyed when +** they are overridden by later calls to the collation creation functions +** or when the [sqlite3*] database handle is closed using [sqlite3_close()]. +** +** The sqlite3_create_collation_v2() interface is experimental and +** subject to change in future releases. The other collation creation +** functions are stable. +*/ +int sqlite3_create_collation( + sqlite3*, + const char *zName, + int eTextRep, + void*, + int(*xCompare)(void*,int,const void*,int,const void*) +); +int sqlite3_create_collation_v2( + sqlite3*, + const char *zName, + int eTextRep, + void*, + int(*xCompare)(void*,int,const void*,int,const void*), + void(*xDestroy)(void*) +); +int sqlite3_create_collation16( + sqlite3*, + const char *zName, + int eTextRep, + void*, + int(*xCompare)(void*,int,const void*,int,const void*) +); + +/* +** CAPI3REF: 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 handle to be called whenever an undefined collation sequence is +** required. +** +** If the function is registered using the sqlite3_collation_needed() API, +** then it is passed the names of undefined collation sequences as strings +** encoded in UTF-8. If sqlite3_collation_needed16() is used, the names +** are passed as UTF-16 in machine native byte order. A call to either +** function replaces any existing callback. +** +** When the callback is invoked, the first argument passed is a copy +** of the second argument to sqlite3_collation_needed() or +** sqlite3_collation_needed16(). The second argument is the database +** handle. The third argument is one of [SQLITE_UTF8], [SQLITE_UTF16BE], or +** [SQLITE_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 +** [sqlite3_create_collation()], [sqlite3_create_collation16()], or +** [sqlite3_create_collation_v2()]. +*/ +int sqlite3_collation_needed( + sqlite3*, + void*, + void(*)(void*,sqlite3*,int eTextRep,const char*) +); +int sqlite3_collation_needed16( + sqlite3*, + void*, + void(*)(void*,sqlite3*,int eTextRep,const void*) +); + +/* +** Specify the key for an encrypted database. This routine should be +** called right after sqlite3_open(). +** +** The code to implement this API is not available in the public release +** of SQLite. +*/ +int sqlite3_key( + sqlite3 *db, /* Database to be rekeyed */ + const void *pKey, int nKey /* The key */ +); + +/* +** Change the key on an open database. If the current database is not +** encrypted, this routine will encrypt it. If pNew==0 or nNew==0, the +** database is decrypted. +** +** The code to implement this API is not available in the public release +** of SQLite. +*/ +int sqlite3_rekey( + sqlite3 *db, /* Database to be rekeyed */ + const void *pKey, int nKey /* The new key */ +); + +/* +** CAPI3REF: Suspend Execution For A Short Time +** +** This function causes the current thread to suspend execution +** a number of milliseconds specified in its parameter. +** +** If the operating system does not support sleep requests with +** millisecond time resolution, then the time will be rounded up to +** the nearest second. The number of milliseconds of sleep actually +** requested from the operating system is returned. +** +** SQLite implements this interface by calling the xSleep() +** method of the default [sqlite3_vfs] object. +*/ +int sqlite3_sleep(int); + +/* +** CAPI3REF: Name Of The Folder Holding Temporary Files +** +** If this global variable is made to point to a string which is +** the name of a folder (a.ka. directory), then all temporary files +** created by SQLite will be placed in that directory. If this variable +** is NULL pointer, then SQLite does a search for an appropriate temporary +** file directory. +** +** It is not safe to modify this variable once a database connection +** has been opened. It is intended that this variable be set once +** as part of process initialization and before any SQLite interface +** routines have been call and remain unchanged thereafter. +*/ +SQLITE_EXTERN char *sqlite3_temp_directory; + +/* +** CAPI3REF: Test To See If The Database Is In Auto-Commit Mode +** +** Test to see whether or not the database connection is in autocommit +** mode. Return TRUE if it is and FALSE if not. Autocommit mode is on +** by default. Autocommit is disabled by a BEGIN statement and reenabled +** by the next COMMIT or ROLLBACK. +** +** If certain kinds of errors occur on a statement within a multi-statement +** transactions (errors including [SQLITE_FULL], [SQLITE_IOERR], +** [SQLITE_NOMEM], [SQLITE_BUSY], and [SQLITE_INTERRUPT]) then the +** transaction might be rolled back automatically. The only way to +** find out if SQLite automatically rolled back the transaction after +** an error is to use this function. +** +** If another thread changes the autocommit status of the database +** connection while this routine is running, then the return value +** is undefined. +*/ +int sqlite3_get_autocommit(sqlite3*); + +/* +** CAPI3REF: Find The Database Handle Associated With A Prepared Statement +** +** Return the [sqlite3*] database handle to which a +** [sqlite3_stmt | prepared statement] belongs. +** This is the same database handle that was +** the first argument to the [sqlite3_prepare_v2()] or its variants +** that was used to create the statement in the first place. +*/ +sqlite3 *sqlite3_db_handle(sqlite3_stmt*); + + +/* +** CAPI3REF: Commit And Rollback Notification Callbacks +** +** These routines +** register callback functions to be invoked whenever a transaction +** is committed or rolled back. The pArg argument is passed through +** to the callback. If the callback on a commit hook function +** returns non-zero, then the commit is converted into a rollback. +** +** If another function was previously registered, its pArg value is returned. +** Otherwise NULL is returned. +** +** Registering a NULL function disables the callback. +** +** For the purposes of this API, a transaction is said to have been +** rolled back if an explicit "ROLLBACK" statement is executed, or +** an error or constraint causes an implicit rollback to occur. The +** callback is not invoked if a transaction is automatically rolled +** back because the database connection is closed. +** +** These are experimental interfaces and are subject to change. +*/ +void *sqlite3_commit_hook(sqlite3*, int(*)(void*), void*); +void *sqlite3_rollback_hook(sqlite3*, void(*)(void *), void*); + +/* +** CAPI3REF: Data Change Notification Callbacks +** +** Register a callback function with the database connection identified by the +** first argument to be invoked whenever a row is updated, inserted or deleted. +** Any callback set by a previous call to this function for the same +** database connection is overridden. +** +** The second argument is a pointer to the function to invoke when a +** row is updated, inserted or deleted. The first argument to the callback is +** a copy of the third argument to sqlite3_update_hook(). The second callback +** argument is one of SQLITE_INSERT, SQLITE_DELETE or SQLITE_UPDATE, depending +** on the operation that caused the callback to be invoked. The third and +** fourth arguments to the callback contain pointers to the database and +** table name containing the affected row. The final callback parameter is +** the rowid of the row. In the case of an update, this is the rowid after +** the update takes place. +** +** The update hook is not invoked when internal system tables are +** modified (i.e. sqlite_master and sqlite_sequence). +** +** If another function was previously registered, its pArg value is returned. +** Otherwise NULL is returned. +*/ +void *sqlite3_update_hook( + sqlite3*, + void(*)(void *,int ,char const *,char const *,sqlite3_int64), + void* +); + +/* +** CAPI3REF: Enable Or Disable Shared Pager Cache +** +** This routine enables or disables the sharing of the database cache +** and schema data structures between connections to the same database. +** Sharing is enabled if the argument is true and disabled if the argument +** is false. +** +** Beginning in SQLite version 3.5.0, cache sharing is enabled and disabled +** for an entire process. In prior versions of SQLite, sharing was +** enabled or disabled for each thread separately. +** +** The cache sharing mode set by this interface effects all subsequent +** calls to [sqlite3_open()], [sqlite3_open_v2()], and [sqlite3_open16()]. +** Existing database connections continue use the sharing mode that was +** in effect at the time they were opened. +** +** Virtual tables cannot be used with a shared cache. When shared +** cache is enabled, the [sqlite3_create_module()] API used to register +** virtual tables will always return an error. +** +** This routine returns [SQLITE_OK] if shared cache was +** enabled or disabled successfully. An [SQLITE_ERROR | error code] +** is returned otherwise. +** +** Shared cache is disabled by default. But this might change in +** future releases of SQLite. Applications that care about shared +** cache setting should set it explicitly. +*/ +int sqlite3_enable_shared_cache(int); + +/* +** CAPI3REF: Attempt To Free Heap Memory +** +** Attempt to free N bytes of heap memory by deallocating non-essential +** memory allocations held by the database library (example: memory +** used to cache database pages to improve performance). +*/ +int sqlite3_release_memory(int); + +/* +** CAPI3REF: Impose A Limit On Heap Size +** +** Place a "soft" limit on the amount of heap memory that may be allocated +** by SQLite. If an internal allocation is requested +** that would exceed the specified limit, [sqlite3_release_memory()] is +** invoked one or more times to free up some space before the allocation +** is made. +** +** The limit is called "soft", because if [sqlite3_release_memory()] cannot +** free sufficient memory to prevent the limit from being exceeded, +** the memory is allocated anyway and the current operation proceeds. +** +** A negative or zero value for N means that there is no soft heap limit and +** [sqlite3_release_memory()] will only be called when memory is exhausted. +** The default value for the soft heap limit is zero. +** +** SQLite makes a best effort to honor the soft heap limit. But if it +** is unable to reduce memory usage below the soft limit, execution will +** continue without error or notification. This is why the limit is +** called a "soft" limit. It is advisory only. +** +** Prior to SQLite version 3.5.0, this routine only constrained the memory +** allocated by a single thread - the same thread in which this routine +** runs. Beginning with SQLite version 3.5.0, the soft heap limit is +** applied to all threads. The value specified for the soft heap limit +** is an upper bound on the total memory allocation for all threads. In +** version 3.5.0 there is no mechanism for limiting the heap usage for +** individual threads. +*/ +void sqlite3_soft_heap_limit(int); + +/* +** CAPI3REF: Extract Metadata About A Column Of A Table +** +** This routine +** returns meta-data about a specific column of a specific database +** table accessible using the connection handle passed as the first function +** argument. +** +** The column is identified by the second, third and fourth parameters to +** this function. The second parameter is either the name of the database +** (i.e. "main", "temp" or an attached database) containing the specified +** table or NULL. If it is NULL, then all attached databases are searched +** for the table using the same algorithm as the database engine uses to +** resolve unqualified table references. +** +** The third and fourth parameters to this function are the table and column +** name of the desired column, respectively. Neither of these parameters +** may be NULL. +** +** Meta information is returned by writing to the memory locations passed as +** the 5th and subsequent parameters to this function. Any of these +** arguments may be NULL, in which case the corresponding element of meta +** information is ommitted. +** +** <pre> +** Parameter Output Type Description +** ----------------------------------- +** +** 5th const char* Data type +** 6th const char* Name of the default collation sequence +** 7th int True if the column has a NOT NULL constraint +** 8th int True if the column is part of the PRIMARY KEY +** 9th int True if the column is AUTOINCREMENT +** </pre> +** +** +** The memory pointed to by the character pointers returned for the +** declaration type and collation sequence is valid only until the next +** call to any sqlite API function. +** +** If the specified table is actually a view, then an error is returned. +** +** If the specified column is "rowid", "oid" or "_rowid_" and an +** INTEGER PRIMARY KEY column has been explicitly declared, then the output +** parameters are set for the explicitly declared column. If there is no +** explicitly declared IPK column, then the output parameters are set as +** follows: +** +** <pre> +** data type: "INTEGER" +** collation sequence: "BINARY" +** not null: 0 +** primary key: 1 +** auto increment: 0 +** </pre> +** +** This function may load one or more schemas from database files. If an +** error occurs during this process, or if the requested table or column +** cannot be found, an SQLITE error code is returned and an error message +** left in the database handle (to be retrieved using sqlite3_errmsg()). +** +** This API is only available if the library was compiled with the +** SQLITE_ENABLE_COLUMN_METADATA preprocessor symbol defined. +*/ +int sqlite3_table_column_metadata( + sqlite3 *db, /* Connection handle */ + const char *zDbName, /* Database name or NULL */ + const char *zTableName, /* Table name */ + const char *zColumnName, /* Column name */ + char const **pzDataType, /* OUTPUT: Declared data type */ + char const **pzCollSeq, /* OUTPUT: Collation sequence name */ + int *pNotNull, /* OUTPUT: True if NOT NULL constraint exists */ + int *pPrimaryKey, /* OUTPUT: True if column part of PK */ + int *pAutoinc /* OUTPUT: True if column is auto-increment */ +); + +/* +** CAPI3REF: Load An Extension +** +** Attempt to load an SQLite extension library contained in the file +** zFile. The entry point is zProc. zProc may be 0 in which case the +** name of the entry point defaults to "sqlite3_extension_init". +** +** Return [SQLITE_OK] on success and [SQLITE_ERROR] if something goes wrong. +** +** If an error occurs and pzErrMsg is not 0, then fill *pzErrMsg with +** error message text. The calling function should free this memory +** by calling [sqlite3_free()]. +** +** Extension loading must be enabled using [sqlite3_enable_load_extension()] +** prior to calling this API or an error will be returned. +*/ +int sqlite3_load_extension( + sqlite3 *db, /* Load the extension into this database connection */ + const char *zFile, /* Name of the shared library containing extension */ + const char *zProc, /* Entry point. Derived from zFile if 0 */ + char **pzErrMsg /* Put error message here if not 0 */ +); + +/* +** CAPI3REF: Enable Or Disable Extension Loading +** +** So as not to open security holes in older applications that are +** unprepared to deal with extension loading, and as a means of disabling +** extension loading while evaluating user-entered SQL, the following +** API is provided to turn the [sqlite3_load_extension()] mechanism on and +** off. It is off by default. See ticket #1863. +** +** Call this routine with onoff==1 to turn extension loading on +** and call it with onoff==0 to turn it back off again. +*/ +int sqlite3_enable_load_extension(sqlite3 *db, int onoff); + +/* +** CAPI3REF: Make Arrangements To Automatically Load An Extension +** +** Register an extension entry point that is automatically invoked +** whenever a new database connection is opened using +** [sqlite3_open()], [sqlite3_open16()], or [sqlite3_open_v2()]. +** +** This API can be invoked at program startup in order to register +** one or more statically linked extensions that will be available +** to all new database connections. +** +** Duplicate extensions are detected so calling this routine multiple +** times with the same extension is harmless. +** +** This routine stores a pointer to the extension in an array +** that is obtained from malloc(). If you run a memory leak +** checker on your program and it reports a leak because of this +** array, then invoke [sqlite3_reset_auto_extension()] prior +** to shutdown to free the memory. +** +** Automatic extensions apply across all threads. +** +** This interface is experimental and is subject to change or +** removal in future releases of SQLite. +*/ +int sqlite3_auto_extension(void *xEntryPoint); + + +/* +** CAPI3REF: Reset Automatic Extension Loading +** +** Disable all previously registered automatic extensions. This +** routine undoes the effect of all prior [sqlite3_automatic_extension()] +** calls. +** +** This call disabled automatic extensions in all threads. +** +** This interface is experimental and is subject to change or +** removal in future releases of SQLite. +*/ +void sqlite3_reset_auto_extension(void); + + +/* +****** EXPERIMENTAL - subject to change without notice ************** +** +** The interface to the virtual-table mechanism is currently considered +** to be experimental. The interface might change in incompatible ways. +** If this is a problem for you, do not use the interface at this time. +** +** When the virtual-table mechanism stablizes, we will declare the +** interface fixed, support it indefinitely, and remove this comment. +*/ + +/* +** Structures used by the virtual table interface +*/ +typedef struct sqlite3_vtab sqlite3_vtab; +typedef struct sqlite3_index_info sqlite3_index_info; +typedef struct sqlite3_vtab_cursor sqlite3_vtab_cursor; +typedef struct sqlite3_module sqlite3_module; + +/* +** A module is a class of virtual tables. Each module is defined +** by an instance of the following structure. This structure consists +** mostly of methods for the module. +*/ +struct sqlite3_module { + int iVersion; + int (*xCreate)(sqlite3*, void *pAux, + int argc, const char *const*argv, + sqlite3_vtab **ppVTab, char**); + int (*xConnect)(sqlite3*, void *pAux, + int argc, const char *const*argv, + sqlite3_vtab **ppVTab, char**); + int (*xBestIndex)(sqlite3_vtab *pVTab, sqlite3_index_info*); + int (*xDisconnect)(sqlite3_vtab *pVTab); + int (*xDestroy)(sqlite3_vtab *pVTab); + int (*xOpen)(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor); + int (*xClose)(sqlite3_vtab_cursor*); + int (*xFilter)(sqlite3_vtab_cursor*, int idxNum, const char *idxStr, + int argc, sqlite3_value **argv); + int (*xNext)(sqlite3_vtab_cursor*); + int (*xEof)(sqlite3_vtab_cursor*); + int (*xColumn)(sqlite3_vtab_cursor*, sqlite3_context*, int); + int (*xRowid)(sqlite3_vtab_cursor*, sqlite3_int64 *pRowid); + int (*xUpdate)(sqlite3_vtab *, int, sqlite3_value **, sqlite3_int64 *); + int (*xBegin)(sqlite3_vtab *pVTab); + int (*xSync)(sqlite3_vtab *pVTab); + int (*xCommit)(sqlite3_vtab *pVTab); + int (*xRollback)(sqlite3_vtab *pVTab); + int (*xFindFunction)(sqlite3_vtab *pVtab, int nArg, const char *zName, + void (**pxFunc)(sqlite3_context*,int,sqlite3_value**), + void **ppArg); + + int (*xRename)(sqlite3_vtab *pVtab, const char *zNew); +}; + +/* +** The sqlite3_index_info structure and its substructures is used to +** pass information into and receive the reply from the xBestIndex +** method of an sqlite3_module. The fields under **Inputs** are the +** inputs to xBestIndex and are read-only. xBestIndex inserts its +** results into the **Outputs** fields. +** +** The aConstraint[] array records WHERE clause constraints of the +** form: +** +** column OP expr +** +** Where OP is =, <, <=, >, or >=. The particular operator is stored +** in aConstraint[].op. The index of the column is stored in +** aConstraint[].iColumn. aConstraint[].usable is TRUE if the +** expr on the right-hand side can be evaluated (and thus the constraint +** is usable) and false if it cannot. +** +** The optimizer automatically inverts terms of the form "expr OP column" +** and makes other simplifications to the WHERE clause in an attempt to +** get as many WHERE clause terms into the form shown above as possible. +** The aConstraint[] array only reports WHERE clause terms in the correct +** form that refer to the particular virtual table being queried. +** +** Information about the ORDER BY clause is stored in aOrderBy[]. +** Each term of aOrderBy records a column of the ORDER BY clause. +** +** The xBestIndex method must fill aConstraintUsage[] with information +** about what parameters to pass to xFilter. If argvIndex>0 then +** the right-hand side of the corresponding aConstraint[] is evaluated +** and becomes the argvIndex-th entry in argv. If aConstraintUsage[].omit +** is true, then the constraint is assumed to be fully handled by the +** virtual table and is not checked again by SQLite. +** +** The idxNum and idxPtr values are recorded and passed into xFilter. +** sqlite3_free() is used to free idxPtr if needToFreeIdxPtr is true. +** +** The orderByConsumed means that output from xFilter will occur in +** the correct order to satisfy the ORDER BY clause so that no separate +** sorting step is required. +** +** The estimatedCost value is an estimate of the cost of doing the +** particular lookup. A full scan of a table with N entries should have +** a cost of N. A binary search of a table of N entries should have a +** cost of approximately log(N). +*/ +struct sqlite3_index_info { + /* Inputs */ + int nConstraint; /* Number of entries in aConstraint */ + struct sqlite3_index_constraint { + int iColumn; /* Column on left-hand side of constraint */ + unsigned char op; /* Constraint operator */ + unsigned char usable; /* True if this constraint is usable */ + int iTermOffset; /* Used internally - xBestIndex should ignore */ + } *aConstraint; /* Table of WHERE clause constraints */ + int nOrderBy; /* Number of terms in the ORDER BY clause */ + struct sqlite3_index_orderby { + int iColumn; /* Column number */ + unsigned char desc; /* True for DESC. False for ASC. */ + } *aOrderBy; /* The ORDER BY clause */ + + /* Outputs */ + struct sqlite3_index_constraint_usage { + int argvIndex; /* if >0, constraint is part of argv to xFilter */ + unsigned char omit; /* Do not code a test for this constraint */ + } *aConstraintUsage; + int idxNum; /* Number used to identify the index */ + char *idxStr; /* String, possibly obtained from sqlite3_malloc */ + int needToFreeIdxStr; /* Free idxStr using sqlite3_free() if true */ + int orderByConsumed; /* True if output is already ordered */ + double estimatedCost; /* Estimated cost of using this index */ +}; +#define SQLITE_INDEX_CONSTRAINT_EQ 2 +#define SQLITE_INDEX_CONSTRAINT_GT 4 +#define SQLITE_INDEX_CONSTRAINT_LE 8 +#define SQLITE_INDEX_CONSTRAINT_LT 16 +#define SQLITE_INDEX_CONSTRAINT_GE 32 +#define SQLITE_INDEX_CONSTRAINT_MATCH 64 + +/* +** This routine is used to register a new module name with an SQLite +** connection. Module names must be registered before creating new +** virtual tables on the module, or before using preexisting virtual +** tables of the module. +*/ +int sqlite3_create_module( + sqlite3 *db, /* SQLite connection to register module with */ + const char *zName, /* Name of the module */ + const sqlite3_module *, /* Methods for the module */ + void * /* Client data for xCreate/xConnect */ +); + +/* +** This routine is identical to the sqlite3_create_module() method above, +** except that it allows a destructor function to be specified. It is +** even more experimental than the rest of the virtual tables API. +*/ +int sqlite3_create_module_v2( + sqlite3 *db, /* SQLite connection to register module with */ + const char *zName, /* Name of the module */ + const sqlite3_module *, /* Methods for the module */ + void *, /* Client data for xCreate/xConnect */ + void(*xDestroy)(void*) /* Module destructor function */ +); + +/* +** Every module implementation uses a subclass of the following structure +** to describe a particular instance of the module. Each subclass will +** be tailored to the specific needs of the module implementation. The +** purpose of this superclass is to define certain fields that are common +** to all module implementations. +** +** Virtual tables methods can set an error message by assigning a +** string obtained from sqlite3_mprintf() to zErrMsg. The method should +** take care that any prior string is freed by a call to sqlite3_free() +** prior to assigning a new string to zErrMsg. After the error message +** is delivered up to the client application, the string will be automatically +** freed by sqlite3_free() and the zErrMsg field will be zeroed. Note +** that sqlite3_mprintf() and sqlite3_free() are used on the zErrMsg field +** since virtual tables are commonly implemented in loadable extensions which +** do not have access to sqlite3MPrintf() or sqlite3Free(). +*/ +struct sqlite3_vtab { + const sqlite3_module *pModule; /* The module for this virtual table */ + int nRef; /* Used internally */ + char *zErrMsg; /* Error message from sqlite3_mprintf() */ + /* Virtual table implementations will typically add additional fields */ +}; + +/* Every module implementation uses a subclass of the following structure +** to describe cursors that point into the virtual table and are used +** to loop through the virtual table. Cursors are created using the +** xOpen method of the module. Each module implementation will define +** the content of a cursor structure to suit its own needs. +** +** This superclass exists in order to define fields of the cursor that +** are common to all implementations. +*/ +struct sqlite3_vtab_cursor { + sqlite3_vtab *pVtab; /* Virtual table of this cursor */ + /* Virtual table implementations will typically add additional fields */ +}; + +/* +** The xCreate and xConnect methods of a module use the following API +** to declare the format (the names and datatypes of the columns) of +** the virtual tables they implement. +*/ +int sqlite3_declare_vtab(sqlite3*, const char *zCreateTable); + +/* +** Virtual tables can provide alternative implementations of functions +** using the xFindFunction method. But global versions of those functions +** must exist in order to be overloaded. +** +** This API makes sure a global version of a function with a particular +** name and number of parameters exists. If no such function exists +** before this API is called, a new function is created. The implementation +** of the new function always causes an exception to be thrown. So +** the new function is not good for anything by itself. Its only +** purpose is to be a place-holder function that can be overloaded +** by virtual tables. +** +** This API should be considered part of the virtual table interface, +** which is experimental and subject to change. +*/ +int sqlite3_overload_function(sqlite3*, const char *zFuncName, int nArg); + +/* +** The interface to the virtual-table mechanism defined above (back up +** to a comment remarkably similar to this one) is currently considered +** to be experimental. The interface might change in incompatible ways. +** If this is a problem for you, do not use the interface at this time. +** +** When the virtual-table mechanism stabilizes, we will declare the +** interface fixed, support it indefinitely, and remove this comment. +** +****** EXPERIMENTAL - subject to change without notice ************** +*/ + +/* +** CAPI3REF: A Handle To An Open BLOB +** +** An instance of the following opaque structure is used to +** represent an blob-handle. A blob-handle is created by +** [sqlite3_blob_open()] and destroyed by [sqlite3_blob_close()]. +** The [sqlite3_blob_read()] and [sqlite3_blob_write()] interfaces +** can be used to read or write small subsections of the blob. +** The [sqlite3_blob_bytes()] interface returns the size of the +** blob in bytes. +*/ +typedef struct sqlite3_blob sqlite3_blob; + +/* +** CAPI3REF: Open A BLOB For Incremental I/O +** +** Open a handle to the blob located in row iRow,, column zColumn, +** table zTable in database zDb. i.e. the same blob that would +** be selected by: +** +** <pre> +** SELECT zColumn FROM zDb.zTable WHERE rowid = iRow; +** </pre> +** +** If the flags parameter is non-zero, the blob is opened for +** read and write access. If it is zero, the blob is opened for read +** access. +** +** On success, [SQLITE_OK] is returned and the new +** [sqlite3_blob | blob handle] is written to *ppBlob. +** Otherwise an error code is returned and +** any value written to *ppBlob should not be used by the caller. +** This function sets the database-handle error code and message +** accessible via [sqlite3_errcode()] and [sqlite3_errmsg()]. +*/ +int sqlite3_blob_open( + sqlite3*, + const char *zDb, + const char *zTable, + const char *zColumn, + sqlite3_int64 iRow, + int flags, + sqlite3_blob **ppBlob +); + +/* +** CAPI3REF: Close A BLOB Handle +** +** Close an open [sqlite3_blob | blob handle]. +*/ +int sqlite3_blob_close(sqlite3_blob *); + +/* +** CAPI3REF: Return The Size Of An Open BLOB +** +** Return the size in bytes of the blob accessible via the open +** [sqlite3_blob | blob-handle] passed as an argument. +*/ +int sqlite3_blob_bytes(sqlite3_blob *); + +/* +** CAPI3REF: Read Data From A BLOB Incrementally +** +** This function is used to read data from an open +** [sqlite3_blob | blob-handle] into a caller supplied buffer. +** n bytes of data are copied into buffer +** z from the open blob, starting at offset iOffset. +** +** On success, SQLITE_OK is returned. Otherwise, an +** [SQLITE_ERROR | SQLite error code] or an +** [SQLITE_IOERR_READ | extended error code] is returned. +*/ +int sqlite3_blob_read(sqlite3_blob *, void *z, int n, int iOffset); + +/* +** CAPI3REF: Write Data Into A BLOB Incrementally +** +** This function is used to write data into an open +** [sqlite3_blob | blob-handle] from a user supplied buffer. +** n bytes of data are copied from the buffer +** pointed to by z into the open blob, starting at offset iOffset. +** +** If the [sqlite3_blob | blob-handle] passed as the first argument +** was not opened for writing (the flags parameter to [sqlite3_blob_open()] +*** was zero), this function returns [SQLITE_READONLY]. +** +** This function may only modify the contents of the blob, it is +** not possible to increase the size of a blob using this API. If +** offset iOffset is less than n bytes from the end of the blob, +** [SQLITE_ERROR] is returned and no data is written. +** +** On success, SQLITE_OK is returned. Otherwise, an +** [SQLITE_ERROR | SQLite error code] or an +** [SQLITE_IOERR_READ | extended error code] is returned. +*/ +int sqlite3_blob_write(sqlite3_blob *, const void *z, int n, int iOffset); + +/* +** CAPI3REF: Virtual File System Objects +** +** A virtual filesystem (VFS) is an [sqlite3_vfs] object +** that SQLite uses to interact +** with the underlying operating system. Most builds come with a +** single default VFS that is appropriate for the host computer. +** New VFSes can be registered and existing VFSes can be unregistered. +** The following interfaces are provided. +** +** The sqlite3_vfs_find() interface returns a pointer to a VFS given its +** name. Names are case sensitive. If there is no match, a NULL +** pointer is returned. If zVfsName is NULL then the default +** VFS is returned. +** +** New VFSes are registered with sqlite3_vfs_register(). Each +** new VFS becomes the default VFS if the makeDflt flag is set. +** The same VFS can be registered multiple times without injury. +** To make an existing VFS into the default VFS, register it again +** with the makeDflt flag set. If two different VFSes with the +** same name are registered, the behavior is undefined. If a +** VFS is registered with a name that is NULL or an empty string, +** then the behavior is undefined. +** +** Unregister a VFS with the sqlite3_vfs_unregister() interface. +** If the default VFS is unregistered, another VFS is chosen as +** the default. The choice for the new VFS is arbitrary. +*/ +sqlite3_vfs *sqlite3_vfs_find(const char *zVfsName); +int sqlite3_vfs_register(sqlite3_vfs*, int makeDflt); +int sqlite3_vfs_unregister(sqlite3_vfs*); + +/* +** CAPI3REF: Mutexes +** +** The SQLite core uses these routines for thread +** synchronization. Though they are intended for internal +** use by SQLite, code that links against SQLite is +** permitted to use any of these routines. +** +** The SQLite source code contains multiple implementations +** of these mutex routines. An appropriate implementation +** is selected automatically at compile-time. The following +** implementations are available in the SQLite core: +** +** <ul> +** <li> SQLITE_MUTEX_OS2 +** <li> SQLITE_MUTEX_PTHREAD +** <li> SQLITE_MUTEX_W32 +** <li> SQLITE_MUTEX_NOOP +** </ul> +** +** The SQLITE_MUTEX_NOOP implementation is a set of routines +** that does no real locking and is appropriate for use in +** a single-threaded application. The SQLITE_MUTEX_OS2, +** SQLITE_MUTEX_PTHREAD, and SQLITE_MUTEX_W32 implementations +** are appropriate for use on os/2, unix, and windows. +** +** If SQLite is compiled with the SQLITE_MUTEX_APPDEF preprocessor +** macro defined (with "-DSQLITE_MUTEX_APPDEF=1"), then no mutex +** implementation is included with the library. The +** mutex interface routines defined here become external +** references in the SQLite library for which implementations +** must be provided by the application. This facility allows an +** application that links against SQLite to provide its own mutex +** implementation without having to modify the SQLite core. +** +** The sqlite3_mutex_alloc() routine allocates a new +** mutex and returns a pointer to it. If it returns NULL +** that means that a mutex could not be allocated. SQLite +** will unwind its stack and return an error. The argument +** to sqlite3_mutex_alloc() is one of these integer constants: +** +** <ul> +** <li> SQLITE_MUTEX_FAST +** <li> SQLITE_MUTEX_RECURSIVE +** <li> SQLITE_MUTEX_STATIC_MASTER +** <li> SQLITE_MUTEX_STATIC_MEM +** <li> SQLITE_MUTEX_STATIC_MEM2 +** <li> SQLITE_MUTEX_STATIC_PRNG +** <li> SQLITE_MUTEX_STATIC_LRU +** </ul> +** +** The first two constants cause sqlite3_mutex_alloc() to create +** a new mutex. The new mutex is recursive when SQLITE_MUTEX_RECURSIVE +** is used but not necessarily so when SQLITE_MUTEX_FAST is used. +** The mutex implementation does not need to make a distinction +** between SQLITE_MUTEX_RECURSIVE and SQLITE_MUTEX_FAST if it does +** not want to. But SQLite will only request a recursive mutex in +** cases where it really needs one. If a faster non-recursive mutex +** implementation is available on the host platform, the mutex subsystem +** might return such a mutex in response to SQLITE_MUTEX_FAST. +** +** The other allowed parameters to sqlite3_mutex_alloc() each return +** a pointer to a static preexisting mutex. Four static mutexes are +** used by the current version of SQLite. Future versions of SQLite +** may add additional static mutexes. Static mutexes are for internal +** use by SQLite only. Applications that use SQLite mutexes should +** use only the dynamic mutexes returned by SQLITE_MUTEX_FAST or +** SQLITE_MUTEX_RECURSIVE. +** +** Note that if one of the dynamic mutex parameters (SQLITE_MUTEX_FAST +** or SQLITE_MUTEX_RECURSIVE) is used then sqlite3_mutex_alloc() +** returns a different mutex on every call. But for the static +** mutex types, the same mutex is returned on every call that has +** the same type number. +** +** The sqlite3_mutex_free() routine deallocates a previously +** allocated dynamic mutex. SQLite is careful to deallocate every +** dynamic mutex that it allocates. The dynamic mutexes must not be in +** use when they are deallocated. Attempting to deallocate a static +** mutex results in undefined behavior. SQLite never deallocates +** a static mutex. +** +** The sqlite3_mutex_enter() and sqlite3_mutex_try() routines attempt +** to enter a mutex. If another thread is already within the mutex, +** sqlite3_mutex_enter() will block and sqlite3_mutex_try() will return +** SQLITE_BUSY. The sqlite3_mutex_try() interface returns SQLITE_OK +** upon successful entry. Mutexes created using SQLITE_MUTEX_RECURSIVE can +** be entered multiple times by the same thread. In such cases the, +** mutex must be exited an equal number of times before another thread +** can enter. If the same thread tries to enter any other kind of mutex +** more than once, the behavior is undefined. SQLite will never exhibit +** such behavior in its own use of mutexes. +** +** Some systems (ex: windows95) do not the operation implemented by +** sqlite3_mutex_try(). On those systems, sqlite3_mutex_try() will +** always return SQLITE_BUSY. The SQLite core only ever uses +** sqlite3_mutex_try() as an optimization so this is acceptable behavior. +** +** The sqlite3_mutex_leave() routine exits a mutex that was +** previously entered by the same thread. The behavior +** is undefined if the mutex is not currently entered by the +** calling thread or is not currently allocated. SQLite will +** never do either. +** +** See also: [sqlite3_mutex_held()] and [sqlite3_mutex_notheld()]. +*/ +sqlite3_mutex *sqlite3_mutex_alloc(int); +void sqlite3_mutex_free(sqlite3_mutex*); +void sqlite3_mutex_enter(sqlite3_mutex*); +int sqlite3_mutex_try(sqlite3_mutex*); +void sqlite3_mutex_leave(sqlite3_mutex*); + +/* +** CAPI3REF: Mutex Verifcation Routines +** +** The sqlite3_mutex_held() and sqlite3_mutex_notheld() routines +** are intended for use inside assert() statements. The SQLite core +** never uses these routines except inside an assert() and applications +** are advised to follow the lead of the core. The core only +** provides implementations for these routines when it is compiled +** with the SQLITE_DEBUG flag. External mutex implementations +** are only required to provide these routines if SQLITE_DEBUG is +** defined and if NDEBUG is not defined. +** +** These routines should return true if the mutex in their argument +** is held or not held, respectively, by the calling thread. +** +** The implementation is not required to provided versions of these +** routines that actually work. +** If the implementation does not provide working +** versions of these routines, it should at least provide stubs +** that always return true so that one does not get spurious +** assertion failures. +** +** If the argument to sqlite3_mutex_held() is a NULL pointer then +** the routine should return 1. This seems counter-intuitive since +** clearly the mutex cannot be held if it does not exist. But the +** the reason the mutex does not exist is because the build is not +** using mutexes. And we do not want the assert() containing the +** call to sqlite3_mutex_held() to fail, so a non-zero return is +** the appropriate thing to do. The sqlite3_mutex_notheld() +** interface should also return 1 when given a NULL pointer. +*/ +int sqlite3_mutex_held(sqlite3_mutex*); +int sqlite3_mutex_notheld(sqlite3_mutex*); + +/* +** CAPI3REF: Mutex Types +** +** The [sqlite3_mutex_alloc()] interface takes a single argument +** which is one of these integer constants. +*/ +#define SQLITE_MUTEX_FAST 0 +#define SQLITE_MUTEX_RECURSIVE 1 +#define SQLITE_MUTEX_STATIC_MASTER 2 +#define SQLITE_MUTEX_STATIC_MEM 3 /* sqlite3_malloc() */ +#define SQLITE_MUTEX_STATIC_MEM2 4 /* sqlite3_release_memory() */ +#define SQLITE_MUTEX_STATIC_PRNG 5 /* sqlite3_random() */ +#define SQLITE_MUTEX_STATIC_LRU 6 /* lru page list */ + +/* +** CAPI3REF: Low-Level Control Of Database Files +** +** The [sqlite3_file_control()] interface makes a direct call to the +** xFileControl method for the [sqlite3_io_methods] object associated +** with a particular database identified by the second argument. The +** name of the database is the name assigned to the database by the +** <a href="lang_attach.html">ATTACH</a> SQL command that opened the +** database. To control the main database file, use the name "main" +** or a NULL pointer. The third and fourth parameters to this routine +** are passed directly through to the second and third parameters of +** the xFileControl method. The return value of the xFileControl +** method becomes the return value of this routine. +** +** If the second parameter (zDbName) does not match the name of any +** open database file, then SQLITE_ERROR is returned. This error +** code is not remembered and will not be recalled by [sqlite3_errcode()] +** or [sqlite3_errmsg()]. The underlying xFileControl method might +** also return SQLITE_ERROR. There is no way to distinguish between +** an incorrect zDbName and an SQLITE_ERROR return from the underlying +** xFileControl method. +** +** See also: [SQLITE_FCNTL_LOCKSTATE] +*/ +int sqlite3_file_control(sqlite3*, const char *zDbName, int op, void*); + +/* +** Undo the hack that converts floating point types to integer for +** builds on processors without floating point support. +*/ +#ifdef SQLITE_OMIT_FLOATING_POINT +# undef double +#endif + +#if 0 +} /* End of the 'extern "C"' block */ +#endif +#endif + +/************** End of sqlite3.h *********************************************/ +/************** Continuing where we left off in fts3_hash.c ******************/ +/************** Include fts3_hash.h in the middle of fts3_hash.c *************/ +/************** Begin file fts3_hash.h ***************************************/ +/* +** 2001 September 22 +** +** 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 is the header file for the generic hash-table implemenation +** used in SQLite. We've modified it slightly to serve as a standalone +** hash table implementation for the full-text indexing module. +** +*/ +#ifndef _FTS3_HASH_H_ +#define _FTS3_HASH_H_ + +/* Forward declarations of structures. */ +typedef struct fts3Hash fts3Hash; +typedef struct fts3HashElem fts3HashElem; + +/* A complete hash table is an instance of the following structure. +** The internals of this structure are intended to be opaque -- client +** code should not attempt to access or modify the fields of this structure +** directly. Change this structure only by using the routines below. +** However, many of the "procedures" and "functions" for modifying and +** accessing this structure are really macros, so we can't really make +** this structure opaque. +*/ +struct fts3Hash { + char keyClass; /* HASH_INT, _POINTER, _STRING, _BINARY */ + char copyKey; /* True if copy of key made on insert */ + int count; /* Number of entries in this table */ + fts3HashElem *first; /* The first element of the array */ + int htsize; /* Number of buckets in the hash table */ + struct _fts3ht { /* the hash table */ + int count; /* Number of entries with this hash */ + fts3HashElem *chain; /* Pointer to first entry with this hash */ + } *ht; +}; + +/* Each element in the hash table is an instance of the following +** structure. All elements are stored on a single doubly-linked list. +** +** Again, this structure is intended to be opaque, but it can't really +** be opaque because it is used by macros. +*/ +struct fts3HashElem { + fts3HashElem *next, *prev; /* Next and previous elements in the table */ + void *data; /* Data associated with this element */ + void *pKey; int nKey; /* Key associated with this element */ +}; + +/* +** There are 2 different modes of operation for a hash table: +** +** FTS3_HASH_STRING pKey points to a string that is nKey bytes long +** (including the null-terminator, if any). Case +** is respected in comparisons. +** +** FTS3_HASH_BINARY pKey points to binary data nKey bytes long. +** memcmp() is used to compare keys. +** +** A copy of the key is made if the copyKey parameter to fts3HashInit is 1. +*/ +#define FTS3_HASH_STRING 1 +#define FTS3_HASH_BINARY 2 + +/* +** Access routines. To delete, insert a NULL pointer. +*/ +void sqlite3Fts3HashInit(fts3Hash*, int keytype, int copyKey); +void *sqlite3Fts3HashInsert(fts3Hash*, const void *pKey, int nKey, void *pData); +void *sqlite3Fts3HashFind(const fts3Hash*, const void *pKey, int nKey); +void sqlite3Fts3HashClear(fts3Hash*); + +/* +** Shorthand for the functions above +*/ +#define fts3HashInit sqlite3Fts3HashInit +#define fts3HashInsert sqlite3Fts3HashInsert +#define fts3HashFind sqlite3Fts3HashFind +#define fts3HashClear sqlite3Fts3HashClear + +/* +** Macros for looping over all elements of a hash table. The idiom is +** like this: +** +** fts3Hash h; +** fts3HashElem *p; +** ... +** for(p=fts3HashFirst(&h); p; p=fts3HashNext(p)){ +** SomeStructure *pData = fts3HashData(p); +** // do something with pData +** } +*/ +#define fts3HashFirst(H) ((H)->first) +#define fts3HashNext(E) ((E)->next) +#define fts3HashData(E) ((E)->data) +#define fts3HashKey(E) ((E)->pKey) +#define fts3HashKeysize(E) ((E)->nKey) + +/* +** Number of entries in a hash table +*/ +#define fts3HashCount(H) ((H)->count) + +#endif /* _FTS3_HASH_H_ */ + +/************** End of fts3_hash.h *******************************************/ +/************** Continuing where we left off in fts3_hash.c ******************/ + +/* +** Malloc and Free functions +*/ +static void *fts3HashMalloc(int n){ + void *p = sqlite3_malloc(n); + if( p ){ + memset(p, 0, n); + } + return p; +} +static void fts3HashFree(void *p){ + sqlite3_free(p); +} + +/* Turn bulk memory into a hash table object by initializing the +** fields of the Hash structure. +** +** "pNew" is a pointer to the hash table that is to be initialized. +** keyClass is one of the constants +** FTS3_HASH_BINARY or FTS3_HASH_STRING. The value of keyClass +** determines what kind of key the hash table will use. "copyKey" is +** true if the hash table should make its own private copy of keys and +** false if it should just use the supplied pointer. +*/ +void sqlite3Fts3HashInit(fts3Hash *pNew, int keyClass, int copyKey){ + assert( pNew!=0 ); + assert( keyClass>=FTS3_HASH_STRING && keyClass<=FTS3_HASH_BINARY ); + pNew->keyClass = keyClass; + pNew->copyKey = copyKey; + pNew->first = 0; + pNew->count = 0; + pNew->htsize = 0; + pNew->ht = 0; +} + +/* Remove all entries from a hash table. Reclaim all memory. +** Call this routine to delete a hash table or to reset a hash table +** to the empty state. +*/ +void sqlite3Fts3HashClear(fts3Hash *pH){ + fts3HashElem *elem; /* For looping over all elements of the table */ + + assert( pH!=0 ); + elem = pH->first; + pH->first = 0; + fts3HashFree(pH->ht); + pH->ht = 0; + pH->htsize = 0; + while( elem ){ + fts3HashElem *next_elem = elem->next; + if( pH->copyKey && elem->pKey ){ + fts3HashFree(elem->pKey); + } + fts3HashFree(elem); + elem = next_elem; + } + pH->count = 0; +} + +/* +** Hash and comparison functions when the mode is FTS3_HASH_STRING +*/ +static int fts3StrHash(const void *pKey, int nKey){ + const char *z = (const char *)pKey; + int h = 0; + if( nKey<=0 ) nKey = (int) strlen(z); + while( nKey > 0 ){ + h = (h<<3) ^ h ^ *z++; + nKey--; + } + return h & 0x7fffffff; +} +static int fts3StrCompare(const void *pKey1, int n1, const void *pKey2, int n2){ + if( n1!=n2 ) return 1; + return strncmp((const char*)pKey1,(const char*)pKey2,n1); +} + +/* +** Hash and comparison functions when the mode is FTS3_HASH_BINARY +*/ +static int fts3BinHash(const void *pKey, int nKey){ + int h = 0; + const char *z = (const char *)pKey; + while( nKey-- > 0 ){ + h = (h<<3) ^ h ^ *(z++); + } + return h & 0x7fffffff; +} +static int fts3BinCompare(const void *pKey1, int n1, const void *pKey2, int n2){ + if( n1!=n2 ) return 1; + return memcmp(pKey1,pKey2,n1); +} + +/* +** Return a pointer to the appropriate hash function given the key class. +** +** The C syntax in this function definition may be unfamilar to some +** programmers, so we provide the following additional explanation: +** +** The name of the function is "ftsHashFunction". The function takes a +** single parameter "keyClass". The return value of ftsHashFunction() +** is a pointer to another function. Specifically, the return value +** of ftsHashFunction() is a pointer to a function that takes two parameters +** with types "const void*" and "int" and returns an "int". +*/ +static int (*ftsHashFunction(int keyClass))(const void*,int){ + if( keyClass==FTS3_HASH_STRING ){ + return &fts3StrHash; + }else{ + assert( keyClass==FTS3_HASH_BINARY ); + return &fts3BinHash; + } +} + +/* +** Return a pointer to the appropriate hash function given the key class. +** +** For help in interpreted the obscure C code in the function definition, +** see the header comment on the previous function. +*/ +static int (*ftsCompareFunction(int keyClass))(const void*,int,const void*,int){ + if( keyClass==FTS3_HASH_STRING ){ + return &fts3StrCompare; + }else{ + assert( keyClass==FTS3_HASH_BINARY ); + return &fts3BinCompare; + } +} + +/* Link an element into the hash table +*/ +static void fts3HashInsertElement( + fts3Hash *pH, /* The complete hash table */ + struct _fts3ht *pEntry, /* The entry into which pNew is inserted */ + fts3HashElem *pNew /* The element to be inserted */ +){ + fts3HashElem *pHead; /* First element already in pEntry */ + pHead = pEntry->chain; + if( pHead ){ + pNew->next = pHead; + pNew->prev = pHead->prev; + if( pHead->prev ){ pHead->prev->next = pNew; } + else { pH->first = pNew; } + pHead->prev = pNew; + }else{ + pNew->next = pH->first; + if( pH->first ){ pH->first->prev = pNew; } + pNew->prev = 0; + pH->first = pNew; + } + pEntry->count++; + pEntry->chain = pNew; +} + + +/* Resize the hash table so that it cantains "new_size" buckets. +** "new_size" must be a power of 2. The hash table might fail +** to resize if sqliteMalloc() fails. +*/ +static void fts3Rehash(fts3Hash *pH, int new_size){ + struct _fts3ht *new_ht; /* The new hash table */ + fts3HashElem *elem, *next_elem; /* For looping over existing elements */ + int (*xHash)(const void*,int); /* The hash function */ + + assert( (new_size & (new_size-1))==0 ); + new_ht = (struct _fts3ht *)fts3HashMalloc( new_size*sizeof(struct _fts3ht) ); + if( new_ht==0 ) return; + fts3HashFree(pH->ht); + pH->ht = new_ht; + pH->htsize = new_size; + xHash = ftsHashFunction(pH->keyClass); + for(elem=pH->first, pH->first=0; elem; elem = next_elem){ + int h = (*xHash)(elem->pKey, elem->nKey) & (new_size-1); + next_elem = elem->next; + fts3HashInsertElement(pH, &new_ht[h], elem); + } +} + +/* This function (for internal use only) locates an element in an +** hash table that matches the given key. The hash for this key has +** already been computed and is passed as the 4th parameter. +*/ +static fts3HashElem *fts3FindElementByHash( + const fts3Hash *pH, /* The pH to be searched */ + const void *pKey, /* The key we are searching for */ + int nKey, + int h /* The hash for this key. */ +){ + fts3HashElem *elem; /* Used to loop thru the element list */ + int count; /* Number of elements left to test */ + int (*xCompare)(const void*,int,const void*,int); /* comparison function */ + + if( pH->ht ){ + struct _fts3ht *pEntry = &pH->ht[h]; + elem = pEntry->chain; + count = pEntry->count; + xCompare = ftsCompareFunction(pH->keyClass); + while( count-- && elem ){ + if( (*xCompare)(elem->pKey,elem->nKey,pKey,nKey)==0 ){ + return elem; + } + elem = elem->next; + } + } + return 0; +} + +/* Remove a single entry from the hash table given a pointer to that +** element and a hash on the element's key. +*/ +static void fts3RemoveElementByHash( + fts3Hash *pH, /* The pH containing "elem" */ + fts3HashElem* elem, /* The element to be removed from the pH */ + int h /* Hash value for the element */ +){ + struct _fts3ht *pEntry; + if( elem->prev ){ + elem->prev->next = elem->next; + }else{ + pH->first = elem->next; + } + if( elem->next ){ + elem->next->prev = elem->prev; + } + pEntry = &pH->ht[h]; + if( pEntry->chain==elem ){ + pEntry->chain = elem->next; + } + pEntry->count--; + if( pEntry->count<=0 ){ + pEntry->chain = 0; + } + if( pH->copyKey && elem->pKey ){ + fts3HashFree(elem->pKey); + } + fts3HashFree( elem ); + pH->count--; + if( pH->count<=0 ){ + assert( pH->first==0 ); + assert( pH->count==0 ); + fts3HashClear(pH); + } +} + +/* Attempt to locate an element of the hash table pH with a key +** that matches pKey,nKey. Return the data for this element if it is +** found, or NULL if there is no match. +*/ +void *sqlite3Fts3HashFind(const fts3Hash *pH, const void *pKey, int nKey){ + int h; /* A hash on key */ + fts3HashElem *elem; /* The element that matches key */ + int (*xHash)(const void*,int); /* The hash function */ + + if( pH==0 || pH->ht==0 ) return 0; + xHash = ftsHashFunction(pH->keyClass); + assert( xHash!=0 ); + h = (*xHash)(pKey,nKey); + assert( (pH->htsize & (pH->htsize-1))==0 ); + elem = fts3FindElementByHash(pH,pKey,nKey, h & (pH->htsize-1)); + return elem ? elem->data : 0; +} + +/* Insert an element into the hash table pH. The key is pKey,nKey +** and the data is "data". +** +** If no element exists with a matching key, then a new +** element is created. A copy of the key is made if the copyKey +** flag is set. NULL is returned. +** +** If another element already exists with the same key, then the +** new data replaces the old data and the old data is returned. +** The key is not copied in this instance. If a malloc fails, then +** the new data is returned and the hash table is unchanged. +** +** If the "data" parameter to this function is NULL, then the +** element corresponding to "key" is removed from the hash table. +*/ +void *sqlite3Fts3HashInsert( + fts3Hash *pH, /* The hash table to insert into */ + const void *pKey, /* The key */ + int nKey, /* Number of bytes in the key */ + void *data /* The data */ +){ + int hraw; /* Raw hash value of the key */ + int h; /* the hash of the key modulo hash table size */ + fts3HashElem *elem; /* Used to loop thru the element list */ + fts3HashElem *new_elem; /* New element added to the pH */ + int (*xHash)(const void*,int); /* The hash function */ + + assert( pH!=0 ); + xHash = ftsHashFunction(pH->keyClass); + assert( xHash!=0 ); + hraw = (*xHash)(pKey, nKey); + assert( (pH->htsize & (pH->htsize-1))==0 ); + h = hraw & (pH->htsize-1); + elem = fts3FindElementByHash(pH,pKey,nKey,h); + if( elem ){ + void *old_data = elem->data; + if( data==0 ){ + fts3RemoveElementByHash(pH,elem,h); + }else{ + elem->data = data; + } + return old_data; + } + if( data==0 ) return 0; + new_elem = (fts3HashElem*)fts3HashMalloc( sizeof(fts3HashElem) ); + if( new_elem==0 ) return data; + if( pH->copyKey && pKey!=0 ){ + new_elem->pKey = fts3HashMalloc( nKey ); + if( new_elem->pKey==0 ){ + fts3HashFree(new_elem); + return data; + } + memcpy((void*)new_elem->pKey, pKey, nKey); + }else{ + new_elem->pKey = (void*)pKey; + } + new_elem->nKey = nKey; + pH->count++; + if( pH->htsize==0 ){ + fts3Rehash(pH,8); + if( pH->htsize==0 ){ + pH->count = 0; + fts3HashFree(new_elem); + return data; + } + } + if( pH->count > pH->htsize ){ + fts3Rehash(pH,pH->htsize*2); + } + assert( pH->htsize>0 ); + assert( (pH->htsize & (pH->htsize-1))==0 ); + h = hraw & (pH->htsize-1); + fts3HashInsertElement(pH, &pH->ht[h], new_elem); + new_elem->data = data; + return 0; +} + +#endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) */ + +/************** End of fts3_hash.c *******************************************/ +/************** Begin file fts3_porter.c *************************************/ +/* +** 2006 September 30 +** +** 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. +** +************************************************************************* +** Implementation of the full-text-search tokenizer that implements +** a Porter stemmer. +*/ + +/* +** The code in this file is only compiled if: +** +** * The FTS3 module is being built as an extension +** (in which case SQLITE_CORE is not defined), or +** +** * The FTS3 module is being built into the core of +** SQLite (in which case SQLITE_ENABLE_FTS3 is defined). +*/ +#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) + + + +/************** Include fts3_tokenizer.h in the middle of fts3_porter.c ******/ +/************** Begin file fts3_tokenizer.h **********************************/ +/* +** 2006 July 10 +** +** The author disclaims copyright to this source code. +** +************************************************************************* +** Defines the interface to tokenizers used by fulltext-search. There +** are three basic components: +** +** sqlite3_tokenizer_module is a singleton defining the tokenizer +** interface functions. This is essentially the class structure for +** tokenizers. +** +** sqlite3_tokenizer is used to define a particular tokenizer, perhaps +** including customization information defined at creation time. +** +** sqlite3_tokenizer_cursor is generated by a tokenizer to generate +** tokens from a particular input. +*/ +#ifndef _FTS3_TOKENIZER_H_ +#define _FTS3_TOKENIZER_H_ + +/* TODO(shess) Only used for SQLITE_OK and SQLITE_DONE at this time. +** If tokenizers are to be allowed to call sqlite3_*() functions, then +** we will need a way to register the API consistently. +*/ +/************** Include sqlite3.h in the middle of fts3_tokenizer.h **********/ +/************** Begin file sqlite3.h *****************************************/ +/* +** 2001 September 15 +** +** 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 header file defines the interface that the SQLite library +** presents to client programs. If a C-function, structure, datatype, +** or constant definition does not appear in this file, then it is +** not a published API of SQLite, is subject to change without +** notice, and should not be referenced by programs that use SQLite. +** +** Some of the definitions that are in this file are marked as +** "experimental". Experimental interfaces are normally new +** features recently added to SQLite. We do not anticipate changes +** to experimental interfaces but reserve to make minor changes if +** experience from use "in the wild" suggest such changes are prudent. +** +** The official C-language API documentation for SQLite is derived +** from comments in this file. This file is the authoritative source +** on how SQLite interfaces are suppose to operate. +** +** The name of this file under configuration management is "sqlite.h.in". +** The makefile makes some minor changes to this file (such as inserting +** the version number) and changes its name to "sqlite3.h" as +** part of the build process. +** +** @(#) $Id: sqlite.h.in,v 1.271 2007/11/21 15:24:01 drh Exp $ +*/ +#ifndef _SQLITE3_H_ +#define _SQLITE3_H_ + +/* +** Make sure we can call this stuff from C++. +*/ +#if 0 +extern "C" { +#endif + + +/* +** Add the ability to override 'extern' +*/ +#ifndef SQLITE_EXTERN +# define SQLITE_EXTERN extern +#endif + +/* +** Make sure these symbols where not defined by some previous header +** file. +*/ +#ifdef SQLITE_VERSION +# undef SQLITE_VERSION +#endif +#ifdef SQLITE_VERSION_NUMBER +# undef SQLITE_VERSION_NUMBER +#endif + +/* +** CAPI3REF: Compile-Time Library Version Numbers +** +** The version of the SQLite library is contained in the sqlite3.h +** header file in a #define named SQLITE_VERSION. The SQLITE_VERSION +** macro resolves to a string constant. +** +** The format of the version string is "X.Y.Z", where +** X is the major version number, Y is the minor version number and Z +** is the release number. The X.Y.Z might be followed by "alpha" or "beta". +** For example "3.1.1beta". +** +** The X value is always 3 in SQLite. The X value only changes when +** backwards compatibility is broken and we intend to never break +** backwards compatibility. The Y value only changes when +** there are major feature enhancements that are forwards compatible +** but not backwards compatible. The Z value is incremented with +** each release but resets back to 0 when Y is incremented. +** +** The SQLITE_VERSION_NUMBER is an integer with the value +** (X*1000000 + Y*1000 + Z). For example, for version "3.1.1beta", +** SQLITE_VERSION_NUMBER is set to 3001001. To detect if they are using +** version 3.1.1 or greater at compile time, programs may use the test +** (SQLITE_VERSION_NUMBER>=3001001). +** +** See also: [sqlite3_libversion()] and [sqlite3_libversion_number()]. +*/ +#define SQLITE_VERSION "3.5.2" +#define SQLITE_VERSION_NUMBER 3005002 + +/* +** CAPI3REF: Run-Time Library Version Numbers +** +** These routines return values equivalent to the header constants +** [SQLITE_VERSION] and [SQLITE_VERSION_NUMBER]. The values returned +** by this routines should only be different from the header values +** if you compile your program using an sqlite3.h header from a +** different version of SQLite that the version of the library you +** link against. +** +** The sqlite3_version[] string constant contains the text of the +** [SQLITE_VERSION] string. The sqlite3_libversion() function returns +** a poiner to the sqlite3_version[] string constant. The function +** is provided for DLL users who can only access functions and not +** constants within the DLL. +*/ +SQLITE_EXTERN const char sqlite3_version[]; +const char *sqlite3_libversion(void); +int sqlite3_libversion_number(void); + +/* +** CAPI3REF: Test To See If The Library Is Threadsafe +** +** This routine returns TRUE (nonzero) if SQLite was compiled with +** all of its mutexes enabled and is thus threadsafe. It returns +** zero if the particular build is for single-threaded operation +** only. +** +** Really all this routine does is return true if SQLite was compiled +** with the -DSQLITE_THREADSAFE=1 option and false if +** compiled with -DSQLITE_THREADSAFE=0. If SQLite uses an +** application-defined mutex subsystem, malloc subsystem, collating +** sequence, VFS, SQL function, progress callback, commit hook, +** extension, or other accessories and these add-ons are not +** threadsafe, then clearly the combination will not be threadsafe +** either. Hence, this routine never reports that the library +** is guaranteed to be threadsafe, only when it is guaranteed not +** to be. +** +** This is an experimental API and may go away or change in future +** releases. +*/ +int sqlite3_threadsafe(void); + +/* +** CAPI3REF: Database Connection Handle +** +** Each open SQLite database is represented by pointer to an instance of the +** opaque structure named "sqlite3". It is useful to think of an sqlite3 +** pointer as an object. The [sqlite3_open()], [sqlite3_open16()], and +** [sqlite3_open_v2()] interfaces are its constructors +** and [sqlite3_close()] is its destructor. There are many other interfaces +** (such as [sqlite3_prepare_v2()], [sqlite3_create_function()], and +** [sqlite3_busy_timeout()] to name but three) that are methods on this +** object. +*/ +typedef struct sqlite3 sqlite3; + + +/* +** CAPI3REF: 64-Bit Integer Types +** +** Some compilers do not support the "long long" datatype. So we have +** to do compiler-specific typedefs for 64-bit signed and unsigned integers. +** +** Many SQLite interface functions require a 64-bit integer arguments. +** Those interfaces are declared using this typedef. +*/ +#ifdef SQLITE_INT64_TYPE + typedef SQLITE_INT64_TYPE sqlite_int64; + typedef unsigned SQLITE_INT64_TYPE sqlite_uint64; +#elif defined(_MSC_VER) || defined(__BORLANDC__) + typedef __int64 sqlite_int64; + typedef unsigned __int64 sqlite_uint64; +#else + typedef long long int sqlite_int64; + typedef unsigned long long int sqlite_uint64; +#endif +typedef sqlite_int64 sqlite3_int64; +typedef sqlite_uint64 sqlite3_uint64; + +/* +** If compiling for a processor that lacks floating point support, +** substitute integer for floating-point +*/ +#ifdef SQLITE_OMIT_FLOATING_POINT +# define double sqlite3_int64 +#endif + +/* +** CAPI3REF: Closing A Database Connection +** +** Call this function with a pointer to a structure that was previously +** returned from [sqlite3_open()], [sqlite3_open16()], or +** [sqlite3_open_v2()] and the corresponding database will by +** closed. +** +** All SQL statements prepared using [sqlite3_prepare_v2()] or +** [sqlite3_prepare16_v2()] must be destroyed using [sqlite3_finalize()] +** before this routine is called. Otherwise, SQLITE_BUSY is returned and the +** database connection remains open. +** +** Passing this routine a database connection that has already been +** closed results in undefined behavior. If other interfaces that +** reference the same database connection are pending (either in the +** same thread or in different threads) when this routine is called, +** then the behavior is undefined and is almost certainly undesirable. +*/ +int sqlite3_close(sqlite3 *); + +/* +** The type for a callback function. +** This is legacy and deprecated. It is included for historical +** compatibility and is not documented. +*/ +typedef int (*sqlite3_callback)(void*,int,char**, char**); + +/* +** CAPI3REF: One-Step Query Execution Interface +** +** This interface is used to do a one-time evaluatation of zero +** or more SQL statements. UTF-8 text of the SQL statements to +** be evaluted is passed in as the second parameter. The statements +** are prepared one by one using [sqlite3_prepare()], evaluated +** using [sqlite3_step()], then destroyed using [sqlite3_finalize()]. +** +** If one or more of the SQL statements are queries, then +** the callback function specified by the 3rd parameter is +** invoked once for each row of the query result. This callback +** should normally return 0. If the callback returns a non-zero +** value then the query is aborted, all subsequent SQL statements +** are skipped and the sqlite3_exec() function returns the [SQLITE_ABORT]. +** +** The 4th parameter to this interface is an arbitrary pointer that is +** passed through to the callback function as its first parameter. +** +** The 2nd parameter to the callback function is the number of +** columns in the query result. The 3rd parameter to the callback +** is an array of strings holding the values for each column +** as extracted using [sqlite3_column_text()]. +** The 4th parameter to the callback is an array of strings +** obtained using [sqlite3_column_name()] and holding +** the names of each column. +** +** The callback function may be NULL, even for queries. A NULL +** callback is not an error. It just means that no callback +** will be invoked. +** +** If an error occurs while parsing or evaluating the SQL (but +** not while executing the callback) then an appropriate error +** message is written into memory obtained from [sqlite3_malloc()] and +** *errmsg is made to point to that message. The calling function +** is responsible for freeing the memory using [sqlite3_free()]. +** If errmsg==NULL, then no error message is ever written. +** +** The return value is is SQLITE_OK if there are no errors and +** some other [SQLITE_OK | return code] if there is an error. +** The particular return value depends on the type of error. +** +*/ +int sqlite3_exec( + sqlite3*, /* An open database */ + const char *sql, /* SQL to be evaluted */ + int (*callback)(void*,int,char**,char**), /* Callback function */ + void *, /* 1st argument to callback */ + char **errmsg /* Error msg written here */ +); + +/* +** CAPI3REF: Result Codes +** KEYWORDS: SQLITE_OK +** +** Many SQLite functions return an integer result code from the set shown +** above in order to indicates success or failure. +** +** The result codes above are the only ones returned by SQLite in its +** default configuration. However, the [sqlite3_extended_result_codes()] +** API can be used to set a database connectoin to return more detailed +** result codes. +** +** See also: [SQLITE_IOERR_READ | extended result codes] +** +*/ +#define SQLITE_OK 0 /* Successful result */ +/* beginning-of-error-codes */ +#define SQLITE_ERROR 1 /* SQL error or missing database */ +#define SQLITE_INTERNAL 2 /* NOT USED. Internal logic error in SQLite */ +#define SQLITE_PERM 3 /* Access permission denied */ +#define SQLITE_ABORT 4 /* Callback routine requested an abort */ +#define SQLITE_BUSY 5 /* The database file is locked */ +#define SQLITE_LOCKED 6 /* A table in the database is locked */ +#define SQLITE_NOMEM 7 /* A malloc() failed */ +#define SQLITE_READONLY 8 /* Attempt to write a readonly database */ +#define SQLITE_INTERRUPT 9 /* Operation terminated by sqlite3_interrupt()*/ +#define SQLITE_IOERR 10 /* Some kind of disk I/O error occurred */ +#define SQLITE_CORRUPT 11 /* The database disk image is malformed */ +#define SQLITE_NOTFOUND 12 /* NOT USED. Table or record not found */ +#define SQLITE_FULL 13 /* Insertion failed because database is full */ +#define SQLITE_CANTOPEN 14 /* Unable to open the database file */ +#define SQLITE_PROTOCOL 15 /* NOT USED. Database lock protocol error */ +#define SQLITE_EMPTY 16 /* Database is empty */ +#define SQLITE_SCHEMA 17 /* The database schema changed */ +#define SQLITE_TOOBIG 18 /* String or BLOB exceeds size limit */ +#define SQLITE_CONSTRAINT 19 /* Abort due to constraint violation */ +#define SQLITE_MISMATCH 20 /* Data type mismatch */ +#define SQLITE_MISUSE 21 /* Library used incorrectly */ +#define SQLITE_NOLFS 22 /* Uses OS features not supported on host */ +#define SQLITE_AUTH 23 /* Authorization denied */ +#define SQLITE_FORMAT 24 /* Auxiliary database format error */ +#define SQLITE_RANGE 25 /* 2nd parameter to sqlite3_bind out of range */ +#define SQLITE_NOTADB 26 /* File opened that is not a database file */ +#define SQLITE_ROW 100 /* sqlite3_step() has another row ready */ +#define SQLITE_DONE 101 /* sqlite3_step() has finished executing */ +/* end-of-error-codes */ + +/* +** CAPI3REF: Extended Result Codes +** +** In its default configuration, SQLite API routines return one of 26 integer +** result codes described at result-codes. However, experience has shown that +** many of these result codes are too course-grained. They do not provide as +** much information about problems as users might like. In an effort to +** address this, newer versions of SQLite (version 3.3.8 and later) include +** support for additional result codes that provide more detailed information +** about errors. The extended result codes are enabled (or disabled) for +** each database +** connection using the [sqlite3_extended_result_codes()] API. +** +** Some of the available extended result codes are listed above. +** We expect the number of extended result codes will be expand +** over time. Software that uses extended result codes should expect +** to see new result codes in future releases of SQLite. +** +** The symbolic name for an extended result code always contains a related +** primary result code as a prefix. Primary result codes contain a single +** "_" character. Extended result codes contain two or more "_" characters. +** The numeric value of an extended result code can be converted to its +** corresponding primary result code by masking off the lower 8 bytes. +** +** The SQLITE_OK result code will never be extended. It will always +** be exactly zero. +*/ +#define SQLITE_IOERR_READ (SQLITE_IOERR | (1<<8)) +#define SQLITE_IOERR_SHORT_READ (SQLITE_IOERR | (2<<8)) +#define SQLITE_IOERR_WRITE (SQLITE_IOERR | (3<<8)) +#define SQLITE_IOERR_FSYNC (SQLITE_IOERR | (4<<8)) +#define SQLITE_IOERR_DIR_FSYNC (SQLITE_IOERR | (5<<8)) +#define SQLITE_IOERR_TRUNCATE (SQLITE_IOERR | (6<<8)) +#define SQLITE_IOERR_FSTAT (SQLITE_IOERR | (7<<8)) +#define SQLITE_IOERR_UNLOCK (SQLITE_IOERR | (8<<8)) +#define SQLITE_IOERR_RDLOCK (SQLITE_IOERR | (9<<8)) +#define SQLITE_IOERR_DELETE (SQLITE_IOERR | (10<<8)) +#define SQLITE_IOERR_BLOCKED (SQLITE_IOERR | (11<<8)) +#define SQLITE_IOERR_NOMEM (SQLITE_IOERR | (12<<8)) + +/* +** CAPI3REF: Flags For File Open Operations +** +** Combination of the following bit values are used as the +** third argument to the [sqlite3_open_v2()] interface and +** as fourth argument to the xOpen method of the +** [sqlite3_vfs] object. +** +*/ +#define SQLITE_OPEN_READONLY 0x00000001 +#define SQLITE_OPEN_READWRITE 0x00000002 +#define SQLITE_OPEN_CREATE 0x00000004 +#define SQLITE_OPEN_DELETEONCLOSE 0x00000008 +#define SQLITE_OPEN_EXCLUSIVE 0x00000010 +#define SQLITE_OPEN_MAIN_DB 0x00000100 +#define SQLITE_OPEN_TEMP_DB 0x00000200 +#define SQLITE_OPEN_TRANSIENT_DB 0x00000400 +#define SQLITE_OPEN_MAIN_JOURNAL 0x00000800 +#define SQLITE_OPEN_TEMP_JOURNAL 0x00001000 +#define SQLITE_OPEN_SUBJOURNAL 0x00002000 +#define SQLITE_OPEN_MASTER_JOURNAL 0x00004000 + +/* +** CAPI3REF: Device Characteristics +** +** The xDeviceCapabilities method of the [sqlite3_io_methods] +** object returns an integer which is a vector of the following +** bit values expressing I/O characteristics of the mass storage +** device that holds the file that the [sqlite3_io_methods] +** refers to. +** +** The SQLITE_IOCAP_ATOMIC property means that all writes of +** any size are atomic. The SQLITE_IOCAP_ATOMICnnn values +** mean that writes of blocks that are nnn bytes in size and +** are aligned to an address which is an integer multiple of +** nnn are atomic. The SQLITE_IOCAP_SAFE_APPEND value means +** that when data is appended to a file, the data is appended +** first then the size of the file is extended, never the other +** way around. The SQLITE_IOCAP_SEQUENTIAL property means that +** information is written to disk in the same order as calls +** to xWrite(). +*/ +#define SQLITE_IOCAP_ATOMIC 0x00000001 +#define SQLITE_IOCAP_ATOMIC512 0x00000002 +#define SQLITE_IOCAP_ATOMIC1K 0x00000004 +#define SQLITE_IOCAP_ATOMIC2K 0x00000008 +#define SQLITE_IOCAP_ATOMIC4K 0x00000010 +#define SQLITE_IOCAP_ATOMIC8K 0x00000020 +#define SQLITE_IOCAP_ATOMIC16K 0x00000040 +#define SQLITE_IOCAP_ATOMIC32K 0x00000080 +#define SQLITE_IOCAP_ATOMIC64K 0x00000100 +#define SQLITE_IOCAP_SAFE_APPEND 0x00000200 +#define SQLITE_IOCAP_SEQUENTIAL 0x00000400 + +/* +** CAPI3REF: File Locking Levels +** +** SQLite uses one of the following integer values as the second +** argument to calls it makes to the xLock() and xUnlock() methods +** of an [sqlite3_io_methods] object. +*/ +#define SQLITE_LOCK_NONE 0 +#define SQLITE_LOCK_SHARED 1 +#define SQLITE_LOCK_RESERVED 2 +#define SQLITE_LOCK_PENDING 3 +#define SQLITE_LOCK_EXCLUSIVE 4 + +/* +** CAPI3REF: Synchronization Type Flags +** +** When SQLite invokes the xSync() method of an [sqlite3_io_methods] +** object it uses a combination of the following integer values as +** the second argument. +** +** When the SQLITE_SYNC_DATAONLY flag is used, it means that the +** sync operation only needs to flush data to mass storage. Inode +** information need not be flushed. The SQLITE_SYNC_NORMAL means +** to use normal fsync() semantics. The SQLITE_SYNC_FULL flag means +** to use Mac OS-X style fullsync instead of fsync(). +*/ +#define SQLITE_SYNC_NORMAL 0x00002 +#define SQLITE_SYNC_FULL 0x00003 +#define SQLITE_SYNC_DATAONLY 0x00010 + + +/* +** CAPI3REF: OS Interface Open File Handle +** +** An [sqlite3_file] object represents an open file in the OS +** interface layer. Individual OS interface implementations will +** want to subclass this object by appending additional fields +** for their own use. The pMethods entry is a pointer to an +** [sqlite3_io_methods] object that defines methods for performing +** I/O operations on the open file. +*/ +typedef struct sqlite3_file sqlite3_file; +struct sqlite3_file { + const struct sqlite3_io_methods *pMethods; /* Methods for an open file */ +}; + +/* +** CAPI3REF: OS Interface File Virtual Methods Object +** +** Every file opened by the [sqlite3_vfs] xOpen method contains a pointer to +** an instance of the this object. This object defines the +** methods used to perform various operations against the open file. +** +** The flags argument to xSync may be one of [SQLITE_SYNC_NORMAL] or +** [SQLITE_SYNC_FULL]. The first choice is the normal fsync(). +* The second choice is an +** OS-X style fullsync. The SQLITE_SYNC_DATA flag may be ORed in to +** indicate that only the data of the file and not its inode needs to be +** synced. +** +** The integer values to xLock() and xUnlock() are one of +** <ul> +** <li> [SQLITE_LOCK_NONE], +** <li> [SQLITE_LOCK_SHARED], +** <li> [SQLITE_LOCK_RESERVED], +** <li> [SQLITE_LOCK_PENDING], or +** <li> [SQLITE_LOCK_EXCLUSIVE]. +** </ul> +** xLock() increases the lock. xUnlock() decreases the lock. +** The xCheckReservedLock() method looks +** to see if any database connection, either in this +** process or in some other process, is holding an RESERVED, +** PENDING, or EXCLUSIVE lock on the file. It returns true +** if such a lock exists and false if not. +** +** The xFileControl() method is a generic interface that allows custom +** VFS implementations to directly control an open file using the +** [sqlite3_file_control()] interface. The second "op" argument +** is an integer opcode. The third +** argument is a generic pointer which is intended to be a pointer +** to a structure that may contain arguments or space in which to +** write return values. Potential uses for xFileControl() might be +** functions to enable blocking locks with timeouts, to change the +** locking strategy (for example to use dot-file locks), to inquire +** about the status of a lock, or to break stale locks. The SQLite +** core reserves opcodes less than 100 for its own use. +** A [SQLITE_FCNTL_LOCKSTATE | list of opcodes] less than 100 is available. +** Applications that define a custom xFileControl method should use opcodes +** greater than 100 to avoid conflicts. +** +** The xSectorSize() method returns the sector size of the +** device that underlies the file. The sector size is the +** minimum write that can be performed without disturbing +** other bytes in the file. The xDeviceCharacteristics() +** method returns a bit vector describing behaviors of the +** underlying device: +** +** <ul> +** <li> [SQLITE_IOCAP_ATOMIC] +** <li> [SQLITE_IOCAP_ATOMIC512] +** <li> [SQLITE_IOCAP_ATOMIC1K] +** <li> [SQLITE_IOCAP_ATOMIC2K] +** <li> [SQLITE_IOCAP_ATOMIC4K] +** <li> [SQLITE_IOCAP_ATOMIC8K] +** <li> [SQLITE_IOCAP_ATOMIC16K] +** <li> [SQLITE_IOCAP_ATOMIC32K] +** <li> [SQLITE_IOCAP_ATOMIC64K] +** <li> [SQLITE_IOCAP_SAFE_APPEND] +** <li> [SQLITE_IOCAP_SEQUENTIAL] +** </ul> +** +** The SQLITE_IOCAP_ATOMIC property means that all writes of +** any size are atomic. The SQLITE_IOCAP_ATOMICnnn values +** mean that writes of blocks that are nnn bytes in size and +** are aligned to an address which is an integer multiple of +** nnn are atomic. The SQLITE_IOCAP_SAFE_APPEND value means +** that when data is appended to a file, the data is appended +** first then the size of the file is extended, never the other +** way around. The SQLITE_IOCAP_SEQUENTIAL property means that +** information is written to disk in the same order as calls +** to xWrite(). +*/ +typedef struct sqlite3_io_methods sqlite3_io_methods; +struct sqlite3_io_methods { + int iVersion; + int (*xClose)(sqlite3_file*); + int (*xRead)(sqlite3_file*, void*, int iAmt, sqlite3_int64 iOfst); + int (*xWrite)(sqlite3_file*, const void*, int iAmt, sqlite3_int64 iOfst); + int (*xTruncate)(sqlite3_file*, sqlite3_int64 size); + int (*xSync)(sqlite3_file*, int flags); + int (*xFileSize)(sqlite3_file*, sqlite3_int64 *pSize); + int (*xLock)(sqlite3_file*, int); + int (*xUnlock)(sqlite3_file*, int); + int (*xCheckReservedLock)(sqlite3_file*); + int (*xFileControl)(sqlite3_file*, int op, void *pArg); + int (*xSectorSize)(sqlite3_file*); + int (*xDeviceCharacteristics)(sqlite3_file*); + /* Additional methods may be added in future releases */ +}; + +/* +** CAPI3REF: Standard File Control Opcodes +** +** These integer constants are opcodes for the xFileControl method +** of the [sqlite3_io_methods] object and to the [sqlite3_file_control()] +** interface. +** +** The [SQLITE_FCNTL_LOCKSTATE] opcode is used for debugging. This +** opcode cases the xFileControl method to write the current state of +** the lock (one of [SQLITE_LOCK_NONE], [SQLITE_LOCK_SHARED], +** [SQLITE_LOCK_RESERVED], [SQLITE_LOCK_PENDING], or [SQLITE_LOCK_EXCLUSIVE]) +** into an integer that the pArg argument points to. This capability +** is used during testing and only needs to be supported when SQLITE_TEST +** is defined. +*/ +#define SQLITE_FCNTL_LOCKSTATE 1 + +/* +** CAPI3REF: Mutex Handle +** +** The mutex module within SQLite defines [sqlite3_mutex] to be an +** abstract type for a mutex object. The SQLite core never looks +** at the internal representation of an [sqlite3_mutex]. It only +** deals with pointers to the [sqlite3_mutex] object. +** +** Mutexes are created using [sqlite3_mutex_alloc()]. +*/ +typedef struct sqlite3_mutex sqlite3_mutex; + +/* +** CAPI3REF: OS Interface Object +** +** An instance of this object defines the interface between the +** SQLite core and the underlying operating system. The "vfs" +** in the name of the object stands for "virtual file system". +** +** The iVersion field is initially 1 but may be larger for future +** versions of SQLite. Additional fields may be appended to this +** object when the iVersion value is increased. +** +** The szOsFile field is the size of the subclassed [sqlite3_file] +** structure used by this VFS. mxPathname is the maximum length of +** a pathname in this VFS. +** +** Registered vfs modules are kept on a linked list formed by +** the pNext pointer. The [sqlite3_vfs_register()] +** and [sqlite3_vfs_unregister()] interfaces manage this list +** in a thread-safe way. The [sqlite3_vfs_find()] interface +** searches the list. +** +** The pNext field is the only fields in the sqlite3_vfs +** structure that SQLite will ever modify. SQLite will only access +** or modify this field while holding a particular static mutex. +** The application should never modify anything within the sqlite3_vfs +** object once the object has been registered. +** +** The zName field holds the name of the VFS module. The name must +** be unique across all VFS modules. +** +** SQLite will guarantee that the zFilename string passed to +** xOpen() is a full pathname as generated by xFullPathname() and +** that the string will be valid and unchanged until xClose() is +** called. So the [sqlite3_file] can store a pointer to the +** filename if it needs to remember the filename for some reason. +** +** The flags argument to xOpen() is a copy of the flags argument +** to [sqlite3_open_v2()]. If [sqlite3_open()] or [sqlite3_open16()] +** is used, then flags is [SQLITE_OPEN_READWRITE] | [SQLITE_OPEN_CREATE]. +** If xOpen() opens a file read-only then it sets *pOutFlags to +** include [SQLITE_OPEN_READONLY]. Other bits in *pOutFlags may be +** set. +** +** SQLite will also add one of the following flags to the xOpen() +** call, depending on the object being opened: +** +** <ul> +** <li> [SQLITE_OPEN_MAIN_DB] +** <li> [SQLITE_OPEN_MAIN_JOURNAL] +** <li> [SQLITE_OPEN_TEMP_DB] +** <li> [SQLITE_OPEN_TEMP_JOURNAL] +** <li> [SQLITE_OPEN_TRANSIENT_DB] +** <li> [SQLITE_OPEN_SUBJOURNAL] +** <li> [SQLITE_OPEN_MASTER_JOURNAL] +** </ul> +** +** The file I/O implementation can use the object type flags to +** changes the way it deals with files. For example, an application +** that does not care about crash recovery or rollback, might make +** the open of a journal file a no-op. Writes to this journal are +** also a no-op. Any attempt to read the journal return SQLITE_IOERR. +** Or the implementation might recognize the a database file will +** be doing page-aligned sector reads and writes in a random order +** and set up its I/O subsystem accordingly. +** +** SQLite might also add one of the following flags to the xOpen +** method: +** +** <ul> +** <li> [SQLITE_OPEN_DELETEONCLOSE] +** <li> [SQLITE_OPEN_EXCLUSIVE] +** </ul> +** +** The [SQLITE_OPEN_DELETEONCLOSE] flag means the file should be +** deleted when it is closed. This will always be set for TEMP +** databases and journals and for subjournals. The +** [SQLITE_OPEN_EXCLUSIVE] flag means the file should be opened +** for exclusive access. This flag is set for all files except +** for the main database file. +** +** Space to hold the [sqlite3_file] structure passed as the third +** argument to xOpen is allocated by caller (the SQLite core). +** szOsFile bytes are allocated for this object. The xOpen method +** fills in the allocated space. +** +** The flags argument to xAccess() may be [SQLITE_ACCESS_EXISTS] +** to test for the existance of a file, +** or [SQLITE_ACCESS_READWRITE] to test to see +** if a file is readable and writable, or [SQLITE_ACCESS_READ] +** to test to see if a file is at least readable. The file can be a +** directory. +** +** SQLite will always allocate at least mxPathname+1 byte for +** the output buffers for xGetTempname and xFullPathname. The exact +** size of the output buffer is also passed as a parameter to both +** methods. If the output buffer is not large enough, SQLITE_CANTOPEN +** should be returned. As this is handled as a fatal error by SQLite, +** vfs implementations should endevour to prevent this by setting +** mxPathname to a sufficiently large value. +** +** The xRandomness(), xSleep(), and xCurrentTime() interfaces +** are not strictly a part of the filesystem, but they are +** included in the VFS structure for completeness. +** The xRandomness() function attempts to return nBytes bytes +** of good-quality randomness into zOut. The return value is +** the actual number of bytes of randomness obtained. The +** xSleep() method cause the calling thread to sleep for at +** least the number of microseconds given. The xCurrentTime() +** method returns a Julian Day Number for the current date and +** time. +*/ +typedef struct sqlite3_vfs sqlite3_vfs; +struct sqlite3_vfs { + int iVersion; /* Structure version number */ + int szOsFile; /* Size of subclassed sqlite3_file */ + int mxPathname; /* Maximum file pathname length */ + sqlite3_vfs *pNext; /* Next registered VFS */ + const char *zName; /* Name of this virtual file system */ + void *pAppData; /* Pointer to application-specific data */ + int (*xOpen)(sqlite3_vfs*, const char *zName, sqlite3_file*, + int flags, int *pOutFlags); + int (*xDelete)(sqlite3_vfs*, const char *zName, int syncDir); + int (*xAccess)(sqlite3_vfs*, const char *zName, int flags); + int (*xGetTempname)(sqlite3_vfs*, int nOut, char *zOut); + int (*xFullPathname)(sqlite3_vfs*, const char *zName, int nOut, char *zOut); + void *(*xDlOpen)(sqlite3_vfs*, const char *zFilename); + void (*xDlError)(sqlite3_vfs*, int nByte, char *zErrMsg); + void *(*xDlSym)(sqlite3_vfs*,void*, const char *zSymbol); + void (*xDlClose)(sqlite3_vfs*, void*); + int (*xRandomness)(sqlite3_vfs*, int nByte, char *zOut); + int (*xSleep)(sqlite3_vfs*, int microseconds); + int (*xCurrentTime)(sqlite3_vfs*, double*); + /* New fields may be appended in figure versions. The iVersion + ** value will increment whenever this happens. */ +}; + +/* +** CAPI3REF: Flags for the xAccess VFS method +** +** These integer constants can be used as the third parameter to +** the xAccess method of an [sqlite3_vfs] object. They determine +** the kind of what kind of permissions the xAccess method is +** looking for. With SQLITE_ACCESS_EXISTS, the xAccess method +** simply checks to see if the file exists. With SQLITE_ACCESS_READWRITE, +** the xAccess method checks to see if the file is both readable +** and writable. With SQLITE_ACCESS_READ the xAccess method +** checks to see if the file is readable. +*/ +#define SQLITE_ACCESS_EXISTS 0 +#define SQLITE_ACCESS_READWRITE 1 +#define SQLITE_ACCESS_READ 2 + +/* +** CAPI3REF: Enable Or Disable Extended Result Codes +** +** This routine enables or disables the +** [SQLITE_IOERR_READ | extended result codes] feature. +** By default, SQLite API routines return one of only 26 integer +** [SQLITE_OK | result codes]. When extended result codes +** are enabled by this routine, the repetoire of result codes can be +** much larger and can (hopefully) provide more detailed information +** about the cause of an error. +** +** The second argument is a boolean value that turns extended result +** codes on and off. Extended result codes are off by default for +** backwards compatibility with older versions of SQLite. +*/ +int sqlite3_extended_result_codes(sqlite3*, int onoff); + +/* +** CAPI3REF: Last Insert Rowid +** +** Each entry in an SQLite table has a unique 64-bit signed integer key +** called the "rowid". The rowid is always available as an undeclared +** column named ROWID, OID, or _ROWID_. If the table has a column of +** type INTEGER PRIMARY KEY then that column is another an alias for the +** rowid. +** +** This routine returns the rowid of the most recent successful INSERT into +** the database from the database connection given in the first +** argument. If no successful inserts have ever occurred on this database +** connection, zero is returned. +** +** If an INSERT occurs within a trigger, then the rowid of the +** inserted row is returned by this routine as long as the trigger +** is running. But once the trigger terminates, the value returned +** by this routine reverts to the last value inserted before the +** trigger fired. +** +** An INSERT that fails due to a constraint violation is not a +** successful insert and does not change the value returned by this +** routine. Thus INSERT OR FAIL, INSERT OR IGNORE, INSERT OR ROLLBACK, +** and INSERT OR ABORT make no changes to the return value of this +** routine when their insertion fails. When INSERT OR REPLACE +** encounters a constraint violation, it does not fail. The +** INSERT continues to completion after deleting rows that caused +** the constraint problem so INSERT OR REPLACE will always change +** the return value of this interface. +** +** If another thread does a new insert on the same database connection +** while this routine is running and thus changes the last insert rowid, +** then the return value of this routine is undefined. +*/ +sqlite3_int64 sqlite3_last_insert_rowid(sqlite3*); + +/* +** CAPI3REF: Count The Number Of Rows Modified +** +** This function returns the number of database rows that were changed +** (or inserted or deleted) by the most recent SQL statement. Only +** changes that are directly specified by the INSERT, UPDATE, or +** DELETE statement are counted. Auxiliary changes caused by +** triggers are not counted. Use the [sqlite3_total_changes()] function +** to find the total number of changes including changes caused by triggers. +** +** Within the body of a trigger, the sqlite3_changes() interface can be +** called to find the number of +** changes in the most recently completed INSERT, UPDATE, or DELETE +** statement within the body of the trigger. +** +** All changes are counted, even if they were later undone by a +** ROLLBACK or ABORT. Except, changes associated with creating and +** dropping tables are not counted. +** +** If a callback invokes [sqlite3_exec()] or [sqlite3_step()] recursively, +** then the changes in the inner, recursive call are counted together +** with the changes in the outer call. +** +** SQLite implements the command "DELETE FROM table" without a WHERE clause +** by dropping and recreating the table. (This is much faster than going +** through and deleting individual elements from the table.) Because of +** this optimization, the change count for "DELETE FROM table" will be +** zero regardless of the number of elements that were originally in the +** table. To get an accurate count of the number of rows deleted, use +** "DELETE FROM table WHERE 1" instead. +** +** If another thread makes changes on the same database connection +** while this routine is running then the return value of this routine +** is undefined. +*/ +int sqlite3_changes(sqlite3*); + +/* +** CAPI3REF: Total Number Of Rows Modified +*** +** This function returns the number of database rows that have been +** modified by INSERT, UPDATE or DELETE statements since the database handle +** was opened. This includes UPDATE, INSERT and DELETE statements executed +** as part of trigger programs. All changes are counted as soon as the +** statement that makes them is completed (when the statement handle is +** passed to [sqlite3_reset()] or [sqlite3_finalize()]). +** +** See also the [sqlite3_change()] interface. +** +** SQLite implements the command "DELETE FROM table" without a WHERE clause +** by dropping and recreating the table. (This is much faster than going +** through and deleting individual elements form the table.) Because of +** this optimization, the change count for "DELETE FROM table" will be +** zero regardless of the number of elements that were originally in the +** table. To get an accurate count of the number of rows deleted, use +** "DELETE FROM table WHERE 1" instead. +** +** If another thread makes changes on the same database connection +** while this routine is running then the return value of this routine +** is undefined. +*/ +int sqlite3_total_changes(sqlite3*); + +/* +** CAPI3REF: Interrupt A Long-Running Query +** +** This function causes any pending database operation to abort and +** return at its earliest opportunity. This routine is typically +** called in response to a user action such as pressing "Cancel" +** or Ctrl-C where the user wants a long query operation to halt +** immediately. +** +** It is safe to call this routine from a thread different from the +** thread that is currently running the database operation. But it +** is not safe to call this routine with a database connection that +** is closed or might close before sqlite3_interrupt() returns. +** +** The SQL operation that is interrupted will return [SQLITE_INTERRUPT]. +** If an interrupted operation was an update that is inside an +** explicit transaction, then the entire transaction will be rolled +** back automatically. +*/ +void sqlite3_interrupt(sqlite3*); + +/* +** CAPI3REF: Determine If An SQL Statement Is Complete +** +** These functions return true if the given input string comprises +** one or more complete SQL statements. For the sqlite3_complete() call, +** the parameter must be a nul-terminated UTF-8 string. For +** sqlite3_complete16(), a nul-terminated machine byte order UTF-16 string +** is required. +** +** These routines are useful for command-line input to determine if the +** currently entered text forms one or more complete SQL statements or +** if additional input is needed before sending the statements into +** SQLite for parsing. The algorithm is simple. If the +** last token other than spaces and comments is a semicolon, then return +** true. Actually, the algorithm is a little more complicated than that +** in order to deal with triggers, but the basic idea is the same: the +** statement is not complete unless it ends in a semicolon. +*/ +int sqlite3_complete(const char *sql); +int sqlite3_complete16(const void *sql); + +/* +** CAPI3REF: Register A Callback To Handle SQLITE_BUSY Errors +** +** This routine identifies a callback function that might be invoked +** whenever an attempt is made to open a database table +** that another thread or process has locked. +** If the busy callback is NULL, then [SQLITE_BUSY] +** (or sometimes [SQLITE_IOERR_BLOCKED]) +** is returned immediately upon encountering the lock. +** If the busy callback is not NULL, then the +** callback will be invoked with two arguments. The +** first argument to the handler is a copy of the void* pointer which +** is the third argument to this routine. The second argument to +** the handler is the number of times that the busy handler has +** been invoked for this locking event. If the +** busy callback returns 0, then no additional attempts are made to +** access the database and [SQLITE_BUSY] or [SQLITE_IOERR_BLOCKED] is returned. +** If the callback returns non-zero, then another attempt is made to open the +** database for reading and the cycle repeats. +** +** The presence of a busy handler does not guarantee that +** it will be invoked when there is lock contention. +** If SQLite determines that invoking the busy handler could result in +** a deadlock, it will return [SQLITE_BUSY] instead. +** Consider a scenario where one process is holding a read lock that +** it is trying to promote to a reserved lock and +** a second process is holding a reserved lock that it is trying +** to promote to an exclusive lock. The first process cannot proceed +** because it is blocked by the second and the second process cannot +** proceed because it is blocked by the first. If both processes +** invoke the busy handlers, neither will make any progress. Therefore, +** SQLite returns [SQLITE_BUSY] for the first process, hoping that this +** will induce the first process to release its read lock and allow +** the second process to proceed. +** +** The default busy callback is NULL. +** +** The [SQLITE_BUSY] error is converted to [SQLITE_IOERR_BLOCKED] when +** SQLite is in the middle of a large transaction where all the +** changes will not fit into the in-memory cache. SQLite will +** already hold a RESERVED lock on the database file, but it needs +** to promote this lock to EXCLUSIVE so that it can spill cache +** pages into the database file without harm to concurrent +** readers. If it is unable to promote the lock, then the in-memory +** cache will be left in an inconsistent state and so the error +** code is promoted from the relatively benign [SQLITE_BUSY] to +** the more severe [SQLITE_IOERR_BLOCKED]. This error code promotion +** forces an automatic rollback of the changes. See the +** <a href="http://www.sqlite.org/cvstrac/wiki?p=CorruptionFollowingBusyError"> +** CorruptionFollowingBusyError</a> wiki page for a discussion of why +** this is important. +** +** Sqlite is re-entrant, so the busy handler may start a new query. +** (It is not clear why anyone would every want to do this, but it +** is allowed, in theory.) But the busy handler may not close the +** database. Closing the database from a busy handler will delete +** data structures out from under the executing query and will +** probably result in a segmentation fault or other runtime error. +** +** There can only be a single busy handler defined for each database +** connection. Setting a new busy handler clears any previous one. +** Note that calling [sqlite3_busy_timeout()] will also set or clear +** the busy handler. +** +** When operating in [sqlite3_enable_shared_cache | shared cache mode], +** only a single busy handler can be defined for each database file. +** So if two database connections share a single cache, then changing +** the busy handler on one connection will also change the busy +** handler in the other connection. The busy handler is invoked +** in the thread that was running when the SQLITE_BUSY was hit. +*/ +int sqlite3_busy_handler(sqlite3*, int(*)(void*,int), void*); + +/* +** CAPI3REF: Set A Busy Timeout +** +** This routine sets a busy handler that sleeps for a while when a +** table is locked. The handler will sleep multiple times until +** at least "ms" milliseconds of sleeping have been done. After +** "ms" milliseconds of sleeping, the handler returns 0 which +** causes [sqlite3_step()] to return [SQLITE_BUSY] or [SQLITE_IOERR_BLOCKED]. +** +** Calling this routine with an argument less than or equal to zero +** turns off all busy handlers. +** +** There can only be a single busy handler for a particular database +** connection. If another busy handler was defined +** (using [sqlite3_busy_handler()]) prior to calling +** this routine, that other busy handler is cleared. +*/ +int sqlite3_busy_timeout(sqlite3*, int ms); + +/* +** CAPI3REF: Convenience Routines For Running Queries +** +** This next routine is a convenience wrapper around [sqlite3_exec()]. +** Instead of invoking a user-supplied callback for each row of the +** result, this routine remembers each row of the result in memory +** obtained from [sqlite3_malloc()], then returns all of the result after the +** query has finished. +** +** As an example, suppose the query result where this table: +** +** <blockquote><pre> +** Name | Age +** ----------------------- +** Alice | 43 +** Bob | 28 +** Cindy | 21 +** </pre></blockquote> +** +** If the 3rd argument were &azResult then after the function returns +** azResult will contain the following data: +** +** <blockquote><pre> +** azResult[0] = "Name"; +** azResult[1] = "Age"; +** azResult[2] = "Alice"; +** azResult[3] = "43"; +** azResult[4] = "Bob"; +** azResult[5] = "28"; +** azResult[6] = "Cindy"; +** azResult[7] = "21"; +** </pre></blockquote> +** +** Notice that there is an extra row of data containing the column +** headers. But the *nrow return value is still 3. *ncolumn is +** set to 2. In general, the number of values inserted into azResult +** will be ((*nrow) + 1)*(*ncolumn). +** +** After the calling function has finished using the result, it should +** pass the result data pointer to sqlite3_free_table() in order to +** release the memory that was malloc-ed. Because of the way the +** [sqlite3_malloc()] happens, the calling function must not try to call +** [sqlite3_free()] directly. Only [sqlite3_free_table()] is able to release +** the memory properly and safely. +** +** The return value of this routine is the same as from [sqlite3_exec()]. +*/ +int sqlite3_get_table( + sqlite3*, /* An open database */ + const char *sql, /* SQL to be executed */ + char ***resultp, /* Result written to a char *[] that this points to */ + int *nrow, /* Number of result rows written here */ + int *ncolumn, /* Number of result columns written here */ + char **errmsg /* Error msg written here */ +); +void sqlite3_free_table(char **result); + +/* +** CAPI3REF: Formatted String Printing Functions +** +** These routines are workalikes of the "printf()" family of functions +** from the standard C library. +** +** The sqlite3_mprintf() and sqlite3_vmprintf() routines write their +** results into memory obtained from [sqlite3_malloc()]. +** The strings returned by these two routines should be +** released by [sqlite3_free()]. Both routines return a +** NULL pointer if [sqlite3_malloc()] is unable to allocate enough +** memory to hold the resulting string. +** +** In sqlite3_snprintf() routine is similar to "snprintf()" from +** the standard C library. The result is written into the +** buffer supplied as the second parameter whose size is given by +** the first parameter. Note that the order of the +** first two parameters is reversed from snprintf(). This is an +** historical accident that cannot be fixed without breaking +** backwards compatibility. Note also that sqlite3_snprintf() +** returns a pointer to its buffer instead of the number of +** characters actually written into the buffer. We admit that +** the number of characters written would be a more useful return +** value but we cannot change the implementation of sqlite3_snprintf() +** now without breaking compatibility. +** +** As long as the buffer size is greater than zero, sqlite3_snprintf() +** guarantees that the buffer is always zero-terminated. The first +** parameter "n" is the total size of the buffer, including space for +** the zero terminator. So the longest string that can be completely +** written will be n-1 characters. +** +** These routines all implement some additional formatting +** options that are useful for constructing SQL statements. +** All of the usual printf formatting options apply. In addition, there +** is are "%q", "%Q", and "%z" options. +** +** The %q option works like %s in that it substitutes a null-terminated +** string from the argument list. But %q also doubles every '\'' character. +** %q is designed for use inside a string literal. By doubling each '\'' +** character it escapes that character and allows it to be inserted into +** the string. +** +** For example, so some string variable contains text as follows: +** +** <blockquote><pre> +** char *zText = "It's a happy day!"; +** </pre></blockquote> +** +** One can use this text in an SQL statement as follows: +** +** <blockquote><pre> +** char *zSQL = sqlite3_mprintf("INSERT INTO table VALUES('%q')", zText); +** sqlite3_exec(db, zSQL, 0, 0, 0); +** sqlite3_free(zSQL); +** </pre></blockquote> +** +** Because the %q format string is used, the '\'' character in zText +** is escaped and the SQL generated is as follows: +** +** <blockquote><pre> +** INSERT INTO table1 VALUES('It''s a happy day!') +** </pre></blockquote> +** +** This is correct. Had we used %s instead of %q, the generated SQL +** would have looked like this: +** +** <blockquote><pre> +** INSERT INTO table1 VALUES('It's a happy day!'); +** </pre></blockquote> +** +** This second example is an SQL syntax error. As a general rule you +** should always use %q instead of %s when inserting text into a string +** literal. +** +** The %Q option works like %q except it also adds single quotes around +** the outside of the total string. Or if the parameter in the argument +** list is a NULL pointer, %Q substitutes the text "NULL" (without single +** quotes) in place of the %Q option. So, for example, one could say: +** +** <blockquote><pre> +** char *zSQL = sqlite3_mprintf("INSERT INTO table VALUES(%Q)", zText); +** sqlite3_exec(db, zSQL, 0, 0, 0); +** sqlite3_free(zSQL); +** </pre></blockquote> +** +** The code above will render a correct SQL statement in the zSQL +** variable even if the zText variable is a NULL pointer. +** +** The "%z" formatting option works exactly like "%s" with the +** addition that after the string has been read and copied into +** the result, [sqlite3_free()] is called on the input string. +*/ +char *sqlite3_mprintf(const char*,...); +char *sqlite3_vmprintf(const char*, va_list); +char *sqlite3_snprintf(int,char*,const char*, ...); + +/* +** CAPI3REF: Memory Allocation Subsystem +** +** The SQLite core uses these three routines for all of its own +** internal memory allocation needs. (See the exception below.) +** +** The default implementation +** of the memory allocation subsystem uses the malloc(), realloc() +** and free() provided by the standard C library. However, if +** SQLite is compiled with the following C preprocessor macro +** +** <blockquote> SQLITE_MEMORY_SIZE=<i>NNN</i> </blockquote> +** +** where <i>NNN</i> is an integer, then SQLite create a static +** array of at least <i>NNN</i> bytes in size and use that array +** for all of its dynamic memory allocation needs. +** +** In SQLite version 3.5.0 and 3.5.1, it was possible to define +** the SQLITE_OMIT_MEMORY_ALLOCATION which would cause the built-in +** implementation of these routines to be omitted. That capability +** is no longer provided. Only built-in memory allocators can be +** used. +** +** <b>Exception:</b> The windows OS interface layer calls +** the system malloc() and free() directly when converting +** filenames between the UTF-8 encoding used by SQLite +** and whatever filename encoding is used by the particular windows +** installation. Memory allocation errors are detected, but +** they are reported back as [SQLITE_CANTOPEN] or +** [SQLITE_IOERR] rather than [SQLITE_NOMEM]. +*/ +void *sqlite3_malloc(int); +void *sqlite3_realloc(void*, int); +void sqlite3_free(void*); + +/* +** CAPI3REF: Memory Allocator Statistics +** +** In addition to the basic three allocation routines +** [sqlite3_malloc()], [sqlite3_free()], and [sqlite3_realloc()], +** the memory allocation subsystem included with the SQLite +** sources provides the interfaces shown below. +** +** The first of these two routines returns the amount of memory +** currently outstanding (malloced but not freed). The second +** returns the largest instantaneous amount of outstanding +** memory. The highwater mark is reset if the argument is +** true. +** +** The value returned may or may not include allocation +** overhead, depending on which built-in memory allocator +** implementation is used. +*/ +sqlite3_int64 sqlite3_memory_used(void); +sqlite3_int64 sqlite3_memory_highwater(int resetFlag); + +/* +** CAPI3REF: Compile-Time Authorization Callbacks +*** +** This routine registers a authorizer callback with the SQLite library. +** The authorizer callback is invoked as SQL statements are being compiled +** by [sqlite3_prepare()] or its variants [sqlite3_prepare_v2()], +** [sqlite3_prepare16()] and [sqlite3_prepare16_v2()]. At various +** points during the compilation process, as logic is being created +** to perform various actions, the authorizer callback is invoked to +** see if those actions are allowed. The authorizer callback should +** return SQLITE_OK to allow the action, [SQLITE_IGNORE] to disallow the +** specific action but allow the SQL statement to continue to be +** compiled, or [SQLITE_DENY] to cause the entire SQL statement to be +** rejected with an error. +** +** Depending on the action, the [SQLITE_IGNORE] and [SQLITE_DENY] return +** codes might mean something different or they might mean the same +** thing. If the action is, for example, to perform a delete opertion, +** then [SQLITE_IGNORE] and [SQLITE_DENY] both cause the statement compilation +** to fail with an error. But if the action is to read a specific column +** from a specific table, then [SQLITE_DENY] will cause the entire +** statement to fail but [SQLITE_IGNORE] will cause a NULL value to be +** read instead of the actual column value. +** +** The first parameter to the authorizer callback is a copy of +** the third parameter to the sqlite3_set_authorizer() interface. +** The second parameter to the callback is an integer +** [SQLITE_COPY | action code] that specifies the particular action +** to be authorized. The available action codes are +** [SQLITE_COPY | documented separately]. The third through sixth +** parameters to the callback are strings that contain additional +** details about the action to be authorized. +** +** An authorizer is used when preparing SQL statements from an untrusted +** source, to ensure that the SQL statements do not try to access data +** that they are not allowed to see, or that they do not try to +** execute malicious statements that damage the database. For +** example, an application may allow a user to enter arbitrary +** SQL queries for evaluation by a database. But the application does +** not want the user to be able to make arbitrary changes to the +** database. An authorizer could then be put in place while the +** user-entered SQL is being prepared that disallows everything +** except SELECT statements. +** +** Only a single authorizer can be in place on a database connection +** at a time. Each call to sqlite3_set_authorizer overrides the +** previous call. A NULL authorizer means that no authorization +** callback is invoked. The default authorizer is NULL. +** +** Note that the authorizer callback is invoked only during +** [sqlite3_prepare()] or its variants. Authorization is not +** performed during statement evaluation in [sqlite3_step()]. +*/ +int sqlite3_set_authorizer( + sqlite3*, + int (*xAuth)(void*,int,const char*,const char*,const char*,const char*), + void *pUserData +); + +/* +** CAPI3REF: Authorizer Return Codes +** +** The [sqlite3_set_authorizer | authorizer callback function] must +** return either [SQLITE_OK] or one of these two constants in order +** to signal SQLite whether or not the action is permitted. See the +** [sqlite3_set_authorizer | authorizer documentation] for additional +** information. +*/ +#define SQLITE_DENY 1 /* Abort the SQL statement with an error */ +#define SQLITE_IGNORE 2 /* Don't allow access, but don't generate an error */ + +/* +** CAPI3REF: Authorizer Action Codes +** +** The [sqlite3_set_authorizer()] interface registers a callback function +** that is invoked to authorizer certain SQL statement actions. The +** second parameter to the callback is an integer code that specifies +** what action is being authorized. These are the integer action codes that +** the authorizer callback may be passed. +** +** These action code values signify what kind of operation is to be +** authorized. The 3rd and 4th parameters to the authorization callback +** function will be parameters or NULL depending on which of these +** codes is used as the second parameter. The 5th parameter to the +** authorizer callback is the name of the database ("main", "temp", +** etc.) if applicable. The 6th parameter to the authorizer callback +** is the name of the inner-most trigger or view that is responsible for +** the access attempt or NULL if this access attempt is directly from +** top-level SQL code. +*/ +/******************************************* 3rd ************ 4th ***********/ +#define SQLITE_CREATE_INDEX 1 /* Index Name Table Name */ +#define SQLITE_CREATE_TABLE 2 /* Table Name NULL */ +#define SQLITE_CREATE_TEMP_INDEX 3 /* Index Name Table Name */ +#define SQLITE_CREATE_TEMP_TABLE 4 /* Table Name NULL */ +#define SQLITE_CREATE_TEMP_TRIGGER 5 /* Trigger Name Table Name */ +#define SQLITE_CREATE_TEMP_VIEW 6 /* View Name NULL */ +#define SQLITE_CREATE_TRIGGER 7 /* Trigger Name Table Name */ +#define SQLITE_CREATE_VIEW 8 /* View Name NULL */ +#define SQLITE_DELETE 9 /* Table Name NULL */ +#define SQLITE_DROP_INDEX 10 /* Index Name Table Name */ +#define SQLITE_DROP_TABLE 11 /* Table Name NULL */ +#define SQLITE_DROP_TEMP_INDEX 12 /* Index Name Table Name */ +#define SQLITE_DROP_TEMP_TABLE 13 /* Table Name NULL */ +#define SQLITE_DROP_TEMP_TRIGGER 14 /* Trigger Name Table Name */ +#define SQLITE_DROP_TEMP_VIEW 15 /* View Name NULL */ +#define SQLITE_DROP_TRIGGER 16 /* Trigger Name Table Name */ +#define SQLITE_DROP_VIEW 17 /* View Name NULL */ +#define SQLITE_INSERT 18 /* Table Name NULL */ +#define SQLITE_PRAGMA 19 /* Pragma Name 1st arg or NULL */ +#define SQLITE_READ 20 /* Table Name Column Name */ +#define SQLITE_SELECT 21 /* NULL NULL */ +#define SQLITE_TRANSACTION 22 /* NULL NULL */ +#define SQLITE_UPDATE 23 /* Table Name Column Name */ +#define SQLITE_ATTACH 24 /* Filename NULL */ +#define SQLITE_DETACH 25 /* Database Name NULL */ +#define SQLITE_ALTER_TABLE 26 /* Database Name Table Name */ +#define SQLITE_REINDEX 27 /* Index Name NULL */ +#define SQLITE_ANALYZE 28 /* Table Name NULL */ +#define SQLITE_CREATE_VTABLE 29 /* Table Name Module Name */ +#define SQLITE_DROP_VTABLE 30 /* Table Name Module Name */ +#define SQLITE_FUNCTION 31 /* Function Name NULL */ +#define SQLITE_COPY 0 /* No longer used */ + +/* +** CAPI3REF: Tracing And Profiling Functions +** +** These routines register callback functions that can be used for +** tracing and profiling the execution of SQL statements. +** The callback function registered by sqlite3_trace() is invoked +** at the first [sqlite3_step()] for the evaluation of an SQL statement. +** The callback function registered by sqlite3_profile() is invoked +** as each SQL statement finishes and includes +** information on how long that statement ran. +** +** The sqlite3_profile() API is currently considered experimental and +** is subject to change. +*/ +void *sqlite3_trace(sqlite3*, void(*xTrace)(void*,const char*), void*); +void *sqlite3_profile(sqlite3*, + void(*xProfile)(void*,const char*,sqlite3_uint64), void*); + +/* +** CAPI3REF: Query Progress Callbacks +** +** This routine configures a callback function - the progress callback - that +** is invoked periodically during long running calls to [sqlite3_exec()], +** [sqlite3_step()] and [sqlite3_get_table()]. An example use for this +** interface is to keep a GUI updated during a large query. +** +** The progress callback is invoked once for every N virtual machine opcodes, +** where N is the second argument to this function. The progress callback +** itself is identified by the third argument to this function. The fourth +** argument to this function is a void pointer passed to the progress callback +** function each time it is invoked. +** +** If a call to [sqlite3_exec()], [sqlite3_step()], or [sqlite3_get_table()] +** results in fewer than N opcodes being executed, then the progress +** callback is never invoked. +** +** Only a single progress callback function may be registered for each +** open database connection. Every call to sqlite3_progress_handler() +** overwrites the results of the previous call. +** To remove the progress callback altogether, pass NULL as the third +** argument to this function. +** +** If the progress callback returns a result other than 0, then the current +** query is immediately terminated and any database changes rolled back. +** The containing [sqlite3_exec()], [sqlite3_step()], or +** [sqlite3_get_table()] call returns SQLITE_INTERRUPT. This feature +** can be used, for example, to implement the "Cancel" button on a +** progress dialog box in a GUI. +*/ +void sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*); + +/* +** CAPI3REF: Opening A New Database Connection +** +** Open the sqlite database file "filename". The "filename" is UTF-8 +** encoded for [sqlite3_open()] and [sqlite3_open_v2()] and UTF-16 encoded +** in the native byte order for [sqlite3_open16()]. +** An [sqlite3*] handle is returned in *ppDb, even +** if an error occurs. If the database is opened (or created) successfully, +** then [SQLITE_OK] is returned. Otherwise an error code is returned. The +** [sqlite3_errmsg()] or [sqlite3_errmsg16()] routines can be used to obtain +** an English language description of the error. +** +** The default encoding for the database will be UTF-8 if +** [sqlite3_open()] or [sqlite3_open_v2()] is called and +** UTF-16 if [sqlite3_open16()] is used. +** +** Whether or not an error occurs when it is opened, resources associated +** with the [sqlite3*] handle should be released by passing it to +** [sqlite3_close()] when it is no longer required. +** +** The [sqlite3_open_v2()] interface works like [sqlite3_open()] except that +** provides two additional parameters for additional control over the +** new database connection. The flags parameter can be one of: +** +** <ol> +** <li> [SQLITE_OPEN_READONLY] +** <li> [SQLITE_OPEN_READWRITE] +** <li> [SQLITE_OPEN_READWRITE] | [SQLITE_OPEN_CREATE] +** </ol> +** +** The first value opens the database read-only. If the database does +** not previously exist, an error is returned. The second option opens +** the database for reading and writing if possible, or reading only if +** if the file is write protected. In either case the database must already +** exist or an error is returned. The third option opens the database +** for reading and writing and creates it if it does not already exist. +** The third options is behavior that is always used for [sqlite3_open()] +** and [sqlite3_open16()]. +** +** If the filename is ":memory:", then an private +** in-memory database is created for the connection. This in-memory +** database will vanish when the database connection is closed. Future +** version of SQLite might make use of additional special filenames +** that begin with the ":" character. It is recommended that +** when a database filename really does begin with +** ":" that you prefix the filename with a pathname like "./" to +** avoid ambiguity. +** +** If the filename is an empty string, then a private temporary +** on-disk database will be created. This private database will be +** automatically deleted as soon as the database connection is closed. +** +** The fourth parameter to sqlite3_open_v2() is the name of the +** [sqlite3_vfs] object that defines the operating system +** interface that the new database connection should use. If the +** fourth parameter is a NULL pointer then the default [sqlite3_vfs] +** object is used. +** +** <b>Note to windows users:</b> The encoding used for the filename argument +** of [sqlite3_open()] and [sqlite3_open_v2()] must be UTF-8, not whatever +** codepage is currently defined. Filenames containing international +** characters must be converted to UTF-8 prior to passing them into +** [sqlite3_open()] or [sqlite3_open_v2()]. +*/ +int sqlite3_open( + const char *filename, /* Database filename (UTF-8) */ + sqlite3 **ppDb /* OUT: SQLite db handle */ +); +int sqlite3_open16( + const void *filename, /* Database filename (UTF-16) */ + sqlite3 **ppDb /* OUT: SQLite db handle */ +); +int sqlite3_open_v2( + const char *filename, /* Database filename (UTF-8) */ + sqlite3 **ppDb, /* OUT: SQLite db handle */ + int flags, /* Flags */ + const char *zVfs /* Name of VFS module to use */ +); + +/* +** CAPI3REF: Error Codes And Messages +** +** The sqlite3_errcode() interface returns the numeric +** [SQLITE_OK | result code] or [SQLITE_IOERR_READ | extended result code] +** for the most recent failed sqlite3_* API call associated +** with [sqlite3] handle 'db'. If a prior API call failed but the +** most recent API call succeeded, the return value from sqlite3_errcode() +** is undefined. +** +** The sqlite3_errmsg() and sqlite3_errmsg16() return English-language +** text that describes the error, as either UTF8 or UTF16 respectively. +** Memory to hold the error message string is managed internally. The +** string may be overwritten or deallocated by subsequent calls to SQLite +** interface functions. +** +** Calls to many sqlite3_* functions set the error code and string returned +** by [sqlite3_errcode()], [sqlite3_errmsg()], and [sqlite3_errmsg16()] +** (overwriting the previous values). Note that calls to [sqlite3_errcode()], +** [sqlite3_errmsg()], and [sqlite3_errmsg16()] themselves do not affect the +** results of future invocations. Calls to API routines that do not return +** an error code (example: [sqlite3_data_count()]) do not +** change the error code returned by this routine. Interfaces that are +** not associated with a specific database connection (examples: +** [sqlite3_mprintf()] or [sqlite3_enable_shared_cache()] do not change +** the return code. +** +** Assuming no other intervening sqlite3_* API calls are made, the error +** code returned by this function is associated with the same error as +** the strings returned by [sqlite3_errmsg()] and [sqlite3_errmsg16()]. +*/ +int sqlite3_errcode(sqlite3 *db); +const char *sqlite3_errmsg(sqlite3*); +const void *sqlite3_errmsg16(sqlite3*); + +/* +** CAPI3REF: SQL Statement Object +** +** Instance of this object represent single SQL statements. This +** is variously known as a "prepared statement" or a +** "compiled SQL statement" or simply as a "statement". +** +** The life of a statement object goes something like this: +** +** <ol> +** <li> Create the object using [sqlite3_prepare_v2()] or a related +** function. +** <li> Bind values to host parameters using +** [sqlite3_bind_blob | sqlite3_bind_* interfaces]. +** <li> Run the SQL by calling [sqlite3_step()] one or more times. +** <li> Reset the statement using [sqlite3_reset()] then go back +** to step 2. Do this zero or more times. +** <li> Destroy the object using [sqlite3_finalize()]. +** </ol> +** +** Refer to documentation on individual methods above for additional +** information. +*/ +typedef struct sqlite3_stmt sqlite3_stmt; + +/* +** CAPI3REF: Compiling An SQL Statement +** +** To execute an SQL query, it must first be compiled into a byte-code +** program using one of these routines. +** +** The first argument "db" is an [sqlite3 | SQLite database handle] +** obtained from a prior call to [sqlite3_open()], [sqlite3_open_v2()] +** or [sqlite3_open16()]. +** The second argument "zSql" is the statement to be compiled, encoded +** as either UTF-8 or UTF-16. The sqlite3_prepare() and sqlite3_prepare_v2() +** interfaces uses UTF-8 and sqlite3_prepare16() and sqlite3_prepare16_v2() +** use UTF-16. +** +** If the nByte argument is less +** than zero, then zSql is read up to the first zero terminator. If +** nByte is non-negative, then it is the maximum number of +** bytes read from zSql. When nByte is non-negative, the +** zSql string ends at either the first '\000' character or +** until the nByte-th byte, whichever comes first. +** +** *pzTail is made to point to the first byte past the end of the first +** SQL statement in zSql. This routine only compiles the first statement +** in zSql, so *pzTail is left pointing to what remains uncompiled. +** +** *ppStmt is left pointing to a compiled +** [sqlite3_stmt | SQL statement structure] that can be +** executed using [sqlite3_step()]. Or if there is an error, *ppStmt may be +** set to NULL. If the input text contained no SQL (if the input is and +** empty string or a comment) then *ppStmt is set to NULL. The calling +** procedure is responsible for deleting the compiled SQL statement +** using [sqlite3_finalize()] after it has finished with it. +** +** On success, [SQLITE_OK] is returned. Otherwise an +** [SQLITE_ERROR | error code] is returned. +** +** The sqlite3_prepare_v2() and sqlite3_prepare16_v2() interfaces are +** recommended for all new programs. The two older interfaces are retained +** for backwards compatibility, but their use is discouraged. +** In the "v2" interfaces, the prepared statement +** that is returned (the [sqlite3_stmt] object) contains a copy of the +** original SQL text. This causes the [sqlite3_step()] interface to +** behave a differently in two ways: +** +** <ol> +** <li> +** If the database schema changes, instead of returning [SQLITE_SCHEMA] as it +** always used to do, [sqlite3_step()] will automatically recompile the SQL +** statement and try to run it again. If the schema has changed in a way +** that makes the statement no longer valid, [sqlite3_step()] will still +** return [SQLITE_SCHEMA]. But unlike the legacy behavior, [SQLITE_SCHEMA] is +** now a fatal error. Calling [sqlite3_prepare_v2()] again will not make the +** error go away. Note: use [sqlite3_errmsg()] to find the text of the parsing +** error that results in an [SQLITE_SCHEMA] return. +** </li> +** +** <li> +** When an error occurs, +** [sqlite3_step()] will return one of the detailed +** [SQLITE_ERROR | result codes] or +** [SQLITE_IOERR_READ | extended result codes] such as directly. +** The legacy behavior was that [sqlite3_step()] would only return a generic +** [SQLITE_ERROR] result code and you would have to make a second call to +** [sqlite3_reset()] in order to find the underlying cause of the problem. +** With the "v2" prepare interfaces, the underlying reason for the error is +** returned immediately. +** </li> +** </ol> +*/ +int sqlite3_prepare( + sqlite3 *db, /* Database handle */ + const char *zSql, /* SQL statement, UTF-8 encoded */ + int nByte, /* Maximum length of zSql in bytes. */ + sqlite3_stmt **ppStmt, /* OUT: Statement handle */ + const char **pzTail /* OUT: Pointer to unused portion of zSql */ +); +int sqlite3_prepare_v2( + sqlite3 *db, /* Database handle */ + const char *zSql, /* SQL statement, UTF-8 encoded */ + int nByte, /* Maximum length of zSql in bytes. */ + sqlite3_stmt **ppStmt, /* OUT: Statement handle */ + const char **pzTail /* OUT: Pointer to unused portion of zSql */ +); +int sqlite3_prepare16( + sqlite3 *db, /* Database handle */ + const void *zSql, /* SQL statement, UTF-16 encoded */ + int nByte, /* Maximum length of zSql in bytes. */ + sqlite3_stmt **ppStmt, /* OUT: Statement handle */ + const void **pzTail /* OUT: Pointer to unused portion of zSql */ +); +int sqlite3_prepare16_v2( + sqlite3 *db, /* Database handle */ + const void *zSql, /* SQL statement, UTF-16 encoded */ + int nByte, /* Maximum length of zSql in bytes. */ + sqlite3_stmt **ppStmt, /* OUT: Statement handle */ + const void **pzTail /* OUT: Pointer to unused portion of zSql */ +); + +/* +** Retrieve the original SQL statement associated with a compiled statement +** in UTF-8 encoding. +** +** If the compiled SQL statement passed as an argument was compiled using +** either sqlite3_prepare_v2 or sqlite3_prepare16_v2, then this function +** returns a pointer to a nul-terminated string containing a copy of +** the original SQL statement. The pointer is valid until the statement +** is deleted using sqlite3_finalize(). +** +** If the statement was compiled using either of the legacy interfaces +** sqlite3_prepare() or sqlite3_prepare16(), this function returns NULL. +** +****** EXPERIMENTAL - subject to change without notice ************** +*/ +const char *sqlite3_sql(sqlite3_stmt *pStmt); + +/* +** CAPI3REF: Dynamically Typed Value Object +** +** SQLite uses dynamic typing for the values it stores. Values can +** be integers, floating point values, strings, BLOBs, or NULL. When +** passing around values internally, each value is represented as +** an instance of the sqlite3_value object. +*/ +typedef struct Mem sqlite3_value; + +/* +** CAPI3REF: SQL Function Context Object +** +** The context in which an SQL function executes is stored in an +** sqlite3_context object. A pointer to such an object is the +** first parameter to user-defined SQL functions. +*/ +typedef struct sqlite3_context sqlite3_context; + +/* +** CAPI3REF: Binding Values To Prepared Statements +** +** In the SQL strings input to [sqlite3_prepare_v2()] and its variants, +** one or more literals can be replace by a parameter in one of these +** forms: +** +** <ul> +** <li> ? +** <li> ?NNN +** <li> :AAA +** <li> @AAA +** <li> $VVV +** </ul> +** +** In the parameter forms shown above NNN is an integer literal, +** AAA is an alphanumeric identifier and VVV is a variable name according +** to the syntax rules of the TCL programming language. +** The values of these parameters (also called "host parameter names") +** can be set using the sqlite3_bind_*() routines defined here. +** +** The first argument to the sqlite3_bind_*() routines always is a pointer +** to the [sqlite3_stmt] object returned from [sqlite3_prepare_v2()] or +** its variants. The second +** argument is the index of the parameter to be set. The first parameter has +** an index of 1. When the same named parameter is used more than once, second +** and subsequent +** occurrences have the same index as the first occurrence. The index for +** named parameters can be looked up using the +** [sqlite3_bind_parameter_name()] API if desired. The index for "?NNN" +** parametes is the value of NNN. +** The NNN value must be between 1 and the compile-time +** parameter SQLITE_MAX_VARIABLE_NUMBER (default value: 999). +** See <a href="limits.html">limits.html</a> for additional information. +** +** The third argument is the value to bind to the parameter. +** +** In those +** routines that have a fourth argument, its value is the number of bytes +** in the parameter. To be clear: the value is the number of bytes in the +** string, not the number of characters. The number +** of bytes does not include the zero-terminator at the end of strings. +** If the fourth parameter is negative, the length of the string is +** number of bytes up to the first zero terminator. +** +** The fifth argument to sqlite3_bind_blob(), sqlite3_bind_text(), and +** sqlite3_bind_text16() is a destructor used to dispose of the BLOB or +** text after SQLite has finished with it. If the fifth argument is the +** special value [SQLITE_STATIC], then the library assumes that the information +** is in static, unmanaged space and does not need to be freed. If the +** fifth argument has the value [SQLITE_TRANSIENT], then SQLite makes its +** own private copy of the data immediately, before the sqlite3_bind_*() +** routine returns. +** +** The sqlite3_bind_zeroblob() routine binds a BLOB of length n that +** is filled with zeros. A zeroblob uses a fixed amount of memory +** (just an integer to hold it size) while it is being processed. +** Zeroblobs are intended to serve as place-holders for BLOBs whose +** content is later written using +** [sqlite3_blob_open | increment BLOB I/O] routines. A negative +** value for the zeroblob results in a zero-length BLOB. +** +** The sqlite3_bind_*() routines must be called after +** [sqlite3_prepare_v2()] (and its variants) or [sqlite3_reset()] and +** before [sqlite3_step()]. +** Bindings are not cleared by the [sqlite3_reset()] routine. +** Unbound parameters are interpreted as NULL. +** +** These routines return [SQLITE_OK] on success or an error code if +** anything goes wrong. [SQLITE_RANGE] is returned if the parameter +** index is out of range. [SQLITE_NOMEM] is returned if malloc fails. +** [SQLITE_MISUSE] is returned if these routines are called on a virtual +** machine that is the wrong state or which has already been finalized. +*/ +int sqlite3_bind_blob(sqlite3_stmt*, int, const void*, int n, void(*)(void*)); +int sqlite3_bind_double(sqlite3_stmt*, int, double); +int sqlite3_bind_int(sqlite3_stmt*, int, int); +int sqlite3_bind_int64(sqlite3_stmt*, int, sqlite3_int64); +int sqlite3_bind_null(sqlite3_stmt*, int); +int sqlite3_bind_text(sqlite3_stmt*, int, const char*, int n, void(*)(void*)); +int sqlite3_bind_text16(sqlite3_stmt*, int, const void*, int, void(*)(void*)); +int sqlite3_bind_value(sqlite3_stmt*, int, const sqlite3_value*); +int sqlite3_bind_zeroblob(sqlite3_stmt*, int, int n); + +/* +** CAPI3REF: Number Of Host Parameters +** +** Return the largest host parameter index in the precompiled statement given +** as the argument. When the host parameters are of the forms like ":AAA" +** or "?", then they are assigned sequential increasing numbers beginning +** with one, so the value returned is the number of parameters. However +** if the same host parameter name is used multiple times, each occurrance +** is given the same number, so the value returned in that case is the number +** of unique host parameter names. If host parameters of the form "?NNN" +** are used (where NNN is an integer) then there might be gaps in the +** numbering and the value returned by this interface is the index of the +** host parameter with the largest index value. +** +** The prepared statement must not be [sqlite3_finalize | finalized] +** prior to this routine returnning. Otherwise the results are undefined +** and probably undesirable. +*/ +int sqlite3_bind_parameter_count(sqlite3_stmt*); + +/* +** CAPI3REF: Name Of A Host Parameter +** +** This routine returns a pointer to the name of the n-th parameter in a +** [sqlite3_stmt | prepared statement]. +** Host parameters of the form ":AAA" or "@AAA" or "$VVV" have a name +** which is the string ":AAA" or "@AAA" or "$VVV". +** In other words, the initial ":" or "$" or "@" +** is included as part of the name. +** Parameters of the form "?" or "?NNN" have no name. +** +** The first bound parameter has an index of 1, not 0. +** +** If the value n is out of range or if the n-th parameter is nameless, +** then NULL is returned. The returned string is always in the +** UTF-8 encoding even if the named parameter was originally specified +** as UTF-16 in [sqlite3_prepare16()] or [sqlite3_prepare16_v2()]. +*/ +const char *sqlite3_bind_parameter_name(sqlite3_stmt*, int); + +/* +** CAPI3REF: Index Of A Parameter With A Given Name +** +** This routine returns the index of a host parameter with the given name. +** The name must match exactly. If no parameter with the given name is +** found, return 0. Parameter names must be UTF8. +*/ +int sqlite3_bind_parameter_index(sqlite3_stmt*, const char *zName); + +/* +** CAPI3REF: Reset All Bindings On A Prepared Statement +** +** Contrary to the intuition of many, [sqlite3_reset()] does not +** reset the [sqlite3_bind_blob | bindings] on a +** [sqlite3_stmt | prepared statement]. Use this routine to +** reset all host parameters to NULL. +*/ +int sqlite3_clear_bindings(sqlite3_stmt*); + +/* +** CAPI3REF: Number Of Columns In A Result Set +** +** Return the number of columns in the result set returned by the +** [sqlite3_stmt | compiled SQL statement]. This routine returns 0 +** if pStmt is an SQL statement that does not return data (for +** example an UPDATE). +*/ +int sqlite3_column_count(sqlite3_stmt *pStmt); + +/* +** CAPI3REF: Column Names In A Result Set +** +** These routines return the name assigned to a particular column +** in the result set of a SELECT statement. The sqlite3_column_name() +** interface returns a pointer to a UTF8 string and sqlite3_column_name16() +** returns a pointer to a UTF16 string. The first parameter is the +** [sqlite3_stmt | prepared statement] that implements the SELECT statement. +** The second parameter is the column number. The left-most column is +** number 0. +** +** The returned string pointer is valid until either the +** [sqlite3_stmt | prepared statement] is destroyed by [sqlite3_finalize()] +** or until the next call sqlite3_column_name() or sqlite3_column_name16() +** on the same column. +** +** If sqlite3_malloc() fails during the processing of either routine +** (for example during a conversion from UTF-8 to UTF-16) then a +** NULL pointer is returned. +*/ +const char *sqlite3_column_name(sqlite3_stmt*, int N); +const void *sqlite3_column_name16(sqlite3_stmt*, int N); + +/* +** CAPI3REF: Source Of Data In A Query Result +** +** These routines provide a means to determine what column of what +** table in which database a result of a SELECT statement comes from. +** The name of the database or table or column can be returned as +** either a UTF8 or UTF16 string. The _database_ routines return +** the database name, the _table_ routines return the table name, and +** the origin_ routines return the column name. +** The returned string is valid until +** the [sqlite3_stmt | prepared statement] is destroyed using +** [sqlite3_finalize()] or until the same information is requested +** again in a different encoding. +** +** The names returned are the original un-aliased names of the +** database, table, and column. +** +** The first argument to the following calls is a +** [sqlite3_stmt | compiled SQL statement]. +** These functions return information about the Nth column returned by +** the statement, where N is the second function argument. +** +** If the Nth column returned by the statement is an expression +** or subquery and is not a column value, then all of these functions +** return NULL. Otherwise, they return the +** name of the attached database, table and column that query result +** column was extracted from. +** +** As with all other SQLite APIs, those postfixed with "16" return UTF-16 +** encoded strings, the other functions return UTF-8. +** +** These APIs are only available if the library was compiled with the +** SQLITE_ENABLE_COLUMN_METADATA preprocessor symbol defined. +** +** If two or more threads call one or more of these routines against the same +** prepared statement and column at the same time then the results are +** undefined. +*/ +const char *sqlite3_column_database_name(sqlite3_stmt*,int); +const void *sqlite3_column_database_name16(sqlite3_stmt*,int); +const char *sqlite3_column_table_name(sqlite3_stmt*,int); +const void *sqlite3_column_table_name16(sqlite3_stmt*,int); +const char *sqlite3_column_origin_name(sqlite3_stmt*,int); +const void *sqlite3_column_origin_name16(sqlite3_stmt*,int); + +/* +** CAPI3REF: Declared Datatype Of A Query Result +** +** The first parameter is a [sqlite3_stmt | compiled SQL statement]. +** If this statement is a SELECT statement and the Nth column of the +** returned result set of that SELECT is a table column (not an +** expression or subquery) then the declared type of the table +** column is returned. If the Nth column of the result set is an +** expression or subquery, then a NULL pointer is returned. +** The returned string is always UTF-8 encoded. For example, in +** the database schema: +** +** CREATE TABLE t1(c1 VARIANT); +** +** And the following statement compiled: +** +** SELECT c1 + 1, c1 FROM t1; +** +** Then this routine would return the string "VARIANT" for the second +** result column (i==1), and a NULL pointer for the first result column +** (i==0). +** +** SQLite uses dynamic run-time typing. So just because a column +** is declared to contain a particular type does not mean that the +** data stored in that column is of the declared type. SQLite is +** strongly typed, but the typing is dynamic not static. Type +** is associated with individual values, not with the containers +** used to hold those values. +*/ +const char *sqlite3_column_decltype(sqlite3_stmt *, int i); +const void *sqlite3_column_decltype16(sqlite3_stmt*,int); + +/* +** CAPI3REF: Evaluate An SQL Statement +** +** After an [sqlite3_stmt | SQL statement] has been prepared with a call +** to either [sqlite3_prepare_v2()] or [sqlite3_prepare16_v2()] or to one of +** the legacy interfaces [sqlite3_prepare()] or [sqlite3_prepare16()], +** then this function must be called one or more times to evaluate the +** statement. +** +** The details of the behavior of this sqlite3_step() interface depend +** on whether the statement was prepared using the newer "v2" interface +** [sqlite3_prepare_v2()] and [sqlite3_prepare16_v2()] or the older legacy +** interface [sqlite3_prepare()] and [sqlite3_prepare16()]. The use of the +** new "v2" interface is recommended for new applications but the legacy +** interface will continue to be supported. +** +** In the lagacy interface, the return value will be either [SQLITE_BUSY], +** [SQLITE_DONE], [SQLITE_ROW], [SQLITE_ERROR], or [SQLITE_MISUSE]. +** With the "v2" interface, any of the other [SQLITE_OK | result code] +** or [SQLITE_IOERR_READ | extended result code] might be returned as +** well. +** +** [SQLITE_BUSY] means that the database engine was unable to acquire the +** database locks it needs to do its job. If the statement is a COMMIT +** or occurs outside of an explicit transaction, then you can retry the +** statement. If the statement is not a COMMIT and occurs within a +** explicit transaction then you should rollback the transaction before +** continuing. +** +** [SQLITE_DONE] means that the statement has finished executing +** successfully. sqlite3_step() should not be called again on this virtual +** machine without first calling [sqlite3_reset()] to reset the virtual +** machine back to its initial state. +** +** If the SQL statement being executed returns any data, then +** [SQLITE_ROW] is returned each time a new row of data is ready +** for processing by the caller. The values may be accessed using +** the [sqlite3_column_int | column access functions]. +** sqlite3_step() is called again to retrieve the next row of data. +** +** [SQLITE_ERROR] means that a run-time error (such as a constraint +** violation) has occurred. sqlite3_step() should not be called again on +** the VM. More information may be found by calling [sqlite3_errmsg()]. +** With the legacy interface, a more specific error code (example: +** [SQLITE_INTERRUPT], [SQLITE_SCHEMA], [SQLITE_CORRUPT], and so forth) +** can be obtained by calling [sqlite3_reset()] on the +** [sqlite3_stmt | prepared statement]. In the "v2" interface, +** the more specific error code is returned directly by sqlite3_step(). +** +** [SQLITE_MISUSE] means that the this routine was called inappropriately. +** Perhaps it was called on a [sqlite3_stmt | prepared statement] that has +** already been [sqlite3_finalize | finalized] or on one that had +** previously returned [SQLITE_ERROR] or [SQLITE_DONE]. Or it could +** be the case that the same database connection is being used by two or +** more threads at the same moment in time. +** +** <b>Goofy Interface Alert:</b> +** In the legacy interface, +** the sqlite3_step() API always returns a generic error code, +** [SQLITE_ERROR], following any error other than [SQLITE_BUSY] +** and [SQLITE_MISUSE]. You must call [sqlite3_reset()] or +** [sqlite3_finalize()] in order to find one of the specific +** [SQLITE_ERROR | result codes] that better describes the error. +** We admit that this is a goofy design. The problem has been fixed +** with the "v2" interface. If you prepare all of your SQL statements +** using either [sqlite3_prepare_v2()] or [sqlite3_prepare16_v2()] instead +** of the legacy [sqlite3_prepare()] and [sqlite3_prepare16()], then the +** more specific [SQLITE_ERROR | result codes] are returned directly +** by sqlite3_step(). The use of the "v2" interface is recommended. +*/ +int sqlite3_step(sqlite3_stmt*); + +/* +** CAPI3REF: +** +** Return the number of values in the current row of the result set. +** +** After a call to [sqlite3_step()] that returns [SQLITE_ROW], this routine +** will return the same value as the [sqlite3_column_count()] function. +** After [sqlite3_step()] has returned an [SQLITE_DONE], [SQLITE_BUSY], or +** a [SQLITE_ERROR | error code], or before [sqlite3_step()] has been +** called on the [sqlite3_stmt | prepared statement] for the first time, +** this routine returns zero. +*/ +int sqlite3_data_count(sqlite3_stmt *pStmt); + +/* +** CAPI3REF: Fundamental Datatypes +** +** Every value in SQLite has one of five fundamental datatypes: +** +** <ul> +** <li> 64-bit signed integer +** <li> 64-bit IEEE floating point number +** <li> string +** <li> BLOB +** <li> NULL +** </ul> +** +** These constants are codes for each of those types. +** +** Note that the SQLITE_TEXT constant was also used in SQLite version 2 +** for a completely different meaning. Software that links against both +** SQLite version 2 and SQLite version 3 should use SQLITE3_TEXT not +** SQLITE_TEXT. +*/ +#define SQLITE_INTEGER 1 +#define SQLITE_FLOAT 2 +#define SQLITE_BLOB 4 +#define SQLITE_NULL 5 +#ifdef SQLITE_TEXT +# undef SQLITE_TEXT +#else +# define SQLITE_TEXT 3 +#endif +#define SQLITE3_TEXT 3 + +/* +** CAPI3REF: Results Values From A Query +** +** These routines return information about +** a single column of the current result row of a query. In every +** case the first argument is a pointer to the +** [sqlite3_stmt | SQL statement] that is being +** evaluated (the [sqlite3_stmt*] that was returned from +** [sqlite3_prepare_v2()] or one of its variants) and +** the second argument is the index of the column for which information +** should be returned. The left-most column of the result set +** has an index of 0. +** +** If the SQL statement is not currently point to a valid row, or if the +** the column index is out of range, the result is undefined. +** These routines may only be called when the most recent call to +** [sqlite3_step()] has returned [SQLITE_ROW] and neither +** [sqlite3_reset()] nor [sqlite3_finalize()] has been call subsequently. +** If any of these routines are called after [sqlite3_reset()] or +** [sqlite3_finalize()] or after [sqlite3_step()] has returned +** something other than [SQLITE_ROW], the results are undefined. +** If [sqlite3_step()] or [sqlite3_reset()] or [sqlite3_finalize()] +** are called from a different thread while any of these routines +** are pending, then the results are undefined. +** +** The sqlite3_column_type() routine returns +** [SQLITE_INTEGER | datatype code] for the initial data type +** of the result column. The returned value is one of [SQLITE_INTEGER], +** [SQLITE_FLOAT], [SQLITE_TEXT], [SQLITE_BLOB], or [SQLITE_NULL]. The value +** returned by sqlite3_column_type() is only meaningful if no type +** conversions have occurred as described below. After a type conversion, +** the value returned by sqlite3_column_type() is undefined. Future +** versions of SQLite may change the behavior of sqlite3_column_type() +** following a type conversion. +** +** If the result is a BLOB or UTF-8 string then the sqlite3_column_bytes() +** routine returns the number of bytes in that BLOB or string. +** If the result is a UTF-16 string, then sqlite3_column_bytes() converts +** the string to UTF-8 and then returns the number of bytes. +** If the result is a numeric value then sqlite3_column_bytes() uses +** [sqlite3_snprintf()] to convert that value to a UTF-8 string and returns +** the number of bytes in that string. +** The value returned does not include the zero terminator at the end +** of the string. For clarity: the value returned is the number of +** bytes in the string, not the number of characters. +** +** Strings returned by sqlite3_column_text() and sqlite3_column_text16(), +** even zero-length strings, are always zero terminated. The return +** value from sqlite3_column_blob() for a zero-length blob is an arbitrary +** pointer, possibly even a NULL pointer. +** +** The sqlite3_column_bytes16() routine is similar to sqlite3_column_bytes() +** but leaves the result in UTF-16 instead of UTF-8. +** The zero terminator is not included in this count. +** +** These routines attempt to convert the value where appropriate. For +** example, if the internal representation is FLOAT and a text result +** is requested, [sqlite3_snprintf()] is used internally to do the conversion +** automatically. The following table details the conversions that +** are applied: +** +** <blockquote> +** <table border="1"> +** <tr><th> Internal<br>Type <th> Requested<br>Type <th> Conversion +** +** <tr><td> NULL <td> INTEGER <td> Result is 0 +** <tr><td> NULL <td> FLOAT <td> Result is 0.0 +** <tr><td> NULL <td> TEXT <td> Result is NULL pointer +** <tr><td> NULL <td> BLOB <td> Result is NULL pointer +** <tr><td> INTEGER <td> FLOAT <td> Convert from integer to float +** <tr><td> INTEGER <td> TEXT <td> ASCII rendering of the integer +** <tr><td> INTEGER <td> BLOB <td> Same as for INTEGER->TEXT +** <tr><td> FLOAT <td> INTEGER <td> Convert from float to integer +** <tr><td> FLOAT <td> TEXT <td> ASCII rendering of the float +** <tr><td> FLOAT <td> BLOB <td> Same as FLOAT->TEXT +** <tr><td> TEXT <td> INTEGER <td> Use atoi() +** <tr><td> TEXT <td> FLOAT <td> Use atof() +** <tr><td> TEXT <td> BLOB <td> No change +** <tr><td> BLOB <td> INTEGER <td> Convert to TEXT then use atoi() +** <tr><td> BLOB <td> FLOAT <td> Convert to TEXT then use atof() +** <tr><td> BLOB <td> TEXT <td> Add a zero terminator if needed +** </table> +** </blockquote> +** +** The table above makes reference to standard C library functions atoi() +** and atof(). SQLite does not really use these functions. It has its +** on equavalent internal routines. The atoi() and atof() names are +** used in the table for brevity and because they are familiar to most +** C programmers. +** +** Note that when type conversions occur, pointers returned by prior +** calls to sqlite3_column_blob(), sqlite3_column_text(), and/or +** sqlite3_column_text16() may be invalidated. +** Type conversions and pointer invalidations might occur +** in the following cases: +** +** <ul> +** <li><p> The initial content is a BLOB and sqlite3_column_text() +** or sqlite3_column_text16() is called. A zero-terminator might +** need to be added to the string.</p></li> +** +** <li><p> The initial content is UTF-8 text and sqlite3_column_bytes16() or +** sqlite3_column_text16() is called. The content must be converted +** to UTF-16.</p></li> +** +** <li><p> The initial content is UTF-16 text and sqlite3_column_bytes() or +** sqlite3_column_text() is called. The content must be converted +** to UTF-8.</p></li> +** </ul> +** +** Conversions between UTF-16be and UTF-16le are always done in place and do +** not invalidate a prior pointer, though of course the content of the buffer +** that the prior pointer points to will have been modified. Other kinds +** of conversion are done in place when it is possible, but sometime it is +** not possible and in those cases prior pointers are invalidated. +** +** The safest and easiest to remember policy is to invoke these routines +** in one of the following ways: +** +** <ul> +** <li>sqlite3_column_text() followed by sqlite3_column_bytes()</li> +** <li>sqlite3_column_blob() followed by sqlite3_column_bytes()</li> +** <li>sqlite3_column_text16() followed by sqlite3_column_bytes16()</li> +** </ul> +** +** In other words, you should call sqlite3_column_text(), sqlite3_column_blob(), +** or sqlite3_column_text16() first to force the result into the desired +** format, then invoke sqlite3_column_bytes() or sqlite3_column_bytes16() to +** find the size of the result. Do not mix call to sqlite3_column_text() or +** sqlite3_column_blob() with calls to sqlite3_column_bytes16(). And do not +** mix calls to sqlite3_column_text16() with calls to sqlite3_column_bytes(). +** +** The pointers returned are valid until a type conversion occurs as +** described above, or until [sqlite3_step()] or [sqlite3_reset()] or +** [sqlite3_finalize()] is called. The memory space used to hold strings +** and blobs is freed automatically. Do <b>not</b> pass the pointers returned +** [sqlite3_column_blob()], [sqlite3_column_text()], etc. into +** [sqlite3_free()]. +** +** If a memory allocation error occurs during the evaluation of any +** of these routines, a default value is returned. The default value +** is either the integer 0, the floating point number 0.0, or a NULL +** pointer. Subsequent calls to [sqlite3_errcode()] will return +** [SQLITE_NOMEM]. +*/ +const void *sqlite3_column_blob(sqlite3_stmt*, int iCol); +int sqlite3_column_bytes(sqlite3_stmt*, int iCol); +int sqlite3_column_bytes16(sqlite3_stmt*, int iCol); +double sqlite3_column_double(sqlite3_stmt*, int iCol); +int sqlite3_column_int(sqlite3_stmt*, int iCol); +sqlite3_int64 sqlite3_column_int64(sqlite3_stmt*, int iCol); +const unsigned char *sqlite3_column_text(sqlite3_stmt*, int iCol); +const void *sqlite3_column_text16(sqlite3_stmt*, int iCol); +int sqlite3_column_type(sqlite3_stmt*, int iCol); +sqlite3_value *sqlite3_column_value(sqlite3_stmt*, int iCol); + +/* +** CAPI3REF: Destroy A Prepared Statement Object +** +** The sqlite3_finalize() function is called to delete a +** [sqlite3_stmt | compiled SQL statement]. If the statement was +** executed successfully, or not executed at all, then SQLITE_OK is returned. +** If execution of the statement failed then an +** [SQLITE_ERROR | error code] or [SQLITE_IOERR_READ | extended error code] +** is returned. +** +** This routine can be called at any point during the execution of the +** [sqlite3_stmt | virtual machine]. If the virtual machine has not +** completed execution when this routine is called, that is like +** encountering an error or an interrupt. (See [sqlite3_interrupt()].) +** Incomplete updates may be rolled back and transactions cancelled, +** depending on the circumstances, and the +** [SQLITE_ERROR | result code] returned will be [SQLITE_ABORT]. +*/ +int sqlite3_finalize(sqlite3_stmt *pStmt); + +/* +** CAPI3REF: Reset A Prepared Statement Object +** +** The sqlite3_reset() function is called to reset a +** [sqlite3_stmt | compiled SQL statement] object. +** back to it's initial state, ready to be re-executed. +** Any SQL statement variables that had values bound to them using +** the [sqlite3_bind_blob | sqlite3_bind_*() API] retain their values. +** Use [sqlite3_clear_bindings()] to reset the bindings. +*/ +int sqlite3_reset(sqlite3_stmt *pStmt); + +/* +** CAPI3REF: Create Or Redefine SQL Functions +** +** The following two functions are used to add SQL functions or aggregates +** or to redefine the behavior of existing SQL functions or aggregates. The +** difference only between the two is that the second parameter, the +** name of the (scalar) function or aggregate, is encoded in UTF-8 for +** sqlite3_create_function() and UTF-16 for sqlite3_create_function16(). +** +** The first argument is the [sqlite3 | database handle] that holds the +** SQL function or aggregate is to be added or redefined. If a single +** program uses more than one database handle internally, then SQL +** functions or aggregates must be added individually to each database +** handle with which they will be used. +** +** The second parameter is the name of the SQL function to be created +** or redefined. +** The length of the name is limited to 255 bytes, exclusive of the +** zero-terminator. Note that the name length limit is in bytes, not +** characters. Any attempt to create a function with a longer name +** will result in an SQLITE_ERROR error. +** +** The third parameter is the number of arguments that the SQL function or +** aggregate takes. If this parameter is negative, then the SQL function or +** aggregate may take any number of arguments. +** +** The fourth parameter, eTextRep, specifies what +** [SQLITE_UTF8 | text encoding] this SQL function prefers for +** its parameters. Any SQL function implementation should be able to work +** work with UTF-8, UTF-16le, or UTF-16be. But some implementations may be +** more efficient with one encoding than another. It is allowed to +** invoke sqlite3_create_function() or sqlite3_create_function16() multiple +** times with the same function but with different values of eTextRep. +** When multiple implementations of the same function are available, SQLite +** will pick the one that involves the least amount of data conversion. +** If there is only a single implementation which does not care what +** text encoding is used, then the fourth argument should be +** [SQLITE_ANY]. +** +** The fifth parameter is an arbitrary pointer. The implementation +** of the function can gain access to this pointer using +** [sqlite3_user_data()]. +** +** The seventh, eighth and ninth parameters, xFunc, xStep and xFinal, are +** pointers to C-language functions that implement the SQL +** function or aggregate. A scalar SQL function requires an implementation of +** the xFunc callback only, NULL pointers should be passed as the xStep +** and xFinal parameters. An aggregate SQL function requires an implementation +** of xStep and xFinal and NULL should be passed for xFunc. To delete an +** existing SQL function or aggregate, pass NULL for all three function +** callback. +** +** It is permitted to register multiple implementations of the same +** functions with the same name but with either differing numbers of +** arguments or differing perferred text encodings. SQLite will use +** the implementation most closely matches the way in which the +** SQL function is used. +*/ +int sqlite3_create_function( + sqlite3 *, + const char *zFunctionName, + int nArg, + int eTextRep, + void*, + void (*xFunc)(sqlite3_context*,int,sqlite3_value**), + void (*xStep)(sqlite3_context*,int,sqlite3_value**), + void (*xFinal)(sqlite3_context*) +); +int sqlite3_create_function16( + sqlite3*, + const void *zFunctionName, + int nArg, + int eTextRep, + void*, + void (*xFunc)(sqlite3_context*,int,sqlite3_value**), + void (*xStep)(sqlite3_context*,int,sqlite3_value**), + void (*xFinal)(sqlite3_context*) +); + +/* +** CAPI3REF: Text Encodings +** +** These constant define integer codes that represent the various +** text encodings supported by SQLite. +*/ +#define SQLITE_UTF8 1 +#define SQLITE_UTF16LE 2 +#define SQLITE_UTF16BE 3 +#define SQLITE_UTF16 4 /* Use native byte order */ +#define SQLITE_ANY 5 /* sqlite3_create_function only */ +#define SQLITE_UTF16_ALIGNED 8 /* sqlite3_create_collation only */ + +/* +** CAPI3REF: Obsolete Functions +** +** These functions are all now obsolete. In order to maintain +** backwards compatibility with older code, we continue to support +** these functions. However, new development projects should avoid +** the use of these functions. To help encourage people to avoid +** using these functions, we are not going to tell you want they do. +*/ +int sqlite3_aggregate_count(sqlite3_context*); +int sqlite3_expired(sqlite3_stmt*); +int sqlite3_transfer_bindings(sqlite3_stmt*, sqlite3_stmt*); +int sqlite3_global_recover(void); +void sqlite3_thread_cleanup(void); +int sqlite3_memory_alarm(void(*)(void*,sqlite3_int64,int),void*,sqlite3_int64); + +/* +** CAPI3REF: Obtaining SQL Function Parameter Values +** +** The C-language implementation of SQL functions and aggregates uses +** this set of interface routines to access the parameter values on +** the function or aggregate. +** +** The xFunc (for scalar functions) or xStep (for aggregates) parameters +** to [sqlite3_create_function()] and [sqlite3_create_function16()] +** define callbacks that implement the SQL functions and aggregates. +** The 4th parameter to these callbacks is an array of pointers to +** [sqlite3_value] objects. There is one [sqlite3_value] object for +** each parameter to the SQL function. These routines are used to +** extract values from the [sqlite3_value] objects. +** +** These routines work just like the corresponding +** [sqlite3_column_blob | sqlite3_column_* routines] except that +** these routines take a single [sqlite3_value*] pointer instead +** of an [sqlite3_stmt*] pointer and an integer column number. +** +** The sqlite3_value_text16() interface extracts a UTF16 string +** in the native byte-order of the host machine. The +** sqlite3_value_text16be() and sqlite3_value_text16le() interfaces +** extract UTF16 strings as big-endian and little-endian respectively. +** +** The sqlite3_value_numeric_type() interface attempts to apply +** numeric affinity to the value. This means that an attempt is +** made to convert the value to an integer or floating point. If +** such a conversion is possible without loss of information (in order +** words if the value is original a string that looks like a number) +** then it is done. Otherwise no conversion occurs. The +** [SQLITE_INTEGER | datatype] after conversion is returned. +** +** Please pay particular attention to the fact that the pointer that +** is returned from [sqlite3_value_blob()], [sqlite3_value_text()], or +** [sqlite3_value_text16()] can be invalidated by a subsequent call to +** [sqlite3_value_bytes()], [sqlite3_value_bytes16()], [sqlite3_value_text()], +** or [sqlite3_value_text16()]. +** +** These routines must be called from the same thread as +** the SQL function that supplied the sqlite3_value* parameters. +** Or, if the sqlite3_value* argument comes from the [sqlite3_column_value()] +** interface, then these routines should be called from the same thread +** that ran [sqlite3_column_value()]. +*/ +const void *sqlite3_value_blob(sqlite3_value*); +int sqlite3_value_bytes(sqlite3_value*); +int sqlite3_value_bytes16(sqlite3_value*); +double sqlite3_value_double(sqlite3_value*); +int sqlite3_value_int(sqlite3_value*); +sqlite3_int64 sqlite3_value_int64(sqlite3_value*); +const unsigned char *sqlite3_value_text(sqlite3_value*); +const void *sqlite3_value_text16(sqlite3_value*); +const void *sqlite3_value_text16le(sqlite3_value*); +const void *sqlite3_value_text16be(sqlite3_value*); +int sqlite3_value_type(sqlite3_value*); +int sqlite3_value_numeric_type(sqlite3_value*); + +/* +** CAPI3REF: Obtain Aggregate Function Context +** +** The implementation of aggregate SQL functions use this routine to allocate +** a structure for storing their state. The first time this routine +** is called for a particular aggregate, a new structure of size nBytes +** is allocated, zeroed, and returned. On subsequent calls (for the +** same aggregate instance) the same buffer is returned. The implementation +** of the aggregate can use the returned buffer to accumulate data. +** +** The buffer allocated is freed automatically by SQLite whan the aggregate +** query concludes. +** +** The first parameter should be a copy of the +** [sqlite3_context | SQL function context] that is the first +** parameter to the callback routine that implements the aggregate +** function. +** +** This routine must be called from the same thread in which +** the aggregate SQL function is running. +*/ +void *sqlite3_aggregate_context(sqlite3_context*, int nBytes); + +/* +** CAPI3REF: User Data For Functions +** +** The pUserData parameter to the [sqlite3_create_function()] +** and [sqlite3_create_function16()] routines +** used to register user functions is available to +** the implementation of the function using this call. +** +** This routine must be called from the same thread in which +** the SQL function is running. +*/ +void *sqlite3_user_data(sqlite3_context*); + +/* +** CAPI3REF: Function Auxiliary Data +** +** The following two functions may be used by scalar SQL functions to +** associate meta-data with argument values. If the same value is passed to +** multiple invocations of the same SQL function during query execution, under +** some circumstances the associated meta-data may be preserved. This may +** be used, for example, to add a regular-expression matching scalar +** function. The compiled version of the regular expression is stored as +** meta-data associated with the SQL value passed as the regular expression +** pattern. The compiled regular expression can be reused on multiple +** invocations of the same function so that the original pattern string +** does not need to be recompiled on each invocation. +** +** The sqlite3_get_auxdata() interface returns a pointer to the meta-data +** associated with the Nth argument value to the current SQL function +** call, where N is the second parameter. If no meta-data has been set for +** that value, then a NULL pointer is returned. +** +** The sqlite3_set_auxdata() is used to associate meta-data with an SQL +** function argument. The third parameter is a pointer to the meta-data +** to be associated with the Nth user function argument value. The fourth +** parameter specifies a destructor that will be called on the meta- +** data pointer to release it when it is no longer required. If the +** destructor is NULL, it is not invoked. +** +** In practice, meta-data is preserved between function calls for +** expressions that are constant at compile time. This includes literal +** values and SQL variables. +** +** These routines must be called from the same thread in which +** the SQL function is running. +*/ +void *sqlite3_get_auxdata(sqlite3_context*, int); +void sqlite3_set_auxdata(sqlite3_context*, int, void*, void (*)(void*)); + + +/* +** CAPI3REF: Constants Defining Special Destructor Behavior +** +** These are special value for the destructor that is passed in as the +** final argument to routines like [sqlite3_result_blob()]. If the destructor +** argument is SQLITE_STATIC, it means that the content pointer is constant +** and will never change. It does not need to be destroyed. The +** SQLITE_TRANSIENT value means that the content will likely change in +** the near future and that SQLite should make its own private copy of +** the content before returning. +** +** The typedef is necessary to work around problems in certain +** C++ compilers. See ticket #2191. +*/ +typedef void (*sqlite3_destructor_type)(void*); +#define SQLITE_STATIC ((sqlite3_destructor_type)0) +#define SQLITE_TRANSIENT ((sqlite3_destructor_type)-1) + +/* +** CAPI3REF: Setting The Result Of An SQL Function +** +** These routines are used by the xFunc or xFinal callbacks that +** implement SQL functions and aggregates. See +** [sqlite3_create_function()] and [sqlite3_create_function16()] +** for additional information. +** +** These functions work very much like the +** [sqlite3_bind_blob | sqlite3_bind_*] family of functions used +** to bind values to host parameters in prepared statements. +** Refer to the +** [sqlite3_bind_blob | sqlite3_bind_* documentation] for +** additional information. +** +** The sqlite3_result_error() and sqlite3_result_error16() functions +** cause the implemented SQL function to throw an exception. The +** parameter to sqlite3_result_error() or sqlite3_result_error16() +** is the text of an error message. +** +** The sqlite3_result_toobig() cause the function implementation +** to throw and error indicating that a string or BLOB is to long +** to represent. +** +** These routines must be called from within the same thread as +** the SQL function associated with the [sqlite3_context] pointer. +*/ +void sqlite3_result_blob(sqlite3_context*, const void*, int, void(*)(void*)); +void sqlite3_result_double(sqlite3_context*, double); +void sqlite3_result_error(sqlite3_context*, const char*, int); +void sqlite3_result_error16(sqlite3_context*, const void*, int); +void sqlite3_result_error_toobig(sqlite3_context*); +void sqlite3_result_error_nomem(sqlite3_context*); +void sqlite3_result_int(sqlite3_context*, int); +void sqlite3_result_int64(sqlite3_context*, sqlite3_int64); +void sqlite3_result_null(sqlite3_context*); +void sqlite3_result_text(sqlite3_context*, const char*, int, void(*)(void*)); +void sqlite3_result_text16(sqlite3_context*, const void*, int, void(*)(void*)); +void sqlite3_result_text16le(sqlite3_context*, const void*, int,void(*)(void*)); +void sqlite3_result_text16be(sqlite3_context*, const void*, int,void(*)(void*)); +void sqlite3_result_value(sqlite3_context*, sqlite3_value*); +void sqlite3_result_zeroblob(sqlite3_context*, int n); + +/* +** CAPI3REF: Define New Collating Sequences +** +** These functions are used to add new collation sequences to the +** [sqlite3*] handle specified as the first argument. +** +** The name of the new collation sequence is specified as a UTF-8 string +** for sqlite3_create_collation() and sqlite3_create_collation_v2() +** and a UTF-16 string for sqlite3_create_collation16(). In all cases +** the name is passed as the second function argument. +** +** The third argument may be one of the constants [SQLITE_UTF8], +** [SQLITE_UTF16LE] or [SQLITE_UTF16BE], indicating that the user-supplied +** routine expects to be passed pointers to strings encoded using UTF-8, +** UTF-16 little-endian or UTF-16 big-endian respectively. The +** third argument might also be [SQLITE_UTF16_ALIGNED] to indicate that +** the routine expects pointers to 16-bit word aligned strings +** of UTF16 in the native byte order of the host computer. +** +** A pointer to the user supplied routine must be passed as the fifth +** argument. If it is NULL, this is the same as deleting the collation +** sequence (so that SQLite cannot call it anymore). Each time the user +** supplied function is invoked, it is passed a copy of the void* passed as +** the fourth argument to sqlite3_create_collation() or +** sqlite3_create_collation16() as its first parameter. +** +** The remaining arguments to the user-supplied routine are two strings, +** each represented by a [length, data] pair and encoded in the encoding +** that was passed as the third argument when the collation sequence was +** registered. The user routine should return negative, zero or positive if +** the first string is less than, equal to, or greater than the second +** string. i.e. (STRING1 - STRING2). +** +** The sqlite3_create_collation_v2() works like sqlite3_create_collation() +** excapt that it takes an extra argument which is a destructor for +** the collation. The destructor is called when the collation is +** destroyed and is passed a copy of the fourth parameter void* pointer +** of the sqlite3_create_collation_v2(). Collations are destroyed when +** they are overridden by later calls to the collation creation functions +** or when the [sqlite3*] database handle is closed using [sqlite3_close()]. +** +** The sqlite3_create_collation_v2() interface is experimental and +** subject to change in future releases. The other collation creation +** functions are stable. +*/ +int sqlite3_create_collation( + sqlite3*, + const char *zName, + int eTextRep, + void*, + int(*xCompare)(void*,int,const void*,int,const void*) +); +int sqlite3_create_collation_v2( + sqlite3*, + const char *zName, + int eTextRep, + void*, + int(*xCompare)(void*,int,const void*,int,const void*), + void(*xDestroy)(void*) +); +int sqlite3_create_collation16( + sqlite3*, + const char *zName, + int eTextRep, + void*, + int(*xCompare)(void*,int,const void*,int,const void*) +); + +/* +** CAPI3REF: 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 handle to be called whenever an undefined collation sequence is +** required. +** +** If the function is registered using the sqlite3_collation_needed() API, +** then it is passed the names of undefined collation sequences as strings +** encoded in UTF-8. If sqlite3_collation_needed16() is used, the names +** are passed as UTF-16 in machine native byte order. A call to either +** function replaces any existing callback. +** +** When the callback is invoked, the first argument passed is a copy +** of the second argument to sqlite3_collation_needed() or +** sqlite3_collation_needed16(). The second argument is the database +** handle. The third argument is one of [SQLITE_UTF8], [SQLITE_UTF16BE], or +** [SQLITE_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 +** [sqlite3_create_collation()], [sqlite3_create_collation16()], or +** [sqlite3_create_collation_v2()]. +*/ +int sqlite3_collation_needed( + sqlite3*, + void*, + void(*)(void*,sqlite3*,int eTextRep,const char*) +); +int sqlite3_collation_needed16( + sqlite3*, + void*, + void(*)(void*,sqlite3*,int eTextRep,const void*) +); + +/* +** Specify the key for an encrypted database. This routine should be +** called right after sqlite3_open(). +** +** The code to implement this API is not available in the public release +** of SQLite. +*/ +int sqlite3_key( + sqlite3 *db, /* Database to be rekeyed */ + const void *pKey, int nKey /* The key */ +); + +/* +** Change the key on an open database. If the current database is not +** encrypted, this routine will encrypt it. If pNew==0 or nNew==0, the +** database is decrypted. +** +** The code to implement this API is not available in the public release +** of SQLite. +*/ +int sqlite3_rekey( + sqlite3 *db, /* Database to be rekeyed */ + const void *pKey, int nKey /* The new key */ +); + +/* +** CAPI3REF: Suspend Execution For A Short Time +** +** This function causes the current thread to suspend execution +** a number of milliseconds specified in its parameter. +** +** If the operating system does not support sleep requests with +** millisecond time resolution, then the time will be rounded up to +** the nearest second. The number of milliseconds of sleep actually +** requested from the operating system is returned. +** +** SQLite implements this interface by calling the xSleep() +** method of the default [sqlite3_vfs] object. +*/ +int sqlite3_sleep(int); + +/* +** CAPI3REF: Name Of The Folder Holding Temporary Files +** +** If this global variable is made to point to a string which is +** the name of a folder (a.ka. directory), then all temporary files +** created by SQLite will be placed in that directory. If this variable +** is NULL pointer, then SQLite does a search for an appropriate temporary +** file directory. +** +** It is not safe to modify this variable once a database connection +** has been opened. It is intended that this variable be set once +** as part of process initialization and before any SQLite interface +** routines have been call and remain unchanged thereafter. +*/ +SQLITE_EXTERN char *sqlite3_temp_directory; + +/* +** CAPI3REF: Test To See If The Database Is In Auto-Commit Mode +** +** Test to see whether or not the database connection is in autocommit +** mode. Return TRUE if it is and FALSE if not. Autocommit mode is on +** by default. Autocommit is disabled by a BEGIN statement and reenabled +** by the next COMMIT or ROLLBACK. +** +** If certain kinds of errors occur on a statement within a multi-statement +** transactions (errors including [SQLITE_FULL], [SQLITE_IOERR], +** [SQLITE_NOMEM], [SQLITE_BUSY], and [SQLITE_INTERRUPT]) then the +** transaction might be rolled back automatically. The only way to +** find out if SQLite automatically rolled back the transaction after +** an error is to use this function. +** +** If another thread changes the autocommit status of the database +** connection while this routine is running, then the return value +** is undefined. +*/ +int sqlite3_get_autocommit(sqlite3*); + +/* +** CAPI3REF: Find The Database Handle Associated With A Prepared Statement +** +** Return the [sqlite3*] database handle to which a +** [sqlite3_stmt | prepared statement] belongs. +** This is the same database handle that was +** the first argument to the [sqlite3_prepare_v2()] or its variants +** that was used to create the statement in the first place. +*/ +sqlite3 *sqlite3_db_handle(sqlite3_stmt*); + + +/* +** CAPI3REF: Commit And Rollback Notification Callbacks +** +** These routines +** register callback functions to be invoked whenever a transaction +** is committed or rolled back. The pArg argument is passed through +** to the callback. If the callback on a commit hook function +** returns non-zero, then the commit is converted into a rollback. +** +** If another function was previously registered, its pArg value is returned. +** Otherwise NULL is returned. +** +** Registering a NULL function disables the callback. +** +** For the purposes of this API, a transaction is said to have been +** rolled back if an explicit "ROLLBACK" statement is executed, or +** an error or constraint causes an implicit rollback to occur. The +** callback is not invoked if a transaction is automatically rolled +** back because the database connection is closed. +** +** These are experimental interfaces and are subject to change. +*/ +void *sqlite3_commit_hook(sqlite3*, int(*)(void*), void*); +void *sqlite3_rollback_hook(sqlite3*, void(*)(void *), void*); + +/* +** CAPI3REF: Data Change Notification Callbacks +** +** Register a callback function with the database connection identified by the +** first argument to be invoked whenever a row is updated, inserted or deleted. +** Any callback set by a previous call to this function for the same +** database connection is overridden. +** +** The second argument is a pointer to the function to invoke when a +** row is updated, inserted or deleted. The first argument to the callback is +** a copy of the third argument to sqlite3_update_hook(). The second callback +** argument is one of SQLITE_INSERT, SQLITE_DELETE or SQLITE_UPDATE, depending +** on the operation that caused the callback to be invoked. The third and +** fourth arguments to the callback contain pointers to the database and +** table name containing the affected row. The final callback parameter is +** the rowid of the row. In the case of an update, this is the rowid after +** the update takes place. +** +** The update hook is not invoked when internal system tables are +** modified (i.e. sqlite_master and sqlite_sequence). +** +** If another function was previously registered, its pArg value is returned. +** Otherwise NULL is returned. +*/ +void *sqlite3_update_hook( + sqlite3*, + void(*)(void *,int ,char const *,char const *,sqlite3_int64), + void* +); + +/* +** CAPI3REF: Enable Or Disable Shared Pager Cache +** +** This routine enables or disables the sharing of the database cache +** and schema data structures between connections to the same database. +** Sharing is enabled if the argument is true and disabled if the argument +** is false. +** +** Beginning in SQLite version 3.5.0, cache sharing is enabled and disabled +** for an entire process. In prior versions of SQLite, sharing was +** enabled or disabled for each thread separately. +** +** The cache sharing mode set by this interface effects all subsequent +** calls to [sqlite3_open()], [sqlite3_open_v2()], and [sqlite3_open16()]. +** Existing database connections continue use the sharing mode that was +** in effect at the time they were opened. +** +** Virtual tables cannot be used with a shared cache. When shared +** cache is enabled, the [sqlite3_create_module()] API used to register +** virtual tables will always return an error. +** +** This routine returns [SQLITE_OK] if shared cache was +** enabled or disabled successfully. An [SQLITE_ERROR | error code] +** is returned otherwise. +** +** Shared cache is disabled by default. But this might change in +** future releases of SQLite. Applications that care about shared +** cache setting should set it explicitly. +*/ +int sqlite3_enable_shared_cache(int); + +/* +** CAPI3REF: Attempt To Free Heap Memory +** +** Attempt to free N bytes of heap memory by deallocating non-essential +** memory allocations held by the database library (example: memory +** used to cache database pages to improve performance). +*/ +int sqlite3_release_memory(int); + +/* +** CAPI3REF: Impose A Limit On Heap Size +** +** Place a "soft" limit on the amount of heap memory that may be allocated +** by SQLite. If an internal allocation is requested +** that would exceed the specified limit, [sqlite3_release_memory()] is +** invoked one or more times to free up some space before the allocation +** is made. +** +** The limit is called "soft", because if [sqlite3_release_memory()] cannot +** free sufficient memory to prevent the limit from being exceeded, +** the memory is allocated anyway and the current operation proceeds. +** +** A negative or zero value for N means that there is no soft heap limit and +** [sqlite3_release_memory()] will only be called when memory is exhausted. +** The default value for the soft heap limit is zero. +** +** SQLite makes a best effort to honor the soft heap limit. But if it +** is unable to reduce memory usage below the soft limit, execution will +** continue without error or notification. This is why the limit is +** called a "soft" limit. It is advisory only. +** +** Prior to SQLite version 3.5.0, this routine only constrained the memory +** allocated by a single thread - the same thread in which this routine +** runs. Beginning with SQLite version 3.5.0, the soft heap limit is +** applied to all threads. The value specified for the soft heap limit +** is an upper bound on the total memory allocation for all threads. In +** version 3.5.0 there is no mechanism for limiting the heap usage for +** individual threads. +*/ +void sqlite3_soft_heap_limit(int); + +/* +** CAPI3REF: Extract Metadata About A Column Of A Table +** +** This routine +** returns meta-data about a specific column of a specific database +** table accessible using the connection handle passed as the first function +** argument. +** +** The column is identified by the second, third and fourth parameters to +** this function. The second parameter is either the name of the database +** (i.e. "main", "temp" or an attached database) containing the specified +** table or NULL. If it is NULL, then all attached databases are searched +** for the table using the same algorithm as the database engine uses to +** resolve unqualified table references. +** +** The third and fourth parameters to this function are the table and column +** name of the desired column, respectively. Neither of these parameters +** may be NULL. +** +** Meta information is returned by writing to the memory locations passed as +** the 5th and subsequent parameters to this function. Any of these +** arguments may be NULL, in which case the corresponding element of meta +** information is ommitted. +** +** <pre> +** Parameter Output Type Description +** ----------------------------------- +** +** 5th const char* Data type +** 6th const char* Name of the default collation sequence +** 7th int True if the column has a NOT NULL constraint +** 8th int True if the column is part of the PRIMARY KEY +** 9th int True if the column is AUTOINCREMENT +** </pre> +** +** +** The memory pointed to by the character pointers returned for the +** declaration type and collation sequence is valid only until the next +** call to any sqlite API function. +** +** If the specified table is actually a view, then an error is returned. +** +** If the specified column is "rowid", "oid" or "_rowid_" and an +** INTEGER PRIMARY KEY column has been explicitly declared, then the output +** parameters are set for the explicitly declared column. If there is no +** explicitly declared IPK column, then the output parameters are set as +** follows: +** +** <pre> +** data type: "INTEGER" +** collation sequence: "BINARY" +** not null: 0 +** primary key: 1 +** auto increment: 0 +** </pre> +** +** This function may load one or more schemas from database files. If an +** error occurs during this process, or if the requested table or column +** cannot be found, an SQLITE error code is returned and an error message +** left in the database handle (to be retrieved using sqlite3_errmsg()). +** +** This API is only available if the library was compiled with the +** SQLITE_ENABLE_COLUMN_METADATA preprocessor symbol defined. +*/ +int sqlite3_table_column_metadata( + sqlite3 *db, /* Connection handle */ + const char *zDbName, /* Database name or NULL */ + const char *zTableName, /* Table name */ + const char *zColumnName, /* Column name */ + char const **pzDataType, /* OUTPUT: Declared data type */ + char const **pzCollSeq, /* OUTPUT: Collation sequence name */ + int *pNotNull, /* OUTPUT: True if NOT NULL constraint exists */ + int *pPrimaryKey, /* OUTPUT: True if column part of PK */ + int *pAutoinc /* OUTPUT: True if column is auto-increment */ +); + +/* +** CAPI3REF: Load An Extension +** +** Attempt to load an SQLite extension library contained in the file +** zFile. The entry point is zProc. zProc may be 0 in which case the +** name of the entry point defaults to "sqlite3_extension_init". +** +** Return [SQLITE_OK] on success and [SQLITE_ERROR] if something goes wrong. +** +** If an error occurs and pzErrMsg is not 0, then fill *pzErrMsg with +** error message text. The calling function should free this memory +** by calling [sqlite3_free()]. +** +** Extension loading must be enabled using [sqlite3_enable_load_extension()] +** prior to calling this API or an error will be returned. +*/ +int sqlite3_load_extension( + sqlite3 *db, /* Load the extension into this database connection */ + const char *zFile, /* Name of the shared library containing extension */ + const char *zProc, /* Entry point. Derived from zFile if 0 */ + char **pzErrMsg /* Put error message here if not 0 */ +); + +/* +** CAPI3REF: Enable Or Disable Extension Loading +** +** So as not to open security holes in older applications that are +** unprepared to deal with extension loading, and as a means of disabling +** extension loading while evaluating user-entered SQL, the following +** API is provided to turn the [sqlite3_load_extension()] mechanism on and +** off. It is off by default. See ticket #1863. +** +** Call this routine with onoff==1 to turn extension loading on +** and call it with onoff==0 to turn it back off again. +*/ +int sqlite3_enable_load_extension(sqlite3 *db, int onoff); + +/* +** CAPI3REF: Make Arrangements To Automatically Load An Extension +** +** Register an extension entry point that is automatically invoked +** whenever a new database connection is opened using +** [sqlite3_open()], [sqlite3_open16()], or [sqlite3_open_v2()]. +** +** This API can be invoked at program startup in order to register +** one or more statically linked extensions that will be available +** to all new database connections. +** +** Duplicate extensions are detected so calling this routine multiple +** times with the same extension is harmless. +** +** This routine stores a pointer to the extension in an array +** that is obtained from malloc(). If you run a memory leak +** checker on your program and it reports a leak because of this +** array, then invoke [sqlite3_reset_auto_extension()] prior +** to shutdown to free the memory. +** +** Automatic extensions apply across all threads. +** +** This interface is experimental and is subject to change or +** removal in future releases of SQLite. +*/ +int sqlite3_auto_extension(void *xEntryPoint); + + +/* +** CAPI3REF: Reset Automatic Extension Loading +** +** Disable all previously registered automatic extensions. This +** routine undoes the effect of all prior [sqlite3_automatic_extension()] +** calls. +** +** This call disabled automatic extensions in all threads. +** +** This interface is experimental and is subject to change or +** removal in future releases of SQLite. +*/ +void sqlite3_reset_auto_extension(void); + + +/* +****** EXPERIMENTAL - subject to change without notice ************** +** +** The interface to the virtual-table mechanism is currently considered +** to be experimental. The interface might change in incompatible ways. +** If this is a problem for you, do not use the interface at this time. +** +** When the virtual-table mechanism stablizes, we will declare the +** interface fixed, support it indefinitely, and remove this comment. +*/ + +/* +** Structures used by the virtual table interface +*/ +typedef struct sqlite3_vtab sqlite3_vtab; +typedef struct sqlite3_index_info sqlite3_index_info; +typedef struct sqlite3_vtab_cursor sqlite3_vtab_cursor; +typedef struct sqlite3_module sqlite3_module; + +/* +** A module is a class of virtual tables. Each module is defined +** by an instance of the following structure. This structure consists +** mostly of methods for the module. +*/ +struct sqlite3_module { + int iVersion; + int (*xCreate)(sqlite3*, void *pAux, + int argc, const char *const*argv, + sqlite3_vtab **ppVTab, char**); + int (*xConnect)(sqlite3*, void *pAux, + int argc, const char *const*argv, + sqlite3_vtab **ppVTab, char**); + int (*xBestIndex)(sqlite3_vtab *pVTab, sqlite3_index_info*); + int (*xDisconnect)(sqlite3_vtab *pVTab); + int (*xDestroy)(sqlite3_vtab *pVTab); + int (*xOpen)(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor); + int (*xClose)(sqlite3_vtab_cursor*); + int (*xFilter)(sqlite3_vtab_cursor*, int idxNum, const char *idxStr, + int argc, sqlite3_value **argv); + int (*xNext)(sqlite3_vtab_cursor*); + int (*xEof)(sqlite3_vtab_cursor*); + int (*xColumn)(sqlite3_vtab_cursor*, sqlite3_context*, int); + int (*xRowid)(sqlite3_vtab_cursor*, sqlite3_int64 *pRowid); + int (*xUpdate)(sqlite3_vtab *, int, sqlite3_value **, sqlite3_int64 *); + int (*xBegin)(sqlite3_vtab *pVTab); + int (*xSync)(sqlite3_vtab *pVTab); + int (*xCommit)(sqlite3_vtab *pVTab); + int (*xRollback)(sqlite3_vtab *pVTab); + int (*xFindFunction)(sqlite3_vtab *pVtab, int nArg, const char *zName, + void (**pxFunc)(sqlite3_context*,int,sqlite3_value**), + void **ppArg); + + int (*xRename)(sqlite3_vtab *pVtab, const char *zNew); +}; + +/* +** The sqlite3_index_info structure and its substructures is used to +** pass information into and receive the reply from the xBestIndex +** method of an sqlite3_module. The fields under **Inputs** are the +** inputs to xBestIndex and are read-only. xBestIndex inserts its +** results into the **Outputs** fields. +** +** The aConstraint[] array records WHERE clause constraints of the +** form: +** +** column OP expr +** +** Where OP is =, <, <=, >, or >=. The particular operator is stored +** in aConstraint[].op. The index of the column is stored in +** aConstraint[].iColumn. aConstraint[].usable is TRUE if the +** expr on the right-hand side can be evaluated (and thus the constraint +** is usable) and false if it cannot. +** +** The optimizer automatically inverts terms of the form "expr OP column" +** and makes other simplifications to the WHERE clause in an attempt to +** get as many WHERE clause terms into the form shown above as possible. +** The aConstraint[] array only reports WHERE clause terms in the correct +** form that refer to the particular virtual table being queried. +** +** Information about the ORDER BY clause is stored in aOrderBy[]. +** Each term of aOrderBy records a column of the ORDER BY clause. +** +** The xBestIndex method must fill aConstraintUsage[] with information +** about what parameters to pass to xFilter. If argvIndex>0 then +** the right-hand side of the corresponding aConstraint[] is evaluated +** and becomes the argvIndex-th entry in argv. If aConstraintUsage[].omit +** is true, then the constraint is assumed to be fully handled by the +** virtual table and is not checked again by SQLite. +** +** The idxNum and idxPtr values are recorded and passed into xFilter. +** sqlite3_free() is used to free idxPtr if needToFreeIdxPtr is true. +** +** The orderByConsumed means that output from xFilter will occur in +** the correct order to satisfy the ORDER BY clause so that no separate +** sorting step is required. +** +** The estimatedCost value is an estimate of the cost of doing the +** particular lookup. A full scan of a table with N entries should have +** a cost of N. A binary search of a table of N entries should have a +** cost of approximately log(N). +*/ +struct sqlite3_index_info { + /* Inputs */ + int nConstraint; /* Number of entries in aConstraint */ + struct sqlite3_index_constraint { + int iColumn; /* Column on left-hand side of constraint */ + unsigned char op; /* Constraint operator */ + unsigned char usable; /* True if this constraint is usable */ + int iTermOffset; /* Used internally - xBestIndex should ignore */ + } *aConstraint; /* Table of WHERE clause constraints */ + int nOrderBy; /* Number of terms in the ORDER BY clause */ + struct sqlite3_index_orderby { + int iColumn; /* Column number */ + unsigned char desc; /* True for DESC. False for ASC. */ + } *aOrderBy; /* The ORDER BY clause */ + + /* Outputs */ + struct sqlite3_index_constraint_usage { + int argvIndex; /* if >0, constraint is part of argv to xFilter */ + unsigned char omit; /* Do not code a test for this constraint */ + } *aConstraintUsage; + int idxNum; /* Number used to identify the index */ + char *idxStr; /* String, possibly obtained from sqlite3_malloc */ + int needToFreeIdxStr; /* Free idxStr using sqlite3_free() if true */ + int orderByConsumed; /* True if output is already ordered */ + double estimatedCost; /* Estimated cost of using this index */ +}; +#define SQLITE_INDEX_CONSTRAINT_EQ 2 +#define SQLITE_INDEX_CONSTRAINT_GT 4 +#define SQLITE_INDEX_CONSTRAINT_LE 8 +#define SQLITE_INDEX_CONSTRAINT_LT 16 +#define SQLITE_INDEX_CONSTRAINT_GE 32 +#define SQLITE_INDEX_CONSTRAINT_MATCH 64 + +/* +** This routine is used to register a new module name with an SQLite +** connection. Module names must be registered before creating new +** virtual tables on the module, or before using preexisting virtual +** tables of the module. +*/ +int sqlite3_create_module( + sqlite3 *db, /* SQLite connection to register module with */ + const char *zName, /* Name of the module */ + const sqlite3_module *, /* Methods for the module */ + void * /* Client data for xCreate/xConnect */ +); + +/* +** This routine is identical to the sqlite3_create_module() method above, +** except that it allows a destructor function to be specified. It is +** even more experimental than the rest of the virtual tables API. +*/ +int sqlite3_create_module_v2( + sqlite3 *db, /* SQLite connection to register module with */ + const char *zName, /* Name of the module */ + const sqlite3_module *, /* Methods for the module */ + void *, /* Client data for xCreate/xConnect */ + void(*xDestroy)(void*) /* Module destructor function */ +); + +/* +** Every module implementation uses a subclass of the following structure +** to describe a particular instance of the module. Each subclass will +** be tailored to the specific needs of the module implementation. The +** purpose of this superclass is to define certain fields that are common +** to all module implementations. +** +** Virtual tables methods can set an error message by assigning a +** string obtained from sqlite3_mprintf() to zErrMsg. The method should +** take care that any prior string is freed by a call to sqlite3_free() +** prior to assigning a new string to zErrMsg. After the error message +** is delivered up to the client application, the string will be automatically +** freed by sqlite3_free() and the zErrMsg field will be zeroed. Note +** that sqlite3_mprintf() and sqlite3_free() are used on the zErrMsg field +** since virtual tables are commonly implemented in loadable extensions which +** do not have access to sqlite3MPrintf() or sqlite3Free(). +*/ +struct sqlite3_vtab { + const sqlite3_module *pModule; /* The module for this virtual table */ + int nRef; /* Used internally */ + char *zErrMsg; /* Error message from sqlite3_mprintf() */ + /* Virtual table implementations will typically add additional fields */ +}; + +/* Every module implementation uses a subclass of the following structure +** to describe cursors that point into the virtual table and are used +** to loop through the virtual table. Cursors are created using the +** xOpen method of the module. Each module implementation will define +** the content of a cursor structure to suit its own needs. +** +** This superclass exists in order to define fields of the cursor that +** are common to all implementations. +*/ +struct sqlite3_vtab_cursor { + sqlite3_vtab *pVtab; /* Virtual table of this cursor */ + /* Virtual table implementations will typically add additional fields */ +}; + +/* +** The xCreate and xConnect methods of a module use the following API +** to declare the format (the names and datatypes of the columns) of +** the virtual tables they implement. +*/ +int sqlite3_declare_vtab(sqlite3*, const char *zCreateTable); + +/* +** Virtual tables can provide alternative implementations of functions +** using the xFindFunction method. But global versions of those functions +** must exist in order to be overloaded. +** +** This API makes sure a global version of a function with a particular +** name and number of parameters exists. If no such function exists +** before this API is called, a new function is created. The implementation +** of the new function always causes an exception to be thrown. So +** the new function is not good for anything by itself. Its only +** purpose is to be a place-holder function that can be overloaded +** by virtual tables. +** +** This API should be considered part of the virtual table interface, +** which is experimental and subject to change. +*/ +int sqlite3_overload_function(sqlite3*, const char *zFuncName, int nArg); + +/* +** The interface to the virtual-table mechanism defined above (back up +** to a comment remarkably similar to this one) is currently considered +** to be experimental. The interface might change in incompatible ways. +** If this is a problem for you, do not use the interface at this time. +** +** When the virtual-table mechanism stabilizes, we will declare the +** interface fixed, support it indefinitely, and remove this comment. +** +****** EXPERIMENTAL - subject to change without notice ************** +*/ + +/* +** CAPI3REF: A Handle To An Open BLOB +** +** An instance of the following opaque structure is used to +** represent an blob-handle. A blob-handle is created by +** [sqlite3_blob_open()] and destroyed by [sqlite3_blob_close()]. +** The [sqlite3_blob_read()] and [sqlite3_blob_write()] interfaces +** can be used to read or write small subsections of the blob. +** The [sqlite3_blob_bytes()] interface returns the size of the +** blob in bytes. +*/ +typedef struct sqlite3_blob sqlite3_blob; + +/* +** CAPI3REF: Open A BLOB For Incremental I/O +** +** Open a handle to the blob located in row iRow,, column zColumn, +** table zTable in database zDb. i.e. the same blob that would +** be selected by: +** +** <pre> +** SELECT zColumn FROM zDb.zTable WHERE rowid = iRow; +** </pre> +** +** If the flags parameter is non-zero, the blob is opened for +** read and write access. If it is zero, the blob is opened for read +** access. +** +** On success, [SQLITE_OK] is returned and the new +** [sqlite3_blob | blob handle] is written to *ppBlob. +** Otherwise an error code is returned and +** any value written to *ppBlob should not be used by the caller. +** This function sets the database-handle error code and message +** accessible via [sqlite3_errcode()] and [sqlite3_errmsg()]. +*/ +int sqlite3_blob_open( + sqlite3*, + const char *zDb, + const char *zTable, + const char *zColumn, + sqlite3_int64 iRow, + int flags, + sqlite3_blob **ppBlob +); + +/* +** CAPI3REF: Close A BLOB Handle +** +** Close an open [sqlite3_blob | blob handle]. +*/ +int sqlite3_blob_close(sqlite3_blob *); + +/* +** CAPI3REF: Return The Size Of An Open BLOB +** +** Return the size in bytes of the blob accessible via the open +** [sqlite3_blob | blob-handle] passed as an argument. +*/ +int sqlite3_blob_bytes(sqlite3_blob *); + +/* +** CAPI3REF: Read Data From A BLOB Incrementally +** +** This function is used to read data from an open +** [sqlite3_blob | blob-handle] into a caller supplied buffer. +** n bytes of data are copied into buffer +** z from the open blob, starting at offset iOffset. +** +** On success, SQLITE_OK is returned. Otherwise, an +** [SQLITE_ERROR | SQLite error code] or an +** [SQLITE_IOERR_READ | extended error code] is returned. +*/ +int sqlite3_blob_read(sqlite3_blob *, void *z, int n, int iOffset); + +/* +** CAPI3REF: Write Data Into A BLOB Incrementally +** +** This function is used to write data into an open +** [sqlite3_blob | blob-handle] from a user supplied buffer. +** n bytes of data are copied from the buffer +** pointed to by z into the open blob, starting at offset iOffset. +** +** If the [sqlite3_blob | blob-handle] passed as the first argument +** was not opened for writing (the flags parameter to [sqlite3_blob_open()] +*** was zero), this function returns [SQLITE_READONLY]. +** +** This function may only modify the contents of the blob, it is +** not possible to increase the size of a blob using this API. If +** offset iOffset is less than n bytes from the end of the blob, +** [SQLITE_ERROR] is returned and no data is written. +** +** On success, SQLITE_OK is returned. Otherwise, an +** [SQLITE_ERROR | SQLite error code] or an +** [SQLITE_IOERR_READ | extended error code] is returned. +*/ +int sqlite3_blob_write(sqlite3_blob *, const void *z, int n, int iOffset); + +/* +** CAPI3REF: Virtual File System Objects +** +** A virtual filesystem (VFS) is an [sqlite3_vfs] object +** that SQLite uses to interact +** with the underlying operating system. Most builds come with a +** single default VFS that is appropriate for the host computer. +** New VFSes can be registered and existing VFSes can be unregistered. +** The following interfaces are provided. +** +** The sqlite3_vfs_find() interface returns a pointer to a VFS given its +** name. Names are case sensitive. If there is no match, a NULL +** pointer is returned. If zVfsName is NULL then the default +** VFS is returned. +** +** New VFSes are registered with sqlite3_vfs_register(). Each +** new VFS becomes the default VFS if the makeDflt flag is set. +** The same VFS can be registered multiple times without injury. +** To make an existing VFS into the default VFS, register it again +** with the makeDflt flag set. If two different VFSes with the +** same name are registered, the behavior is undefined. If a +** VFS is registered with a name that is NULL or an empty string, +** then the behavior is undefined. +** +** Unregister a VFS with the sqlite3_vfs_unregister() interface. +** If the default VFS is unregistered, another VFS is chosen as +** the default. The choice for the new VFS is arbitrary. +*/ +sqlite3_vfs *sqlite3_vfs_find(const char *zVfsName); +int sqlite3_vfs_register(sqlite3_vfs*, int makeDflt); +int sqlite3_vfs_unregister(sqlite3_vfs*); + +/* +** CAPI3REF: Mutexes +** +** The SQLite core uses these routines for thread +** synchronization. Though they are intended for internal +** use by SQLite, code that links against SQLite is +** permitted to use any of these routines. +** +** The SQLite source code contains multiple implementations +** of these mutex routines. An appropriate implementation +** is selected automatically at compile-time. The following +** implementations are available in the SQLite core: +** +** <ul> +** <li> SQLITE_MUTEX_OS2 +** <li> SQLITE_MUTEX_PTHREAD +** <li> SQLITE_MUTEX_W32 +** <li> SQLITE_MUTEX_NOOP +** </ul> +** +** The SQLITE_MUTEX_NOOP implementation is a set of routines +** that does no real locking and is appropriate for use in +** a single-threaded application. The SQLITE_MUTEX_OS2, +** SQLITE_MUTEX_PTHREAD, and SQLITE_MUTEX_W32 implementations +** are appropriate for use on os/2, unix, and windows. +** +** If SQLite is compiled with the SQLITE_MUTEX_APPDEF preprocessor +** macro defined (with "-DSQLITE_MUTEX_APPDEF=1"), then no mutex +** implementation is included with the library. The +** mutex interface routines defined here become external +** references in the SQLite library for which implementations +** must be provided by the application. This facility allows an +** application that links against SQLite to provide its own mutex +** implementation without having to modify the SQLite core. +** +** The sqlite3_mutex_alloc() routine allocates a new +** mutex and returns a pointer to it. If it returns NULL +** that means that a mutex could not be allocated. SQLite +** will unwind its stack and return an error. The argument +** to sqlite3_mutex_alloc() is one of these integer constants: +** +** <ul> +** <li> SQLITE_MUTEX_FAST +** <li> SQLITE_MUTEX_RECURSIVE +** <li> SQLITE_MUTEX_STATIC_MASTER +** <li> SQLITE_MUTEX_STATIC_MEM +** <li> SQLITE_MUTEX_STATIC_MEM2 +** <li> SQLITE_MUTEX_STATIC_PRNG +** <li> SQLITE_MUTEX_STATIC_LRU +** </ul> +** +** The first two constants cause sqlite3_mutex_alloc() to create +** a new mutex. The new mutex is recursive when SQLITE_MUTEX_RECURSIVE +** is used but not necessarily so when SQLITE_MUTEX_FAST is used. +** The mutex implementation does not need to make a distinction +** between SQLITE_MUTEX_RECURSIVE and SQLITE_MUTEX_FAST if it does +** not want to. But SQLite will only request a recursive mutex in +** cases where it really needs one. If a faster non-recursive mutex +** implementation is available on the host platform, the mutex subsystem +** might return such a mutex in response to SQLITE_MUTEX_FAST. +** +** The other allowed parameters to sqlite3_mutex_alloc() each return +** a pointer to a static preexisting mutex. Four static mutexes are +** used by the current version of SQLite. Future versions of SQLite +** may add additional static mutexes. Static mutexes are for internal +** use by SQLite only. Applications that use SQLite mutexes should +** use only the dynamic mutexes returned by SQLITE_MUTEX_FAST or +** SQLITE_MUTEX_RECURSIVE. +** +** Note that if one of the dynamic mutex parameters (SQLITE_MUTEX_FAST +** or SQLITE_MUTEX_RECURSIVE) is used then sqlite3_mutex_alloc() +** returns a different mutex on every call. But for the static +** mutex types, the same mutex is returned on every call that has +** the same type number. +** +** The sqlite3_mutex_free() routine deallocates a previously +** allocated dynamic mutex. SQLite is careful to deallocate every +** dynamic mutex that it allocates. The dynamic mutexes must not be in +** use when they are deallocated. Attempting to deallocate a static +** mutex results in undefined behavior. SQLite never deallocates +** a static mutex. +** +** The sqlite3_mutex_enter() and sqlite3_mutex_try() routines attempt +** to enter a mutex. If another thread is already within the mutex, +** sqlite3_mutex_enter() will block and sqlite3_mutex_try() will return +** SQLITE_BUSY. The sqlite3_mutex_try() interface returns SQLITE_OK +** upon successful entry. Mutexes created using SQLITE_MUTEX_RECURSIVE can +** be entered multiple times by the same thread. In such cases the, +** mutex must be exited an equal number of times before another thread +** can enter. If the same thread tries to enter any other kind of mutex +** more than once, the behavior is undefined. SQLite will never exhibit +** such behavior in its own use of mutexes. +** +** Some systems (ex: windows95) do not the operation implemented by +** sqlite3_mutex_try(). On those systems, sqlite3_mutex_try() will +** always return SQLITE_BUSY. The SQLite core only ever uses +** sqlite3_mutex_try() as an optimization so this is acceptable behavior. +** +** The sqlite3_mutex_leave() routine exits a mutex that was +** previously entered by the same thread. The behavior +** is undefined if the mutex is not currently entered by the +** calling thread or is not currently allocated. SQLite will +** never do either. +** +** See also: [sqlite3_mutex_held()] and [sqlite3_mutex_notheld()]. +*/ +sqlite3_mutex *sqlite3_mutex_alloc(int); +void sqlite3_mutex_free(sqlite3_mutex*); +void sqlite3_mutex_enter(sqlite3_mutex*); +int sqlite3_mutex_try(sqlite3_mutex*); +void sqlite3_mutex_leave(sqlite3_mutex*); + +/* +** CAPI3REF: Mutex Verifcation Routines +** +** The sqlite3_mutex_held() and sqlite3_mutex_notheld() routines +** are intended for use inside assert() statements. The SQLite core +** never uses these routines except inside an assert() and applications +** are advised to follow the lead of the core. The core only +** provides implementations for these routines when it is compiled +** with the SQLITE_DEBUG flag. External mutex implementations +** are only required to provide these routines if SQLITE_DEBUG is +** defined and if NDEBUG is not defined. +** +** These routines should return true if the mutex in their argument +** is held or not held, respectively, by the calling thread. +** +** The implementation is not required to provided versions of these +** routines that actually work. +** If the implementation does not provide working +** versions of these routines, it should at least provide stubs +** that always return true so that one does not get spurious +** assertion failures. +** +** If the argument to sqlite3_mutex_held() is a NULL pointer then +** the routine should return 1. This seems counter-intuitive since +** clearly the mutex cannot be held if it does not exist. But the +** the reason the mutex does not exist is because the build is not +** using mutexes. And we do not want the assert() containing the +** call to sqlite3_mutex_held() to fail, so a non-zero return is +** the appropriate thing to do. The sqlite3_mutex_notheld() +** interface should also return 1 when given a NULL pointer. +*/ +int sqlite3_mutex_held(sqlite3_mutex*); +int sqlite3_mutex_notheld(sqlite3_mutex*); + +/* +** CAPI3REF: Mutex Types +** +** The [sqlite3_mutex_alloc()] interface takes a single argument +** which is one of these integer constants. +*/ +#define SQLITE_MUTEX_FAST 0 +#define SQLITE_MUTEX_RECURSIVE 1 +#define SQLITE_MUTEX_STATIC_MASTER 2 +#define SQLITE_MUTEX_STATIC_MEM 3 /* sqlite3_malloc() */ +#define SQLITE_MUTEX_STATIC_MEM2 4 /* sqlite3_release_memory() */ +#define SQLITE_MUTEX_STATIC_PRNG 5 /* sqlite3_random() */ +#define SQLITE_MUTEX_STATIC_LRU 6 /* lru page list */ + +/* +** CAPI3REF: Low-Level Control Of Database Files +** +** The [sqlite3_file_control()] interface makes a direct call to the +** xFileControl method for the [sqlite3_io_methods] object associated +** with a particular database identified by the second argument. The +** name of the database is the name assigned to the database by the +** <a href="lang_attach.html">ATTACH</a> SQL command that opened the +** database. To control the main database file, use the name "main" +** or a NULL pointer. The third and fourth parameters to this routine +** are passed directly through to the second and third parameters of +** the xFileControl method. The return value of the xFileControl +** method becomes the return value of this routine. +** +** If the second parameter (zDbName) does not match the name of any +** open database file, then SQLITE_ERROR is returned. This error +** code is not remembered and will not be recalled by [sqlite3_errcode()] +** or [sqlite3_errmsg()]. The underlying xFileControl method might +** also return SQLITE_ERROR. There is no way to distinguish between +** an incorrect zDbName and an SQLITE_ERROR return from the underlying +** xFileControl method. +** +** See also: [SQLITE_FCNTL_LOCKSTATE] +*/ +int sqlite3_file_control(sqlite3*, const char *zDbName, int op, void*); + +/* +** Undo the hack that converts floating point types to integer for +** builds on processors without floating point support. +*/ +#ifdef SQLITE_OMIT_FLOATING_POINT +# undef double +#endif + +#if 0 +} /* End of the 'extern "C"' block */ +#endif +#endif + +/************** End of sqlite3.h *********************************************/ +/************** Continuing where we left off in fts3_tokenizer.h *************/ + +/* +** Structures used by the tokenizer interface. When a new tokenizer +** implementation is registered, the caller provides a pointer to +** an sqlite3_tokenizer_module containing pointers to the callback +** functions that make up an implementation. +** +** When an fts3 table is created, it passes any arguments passed to +** the tokenizer clause of the CREATE VIRTUAL TABLE statement to the +** sqlite3_tokenizer_module.xCreate() function of the requested tokenizer +** implementation. The xCreate() function in turn returns an +** sqlite3_tokenizer structure representing the specific tokenizer to +** be used for the fts3 table (customized by the tokenizer clause arguments). +** +** To tokenize an input buffer, the sqlite3_tokenizer_module.xOpen() +** method is called. It returns an sqlite3_tokenizer_cursor object +** that may be used to tokenize a specific input buffer based on +** the tokenization rules supplied by a specific sqlite3_tokenizer +** object. +*/ +typedef struct sqlite3_tokenizer_module sqlite3_tokenizer_module; +typedef struct sqlite3_tokenizer sqlite3_tokenizer; +typedef struct sqlite3_tokenizer_cursor sqlite3_tokenizer_cursor; + +struct sqlite3_tokenizer_module { + + /* + ** Structure version. Should always be set to 0. + */ + int iVersion; + + /* + ** Create a new tokenizer. The values in the argv[] array are the + ** arguments passed to the "tokenizer" clause of the CREATE VIRTUAL + ** TABLE statement that created the fts3 table. For example, if + ** the following SQL is executed: + ** + ** CREATE .. USING fts3( ... , tokenizer <tokenizer-name> arg1 arg2) + ** + ** then argc is set to 2, and the argv[] array contains pointers + ** to the strings "arg1" and "arg2". + ** + ** This method should return either SQLITE_OK (0), or an SQLite error + ** code. If SQLITE_OK is returned, then *ppTokenizer should be set + ** to point at the newly created tokenizer structure. The generic + ** sqlite3_tokenizer.pModule variable should not be initialised by + ** this callback. The caller will do so. + */ + int (*xCreate)( + int argc, /* Size of argv array */ + const char *const*argv, /* Tokenizer argument strings */ + sqlite3_tokenizer **ppTokenizer /* OUT: Created tokenizer */ + ); + + /* + ** Destroy an existing tokenizer. The fts3 module calls this method + ** exactly once for each successful call to xCreate(). + */ + int (*xDestroy)(sqlite3_tokenizer *pTokenizer); + + /* + ** Create a tokenizer cursor to tokenize an input buffer. The caller + ** is responsible for ensuring that the input buffer remains valid + ** until the cursor is closed (using the xClose() method). + */ + int (*xOpen)( + sqlite3_tokenizer *pTokenizer, /* Tokenizer object */ + const char *pInput, int nBytes, /* Input buffer */ + sqlite3_tokenizer_cursor **ppCursor /* OUT: Created tokenizer cursor */ + ); + + /* + ** Destroy an existing tokenizer cursor. The fts3 module calls this + ** method exactly once for each successful call to xOpen(). + */ + int (*xClose)(sqlite3_tokenizer_cursor *pCursor); + + /* + ** Retrieve the next token from the tokenizer cursor pCursor. This + ** method should either return SQLITE_OK and set the values of the + ** "OUT" variables identified below, or SQLITE_DONE to indicate that + ** the end of the buffer has been reached, or an SQLite error code. + ** + ** *ppToken should be set to point at a buffer containing the + ** normalized version of the token (i.e. after any case-folding and/or + ** stemming has been performed). *pnBytes should be set to the length + ** of this buffer in bytes. The input text that generated the token is + ** identified by the byte offsets returned in *piStartOffset and + ** *piEndOffset. + ** + ** The buffer *ppToken is set to point at is managed by the tokenizer + ** implementation. It is only required to be valid until the next call + ** to xNext() or xClose(). + */ + /* TODO(shess) current implementation requires pInput to be + ** nul-terminated. This should either be fixed, or pInput/nBytes + ** should be converted to zInput. + */ + int (*xNext)( + sqlite3_tokenizer_cursor *pCursor, /* Tokenizer cursor */ + const char **ppToken, int *pnBytes, /* OUT: Normalized text for token */ + int *piStartOffset, /* OUT: Byte offset of token in input buffer */ + int *piEndOffset, /* OUT: Byte offset of end of token in input buffer */ + int *piPosition /* OUT: Number of tokens returned before this one */ + ); +}; + +struct sqlite3_tokenizer { + const sqlite3_tokenizer_module *pModule; /* The module for this tokenizer */ + /* Tokenizer implementations will typically add additional fields */ +}; + +struct sqlite3_tokenizer_cursor { + sqlite3_tokenizer *pTokenizer; /* Tokenizer for this cursor. */ + /* Tokenizer implementations will typically add additional fields */ +}; + +#endif /* _FTS3_TOKENIZER_H_ */ + +/************** End of fts3_tokenizer.h **************************************/ +/************** Continuing where we left off in fts3_porter.c ****************/ + +/* +** Class derived from sqlite3_tokenizer +*/ +typedef struct porter_tokenizer { + sqlite3_tokenizer base; /* Base class */ +} porter_tokenizer; + +/* +** Class derived from sqlit3_tokenizer_cursor +*/ +typedef struct porter_tokenizer_cursor { + sqlite3_tokenizer_cursor base; + const char *zInput; /* input we are tokenizing */ + int nInput; /* size of the input */ + int iOffset; /* current position in zInput */ + int iToken; /* index of next token to be returned */ + char *zToken; /* storage for current token */ + int nAllocated; /* space allocated to zToken buffer */ +} porter_tokenizer_cursor; + + +/* Forward declaration */ +static const sqlite3_tokenizer_module porterTokenizerModule; + + +/* +** Create a new tokenizer instance. +*/ +static int porterCreate( + int argc, const char * const *argv, + sqlite3_tokenizer **ppTokenizer +){ + porter_tokenizer *t; + t = (porter_tokenizer *) sqlite3_malloc(sizeof(*t)); + if( t==NULL ) return SQLITE_NOMEM; + memset(t, 0, sizeof(*t)); + *ppTokenizer = &t->base; + return SQLITE_OK; +} + +/* +** Destroy a tokenizer +*/ +static int porterDestroy(sqlite3_tokenizer *pTokenizer){ + sqlite3_free(pTokenizer); + return SQLITE_OK; +} + +/* +** Prepare to begin tokenizing a particular string. The input +** string to be tokenized is zInput[0..nInput-1]. A cursor +** used to incrementally tokenize this string is returned in +** *ppCursor. +*/ +static int porterOpen( + sqlite3_tokenizer *pTokenizer, /* The tokenizer */ + const char *zInput, int nInput, /* String to be tokenized */ + sqlite3_tokenizer_cursor **ppCursor /* OUT: Tokenization cursor */ +){ + porter_tokenizer_cursor *c; + + c = (porter_tokenizer_cursor *) sqlite3_malloc(sizeof(*c)); + if( c==NULL ) return SQLITE_NOMEM; + + c->zInput = zInput; + if( zInput==0 ){ + c->nInput = 0; + }else if( nInput<0 ){ + c->nInput = (int)strlen(zInput); + }else{ + c->nInput = nInput; + } + c->iOffset = 0; /* start tokenizing at the beginning */ + c->iToken = 0; + c->zToken = NULL; /* no space allocated, yet. */ + c->nAllocated = 0; + + *ppCursor = &c->base; + return SQLITE_OK; +} + +/* +** Close a tokenization cursor previously opened by a call to +** porterOpen() above. +*/ +static int porterClose(sqlite3_tokenizer_cursor *pCursor){ + porter_tokenizer_cursor *c = (porter_tokenizer_cursor *) pCursor; + sqlite3_free(c->zToken); + sqlite3_free(c); + return SQLITE_OK; +} +/* +** Vowel or consonant +*/ +static const char cType[] = { + 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, + 1, 1, 1, 2, 1 +}; + +/* +** isConsonant() and isVowel() determine if their first character in +** the string they point to is a consonant or a vowel, according +** to Porter ruls. +** +** A consonate is any letter other than 'a', 'e', 'i', 'o', or 'u'. +** 'Y' is a consonant unless it follows another consonant, +** in which case it is a vowel. +** +** In these routine, the letters are in reverse order. So the 'y' rule +** is that 'y' is a consonant unless it is followed by another +** consonent. +*/ +static int isVowel(const char*); +static int isConsonant(const char *z){ + int j; + char x = *z; + if( x==0 ) return 0; + assert( x>='a' && x<='z' ); + j = cType[x-'a']; + if( j<2 ) return j; + return z[1]==0 || isVowel(z + 1); +} +static int isVowel(const char *z){ + int j; + char x = *z; + if( x==0 ) return 0; + assert( x>='a' && x<='z' ); + j = cType[x-'a']; + if( j<2 ) return 1-j; + return isConsonant(z + 1); +} + +/* +** Let any sequence of one or more vowels be represented by V and let +** C be sequence of one or more consonants. Then every word can be +** represented as: +** +** [C] (VC){m} [V] +** +** In prose: A word is an optional consonant followed by zero or +** vowel-consonant pairs followed by an optional vowel. "m" is the +** number of vowel consonant pairs. This routine computes the value +** of m for the first i bytes of a word. +** +** Return true if the m-value for z is 1 or more. In other words, +** return true if z contains at least one vowel that is followed +** by a consonant. +** +** In this routine z[] is in reverse order. So we are really looking +** for an instance of of a consonant followed by a vowel. +*/ +static int m_gt_0(const char *z){ + while( isVowel(z) ){ z++; } + if( *z==0 ) return 0; + while( isConsonant(z) ){ z++; } + return *z!=0; +} + +/* Like mgt0 above except we are looking for a value of m which is +** exactly 1 +*/ +static int m_eq_1(const char *z){ + while( isVowel(z) ){ z++; } + if( *z==0 ) return 0; + while( isConsonant(z) ){ z++; } + if( *z==0 ) return 0; + while( isVowel(z) ){ z++; } + if( *z==0 ) return 1; + while( isConsonant(z) ){ z++; } + return *z==0; +} + +/* Like mgt0 above except we are looking for a value of m>1 instead +** or m>0 +*/ +static int m_gt_1(const char *z){ + while( isVowel(z) ){ z++; } + if( *z==0 ) return 0; + while( isConsonant(z) ){ z++; } + if( *z==0 ) return 0; + while( isVowel(z) ){ z++; } + if( *z==0 ) return 0; + while( isConsonant(z) ){ z++; } + return *z!=0; +} + +/* +** Return TRUE if there is a vowel anywhere within z[0..n-1] +*/ +static int hasVowel(const char *z){ + while( isConsonant(z) ){ z++; } + return *z!=0; +} + +/* +** Return TRUE if the word ends in a double consonant. +** +** The text is reversed here. So we are really looking at +** the first two characters of z[]. +*/ +static int doubleConsonant(const char *z){ + return isConsonant(z) && z[0]==z[1] && isConsonant(z+1); +} + +/* +** Return TRUE if the word ends with three letters which +** are consonant-vowel-consonent and where the final consonant +** is not 'w', 'x', or 'y'. +** +** The word is reversed here. So we are really checking the +** first three letters and the first one cannot be in [wxy]. +*/ +static int star_oh(const char *z){ + return + z[0]!=0 && isConsonant(z) && + z[0]!='w' && z[0]!='x' && z[0]!='y' && + z[1]!=0 && isVowel(z+1) && + z[2]!=0 && isConsonant(z+2); +} + +/* +** If the word ends with zFrom and xCond() is true for the stem +** of the word that preceeds the zFrom ending, then change the +** ending to zTo. +** +** The input word *pz and zFrom are both in reverse order. zTo +** is in normal order. +** +** Return TRUE if zFrom matches. Return FALSE if zFrom does not +** match. Not that TRUE is returned even if xCond() fails and +** no substitution occurs. +*/ +static int stem( + char **pz, /* The word being stemmed (Reversed) */ + const char *zFrom, /* If the ending matches this... (Reversed) */ + const char *zTo, /* ... change the ending to this (not reversed) */ + int (*xCond)(const char*) /* Condition that must be true */ +){ + char *z = *pz; + while( *zFrom && *zFrom==*z ){ z++; zFrom++; } + if( *zFrom!=0 ) return 0; + if( xCond && !xCond(z) ) return 1; + while( *zTo ){ + *(--z) = *(zTo++); + } + *pz = z; + return 1; +} + +/* +** This is the fallback stemmer used when the porter stemmer is +** inappropriate. The input word is copied into the output with +** US-ASCII case folding. If the input word is too long (more +** than 20 bytes if it contains no digits or more than 6 bytes if +** it contains digits) then word is truncated to 20 or 6 bytes +** by taking 10 or 3 bytes from the beginning and end. +*/ +static void copy_stemmer(const char *zIn, int nIn, char *zOut, int *pnOut){ + int i, mx, j; + int hasDigit = 0; + for(i=0; i<nIn; i++){ + int c = zIn[i]; + if( c>='A' && c<='Z' ){ + zOut[i] = c - 'A' + 'a'; + }else{ + if( c>='0' && c<='9' ) hasDigit = 1; + zOut[i] = c; + } + } + mx = hasDigit ? 3 : 10; + if( nIn>mx*2 ){ + for(j=mx, i=nIn-mx; i<nIn; i++, j++){ + zOut[j] = zOut[i]; + } + i = j; + } + zOut[i] = 0; + *pnOut = i; +} + + +/* +** Stem the input word zIn[0..nIn-1]. Store the output in zOut. +** zOut is at least big enough to hold nIn bytes. Write the actual +** size of the output word (exclusive of the '\0' terminator) into *pnOut. +** +** Any upper-case characters in the US-ASCII character set ([A-Z]) +** are converted to lower case. Upper-case UTF characters are +** unchanged. +** +** Words that are longer than about 20 bytes are stemmed by retaining +** a few bytes from the beginning and the end of the word. If the +** word contains digits, 3 bytes are taken from the beginning and +** 3 bytes from the end. For long words without digits, 10 bytes +** are taken from each end. US-ASCII case folding still applies. +** +** If the input word contains not digits but does characters not +** in [a-zA-Z] then no stemming is attempted and this routine just +** copies the input into the input into the output with US-ASCII +** case folding. +** +** Stemming never increases the length of the word. So there is +** no chance of overflowing the zOut buffer. +*/ +static void porter_stemmer(const char *zIn, int nIn, char *zOut, int *pnOut){ + int i, j, c; + char zReverse[28]; + char *z, *z2; + if( nIn<3 || nIn>=sizeof(zReverse)-7 ){ + /* The word is too big or too small for the porter stemmer. + ** Fallback to the copy stemmer */ + copy_stemmer(zIn, nIn, zOut, pnOut); + return; + } + for(i=0, j=sizeof(zReverse)-6; i<nIn; i++, j--){ + c = zIn[i]; + if( c>='A' && c<='Z' ){ + zReverse[j] = c + 'a' - 'A'; + }else if( c>='a' && c<='z' ){ + zReverse[j] = c; + }else{ + /* The use of a character not in [a-zA-Z] means that we fallback + ** to the copy stemmer */ + copy_stemmer(zIn, nIn, zOut, pnOut); + return; + } + } + memset(&zReverse[sizeof(zReverse)-5], 0, 5); + z = &zReverse[j+1]; + + + /* Step 1a */ + if( z[0]=='s' ){ + if( + !stem(&z, "sess", "ss", 0) && + !stem(&z, "sei", "i", 0) && + !stem(&z, "ss", "ss", 0) + ){ + z++; + } + } + + /* Step 1b */ + z2 = z; + if( stem(&z, "dee", "ee", m_gt_0) ){ + /* Do nothing. The work was all in the test */ + }else if( + (stem(&z, "gni", "", hasVowel) || stem(&z, "de", "", hasVowel)) + && z!=z2 + ){ + if( stem(&z, "ta", "ate", 0) || + stem(&z, "lb", "ble", 0) || + stem(&z, "zi", "ize", 0) ){ + /* Do nothing. The work was all in the test */ + }else if( doubleConsonant(z) && (*z!='l' && *z!='s' && *z!='z') ){ + z++; + }else if( m_eq_1(z) && star_oh(z) ){ + *(--z) = 'e'; + } + } + + /* Step 1c */ + if( z[0]=='y' && hasVowel(z+1) ){ + z[0] = 'i'; + } + + /* Step 2 */ + switch( z[1] ){ + case 'a': + stem(&z, "lanoita", "ate", m_gt_0) || + stem(&z, "lanoit", "tion", m_gt_0); + break; + case 'c': + stem(&z, "icne", "ence", m_gt_0) || + stem(&z, "icna", "ance", m_gt_0); + break; + case 'e': + stem(&z, "rezi", "ize", m_gt_0); + break; + case 'g': + stem(&z, "igol", "log", m_gt_0); + break; + case 'l': + stem(&z, "ilb", "ble", m_gt_0) || + stem(&z, "illa", "al", m_gt_0) || + stem(&z, "iltne", "ent", m_gt_0) || + stem(&z, "ile", "e", m_gt_0) || + stem(&z, "ilsuo", "ous", m_gt_0); + break; + case 'o': + stem(&z, "noitazi", "ize", m_gt_0) || + stem(&z, "noita", "ate", m_gt_0) || + stem(&z, "rota", "ate", m_gt_0); + break; + case 's': + stem(&z, "msila", "al", m_gt_0) || + stem(&z, "ssenevi", "ive", m_gt_0) || + stem(&z, "ssenluf", "ful", m_gt_0) || + stem(&z, "ssensuo", "ous", m_gt_0); + break; + case 't': + stem(&z, "itila", "al", m_gt_0) || + stem(&z, "itivi", "ive", m_gt_0) || + stem(&z, "itilib", "ble", m_gt_0); + break; + } + + /* Step 3 */ + switch( z[0] ){ + case 'e': + stem(&z, "etaci", "ic", m_gt_0) || + stem(&z, "evita", "", m_gt_0) || + stem(&z, "ezila", "al", m_gt_0); + break; + case 'i': + stem(&z, "itici", "ic", m_gt_0); + break; + case 'l': + stem(&z, "laci", "ic", m_gt_0) || + stem(&z, "luf", "", m_gt_0); + break; + case 's': + stem(&z, "ssen", "", m_gt_0); + break; + } + + /* Step 4 */ + switch( z[1] ){ + case 'a': + if( z[0]=='l' && m_gt_1(z+2) ){ + z += 2; + } + break; + case 'c': + if( z[0]=='e' && z[2]=='n' && (z[3]=='a' || z[3]=='e') && m_gt_1(z+4) ){ + z += 4; + } + break; + case 'e': + if( z[0]=='r' && m_gt_1(z+2) ){ + z += 2; + } + break; + case 'i': + if( z[0]=='c' && m_gt_1(z+2) ){ + z += 2; + } + break; + case 'l': + if( z[0]=='e' && z[2]=='b' && (z[3]=='a' || z[3]=='i') && m_gt_1(z+4) ){ + z += 4; + } + break; + case 'n': + if( z[0]=='t' ){ + if( z[2]=='a' ){ + if( m_gt_1(z+3) ){ + z += 3; + } + }else if( z[2]=='e' ){ + stem(&z, "tneme", "", m_gt_1) || + stem(&z, "tnem", "", m_gt_1) || + stem(&z, "tne", "", m_gt_1); + } + } + break; + case 'o': + if( z[0]=='u' ){ + if( m_gt_1(z+2) ){ + z += 2; + } + }else if( z[3]=='s' || z[3]=='t' ){ + stem(&z, "noi", "", m_gt_1); + } + break; + case 's': + if( z[0]=='m' && z[2]=='i' && m_gt_1(z+3) ){ + z += 3; + } + break; + case 't': + stem(&z, "eta", "", m_gt_1) || + stem(&z, "iti", "", m_gt_1); + break; + case 'u': + if( z[0]=='s' && z[2]=='o' && m_gt_1(z+3) ){ + z += 3; + } + break; + case 'v': + case 'z': + if( z[0]=='e' && z[2]=='i' && m_gt_1(z+3) ){ + z += 3; + } + break; + } + + /* Step 5a */ + if( z[0]=='e' ){ + if( m_gt_1(z+1) ){ + z++; + }else if( m_eq_1(z+1) && !star_oh(z+1) ){ + z++; + } + } + + /* Step 5b */ + if( m_gt_1(z) && z[0]=='l' && z[1]=='l' ){ + z++; + } + + /* z[] is now the stemmed word in reverse order. Flip it back + ** around into forward order and return. + */ + *pnOut = i = strlen(z); + zOut[i] = 0; + while( *z ){ + zOut[--i] = *(z++); + } +} + +/* +** Characters that can be part of a token. We assume any character +** whose value is greater than 0x80 (any UTF character) can be +** part of a token. In other words, delimiters all must have +** values of 0x7f or lower. +*/ +static const char porterIdChar[] = { +/* x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xA xB xC xD xE xF */ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, /* 3x */ + 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 4x */ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, /* 5x */ + 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 6x */ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, /* 7x */ +}; +#define isDelim(C) (((ch=C)&0x80)==0 && (ch<0x30 || !porterIdChar[ch-0x30])) + +/* +** Extract the next token from a tokenization cursor. The cursor must +** have been opened by a prior call to porterOpen(). +*/ +static int porterNext( + sqlite3_tokenizer_cursor *pCursor, /* Cursor returned by porterOpen */ + const char **pzToken, /* OUT: *pzToken is the token text */ + int *pnBytes, /* OUT: Number of bytes in token */ + int *piStartOffset, /* OUT: Starting offset of token */ + int *piEndOffset, /* OUT: Ending offset of token */ + int *piPosition /* OUT: Position integer of token */ +){ + porter_tokenizer_cursor *c = (porter_tokenizer_cursor *) pCursor; + const char *z = c->zInput; + + while( c->iOffset<c->nInput ){ + int iStartOffset, ch; + + /* Scan past delimiter characters */ + while( c->iOffset<c->nInput && isDelim(z[c->iOffset]) ){ + c->iOffset++; + } + + /* Count non-delimiter characters. */ + iStartOffset = c->iOffset; + while( c->iOffset<c->nInput && !isDelim(z[c->iOffset]) ){ + c->iOffset++; + } + + if( c->iOffset>iStartOffset ){ + int n = c->iOffset-iStartOffset; + if( n>c->nAllocated ){ + c->nAllocated = n+20; + c->zToken = sqlite3_realloc(c->zToken, c->nAllocated); + if( c->zToken==NULL ) return SQLITE_NOMEM; + } + porter_stemmer(&z[iStartOffset], n, c->zToken, pnBytes); + *pzToken = c->zToken; + *piStartOffset = iStartOffset; + *piEndOffset = c->iOffset; + *piPosition = c->iToken++; + return SQLITE_OK; + } + } + return SQLITE_DONE; +} + +/* +** The set of routines that implement the porter-stemmer tokenizer +*/ +static const sqlite3_tokenizer_module porterTokenizerModule = { + 0, + porterCreate, + porterDestroy, + porterOpen, + porterClose, + porterNext, +}; + +/* +** Allocate a new porter tokenizer. Return a pointer to the new +** tokenizer in *ppModule +*/ +void sqlite3Fts3PorterTokenizerModule( + sqlite3_tokenizer_module const**ppModule +){ + *ppModule = &porterTokenizerModule; +} + +#endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) */ + +/************** End of fts3_porter.c *****************************************/ +/************** Begin file fts3_tokenizer.c **********************************/ +/* +** 2007 June 22 +** +** 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 is part of an SQLite module implementing full-text search. +** This particular file implements the generic tokenizer interface. +*/ + +/* +** The code in this file is only compiled if: +** +** * The FTS3 module is being built as an extension +** (in which case SQLITE_CORE is not defined), or +** +** * The FTS3 module is being built into the core of +** SQLite (in which case SQLITE_ENABLE_FTS3 is defined). +*/ +#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) + +/************** Include sqlite3ext.h in the middle of fts3_tokenizer.c *******/ +/************** Begin file sqlite3ext.h **************************************/ +/* +** 2006 June 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 header file defines the SQLite interface for use by +** shared libraries that want to be imported as extensions into +** an SQLite instance. Shared libraries that intend to be loaded +** as extensions by SQLite should #include this file instead of +** sqlite3.h. +** +** @(#) $Id: sqlite3ext.h,v 1.17 2007/08/31 16:11:36 drh Exp $ +*/ +#ifndef _SQLITE3EXT_H_ +#define _SQLITE3EXT_H_ +/************** Include sqlite3.h in the middle of sqlite3ext.h **************/ +/************** Begin file sqlite3.h *****************************************/ +/* +** 2001 September 15 +** +** 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 header file defines the interface that the SQLite library +** presents to client programs. If a C-function, structure, datatype, +** or constant definition does not appear in this file, then it is +** not a published API of SQLite, is subject to change without +** notice, and should not be referenced by programs that use SQLite. +** +** Some of the definitions that are in this file are marked as +** "experimental". Experimental interfaces are normally new +** features recently added to SQLite. We do not anticipate changes +** to experimental interfaces but reserve to make minor changes if +** experience from use "in the wild" suggest such changes are prudent. +** +** The official C-language API documentation for SQLite is derived +** from comments in this file. This file is the authoritative source +** on how SQLite interfaces are suppose to operate. +** +** The name of this file under configuration management is "sqlite.h.in". +** The makefile makes some minor changes to this file (such as inserting +** the version number) and changes its name to "sqlite3.h" as +** part of the build process. +** +** @(#) $Id: sqlite.h.in,v 1.271 2007/11/21 15:24:01 drh Exp $ +*/ +#ifndef _SQLITE3_H_ +#define _SQLITE3_H_ + +/* +** Make sure we can call this stuff from C++. +*/ +#if 0 +extern "C" { +#endif + + +/* +** Add the ability to override 'extern' +*/ +#ifndef SQLITE_EXTERN +# define SQLITE_EXTERN extern +#endif + +/* +** Make sure these symbols where not defined by some previous header +** file. +*/ +#ifdef SQLITE_VERSION +# undef SQLITE_VERSION +#endif +#ifdef SQLITE_VERSION_NUMBER +# undef SQLITE_VERSION_NUMBER +#endif + +/* +** CAPI3REF: Compile-Time Library Version Numbers +** +** The version of the SQLite library is contained in the sqlite3.h +** header file in a #define named SQLITE_VERSION. The SQLITE_VERSION +** macro resolves to a string constant. +** +** The format of the version string is "X.Y.Z", where +** X is the major version number, Y is the minor version number and Z +** is the release number. The X.Y.Z might be followed by "alpha" or "beta". +** For example "3.1.1beta". +** +** The X value is always 3 in SQLite. The X value only changes when +** backwards compatibility is broken and we intend to never break +** backwards compatibility. The Y value only changes when +** there are major feature enhancements that are forwards compatible +** but not backwards compatible. The Z value is incremented with +** each release but resets back to 0 when Y is incremented. +** +** The SQLITE_VERSION_NUMBER is an integer with the value +** (X*1000000 + Y*1000 + Z). For example, for version "3.1.1beta", +** SQLITE_VERSION_NUMBER is set to 3001001. To detect if they are using +** version 3.1.1 or greater at compile time, programs may use the test +** (SQLITE_VERSION_NUMBER>=3001001). +** +** See also: [sqlite3_libversion()] and [sqlite3_libversion_number()]. +*/ +#define SQLITE_VERSION "3.5.2" +#define SQLITE_VERSION_NUMBER 3005002 + +/* +** CAPI3REF: Run-Time Library Version Numbers +** +** These routines return values equivalent to the header constants +** [SQLITE_VERSION] and [SQLITE_VERSION_NUMBER]. The values returned +** by this routines should only be different from the header values +** if you compile your program using an sqlite3.h header from a +** different version of SQLite that the version of the library you +** link against. +** +** The sqlite3_version[] string constant contains the text of the +** [SQLITE_VERSION] string. The sqlite3_libversion() function returns +** a poiner to the sqlite3_version[] string constant. The function +** is provided for DLL users who can only access functions and not +** constants within the DLL. +*/ +SQLITE_EXTERN const char sqlite3_version[]; +const char *sqlite3_libversion(void); +int sqlite3_libversion_number(void); + +/* +** CAPI3REF: Test To See If The Library Is Threadsafe +** +** This routine returns TRUE (nonzero) if SQLite was compiled with +** all of its mutexes enabled and is thus threadsafe. It returns +** zero if the particular build is for single-threaded operation +** only. +** +** Really all this routine does is return true if SQLite was compiled +** with the -DSQLITE_THREADSAFE=1 option and false if +** compiled with -DSQLITE_THREADSAFE=0. If SQLite uses an +** application-defined mutex subsystem, malloc subsystem, collating +** sequence, VFS, SQL function, progress callback, commit hook, +** extension, or other accessories and these add-ons are not +** threadsafe, then clearly the combination will not be threadsafe +** either. Hence, this routine never reports that the library +** is guaranteed to be threadsafe, only when it is guaranteed not +** to be. +** +** This is an experimental API and may go away or change in future +** releases. +*/ +int sqlite3_threadsafe(void); + +/* +** CAPI3REF: Database Connection Handle +** +** Each open SQLite database is represented by pointer to an instance of the +** opaque structure named "sqlite3". It is useful to think of an sqlite3 +** pointer as an object. The [sqlite3_open()], [sqlite3_open16()], and +** [sqlite3_open_v2()] interfaces are its constructors +** and [sqlite3_close()] is its destructor. There are many other interfaces +** (such as [sqlite3_prepare_v2()], [sqlite3_create_function()], and +** [sqlite3_busy_timeout()] to name but three) that are methods on this +** object. +*/ +typedef struct sqlite3 sqlite3; + + +/* +** CAPI3REF: 64-Bit Integer Types +** +** Some compilers do not support the "long long" datatype. So we have +** to do compiler-specific typedefs for 64-bit signed and unsigned integers. +** +** Many SQLite interface functions require a 64-bit integer arguments. +** Those interfaces are declared using this typedef. +*/ +#ifdef SQLITE_INT64_TYPE + typedef SQLITE_INT64_TYPE sqlite_int64; + typedef unsigned SQLITE_INT64_TYPE sqlite_uint64; +#elif defined(_MSC_VER) || defined(__BORLANDC__) + typedef __int64 sqlite_int64; + typedef unsigned __int64 sqlite_uint64; +#else + typedef long long int sqlite_int64; + typedef unsigned long long int sqlite_uint64; +#endif +typedef sqlite_int64 sqlite3_int64; +typedef sqlite_uint64 sqlite3_uint64; + +/* +** If compiling for a processor that lacks floating point support, +** substitute integer for floating-point +*/ +#ifdef SQLITE_OMIT_FLOATING_POINT +# define double sqlite3_int64 +#endif + +/* +** CAPI3REF: Closing A Database Connection +** +** Call this function with a pointer to a structure that was previously +** returned from [sqlite3_open()], [sqlite3_open16()], or +** [sqlite3_open_v2()] and the corresponding database will by +** closed. +** +** All SQL statements prepared using [sqlite3_prepare_v2()] or +** [sqlite3_prepare16_v2()] must be destroyed using [sqlite3_finalize()] +** before this routine is called. Otherwise, SQLITE_BUSY is returned and the +** database connection remains open. +** +** Passing this routine a database connection that has already been +** closed results in undefined behavior. If other interfaces that +** reference the same database connection are pending (either in the +** same thread or in different threads) when this routine is called, +** then the behavior is undefined and is almost certainly undesirable. +*/ +int sqlite3_close(sqlite3 *); + +/* +** The type for a callback function. +** This is legacy and deprecated. It is included for historical +** compatibility and is not documented. +*/ +typedef int (*sqlite3_callback)(void*,int,char**, char**); + +/* +** CAPI3REF: One-Step Query Execution Interface +** +** This interface is used to do a one-time evaluatation of zero +** or more SQL statements. UTF-8 text of the SQL statements to +** be evaluted is passed in as the second parameter. The statements +** are prepared one by one using [sqlite3_prepare()], evaluated +** using [sqlite3_step()], then destroyed using [sqlite3_finalize()]. +** +** If one or more of the SQL statements are queries, then +** the callback function specified by the 3rd parameter is +** invoked once for each row of the query result. This callback +** should normally return 0. If the callback returns a non-zero +** value then the query is aborted, all subsequent SQL statements +** are skipped and the sqlite3_exec() function returns the [SQLITE_ABORT]. +** +** The 4th parameter to this interface is an arbitrary pointer that is +** passed through to the callback function as its first parameter. +** +** The 2nd parameter to the callback function is the number of +** columns in the query result. The 3rd parameter to the callback +** is an array of strings holding the values for each column +** as extracted using [sqlite3_column_text()]. +** The 4th parameter to the callback is an array of strings +** obtained using [sqlite3_column_name()] and holding +** the names of each column. +** +** The callback function may be NULL, even for queries. A NULL +** callback is not an error. It just means that no callback +** will be invoked. +** +** If an error occurs while parsing or evaluating the SQL (but +** not while executing the callback) then an appropriate error +** message is written into memory obtained from [sqlite3_malloc()] and +** *errmsg is made to point to that message. The calling function +** is responsible for freeing the memory using [sqlite3_free()]. +** If errmsg==NULL, then no error message is ever written. +** +** The return value is is SQLITE_OK if there are no errors and +** some other [SQLITE_OK | return code] if there is an error. +** The particular return value depends on the type of error. +** +*/ +int sqlite3_exec( + sqlite3*, /* An open database */ + const char *sql, /* SQL to be evaluted */ + int (*callback)(void*,int,char**,char**), /* Callback function */ + void *, /* 1st argument to callback */ + char **errmsg /* Error msg written here */ +); + +/* +** CAPI3REF: Result Codes +** KEYWORDS: SQLITE_OK +** +** Many SQLite functions return an integer result code from the set shown +** above in order to indicates success or failure. +** +** The result codes above are the only ones returned by SQLite in its +** default configuration. However, the [sqlite3_extended_result_codes()] +** API can be used to set a database connectoin to return more detailed +** result codes. +** +** See also: [SQLITE_IOERR_READ | extended result codes] +** +*/ +#define SQLITE_OK 0 /* Successful result */ +/* beginning-of-error-codes */ +#define SQLITE_ERROR 1 /* SQL error or missing database */ +#define SQLITE_INTERNAL 2 /* NOT USED. Internal logic error in SQLite */ +#define SQLITE_PERM 3 /* Access permission denied */ +#define SQLITE_ABORT 4 /* Callback routine requested an abort */ +#define SQLITE_BUSY 5 /* The database file is locked */ +#define SQLITE_LOCKED 6 /* A table in the database is locked */ +#define SQLITE_NOMEM 7 /* A malloc() failed */ +#define SQLITE_READONLY 8 /* Attempt to write a readonly database */ +#define SQLITE_INTERRUPT 9 /* Operation terminated by sqlite3_interrupt()*/ +#define SQLITE_IOERR 10 /* Some kind of disk I/O error occurred */ +#define SQLITE_CORRUPT 11 /* The database disk image is malformed */ +#define SQLITE_NOTFOUND 12 /* NOT USED. Table or record not found */ +#define SQLITE_FULL 13 /* Insertion failed because database is full */ +#define SQLITE_CANTOPEN 14 /* Unable to open the database file */ +#define SQLITE_PROTOCOL 15 /* NOT USED. Database lock protocol error */ +#define SQLITE_EMPTY 16 /* Database is empty */ +#define SQLITE_SCHEMA 17 /* The database schema changed */ +#define SQLITE_TOOBIG 18 /* String or BLOB exceeds size limit */ +#define SQLITE_CONSTRAINT 19 /* Abort due to constraint violation */ +#define SQLITE_MISMATCH 20 /* Data type mismatch */ +#define SQLITE_MISUSE 21 /* Library used incorrectly */ +#define SQLITE_NOLFS 22 /* Uses OS features not supported on host */ +#define SQLITE_AUTH 23 /* Authorization denied */ +#define SQLITE_FORMAT 24 /* Auxiliary database format error */ +#define SQLITE_RANGE 25 /* 2nd parameter to sqlite3_bind out of range */ +#define SQLITE_NOTADB 26 /* File opened that is not a database file */ +#define SQLITE_ROW 100 /* sqlite3_step() has another row ready */ +#define SQLITE_DONE 101 /* sqlite3_step() has finished executing */ +/* end-of-error-codes */ + +/* +** CAPI3REF: Extended Result Codes +** +** In its default configuration, SQLite API routines return one of 26 integer +** result codes described at result-codes. However, experience has shown that +** many of these result codes are too course-grained. They do not provide as +** much information about problems as users might like. In an effort to +** address this, newer versions of SQLite (version 3.3.8 and later) include +** support for additional result codes that provide more detailed information +** about errors. The extended result codes are enabled (or disabled) for +** each database +** connection using the [sqlite3_extended_result_codes()] API. +** +** Some of the available extended result codes are listed above. +** We expect the number of extended result codes will be expand +** over time. Software that uses extended result codes should expect +** to see new result codes in future releases of SQLite. +** +** The symbolic name for an extended result code always contains a related +** primary result code as a prefix. Primary result codes contain a single +** "_" character. Extended result codes contain two or more "_" characters. +** The numeric value of an extended result code can be converted to its +** corresponding primary result code by masking off the lower 8 bytes. +** +** The SQLITE_OK result code will never be extended. It will always +** be exactly zero. +*/ +#define SQLITE_IOERR_READ (SQLITE_IOERR | (1<<8)) +#define SQLITE_IOERR_SHORT_READ (SQLITE_IOERR | (2<<8)) +#define SQLITE_IOERR_WRITE (SQLITE_IOERR | (3<<8)) +#define SQLITE_IOERR_FSYNC (SQLITE_IOERR | (4<<8)) +#define SQLITE_IOERR_DIR_FSYNC (SQLITE_IOERR | (5<<8)) +#define SQLITE_IOERR_TRUNCATE (SQLITE_IOERR | (6<<8)) +#define SQLITE_IOERR_FSTAT (SQLITE_IOERR | (7<<8)) +#define SQLITE_IOERR_UNLOCK (SQLITE_IOERR | (8<<8)) +#define SQLITE_IOERR_RDLOCK (SQLITE_IOERR | (9<<8)) +#define SQLITE_IOERR_DELETE (SQLITE_IOERR | (10<<8)) +#define SQLITE_IOERR_BLOCKED (SQLITE_IOERR | (11<<8)) +#define SQLITE_IOERR_NOMEM (SQLITE_IOERR | (12<<8)) + +/* +** CAPI3REF: Flags For File Open Operations +** +** Combination of the following bit values are used as the +** third argument to the [sqlite3_open_v2()] interface and +** as fourth argument to the xOpen method of the +** [sqlite3_vfs] object. +** +*/ +#define SQLITE_OPEN_READONLY 0x00000001 +#define SQLITE_OPEN_READWRITE 0x00000002 +#define SQLITE_OPEN_CREATE 0x00000004 +#define SQLITE_OPEN_DELETEONCLOSE 0x00000008 +#define SQLITE_OPEN_EXCLUSIVE 0x00000010 +#define SQLITE_OPEN_MAIN_DB 0x00000100 +#define SQLITE_OPEN_TEMP_DB 0x00000200 +#define SQLITE_OPEN_TRANSIENT_DB 0x00000400 +#define SQLITE_OPEN_MAIN_JOURNAL 0x00000800 +#define SQLITE_OPEN_TEMP_JOURNAL 0x00001000 +#define SQLITE_OPEN_SUBJOURNAL 0x00002000 +#define SQLITE_OPEN_MASTER_JOURNAL 0x00004000 + +/* +** CAPI3REF: Device Characteristics +** +** The xDeviceCapabilities method of the [sqlite3_io_methods] +** object returns an integer which is a vector of the following +** bit values expressing I/O characteristics of the mass storage +** device that holds the file that the [sqlite3_io_methods] +** refers to. +** +** The SQLITE_IOCAP_ATOMIC property means that all writes of +** any size are atomic. The SQLITE_IOCAP_ATOMICnnn values +** mean that writes of blocks that are nnn bytes in size and +** are aligned to an address which is an integer multiple of +** nnn are atomic. The SQLITE_IOCAP_SAFE_APPEND value means +** that when data is appended to a file, the data is appended +** first then the size of the file is extended, never the other +** way around. The SQLITE_IOCAP_SEQUENTIAL property means that +** information is written to disk in the same order as calls +** to xWrite(). +*/ +#define SQLITE_IOCAP_ATOMIC 0x00000001 +#define SQLITE_IOCAP_ATOMIC512 0x00000002 +#define SQLITE_IOCAP_ATOMIC1K 0x00000004 +#define SQLITE_IOCAP_ATOMIC2K 0x00000008 +#define SQLITE_IOCAP_ATOMIC4K 0x00000010 +#define SQLITE_IOCAP_ATOMIC8K 0x00000020 +#define SQLITE_IOCAP_ATOMIC16K 0x00000040 +#define SQLITE_IOCAP_ATOMIC32K 0x00000080 +#define SQLITE_IOCAP_ATOMIC64K 0x00000100 +#define SQLITE_IOCAP_SAFE_APPEND 0x00000200 +#define SQLITE_IOCAP_SEQUENTIAL 0x00000400 + +/* +** CAPI3REF: File Locking Levels +** +** SQLite uses one of the following integer values as the second +** argument to calls it makes to the xLock() and xUnlock() methods +** of an [sqlite3_io_methods] object. +*/ +#define SQLITE_LOCK_NONE 0 +#define SQLITE_LOCK_SHARED 1 +#define SQLITE_LOCK_RESERVED 2 +#define SQLITE_LOCK_PENDING 3 +#define SQLITE_LOCK_EXCLUSIVE 4 + +/* +** CAPI3REF: Synchronization Type Flags +** +** When SQLite invokes the xSync() method of an [sqlite3_io_methods] +** object it uses a combination of the following integer values as +** the second argument. +** +** When the SQLITE_SYNC_DATAONLY flag is used, it means that the +** sync operation only needs to flush data to mass storage. Inode +** information need not be flushed. The SQLITE_SYNC_NORMAL means +** to use normal fsync() semantics. The SQLITE_SYNC_FULL flag means +** to use Mac OS-X style fullsync instead of fsync(). +*/ +#define SQLITE_SYNC_NORMAL 0x00002 +#define SQLITE_SYNC_FULL 0x00003 +#define SQLITE_SYNC_DATAONLY 0x00010 + + +/* +** CAPI3REF: OS Interface Open File Handle +** +** An [sqlite3_file] object represents an open file in the OS +** interface layer. Individual OS interface implementations will +** want to subclass this object by appending additional fields +** for their own use. The pMethods entry is a pointer to an +** [sqlite3_io_methods] object that defines methods for performing +** I/O operations on the open file. +*/ +typedef struct sqlite3_file sqlite3_file; +struct sqlite3_file { + const struct sqlite3_io_methods *pMethods; /* Methods for an open file */ +}; + +/* +** CAPI3REF: OS Interface File Virtual Methods Object +** +** Every file opened by the [sqlite3_vfs] xOpen method contains a pointer to +** an instance of the this object. This object defines the +** methods used to perform various operations against the open file. +** +** The flags argument to xSync may be one of [SQLITE_SYNC_NORMAL] or +** [SQLITE_SYNC_FULL]. The first choice is the normal fsync(). +* The second choice is an +** OS-X style fullsync. The SQLITE_SYNC_DATA flag may be ORed in to +** indicate that only the data of the file and not its inode needs to be +** synced. +** +** The integer values to xLock() and xUnlock() are one of +** <ul> +** <li> [SQLITE_LOCK_NONE], +** <li> [SQLITE_LOCK_SHARED], +** <li> [SQLITE_LOCK_RESERVED], +** <li> [SQLITE_LOCK_PENDING], or +** <li> [SQLITE_LOCK_EXCLUSIVE]. +** </ul> +** xLock() increases the lock. xUnlock() decreases the lock. +** The xCheckReservedLock() method looks +** to see if any database connection, either in this +** process or in some other process, is holding an RESERVED, +** PENDING, or EXCLUSIVE lock on the file. It returns true +** if such a lock exists and false if not. +** +** The xFileControl() method is a generic interface that allows custom +** VFS implementations to directly control an open file using the +** [sqlite3_file_control()] interface. The second "op" argument +** is an integer opcode. The third +** argument is a generic pointer which is intended to be a pointer +** to a structure that may contain arguments or space in which to +** write return values. Potential uses for xFileControl() might be +** functions to enable blocking locks with timeouts, to change the +** locking strategy (for example to use dot-file locks), to inquire +** about the status of a lock, or to break stale locks. The SQLite +** core reserves opcodes less than 100 for its own use. +** A [SQLITE_FCNTL_LOCKSTATE | list of opcodes] less than 100 is available. +** Applications that define a custom xFileControl method should use opcodes +** greater than 100 to avoid conflicts. +** +** The xSectorSize() method returns the sector size of the +** device that underlies the file. The sector size is the +** minimum write that can be performed without disturbing +** other bytes in the file. The xDeviceCharacteristics() +** method returns a bit vector describing behaviors of the +** underlying device: +** +** <ul> +** <li> [SQLITE_IOCAP_ATOMIC] +** <li> [SQLITE_IOCAP_ATOMIC512] +** <li> [SQLITE_IOCAP_ATOMIC1K] +** <li> [SQLITE_IOCAP_ATOMIC2K] +** <li> [SQLITE_IOCAP_ATOMIC4K] +** <li> [SQLITE_IOCAP_ATOMIC8K] +** <li> [SQLITE_IOCAP_ATOMIC16K] +** <li> [SQLITE_IOCAP_ATOMIC32K] +** <li> [SQLITE_IOCAP_ATOMIC64K] +** <li> [SQLITE_IOCAP_SAFE_APPEND] +** <li> [SQLITE_IOCAP_SEQUENTIAL] +** </ul> +** +** The SQLITE_IOCAP_ATOMIC property means that all writes of +** any size are atomic. The SQLITE_IOCAP_ATOMICnnn values +** mean that writes of blocks that are nnn bytes in size and +** are aligned to an address which is an integer multiple of +** nnn are atomic. The SQLITE_IOCAP_SAFE_APPEND value means +** that when data is appended to a file, the data is appended +** first then the size of the file is extended, never the other +** way around. The SQLITE_IOCAP_SEQUENTIAL property means that +** information is written to disk in the same order as calls +** to xWrite(). +*/ +typedef struct sqlite3_io_methods sqlite3_io_methods; +struct sqlite3_io_methods { + int iVersion; + int (*xClose)(sqlite3_file*); + int (*xRead)(sqlite3_file*, void*, int iAmt, sqlite3_int64 iOfst); + int (*xWrite)(sqlite3_file*, const void*, int iAmt, sqlite3_int64 iOfst); + int (*xTruncate)(sqlite3_file*, sqlite3_int64 size); + int (*xSync)(sqlite3_file*, int flags); + int (*xFileSize)(sqlite3_file*, sqlite3_int64 *pSize); + int (*xLock)(sqlite3_file*, int); + int (*xUnlock)(sqlite3_file*, int); + int (*xCheckReservedLock)(sqlite3_file*); + int (*xFileControl)(sqlite3_file*, int op, void *pArg); + int (*xSectorSize)(sqlite3_file*); + int (*xDeviceCharacteristics)(sqlite3_file*); + /* Additional methods may be added in future releases */ +}; + +/* +** CAPI3REF: Standard File Control Opcodes +** +** These integer constants are opcodes for the xFileControl method +** of the [sqlite3_io_methods] object and to the [sqlite3_file_control()] +** interface. +** +** The [SQLITE_FCNTL_LOCKSTATE] opcode is used for debugging. This +** opcode cases the xFileControl method to write the current state of +** the lock (one of [SQLITE_LOCK_NONE], [SQLITE_LOCK_SHARED], +** [SQLITE_LOCK_RESERVED], [SQLITE_LOCK_PENDING], or [SQLITE_LOCK_EXCLUSIVE]) +** into an integer that the pArg argument points to. This capability +** is used during testing and only needs to be supported when SQLITE_TEST +** is defined. +*/ +#define SQLITE_FCNTL_LOCKSTATE 1 + +/* +** CAPI3REF: Mutex Handle +** +** The mutex module within SQLite defines [sqlite3_mutex] to be an +** abstract type for a mutex object. The SQLite core never looks +** at the internal representation of an [sqlite3_mutex]. It only +** deals with pointers to the [sqlite3_mutex] object. +** +** Mutexes are created using [sqlite3_mutex_alloc()]. +*/ +typedef struct sqlite3_mutex sqlite3_mutex; + +/* +** CAPI3REF: OS Interface Object +** +** An instance of this object defines the interface between the +** SQLite core and the underlying operating system. The "vfs" +** in the name of the object stands for "virtual file system". +** +** The iVersion field is initially 1 but may be larger for future +** versions of SQLite. Additional fields may be appended to this +** object when the iVersion value is increased. +** +** The szOsFile field is the size of the subclassed [sqlite3_file] +** structure used by this VFS. mxPathname is the maximum length of +** a pathname in this VFS. +** +** Registered vfs modules are kept on a linked list formed by +** the pNext pointer. The [sqlite3_vfs_register()] +** and [sqlite3_vfs_unregister()] interfaces manage this list +** in a thread-safe way. The [sqlite3_vfs_find()] interface +** searches the list. +** +** The pNext field is the only fields in the sqlite3_vfs +** structure that SQLite will ever modify. SQLite will only access +** or modify this field while holding a particular static mutex. +** The application should never modify anything within the sqlite3_vfs +** object once the object has been registered. +** +** The zName field holds the name of the VFS module. The name must +** be unique across all VFS modules. +** +** SQLite will guarantee that the zFilename string passed to +** xOpen() is a full pathname as generated by xFullPathname() and +** that the string will be valid and unchanged until xClose() is +** called. So the [sqlite3_file] can store a pointer to the +** filename if it needs to remember the filename for some reason. +** +** The flags argument to xOpen() is a copy of the flags argument +** to [sqlite3_open_v2()]. If [sqlite3_open()] or [sqlite3_open16()] +** is used, then flags is [SQLITE_OPEN_READWRITE] | [SQLITE_OPEN_CREATE]. +** If xOpen() opens a file read-only then it sets *pOutFlags to +** include [SQLITE_OPEN_READONLY]. Other bits in *pOutFlags may be +** set. +** +** SQLite will also add one of the following flags to the xOpen() +** call, depending on the object being opened: +** +** <ul> +** <li> [SQLITE_OPEN_MAIN_DB] +** <li> [SQLITE_OPEN_MAIN_JOURNAL] +** <li> [SQLITE_OPEN_TEMP_DB] +** <li> [SQLITE_OPEN_TEMP_JOURNAL] +** <li> [SQLITE_OPEN_TRANSIENT_DB] +** <li> [SQLITE_OPEN_SUBJOURNAL] +** <li> [SQLITE_OPEN_MASTER_JOURNAL] +** </ul> +** +** The file I/O implementation can use the object type flags to +** changes the way it deals with files. For example, an application +** that does not care about crash recovery or rollback, might make +** the open of a journal file a no-op. Writes to this journal are +** also a no-op. Any attempt to read the journal return SQLITE_IOERR. +** Or the implementation might recognize the a database file will +** be doing page-aligned sector reads and writes in a random order +** and set up its I/O subsystem accordingly. +** +** SQLite might also add one of the following flags to the xOpen +** method: +** +** <ul> +** <li> [SQLITE_OPEN_DELETEONCLOSE] +** <li> [SQLITE_OPEN_EXCLUSIVE] +** </ul> +** +** The [SQLITE_OPEN_DELETEONCLOSE] flag means the file should be +** deleted when it is closed. This will always be set for TEMP +** databases and journals and for subjournals. The +** [SQLITE_OPEN_EXCLUSIVE] flag means the file should be opened +** for exclusive access. This flag is set for all files except +** for the main database file. +** +** Space to hold the [sqlite3_file] structure passed as the third +** argument to xOpen is allocated by caller (the SQLite core). +** szOsFile bytes are allocated for this object. The xOpen method +** fills in the allocated space. +** +** The flags argument to xAccess() may be [SQLITE_ACCESS_EXISTS] +** to test for the existance of a file, +** or [SQLITE_ACCESS_READWRITE] to test to see +** if a file is readable and writable, or [SQLITE_ACCESS_READ] +** to test to see if a file is at least readable. The file can be a +** directory. +** +** SQLite will always allocate at least mxPathname+1 byte for +** the output buffers for xGetTempname and xFullPathname. The exact +** size of the output buffer is also passed as a parameter to both +** methods. If the output buffer is not large enough, SQLITE_CANTOPEN +** should be returned. As this is handled as a fatal error by SQLite, +** vfs implementations should endevour to prevent this by setting +** mxPathname to a sufficiently large value. +** +** The xRandomness(), xSleep(), and xCurrentTime() interfaces +** are not strictly a part of the filesystem, but they are +** included in the VFS structure for completeness. +** The xRandomness() function attempts to return nBytes bytes +** of good-quality randomness into zOut. The return value is +** the actual number of bytes of randomness obtained. The +** xSleep() method cause the calling thread to sleep for at +** least the number of microseconds given. The xCurrentTime() +** method returns a Julian Day Number for the current date and +** time. +*/ +typedef struct sqlite3_vfs sqlite3_vfs; +struct sqlite3_vfs { + int iVersion; /* Structure version number */ + int szOsFile; /* Size of subclassed sqlite3_file */ + int mxPathname; /* Maximum file pathname length */ + sqlite3_vfs *pNext; /* Next registered VFS */ + const char *zName; /* Name of this virtual file system */ + void *pAppData; /* Pointer to application-specific data */ + int (*xOpen)(sqlite3_vfs*, const char *zName, sqlite3_file*, + int flags, int *pOutFlags); + int (*xDelete)(sqlite3_vfs*, const char *zName, int syncDir); + int (*xAccess)(sqlite3_vfs*, const char *zName, int flags); + int (*xGetTempname)(sqlite3_vfs*, int nOut, char *zOut); + int (*xFullPathname)(sqlite3_vfs*, const char *zName, int nOut, char *zOut); + void *(*xDlOpen)(sqlite3_vfs*, const char *zFilename); + void (*xDlError)(sqlite3_vfs*, int nByte, char *zErrMsg); + void *(*xDlSym)(sqlite3_vfs*,void*, const char *zSymbol); + void (*xDlClose)(sqlite3_vfs*, void*); + int (*xRandomness)(sqlite3_vfs*, int nByte, char *zOut); + int (*xSleep)(sqlite3_vfs*, int microseconds); + int (*xCurrentTime)(sqlite3_vfs*, double*); + /* New fields may be appended in figure versions. The iVersion + ** value will increment whenever this happens. */ +}; + +/* +** CAPI3REF: Flags for the xAccess VFS method +** +** These integer constants can be used as the third parameter to +** the xAccess method of an [sqlite3_vfs] object. They determine +** the kind of what kind of permissions the xAccess method is +** looking for. With SQLITE_ACCESS_EXISTS, the xAccess method +** simply checks to see if the file exists. With SQLITE_ACCESS_READWRITE, +** the xAccess method checks to see if the file is both readable +** and writable. With SQLITE_ACCESS_READ the xAccess method +** checks to see if the file is readable. +*/ +#define SQLITE_ACCESS_EXISTS 0 +#define SQLITE_ACCESS_READWRITE 1 +#define SQLITE_ACCESS_READ 2 + +/* +** CAPI3REF: Enable Or Disable Extended Result Codes +** +** This routine enables or disables the +** [SQLITE_IOERR_READ | extended result codes] feature. +** By default, SQLite API routines return one of only 26 integer +** [SQLITE_OK | result codes]. When extended result codes +** are enabled by this routine, the repetoire of result codes can be +** much larger and can (hopefully) provide more detailed information +** about the cause of an error. +** +** The second argument is a boolean value that turns extended result +** codes on and off. Extended result codes are off by default for +** backwards compatibility with older versions of SQLite. +*/ +int sqlite3_extended_result_codes(sqlite3*, int onoff); + +/* +** CAPI3REF: Last Insert Rowid +** +** Each entry in an SQLite table has a unique 64-bit signed integer key +** called the "rowid". The rowid is always available as an undeclared +** column named ROWID, OID, or _ROWID_. If the table has a column of +** type INTEGER PRIMARY KEY then that column is another an alias for the +** rowid. +** +** This routine returns the rowid of the most recent successful INSERT into +** the database from the database connection given in the first +** argument. If no successful inserts have ever occurred on this database +** connection, zero is returned. +** +** If an INSERT occurs within a trigger, then the rowid of the +** inserted row is returned by this routine as long as the trigger +** is running. But once the trigger terminates, the value returned +** by this routine reverts to the last value inserted before the +** trigger fired. +** +** An INSERT that fails due to a constraint violation is not a +** successful insert and does not change the value returned by this +** routine. Thus INSERT OR FAIL, INSERT OR IGNORE, INSERT OR ROLLBACK, +** and INSERT OR ABORT make no changes to the return value of this +** routine when their insertion fails. When INSERT OR REPLACE +** encounters a constraint violation, it does not fail. The +** INSERT continues to completion after deleting rows that caused +** the constraint problem so INSERT OR REPLACE will always change +** the return value of this interface. +** +** If another thread does a new insert on the same database connection +** while this routine is running and thus changes the last insert rowid, +** then the return value of this routine is undefined. +*/ +sqlite3_int64 sqlite3_last_insert_rowid(sqlite3*); + +/* +** CAPI3REF: Count The Number Of Rows Modified +** +** This function returns the number of database rows that were changed +** (or inserted or deleted) by the most recent SQL statement. Only +** changes that are directly specified by the INSERT, UPDATE, or +** DELETE statement are counted. Auxiliary changes caused by +** triggers are not counted. Use the [sqlite3_total_changes()] function +** to find the total number of changes including changes caused by triggers. +** +** Within the body of a trigger, the sqlite3_changes() interface can be +** called to find the number of +** changes in the most recently completed INSERT, UPDATE, or DELETE +** statement within the body of the trigger. +** +** All changes are counted, even if they were later undone by a +** ROLLBACK or ABORT. Except, changes associated with creating and +** dropping tables are not counted. +** +** If a callback invokes [sqlite3_exec()] or [sqlite3_step()] recursively, +** then the changes in the inner, recursive call are counted together +** with the changes in the outer call. +** +** SQLite implements the command "DELETE FROM table" without a WHERE clause +** by dropping and recreating the table. (This is much faster than going +** through and deleting individual elements from the table.) Because of +** this optimization, the change count for "DELETE FROM table" will be +** zero regardless of the number of elements that were originally in the +** table. To get an accurate count of the number of rows deleted, use +** "DELETE FROM table WHERE 1" instead. +** +** If another thread makes changes on the same database connection +** while this routine is running then the return value of this routine +** is undefined. +*/ +int sqlite3_changes(sqlite3*); + +/* +** CAPI3REF: Total Number Of Rows Modified +*** +** This function returns the number of database rows that have been +** modified by INSERT, UPDATE or DELETE statements since the database handle +** was opened. This includes UPDATE, INSERT and DELETE statements executed +** as part of trigger programs. All changes are counted as soon as the +** statement that makes them is completed (when the statement handle is +** passed to [sqlite3_reset()] or [sqlite3_finalize()]). +** +** See also the [sqlite3_change()] interface. +** +** SQLite implements the command "DELETE FROM table" without a WHERE clause +** by dropping and recreating the table. (This is much faster than going +** through and deleting individual elements form the table.) Because of +** this optimization, the change count for "DELETE FROM table" will be +** zero regardless of the number of elements that were originally in the +** table. To get an accurate count of the number of rows deleted, use +** "DELETE FROM table WHERE 1" instead. +** +** If another thread makes changes on the same database connection +** while this routine is running then the return value of this routine +** is undefined. +*/ +int sqlite3_total_changes(sqlite3*); + +/* +** CAPI3REF: Interrupt A Long-Running Query +** +** This function causes any pending database operation to abort and +** return at its earliest opportunity. This routine is typically +** called in response to a user action such as pressing "Cancel" +** or Ctrl-C where the user wants a long query operation to halt +** immediately. +** +** It is safe to call this routine from a thread different from the +** thread that is currently running the database operation. But it +** is not safe to call this routine with a database connection that +** is closed or might close before sqlite3_interrupt() returns. +** +** The SQL operation that is interrupted will return [SQLITE_INTERRUPT]. +** If an interrupted operation was an update that is inside an +** explicit transaction, then the entire transaction will be rolled +** back automatically. +*/ +void sqlite3_interrupt(sqlite3*); + +/* +** CAPI3REF: Determine If An SQL Statement Is Complete +** +** These functions return true if the given input string comprises +** one or more complete SQL statements. For the sqlite3_complete() call, +** the parameter must be a nul-terminated UTF-8 string. For +** sqlite3_complete16(), a nul-terminated machine byte order UTF-16 string +** is required. +** +** These routines are useful for command-line input to determine if the +** currently entered text forms one or more complete SQL statements or +** if additional input is needed before sending the statements into +** SQLite for parsing. The algorithm is simple. If the +** last token other than spaces and comments is a semicolon, then return +** true. Actually, the algorithm is a little more complicated than that +** in order to deal with triggers, but the basic idea is the same: the +** statement is not complete unless it ends in a semicolon. +*/ +int sqlite3_complete(const char *sql); +int sqlite3_complete16(const void *sql); + +/* +** CAPI3REF: Register A Callback To Handle SQLITE_BUSY Errors +** +** This routine identifies a callback function that might be invoked +** whenever an attempt is made to open a database table +** that another thread or process has locked. +** If the busy callback is NULL, then [SQLITE_BUSY] +** (or sometimes [SQLITE_IOERR_BLOCKED]) +** is returned immediately upon encountering the lock. +** If the busy callback is not NULL, then the +** callback will be invoked with two arguments. The +** first argument to the handler is a copy of the void* pointer which +** is the third argument to this routine. The second argument to +** the handler is the number of times that the busy handler has +** been invoked for this locking event. If the +** busy callback returns 0, then no additional attempts are made to +** access the database and [SQLITE_BUSY] or [SQLITE_IOERR_BLOCKED] is returned. +** If the callback returns non-zero, then another attempt is made to open the +** database for reading and the cycle repeats. +** +** The presence of a busy handler does not guarantee that +** it will be invoked when there is lock contention. +** If SQLite determines that invoking the busy handler could result in +** a deadlock, it will return [SQLITE_BUSY] instead. +** Consider a scenario where one process is holding a read lock that +** it is trying to promote to a reserved lock and +** a second process is holding a reserved lock that it is trying +** to promote to an exclusive lock. The first process cannot proceed +** because it is blocked by the second and the second process cannot +** proceed because it is blocked by the first. If both processes +** invoke the busy handlers, neither will make any progress. Therefore, +** SQLite returns [SQLITE_BUSY] for the first process, hoping that this +** will induce the first process to release its read lock and allow +** the second process to proceed. +** +** The default busy callback is NULL. +** +** The [SQLITE_BUSY] error is converted to [SQLITE_IOERR_BLOCKED] when +** SQLite is in the middle of a large transaction where all the +** changes will not fit into the in-memory cache. SQLite will +** already hold a RESERVED lock on the database file, but it needs +** to promote this lock to EXCLUSIVE so that it can spill cache +** pages into the database file without harm to concurrent +** readers. If it is unable to promote the lock, then the in-memory +** cache will be left in an inconsistent state and so the error +** code is promoted from the relatively benign [SQLITE_BUSY] to +** the more severe [SQLITE_IOERR_BLOCKED]. This error code promotion +** forces an automatic rollback of the changes. See the +** <a href="http://www.sqlite.org/cvstrac/wiki?p=CorruptionFollowingBusyError"> +** CorruptionFollowingBusyError</a> wiki page for a discussion of why +** this is important. +** +** Sqlite is re-entrant, so the busy handler may start a new query. +** (It is not clear why anyone would every want to do this, but it +** is allowed, in theory.) But the busy handler may not close the +** database. Closing the database from a busy handler will delete +** data structures out from under the executing query and will +** probably result in a segmentation fault or other runtime error. +** +** There can only be a single busy handler defined for each database +** connection. Setting a new busy handler clears any previous one. +** Note that calling [sqlite3_busy_timeout()] will also set or clear +** the busy handler. +** +** When operating in [sqlite3_enable_shared_cache | shared cache mode], +** only a single busy handler can be defined for each database file. +** So if two database connections share a single cache, then changing +** the busy handler on one connection will also change the busy +** handler in the other connection. The busy handler is invoked +** in the thread that was running when the SQLITE_BUSY was hit. +*/ +int sqlite3_busy_handler(sqlite3*, int(*)(void*,int), void*); + +/* +** CAPI3REF: Set A Busy Timeout +** +** This routine sets a busy handler that sleeps for a while when a +** table is locked. The handler will sleep multiple times until +** at least "ms" milliseconds of sleeping have been done. After +** "ms" milliseconds of sleeping, the handler returns 0 which +** causes [sqlite3_step()] to return [SQLITE_BUSY] or [SQLITE_IOERR_BLOCKED]. +** +** Calling this routine with an argument less than or equal to zero +** turns off all busy handlers. +** +** There can only be a single busy handler for a particular database +** connection. If another busy handler was defined +** (using [sqlite3_busy_handler()]) prior to calling +** this routine, that other busy handler is cleared. +*/ +int sqlite3_busy_timeout(sqlite3*, int ms); + +/* +** CAPI3REF: Convenience Routines For Running Queries +** +** This next routine is a convenience wrapper around [sqlite3_exec()]. +** Instead of invoking a user-supplied callback for each row of the +** result, this routine remembers each row of the result in memory +** obtained from [sqlite3_malloc()], then returns all of the result after the +** query has finished. +** +** As an example, suppose the query result where this table: +** +** <blockquote><pre> +** Name | Age +** ----------------------- +** Alice | 43 +** Bob | 28 +** Cindy | 21 +** </pre></blockquote> +** +** If the 3rd argument were &azResult then after the function returns +** azResult will contain the following data: +** +** <blockquote><pre> +** azResult[0] = "Name"; +** azResult[1] = "Age"; +** azResult[2] = "Alice"; +** azResult[3] = "43"; +** azResult[4] = "Bob"; +** azResult[5] = "28"; +** azResult[6] = "Cindy"; +** azResult[7] = "21"; +** </pre></blockquote> +** +** Notice that there is an extra row of data containing the column +** headers. But the *nrow return value is still 3. *ncolumn is +** set to 2. In general, the number of values inserted into azResult +** will be ((*nrow) + 1)*(*ncolumn). +** +** After the calling function has finished using the result, it should +** pass the result data pointer to sqlite3_free_table() in order to +** release the memory that was malloc-ed. Because of the way the +** [sqlite3_malloc()] happens, the calling function must not try to call +** [sqlite3_free()] directly. Only [sqlite3_free_table()] is able to release +** the memory properly and safely. +** +** The return value of this routine is the same as from [sqlite3_exec()]. +*/ +int sqlite3_get_table( + sqlite3*, /* An open database */ + const char *sql, /* SQL to be executed */ + char ***resultp, /* Result written to a char *[] that this points to */ + int *nrow, /* Number of result rows written here */ + int *ncolumn, /* Number of result columns written here */ + char **errmsg /* Error msg written here */ +); +void sqlite3_free_table(char **result); + +/* +** CAPI3REF: Formatted String Printing Functions +** +** These routines are workalikes of the "printf()" family of functions +** from the standard C library. +** +** The sqlite3_mprintf() and sqlite3_vmprintf() routines write their +** results into memory obtained from [sqlite3_malloc()]. +** The strings returned by these two routines should be +** released by [sqlite3_free()]. Both routines return a +** NULL pointer if [sqlite3_malloc()] is unable to allocate enough +** memory to hold the resulting string. +** +** In sqlite3_snprintf() routine is similar to "snprintf()" from +** the standard C library. The result is written into the +** buffer supplied as the second parameter whose size is given by +** the first parameter. Note that the order of the +** first two parameters is reversed from snprintf(). This is an +** historical accident that cannot be fixed without breaking +** backwards compatibility. Note also that sqlite3_snprintf() +** returns a pointer to its buffer instead of the number of +** characters actually written into the buffer. We admit that +** the number of characters written would be a more useful return +** value but we cannot change the implementation of sqlite3_snprintf() +** now without breaking compatibility. +** +** As long as the buffer size is greater than zero, sqlite3_snprintf() +** guarantees that the buffer is always zero-terminated. The first +** parameter "n" is the total size of the buffer, including space for +** the zero terminator. So the longest string that can be completely +** written will be n-1 characters. +** +** These routines all implement some additional formatting +** options that are useful for constructing SQL statements. +** All of the usual printf formatting options apply. In addition, there +** is are "%q", "%Q", and "%z" options. +** +** The %q option works like %s in that it substitutes a null-terminated +** string from the argument list. But %q also doubles every '\'' character. +** %q is designed for use inside a string literal. By doubling each '\'' +** character it escapes that character and allows it to be inserted into +** the string. +** +** For example, so some string variable contains text as follows: +** +** <blockquote><pre> +** char *zText = "It's a happy day!"; +** </pre></blockquote> +** +** One can use this text in an SQL statement as follows: +** +** <blockquote><pre> +** char *zSQL = sqlite3_mprintf("INSERT INTO table VALUES('%q')", zText); +** sqlite3_exec(db, zSQL, 0, 0, 0); +** sqlite3_free(zSQL); +** </pre></blockquote> +** +** Because the %q format string is used, the '\'' character in zText +** is escaped and the SQL generated is as follows: +** +** <blockquote><pre> +** INSERT INTO table1 VALUES('It''s a happy day!') +** </pre></blockquote> +** +** This is correct. Had we used %s instead of %q, the generated SQL +** would have looked like this: +** +** <blockquote><pre> +** INSERT INTO table1 VALUES('It's a happy day!'); +** </pre></blockquote> +** +** This second example is an SQL syntax error. As a general rule you +** should always use %q instead of %s when inserting text into a string +** literal. +** +** The %Q option works like %q except it also adds single quotes around +** the outside of the total string. Or if the parameter in the argument +** list is a NULL pointer, %Q substitutes the text "NULL" (without single +** quotes) in place of the %Q option. So, for example, one could say: +** +** <blockquote><pre> +** char *zSQL = sqlite3_mprintf("INSERT INTO table VALUES(%Q)", zText); +** sqlite3_exec(db, zSQL, 0, 0, 0); +** sqlite3_free(zSQL); +** </pre></blockquote> +** +** The code above will render a correct SQL statement in the zSQL +** variable even if the zText variable is a NULL pointer. +** +** The "%z" formatting option works exactly like "%s" with the +** addition that after the string has been read and copied into +** the result, [sqlite3_free()] is called on the input string. +*/ +char *sqlite3_mprintf(const char*,...); +char *sqlite3_vmprintf(const char*, va_list); +char *sqlite3_snprintf(int,char*,const char*, ...); + +/* +** CAPI3REF: Memory Allocation Subsystem +** +** The SQLite core uses these three routines for all of its own +** internal memory allocation needs. (See the exception below.) +** +** The default implementation +** of the memory allocation subsystem uses the malloc(), realloc() +** and free() provided by the standard C library. However, if +** SQLite is compiled with the following C preprocessor macro +** +** <blockquote> SQLITE_MEMORY_SIZE=<i>NNN</i> </blockquote> +** +** where <i>NNN</i> is an integer, then SQLite create a static +** array of at least <i>NNN</i> bytes in size and use that array +** for all of its dynamic memory allocation needs. +** +** In SQLite version 3.5.0 and 3.5.1, it was possible to define +** the SQLITE_OMIT_MEMORY_ALLOCATION which would cause the built-in +** implementation of these routines to be omitted. That capability +** is no longer provided. Only built-in memory allocators can be +** used. +** +** <b>Exception:</b> The windows OS interface layer calls +** the system malloc() and free() directly when converting +** filenames between the UTF-8 encoding used by SQLite +** and whatever filename encoding is used by the particular windows +** installation. Memory allocation errors are detected, but +** they are reported back as [SQLITE_CANTOPEN] or +** [SQLITE_IOERR] rather than [SQLITE_NOMEM]. +*/ +void *sqlite3_malloc(int); +void *sqlite3_realloc(void*, int); +void sqlite3_free(void*); + +/* +** CAPI3REF: Memory Allocator Statistics +** +** In addition to the basic three allocation routines +** [sqlite3_malloc()], [sqlite3_free()], and [sqlite3_realloc()], +** the memory allocation subsystem included with the SQLite +** sources provides the interfaces shown below. +** +** The first of these two routines returns the amount of memory +** currently outstanding (malloced but not freed). The second +** returns the largest instantaneous amount of outstanding +** memory. The highwater mark is reset if the argument is +** true. +** +** The value returned may or may not include allocation +** overhead, depending on which built-in memory allocator +** implementation is used. +*/ +sqlite3_int64 sqlite3_memory_used(void); +sqlite3_int64 sqlite3_memory_highwater(int resetFlag); + +/* +** CAPI3REF: Compile-Time Authorization Callbacks +*** +** This routine registers a authorizer callback with the SQLite library. +** The authorizer callback is invoked as SQL statements are being compiled +** by [sqlite3_prepare()] or its variants [sqlite3_prepare_v2()], +** [sqlite3_prepare16()] and [sqlite3_prepare16_v2()]. At various +** points during the compilation process, as logic is being created +** to perform various actions, the authorizer callback is invoked to +** see if those actions are allowed. The authorizer callback should +** return SQLITE_OK to allow the action, [SQLITE_IGNORE] to disallow the +** specific action but allow the SQL statement to continue to be +** compiled, or [SQLITE_DENY] to cause the entire SQL statement to be +** rejected with an error. +** +** Depending on the action, the [SQLITE_IGNORE] and [SQLITE_DENY] return +** codes might mean something different or they might mean the same +** thing. If the action is, for example, to perform a delete opertion, +** then [SQLITE_IGNORE] and [SQLITE_DENY] both cause the statement compilation +** to fail with an error. But if the action is to read a specific column +** from a specific table, then [SQLITE_DENY] will cause the entire +** statement to fail but [SQLITE_IGNORE] will cause a NULL value to be +** read instead of the actual column value. +** +** The first parameter to the authorizer callback is a copy of +** the third parameter to the sqlite3_set_authorizer() interface. +** The second parameter to the callback is an integer +** [SQLITE_COPY | action code] that specifies the particular action +** to be authorized. The available action codes are +** [SQLITE_COPY | documented separately]. The third through sixth +** parameters to the callback are strings that contain additional +** details about the action to be authorized. +** +** An authorizer is used when preparing SQL statements from an untrusted +** source, to ensure that the SQL statements do not try to access data +** that they are not allowed to see, or that they do not try to +** execute malicious statements that damage the database. For +** example, an application may allow a user to enter arbitrary +** SQL queries for evaluation by a database. But the application does +** not want the user to be able to make arbitrary changes to the +** database. An authorizer could then be put in place while the +** user-entered SQL is being prepared that disallows everything +** except SELECT statements. +** +** Only a single authorizer can be in place on a database connection +** at a time. Each call to sqlite3_set_authorizer overrides the +** previous call. A NULL authorizer means that no authorization +** callback is invoked. The default authorizer is NULL. +** +** Note that the authorizer callback is invoked only during +** [sqlite3_prepare()] or its variants. Authorization is not +** performed during statement evaluation in [sqlite3_step()]. +*/ +int sqlite3_set_authorizer( + sqlite3*, + int (*xAuth)(void*,int,const char*,const char*,const char*,const char*), + void *pUserData +); + +/* +** CAPI3REF: Authorizer Return Codes +** +** The [sqlite3_set_authorizer | authorizer callback function] must +** return either [SQLITE_OK] or one of these two constants in order +** to signal SQLite whether or not the action is permitted. See the +** [sqlite3_set_authorizer | authorizer documentation] for additional +** information. +*/ +#define SQLITE_DENY 1 /* Abort the SQL statement with an error */ +#define SQLITE_IGNORE 2 /* Don't allow access, but don't generate an error */ + +/* +** CAPI3REF: Authorizer Action Codes +** +** The [sqlite3_set_authorizer()] interface registers a callback function +** that is invoked to authorizer certain SQL statement actions. The +** second parameter to the callback is an integer code that specifies +** what action is being authorized. These are the integer action codes that +** the authorizer callback may be passed. +** +** These action code values signify what kind of operation is to be +** authorized. The 3rd and 4th parameters to the authorization callback +** function will be parameters or NULL depending on which of these +** codes is used as the second parameter. The 5th parameter to the +** authorizer callback is the name of the database ("main", "temp", +** etc.) if applicable. The 6th parameter to the authorizer callback +** is the name of the inner-most trigger or view that is responsible for +** the access attempt or NULL if this access attempt is directly from +** top-level SQL code. +*/ +/******************************************* 3rd ************ 4th ***********/ +#define SQLITE_CREATE_INDEX 1 /* Index Name Table Name */ +#define SQLITE_CREATE_TABLE 2 /* Table Name NULL */ +#define SQLITE_CREATE_TEMP_INDEX 3 /* Index Name Table Name */ +#define SQLITE_CREATE_TEMP_TABLE 4 /* Table Name NULL */ +#define SQLITE_CREATE_TEMP_TRIGGER 5 /* Trigger Name Table Name */ +#define SQLITE_CREATE_TEMP_VIEW 6 /* View Name NULL */ +#define SQLITE_CREATE_TRIGGER 7 /* Trigger Name Table Name */ +#define SQLITE_CREATE_VIEW 8 /* View Name NULL */ +#define SQLITE_DELETE 9 /* Table Name NULL */ +#define SQLITE_DROP_INDEX 10 /* Index Name Table Name */ +#define SQLITE_DROP_TABLE 11 /* Table Name NULL */ +#define SQLITE_DROP_TEMP_INDEX 12 /* Index Name Table Name */ +#define SQLITE_DROP_TEMP_TABLE 13 /* Table Name NULL */ +#define SQLITE_DROP_TEMP_TRIGGER 14 /* Trigger Name Table Name */ +#define SQLITE_DROP_TEMP_VIEW 15 /* View Name NULL */ +#define SQLITE_DROP_TRIGGER 16 /* Trigger Name Table Name */ +#define SQLITE_DROP_VIEW 17 /* View Name NULL */ +#define SQLITE_INSERT 18 /* Table Name NULL */ +#define SQLITE_PRAGMA 19 /* Pragma Name 1st arg or NULL */ +#define SQLITE_READ 20 /* Table Name Column Name */ +#define SQLITE_SELECT 21 /* NULL NULL */ +#define SQLITE_TRANSACTION 22 /* NULL NULL */ +#define SQLITE_UPDATE 23 /* Table Name Column Name */ +#define SQLITE_ATTACH 24 /* Filename NULL */ +#define SQLITE_DETACH 25 /* Database Name NULL */ +#define SQLITE_ALTER_TABLE 26 /* Database Name Table Name */ +#define SQLITE_REINDEX 27 /* Index Name NULL */ +#define SQLITE_ANALYZE 28 /* Table Name NULL */ +#define SQLITE_CREATE_VTABLE 29 /* Table Name Module Name */ +#define SQLITE_DROP_VTABLE 30 /* Table Name Module Name */ +#define SQLITE_FUNCTION 31 /* Function Name NULL */ +#define SQLITE_COPY 0 /* No longer used */ + +/* +** CAPI3REF: Tracing And Profiling Functions +** +** These routines register callback functions that can be used for +** tracing and profiling the execution of SQL statements. +** The callback function registered by sqlite3_trace() is invoked +** at the first [sqlite3_step()] for the evaluation of an SQL statement. +** The callback function registered by sqlite3_profile() is invoked +** as each SQL statement finishes and includes +** information on how long that statement ran. +** +** The sqlite3_profile() API is currently considered experimental and +** is subject to change. +*/ +void *sqlite3_trace(sqlite3*, void(*xTrace)(void*,const char*), void*); +void *sqlite3_profile(sqlite3*, + void(*xProfile)(void*,const char*,sqlite3_uint64), void*); + +/* +** CAPI3REF: Query Progress Callbacks +** +** This routine configures a callback function - the progress callback - that +** is invoked periodically during long running calls to [sqlite3_exec()], +** [sqlite3_step()] and [sqlite3_get_table()]. An example use for this +** interface is to keep a GUI updated during a large query. +** +** The progress callback is invoked once for every N virtual machine opcodes, +** where N is the second argument to this function. The progress callback +** itself is identified by the third argument to this function. The fourth +** argument to this function is a void pointer passed to the progress callback +** function each time it is invoked. +** +** If a call to [sqlite3_exec()], [sqlite3_step()], or [sqlite3_get_table()] +** results in fewer than N opcodes being executed, then the progress +** callback is never invoked. +** +** Only a single progress callback function may be registered for each +** open database connection. Every call to sqlite3_progress_handler() +** overwrites the results of the previous call. +** To remove the progress callback altogether, pass NULL as the third +** argument to this function. +** +** If the progress callback returns a result other than 0, then the current +** query is immediately terminated and any database changes rolled back. +** The containing [sqlite3_exec()], [sqlite3_step()], or +** [sqlite3_get_table()] call returns SQLITE_INTERRUPT. This feature +** can be used, for example, to implement the "Cancel" button on a +** progress dialog box in a GUI. +*/ +void sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*); + +/* +** CAPI3REF: Opening A New Database Connection +** +** Open the sqlite database file "filename". The "filename" is UTF-8 +** encoded for [sqlite3_open()] and [sqlite3_open_v2()] and UTF-16 encoded +** in the native byte order for [sqlite3_open16()]. +** An [sqlite3*] handle is returned in *ppDb, even +** if an error occurs. If the database is opened (or created) successfully, +** then [SQLITE_OK] is returned. Otherwise an error code is returned. The +** [sqlite3_errmsg()] or [sqlite3_errmsg16()] routines can be used to obtain +** an English language description of the error. +** +** The default encoding for the database will be UTF-8 if +** [sqlite3_open()] or [sqlite3_open_v2()] is called and +** UTF-16 if [sqlite3_open16()] is used. +** +** Whether or not an error occurs when it is opened, resources associated +** with the [sqlite3*] handle should be released by passing it to +** [sqlite3_close()] when it is no longer required. +** +** The [sqlite3_open_v2()] interface works like [sqlite3_open()] except that +** provides two additional parameters for additional control over the +** new database connection. The flags parameter can be one of: +** +** <ol> +** <li> [SQLITE_OPEN_READONLY] +** <li> [SQLITE_OPEN_READWRITE] +** <li> [SQLITE_OPEN_READWRITE] | [SQLITE_OPEN_CREATE] +** </ol> +** +** The first value opens the database read-only. If the database does +** not previously exist, an error is returned. The second option opens +** the database for reading and writing if possible, or reading only if +** if the file is write protected. In either case the database must already +** exist or an error is returned. The third option opens the database +** for reading and writing and creates it if it does not already exist. +** The third options is behavior that is always used for [sqlite3_open()] +** and [sqlite3_open16()]. +** +** If the filename is ":memory:", then an private +** in-memory database is created for the connection. This in-memory +** database will vanish when the database connection is closed. Future +** version of SQLite might make use of additional special filenames +** that begin with the ":" character. It is recommended that +** when a database filename really does begin with +** ":" that you prefix the filename with a pathname like "./" to +** avoid ambiguity. +** +** If the filename is an empty string, then a private temporary +** on-disk database will be created. This private database will be +** automatically deleted as soon as the database connection is closed. +** +** The fourth parameter to sqlite3_open_v2() is the name of the +** [sqlite3_vfs] object that defines the operating system +** interface that the new database connection should use. If the +** fourth parameter is a NULL pointer then the default [sqlite3_vfs] +** object is used. +** +** <b>Note to windows users:</b> The encoding used for the filename argument +** of [sqlite3_open()] and [sqlite3_open_v2()] must be UTF-8, not whatever +** codepage is currently defined. Filenames containing international +** characters must be converted to UTF-8 prior to passing them into +** [sqlite3_open()] or [sqlite3_open_v2()]. +*/ +int sqlite3_open( + const char *filename, /* Database filename (UTF-8) */ + sqlite3 **ppDb /* OUT: SQLite db handle */ +); +int sqlite3_open16( + const void *filename, /* Database filename (UTF-16) */ + sqlite3 **ppDb /* OUT: SQLite db handle */ +); +int sqlite3_open_v2( + const char *filename, /* Database filename (UTF-8) */ + sqlite3 **ppDb, /* OUT: SQLite db handle */ + int flags, /* Flags */ + const char *zVfs /* Name of VFS module to use */ +); + +/* +** CAPI3REF: Error Codes And Messages +** +** The sqlite3_errcode() interface returns the numeric +** [SQLITE_OK | result code] or [SQLITE_IOERR_READ | extended result code] +** for the most recent failed sqlite3_* API call associated +** with [sqlite3] handle 'db'. If a prior API call failed but the +** most recent API call succeeded, the return value from sqlite3_errcode() +** is undefined. +** +** The sqlite3_errmsg() and sqlite3_errmsg16() return English-language +** text that describes the error, as either UTF8 or UTF16 respectively. +** Memory to hold the error message string is managed internally. The +** string may be overwritten or deallocated by subsequent calls to SQLite +** interface functions. +** +** Calls to many sqlite3_* functions set the error code and string returned +** by [sqlite3_errcode()], [sqlite3_errmsg()], and [sqlite3_errmsg16()] +** (overwriting the previous values). Note that calls to [sqlite3_errcode()], +** [sqlite3_errmsg()], and [sqlite3_errmsg16()] themselves do not affect the +** results of future invocations. Calls to API routines that do not return +** an error code (example: [sqlite3_data_count()]) do not +** change the error code returned by this routine. Interfaces that are +** not associated with a specific database connection (examples: +** [sqlite3_mprintf()] or [sqlite3_enable_shared_cache()] do not change +** the return code. +** +** Assuming no other intervening sqlite3_* API calls are made, the error +** code returned by this function is associated with the same error as +** the strings returned by [sqlite3_errmsg()] and [sqlite3_errmsg16()]. +*/ +int sqlite3_errcode(sqlite3 *db); +const char *sqlite3_errmsg(sqlite3*); +const void *sqlite3_errmsg16(sqlite3*); + +/* +** CAPI3REF: SQL Statement Object +** +** Instance of this object represent single SQL statements. This +** is variously known as a "prepared statement" or a +** "compiled SQL statement" or simply as a "statement". +** +** The life of a statement object goes something like this: +** +** <ol> +** <li> Create the object using [sqlite3_prepare_v2()] or a related +** function. +** <li> Bind values to host parameters using +** [sqlite3_bind_blob | sqlite3_bind_* interfaces]. +** <li> Run the SQL by calling [sqlite3_step()] one or more times. +** <li> Reset the statement using [sqlite3_reset()] then go back +** to step 2. Do this zero or more times. +** <li> Destroy the object using [sqlite3_finalize()]. +** </ol> +** +** Refer to documentation on individual methods above for additional +** information. +*/ +typedef struct sqlite3_stmt sqlite3_stmt; + +/* +** CAPI3REF: Compiling An SQL Statement +** +** To execute an SQL query, it must first be compiled into a byte-code +** program using one of these routines. +** +** The first argument "db" is an [sqlite3 | SQLite database handle] +** obtained from a prior call to [sqlite3_open()], [sqlite3_open_v2()] +** or [sqlite3_open16()]. +** The second argument "zSql" is the statement to be compiled, encoded +** as either UTF-8 or UTF-16. The sqlite3_prepare() and sqlite3_prepare_v2() +** interfaces uses UTF-8 and sqlite3_prepare16() and sqlite3_prepare16_v2() +** use UTF-16. +** +** If the nByte argument is less +** than zero, then zSql is read up to the first zero terminator. If +** nByte is non-negative, then it is the maximum number of +** bytes read from zSql. When nByte is non-negative, the +** zSql string ends at either the first '\000' character or +** until the nByte-th byte, whichever comes first. +** +** *pzTail is made to point to the first byte past the end of the first +** SQL statement in zSql. This routine only compiles the first statement +** in zSql, so *pzTail is left pointing to what remains uncompiled. +** +** *ppStmt is left pointing to a compiled +** [sqlite3_stmt | SQL statement structure] that can be +** executed using [sqlite3_step()]. Or if there is an error, *ppStmt may be +** set to NULL. If the input text contained no SQL (if the input is and +** empty string or a comment) then *ppStmt is set to NULL. The calling +** procedure is responsible for deleting the compiled SQL statement +** using [sqlite3_finalize()] after it has finished with it. +** +** On success, [SQLITE_OK] is returned. Otherwise an +** [SQLITE_ERROR | error code] is returned. +** +** The sqlite3_prepare_v2() and sqlite3_prepare16_v2() interfaces are +** recommended for all new programs. The two older interfaces are retained +** for backwards compatibility, but their use is discouraged. +** In the "v2" interfaces, the prepared statement +** that is returned (the [sqlite3_stmt] object) contains a copy of the +** original SQL text. This causes the [sqlite3_step()] interface to +** behave a differently in two ways: +** +** <ol> +** <li> +** If the database schema changes, instead of returning [SQLITE_SCHEMA] as it +** always used to do, [sqlite3_step()] will automatically recompile the SQL +** statement and try to run it again. If the schema has changed in a way +** that makes the statement no longer valid, [sqlite3_step()] will still +** return [SQLITE_SCHEMA]. But unlike the legacy behavior, [SQLITE_SCHEMA] is +** now a fatal error. Calling [sqlite3_prepare_v2()] again will not make the +** error go away. Note: use [sqlite3_errmsg()] to find the text of the parsing +** error that results in an [SQLITE_SCHEMA] return. +** </li> +** +** <li> +** When an error occurs, +** [sqlite3_step()] will return one of the detailed +** [SQLITE_ERROR | result codes] or +** [SQLITE_IOERR_READ | extended result codes] such as directly. +** The legacy behavior was that [sqlite3_step()] would only return a generic +** [SQLITE_ERROR] result code and you would have to make a second call to +** [sqlite3_reset()] in order to find the underlying cause of the problem. +** With the "v2" prepare interfaces, the underlying reason for the error is +** returned immediately. +** </li> +** </ol> +*/ +int sqlite3_prepare( + sqlite3 *db, /* Database handle */ + const char *zSql, /* SQL statement, UTF-8 encoded */ + int nByte, /* Maximum length of zSql in bytes. */ + sqlite3_stmt **ppStmt, /* OUT: Statement handle */ + const char **pzTail /* OUT: Pointer to unused portion of zSql */ +); +int sqlite3_prepare_v2( + sqlite3 *db, /* Database handle */ + const char *zSql, /* SQL statement, UTF-8 encoded */ + int nByte, /* Maximum length of zSql in bytes. */ + sqlite3_stmt **ppStmt, /* OUT: Statement handle */ + const char **pzTail /* OUT: Pointer to unused portion of zSql */ +); +int sqlite3_prepare16( + sqlite3 *db, /* Database handle */ + const void *zSql, /* SQL statement, UTF-16 encoded */ + int nByte, /* Maximum length of zSql in bytes. */ + sqlite3_stmt **ppStmt, /* OUT: Statement handle */ + const void **pzTail /* OUT: Pointer to unused portion of zSql */ +); +int sqlite3_prepare16_v2( + sqlite3 *db, /* Database handle */ + const void *zSql, /* SQL statement, UTF-16 encoded */ + int nByte, /* Maximum length of zSql in bytes. */ + sqlite3_stmt **ppStmt, /* OUT: Statement handle */ + const void **pzTail /* OUT: Pointer to unused portion of zSql */ +); + +/* +** Retrieve the original SQL statement associated with a compiled statement +** in UTF-8 encoding. +** +** If the compiled SQL statement passed as an argument was compiled using +** either sqlite3_prepare_v2 or sqlite3_prepare16_v2, then this function +** returns a pointer to a nul-terminated string containing a copy of +** the original SQL statement. The pointer is valid until the statement +** is deleted using sqlite3_finalize(). +** +** If the statement was compiled using either of the legacy interfaces +** sqlite3_prepare() or sqlite3_prepare16(), this function returns NULL. +** +****** EXPERIMENTAL - subject to change without notice ************** +*/ +const char *sqlite3_sql(sqlite3_stmt *pStmt); + +/* +** CAPI3REF: Dynamically Typed Value Object +** +** SQLite uses dynamic typing for the values it stores. Values can +** be integers, floating point values, strings, BLOBs, or NULL. When +** passing around values internally, each value is represented as +** an instance of the sqlite3_value object. +*/ +typedef struct Mem sqlite3_value; + +/* +** CAPI3REF: SQL Function Context Object +** +** The context in which an SQL function executes is stored in an +** sqlite3_context object. A pointer to such an object is the +** first parameter to user-defined SQL functions. +*/ +typedef struct sqlite3_context sqlite3_context; + +/* +** CAPI3REF: Binding Values To Prepared Statements +** +** In the SQL strings input to [sqlite3_prepare_v2()] and its variants, +** one or more literals can be replace by a parameter in one of these +** forms: +** +** <ul> +** <li> ? +** <li> ?NNN +** <li> :AAA +** <li> @AAA +** <li> $VVV +** </ul> +** +** In the parameter forms shown above NNN is an integer literal, +** AAA is an alphanumeric identifier and VVV is a variable name according +** to the syntax rules of the TCL programming language. +** The values of these parameters (also called "host parameter names") +** can be set using the sqlite3_bind_*() routines defined here. +** +** The first argument to the sqlite3_bind_*() routines always is a pointer +** to the [sqlite3_stmt] object returned from [sqlite3_prepare_v2()] or +** its variants. The second +** argument is the index of the parameter to be set. The first parameter has +** an index of 1. When the same named parameter is used more than once, second +** and subsequent +** occurrences have the same index as the first occurrence. The index for +** named parameters can be looked up using the +** [sqlite3_bind_parameter_name()] API if desired. The index for "?NNN" +** parametes is the value of NNN. +** The NNN value must be between 1 and the compile-time +** parameter SQLITE_MAX_VARIABLE_NUMBER (default value: 999). +** See <a href="limits.html">limits.html</a> for additional information. +** +** The third argument is the value to bind to the parameter. +** +** In those +** routines that have a fourth argument, its value is the number of bytes +** in the parameter. To be clear: the value is the number of bytes in the +** string, not the number of characters. The number +** of bytes does not include the zero-terminator at the end of strings. +** If the fourth parameter is negative, the length of the string is +** number of bytes up to the first zero terminator. +** +** The fifth argument to sqlite3_bind_blob(), sqlite3_bind_text(), and +** sqlite3_bind_text16() is a destructor used to dispose of the BLOB or +** text after SQLite has finished with it. If the fifth argument is the +** special value [SQLITE_STATIC], then the library assumes that the information +** is in static, unmanaged space and does not need to be freed. If the +** fifth argument has the value [SQLITE_TRANSIENT], then SQLite makes its +** own private copy of the data immediately, before the sqlite3_bind_*() +** routine returns. +** +** The sqlite3_bind_zeroblob() routine binds a BLOB of length n that +** is filled with zeros. A zeroblob uses a fixed amount of memory +** (just an integer to hold it size) while it is being processed. +** Zeroblobs are intended to serve as place-holders for BLOBs whose +** content is later written using +** [sqlite3_blob_open | increment BLOB I/O] routines. A negative +** value for the zeroblob results in a zero-length BLOB. +** +** The sqlite3_bind_*() routines must be called after +** [sqlite3_prepare_v2()] (and its variants) or [sqlite3_reset()] and +** before [sqlite3_step()]. +** Bindings are not cleared by the [sqlite3_reset()] routine. +** Unbound parameters are interpreted as NULL. +** +** These routines return [SQLITE_OK] on success or an error code if +** anything goes wrong. [SQLITE_RANGE] is returned if the parameter +** index is out of range. [SQLITE_NOMEM] is returned if malloc fails. +** [SQLITE_MISUSE] is returned if these routines are called on a virtual +** machine that is the wrong state or which has already been finalized. +*/ +int sqlite3_bind_blob(sqlite3_stmt*, int, const void*, int n, void(*)(void*)); +int sqlite3_bind_double(sqlite3_stmt*, int, double); +int sqlite3_bind_int(sqlite3_stmt*, int, int); +int sqlite3_bind_int64(sqlite3_stmt*, int, sqlite3_int64); +int sqlite3_bind_null(sqlite3_stmt*, int); +int sqlite3_bind_text(sqlite3_stmt*, int, const char*, int n, void(*)(void*)); +int sqlite3_bind_text16(sqlite3_stmt*, int, const void*, int, void(*)(void*)); +int sqlite3_bind_value(sqlite3_stmt*, int, const sqlite3_value*); +int sqlite3_bind_zeroblob(sqlite3_stmt*, int, int n); + +/* +** CAPI3REF: Number Of Host Parameters +** +** Return the largest host parameter index in the precompiled statement given +** as the argument. When the host parameters are of the forms like ":AAA" +** or "?", then they are assigned sequential increasing numbers beginning +** with one, so the value returned is the number of parameters. However +** if the same host parameter name is used multiple times, each occurrance +** is given the same number, so the value returned in that case is the number +** of unique host parameter names. If host parameters of the form "?NNN" +** are used (where NNN is an integer) then there might be gaps in the +** numbering and the value returned by this interface is the index of the +** host parameter with the largest index value. +** +** The prepared statement must not be [sqlite3_finalize | finalized] +** prior to this routine returnning. Otherwise the results are undefined +** and probably undesirable. +*/ +int sqlite3_bind_parameter_count(sqlite3_stmt*); + +/* +** CAPI3REF: Name Of A Host Parameter +** +** This routine returns a pointer to the name of the n-th parameter in a +** [sqlite3_stmt | prepared statement]. +** Host parameters of the form ":AAA" or "@AAA" or "$VVV" have a name +** which is the string ":AAA" or "@AAA" or "$VVV". +** In other words, the initial ":" or "$" or "@" +** is included as part of the name. +** Parameters of the form "?" or "?NNN" have no name. +** +** The first bound parameter has an index of 1, not 0. +** +** If the value n is out of range or if the n-th parameter is nameless, +** then NULL is returned. The returned string is always in the +** UTF-8 encoding even if the named parameter was originally specified +** as UTF-16 in [sqlite3_prepare16()] or [sqlite3_prepare16_v2()]. +*/ +const char *sqlite3_bind_parameter_name(sqlite3_stmt*, int); + +/* +** CAPI3REF: Index Of A Parameter With A Given Name +** +** This routine returns the index of a host parameter with the given name. +** The name must match exactly. If no parameter with the given name is +** found, return 0. Parameter names must be UTF8. +*/ +int sqlite3_bind_parameter_index(sqlite3_stmt*, const char *zName); + +/* +** CAPI3REF: Reset All Bindings On A Prepared Statement +** +** Contrary to the intuition of many, [sqlite3_reset()] does not +** reset the [sqlite3_bind_blob | bindings] on a +** [sqlite3_stmt | prepared statement]. Use this routine to +** reset all host parameters to NULL. +*/ +int sqlite3_clear_bindings(sqlite3_stmt*); + +/* +** CAPI3REF: Number Of Columns In A Result Set +** +** Return the number of columns in the result set returned by the +** [sqlite3_stmt | compiled SQL statement]. This routine returns 0 +** if pStmt is an SQL statement that does not return data (for +** example an UPDATE). +*/ +int sqlite3_column_count(sqlite3_stmt *pStmt); + +/* +** CAPI3REF: Column Names In A Result Set +** +** These routines return the name assigned to a particular column +** in the result set of a SELECT statement. The sqlite3_column_name() +** interface returns a pointer to a UTF8 string and sqlite3_column_name16() +** returns a pointer to a UTF16 string. The first parameter is the +** [sqlite3_stmt | prepared statement] that implements the SELECT statement. +** The second parameter is the column number. The left-most column is +** number 0. +** +** The returned string pointer is valid until either the +** [sqlite3_stmt | prepared statement] is destroyed by [sqlite3_finalize()] +** or until the next call sqlite3_column_name() or sqlite3_column_name16() +** on the same column. +** +** If sqlite3_malloc() fails during the processing of either routine +** (for example during a conversion from UTF-8 to UTF-16) then a +** NULL pointer is returned. +*/ +const char *sqlite3_column_name(sqlite3_stmt*, int N); +const void *sqlite3_column_name16(sqlite3_stmt*, int N); + +/* +** CAPI3REF: Source Of Data In A Query Result +** +** These routines provide a means to determine what column of what +** table in which database a result of a SELECT statement comes from. +** The name of the database or table or column can be returned as +** either a UTF8 or UTF16 string. The _database_ routines return +** the database name, the _table_ routines return the table name, and +** the origin_ routines return the column name. +** The returned string is valid until +** the [sqlite3_stmt | prepared statement] is destroyed using +** [sqlite3_finalize()] or until the same information is requested +** again in a different encoding. +** +** The names returned are the original un-aliased names of the +** database, table, and column. +** +** The first argument to the following calls is a +** [sqlite3_stmt | compiled SQL statement]. +** These functions return information about the Nth column returned by +** the statement, where N is the second function argument. +** +** If the Nth column returned by the statement is an expression +** or subquery and is not a column value, then all of these functions +** return NULL. Otherwise, they return the +** name of the attached database, table and column that query result +** column was extracted from. +** +** As with all other SQLite APIs, those postfixed with "16" return UTF-16 +** encoded strings, the other functions return UTF-8. +** +** These APIs are only available if the library was compiled with the +** SQLITE_ENABLE_COLUMN_METADATA preprocessor symbol defined. +** +** If two or more threads call one or more of these routines against the same +** prepared statement and column at the same time then the results are +** undefined. +*/ +const char *sqlite3_column_database_name(sqlite3_stmt*,int); +const void *sqlite3_column_database_name16(sqlite3_stmt*,int); +const char *sqlite3_column_table_name(sqlite3_stmt*,int); +const void *sqlite3_column_table_name16(sqlite3_stmt*,int); +const char *sqlite3_column_origin_name(sqlite3_stmt*,int); +const void *sqlite3_column_origin_name16(sqlite3_stmt*,int); + +/* +** CAPI3REF: Declared Datatype Of A Query Result +** +** The first parameter is a [sqlite3_stmt | compiled SQL statement]. +** If this statement is a SELECT statement and the Nth column of the +** returned result set of that SELECT is a table column (not an +** expression or subquery) then the declared type of the table +** column is returned. If the Nth column of the result set is an +** expression or subquery, then a NULL pointer is returned. +** The returned string is always UTF-8 encoded. For example, in +** the database schema: +** +** CREATE TABLE t1(c1 VARIANT); +** +** And the following statement compiled: +** +** SELECT c1 + 1, c1 FROM t1; +** +** Then this routine would return the string "VARIANT" for the second +** result column (i==1), and a NULL pointer for the first result column +** (i==0). +** +** SQLite uses dynamic run-time typing. So just because a column +** is declared to contain a particular type does not mean that the +** data stored in that column is of the declared type. SQLite is +** strongly typed, but the typing is dynamic not static. Type +** is associated with individual values, not with the containers +** used to hold those values. +*/ +const char *sqlite3_column_decltype(sqlite3_stmt *, int i); +const void *sqlite3_column_decltype16(sqlite3_stmt*,int); + +/* +** CAPI3REF: Evaluate An SQL Statement +** +** After an [sqlite3_stmt | SQL statement] has been prepared with a call +** to either [sqlite3_prepare_v2()] or [sqlite3_prepare16_v2()] or to one of +** the legacy interfaces [sqlite3_prepare()] or [sqlite3_prepare16()], +** then this function must be called one or more times to evaluate the +** statement. +** +** The details of the behavior of this sqlite3_step() interface depend +** on whether the statement was prepared using the newer "v2" interface +** [sqlite3_prepare_v2()] and [sqlite3_prepare16_v2()] or the older legacy +** interface [sqlite3_prepare()] and [sqlite3_prepare16()]. The use of the +** new "v2" interface is recommended for new applications but the legacy +** interface will continue to be supported. +** +** In the lagacy interface, the return value will be either [SQLITE_BUSY], +** [SQLITE_DONE], [SQLITE_ROW], [SQLITE_ERROR], or [SQLITE_MISUSE]. +** With the "v2" interface, any of the other [SQLITE_OK | result code] +** or [SQLITE_IOERR_READ | extended result code] might be returned as +** well. +** +** [SQLITE_BUSY] means that the database engine was unable to acquire the +** database locks it needs to do its job. If the statement is a COMMIT +** or occurs outside of an explicit transaction, then you can retry the +** statement. If the statement is not a COMMIT and occurs within a +** explicit transaction then you should rollback the transaction before +** continuing. +** +** [SQLITE_DONE] means that the statement has finished executing +** successfully. sqlite3_step() should not be called again on this virtual +** machine without first calling [sqlite3_reset()] to reset the virtual +** machine back to its initial state. +** +** If the SQL statement being executed returns any data, then +** [SQLITE_ROW] is returned each time a new row of data is ready +** for processing by the caller. The values may be accessed using +** the [sqlite3_column_int | column access functions]. +** sqlite3_step() is called again to retrieve the next row of data. +** +** [SQLITE_ERROR] means that a run-time error (such as a constraint +** violation) has occurred. sqlite3_step() should not be called again on +** the VM. More information may be found by calling [sqlite3_errmsg()]. +** With the legacy interface, a more specific error code (example: +** [SQLITE_INTERRUPT], [SQLITE_SCHEMA], [SQLITE_CORRUPT], and so forth) +** can be obtained by calling [sqlite3_reset()] on the +** [sqlite3_stmt | prepared statement]. In the "v2" interface, +** the more specific error code is returned directly by sqlite3_step(). +** +** [SQLITE_MISUSE] means that the this routine was called inappropriately. +** Perhaps it was called on a [sqlite3_stmt | prepared statement] that has +** already been [sqlite3_finalize | finalized] or on one that had +** previously returned [SQLITE_ERROR] or [SQLITE_DONE]. Or it could +** be the case that the same database connection is being used by two or +** more threads at the same moment in time. +** +** <b>Goofy Interface Alert:</b> +** In the legacy interface, +** the sqlite3_step() API always returns a generic error code, +** [SQLITE_ERROR], following any error other than [SQLITE_BUSY] +** and [SQLITE_MISUSE]. You must call [sqlite3_reset()] or +** [sqlite3_finalize()] in order to find one of the specific +** [SQLITE_ERROR | result codes] that better describes the error. +** We admit that this is a goofy design. The problem has been fixed +** with the "v2" interface. If you prepare all of your SQL statements +** using either [sqlite3_prepare_v2()] or [sqlite3_prepare16_v2()] instead +** of the legacy [sqlite3_prepare()] and [sqlite3_prepare16()], then the +** more specific [SQLITE_ERROR | result codes] are returned directly +** by sqlite3_step(). The use of the "v2" interface is recommended. +*/ +int sqlite3_step(sqlite3_stmt*); + +/* +** CAPI3REF: +** +** Return the number of values in the current row of the result set. +** +** After a call to [sqlite3_step()] that returns [SQLITE_ROW], this routine +** will return the same value as the [sqlite3_column_count()] function. +** After [sqlite3_step()] has returned an [SQLITE_DONE], [SQLITE_BUSY], or +** a [SQLITE_ERROR | error code], or before [sqlite3_step()] has been +** called on the [sqlite3_stmt | prepared statement] for the first time, +** this routine returns zero. +*/ +int sqlite3_data_count(sqlite3_stmt *pStmt); + +/* +** CAPI3REF: Fundamental Datatypes +** +** Every value in SQLite has one of five fundamental datatypes: +** +** <ul> +** <li> 64-bit signed integer +** <li> 64-bit IEEE floating point number +** <li> string +** <li> BLOB +** <li> NULL +** </ul> +** +** These constants are codes for each of those types. +** +** Note that the SQLITE_TEXT constant was also used in SQLite version 2 +** for a completely different meaning. Software that links against both +** SQLite version 2 and SQLite version 3 should use SQLITE3_TEXT not +** SQLITE_TEXT. +*/ +#define SQLITE_INTEGER 1 +#define SQLITE_FLOAT 2 +#define SQLITE_BLOB 4 +#define SQLITE_NULL 5 +#ifdef SQLITE_TEXT +# undef SQLITE_TEXT +#else +# define SQLITE_TEXT 3 +#endif +#define SQLITE3_TEXT 3 + +/* +** CAPI3REF: Results Values From A Query +** +** These routines return information about +** a single column of the current result row of a query. In every +** case the first argument is a pointer to the +** [sqlite3_stmt | SQL statement] that is being +** evaluated (the [sqlite3_stmt*] that was returned from +** [sqlite3_prepare_v2()] or one of its variants) and +** the second argument is the index of the column for which information +** should be returned. The left-most column of the result set +** has an index of 0. +** +** If the SQL statement is not currently point to a valid row, or if the +** the column index is out of range, the result is undefined. +** These routines may only be called when the most recent call to +** [sqlite3_step()] has returned [SQLITE_ROW] and neither +** [sqlite3_reset()] nor [sqlite3_finalize()] has been call subsequently. +** If any of these routines are called after [sqlite3_reset()] or +** [sqlite3_finalize()] or after [sqlite3_step()] has returned +** something other than [SQLITE_ROW], the results are undefined. +** If [sqlite3_step()] or [sqlite3_reset()] or [sqlite3_finalize()] +** are called from a different thread while any of these routines +** are pending, then the results are undefined. +** +** The sqlite3_column_type() routine returns +** [SQLITE_INTEGER | datatype code] for the initial data type +** of the result column. The returned value is one of [SQLITE_INTEGER], +** [SQLITE_FLOAT], [SQLITE_TEXT], [SQLITE_BLOB], or [SQLITE_NULL]. The value +** returned by sqlite3_column_type() is only meaningful if no type +** conversions have occurred as described below. After a type conversion, +** the value returned by sqlite3_column_type() is undefined. Future +** versions of SQLite may change the behavior of sqlite3_column_type() +** following a type conversion. +** +** If the result is a BLOB or UTF-8 string then the sqlite3_column_bytes() +** routine returns the number of bytes in that BLOB or string. +** If the result is a UTF-16 string, then sqlite3_column_bytes() converts +** the string to UTF-8 and then returns the number of bytes. +** If the result is a numeric value then sqlite3_column_bytes() uses +** [sqlite3_snprintf()] to convert that value to a UTF-8 string and returns +** the number of bytes in that string. +** The value returned does not include the zero terminator at the end +** of the string. For clarity: the value returned is the number of +** bytes in the string, not the number of characters. +** +** Strings returned by sqlite3_column_text() and sqlite3_column_text16(), +** even zero-length strings, are always zero terminated. The return +** value from sqlite3_column_blob() for a zero-length blob is an arbitrary +** pointer, possibly even a NULL pointer. +** +** The sqlite3_column_bytes16() routine is similar to sqlite3_column_bytes() +** but leaves the result in UTF-16 instead of UTF-8. +** The zero terminator is not included in this count. +** +** These routines attempt to convert the value where appropriate. For +** example, if the internal representation is FLOAT and a text result +** is requested, [sqlite3_snprintf()] is used internally to do the conversion +** automatically. The following table details the conversions that +** are applied: +** +** <blockquote> +** <table border="1"> +** <tr><th> Internal<br>Type <th> Requested<br>Type <th> Conversion +** +** <tr><td> NULL <td> INTEGER <td> Result is 0 +** <tr><td> NULL <td> FLOAT <td> Result is 0.0 +** <tr><td> NULL <td> TEXT <td> Result is NULL pointer +** <tr><td> NULL <td> BLOB <td> Result is NULL pointer +** <tr><td> INTEGER <td> FLOAT <td> Convert from integer to float +** <tr><td> INTEGER <td> TEXT <td> ASCII rendering of the integer +** <tr><td> INTEGER <td> BLOB <td> Same as for INTEGER->TEXT +** <tr><td> FLOAT <td> INTEGER <td> Convert from float to integer +** <tr><td> FLOAT <td> TEXT <td> ASCII rendering of the float +** <tr><td> FLOAT <td> BLOB <td> Same as FLOAT->TEXT +** <tr><td> TEXT <td> INTEGER <td> Use atoi() +** <tr><td> TEXT <td> FLOAT <td> Use atof() +** <tr><td> TEXT <td> BLOB <td> No change +** <tr><td> BLOB <td> INTEGER <td> Convert to TEXT then use atoi() +** <tr><td> BLOB <td> FLOAT <td> Convert to TEXT then use atof() +** <tr><td> BLOB <td> TEXT <td> Add a zero terminator if needed +** </table> +** </blockquote> +** +** The table above makes reference to standard C library functions atoi() +** and atof(). SQLite does not really use these functions. It has its +** on equavalent internal routines. The atoi() and atof() names are +** used in the table for brevity and because they are familiar to most +** C programmers. +** +** Note that when type conversions occur, pointers returned by prior +** calls to sqlite3_column_blob(), sqlite3_column_text(), and/or +** sqlite3_column_text16() may be invalidated. +** Type conversions and pointer invalidations might occur +** in the following cases: +** +** <ul> +** <li><p> The initial content is a BLOB and sqlite3_column_text() +** or sqlite3_column_text16() is called. A zero-terminator might +** need to be added to the string.</p></li> +** +** <li><p> The initial content is UTF-8 text and sqlite3_column_bytes16() or +** sqlite3_column_text16() is called. The content must be converted +** to UTF-16.</p></li> +** +** <li><p> The initial content is UTF-16 text and sqlite3_column_bytes() or +** sqlite3_column_text() is called. The content must be converted +** to UTF-8.</p></li> +** </ul> +** +** Conversions between UTF-16be and UTF-16le are always done in place and do +** not invalidate a prior pointer, though of course the content of the buffer +** that the prior pointer points to will have been modified. Other kinds +** of conversion are done in place when it is possible, but sometime it is +** not possible and in those cases prior pointers are invalidated. +** +** The safest and easiest to remember policy is to invoke these routines +** in one of the following ways: +** +** <ul> +** <li>sqlite3_column_text() followed by sqlite3_column_bytes()</li> +** <li>sqlite3_column_blob() followed by sqlite3_column_bytes()</li> +** <li>sqlite3_column_text16() followed by sqlite3_column_bytes16()</li> +** </ul> +** +** In other words, you should call sqlite3_column_text(), sqlite3_column_blob(), +** or sqlite3_column_text16() first to force the result into the desired +** format, then invoke sqlite3_column_bytes() or sqlite3_column_bytes16() to +** find the size of the result. Do not mix call to sqlite3_column_text() or +** sqlite3_column_blob() with calls to sqlite3_column_bytes16(). And do not +** mix calls to sqlite3_column_text16() with calls to sqlite3_column_bytes(). +** +** The pointers returned are valid until a type conversion occurs as +** described above, or until [sqlite3_step()] or [sqlite3_reset()] or +** [sqlite3_finalize()] is called. The memory space used to hold strings +** and blobs is freed automatically. Do <b>not</b> pass the pointers returned +** [sqlite3_column_blob()], [sqlite3_column_text()], etc. into +** [sqlite3_free()]. +** +** If a memory allocation error occurs during the evaluation of any +** of these routines, a default value is returned. The default value +** is either the integer 0, the floating point number 0.0, or a NULL +** pointer. Subsequent calls to [sqlite3_errcode()] will return +** [SQLITE_NOMEM]. +*/ +const void *sqlite3_column_blob(sqlite3_stmt*, int iCol); +int sqlite3_column_bytes(sqlite3_stmt*, int iCol); +int sqlite3_column_bytes16(sqlite3_stmt*, int iCol); +double sqlite3_column_double(sqlite3_stmt*, int iCol); +int sqlite3_column_int(sqlite3_stmt*, int iCol); +sqlite3_int64 sqlite3_column_int64(sqlite3_stmt*, int iCol); +const unsigned char *sqlite3_column_text(sqlite3_stmt*, int iCol); +const void *sqlite3_column_text16(sqlite3_stmt*, int iCol); +int sqlite3_column_type(sqlite3_stmt*, int iCol); +sqlite3_value *sqlite3_column_value(sqlite3_stmt*, int iCol); + +/* +** CAPI3REF: Destroy A Prepared Statement Object +** +** The sqlite3_finalize() function is called to delete a +** [sqlite3_stmt | compiled SQL statement]. If the statement was +** executed successfully, or not executed at all, then SQLITE_OK is returned. +** If execution of the statement failed then an +** [SQLITE_ERROR | error code] or [SQLITE_IOERR_READ | extended error code] +** is returned. +** +** This routine can be called at any point during the execution of the +** [sqlite3_stmt | virtual machine]. If the virtual machine has not +** completed execution when this routine is called, that is like +** encountering an error or an interrupt. (See [sqlite3_interrupt()].) +** Incomplete updates may be rolled back and transactions cancelled, +** depending on the circumstances, and the +** [SQLITE_ERROR | result code] returned will be [SQLITE_ABORT]. +*/ +int sqlite3_finalize(sqlite3_stmt *pStmt); + +/* +** CAPI3REF: Reset A Prepared Statement Object +** +** The sqlite3_reset() function is called to reset a +** [sqlite3_stmt | compiled SQL statement] object. +** back to it's initial state, ready to be re-executed. +** Any SQL statement variables that had values bound to them using +** the [sqlite3_bind_blob | sqlite3_bind_*() API] retain their values. +** Use [sqlite3_clear_bindings()] to reset the bindings. +*/ +int sqlite3_reset(sqlite3_stmt *pStmt); + +/* +** CAPI3REF: Create Or Redefine SQL Functions +** +** The following two functions are used to add SQL functions or aggregates +** or to redefine the behavior of existing SQL functions or aggregates. The +** difference only between the two is that the second parameter, the +** name of the (scalar) function or aggregate, is encoded in UTF-8 for +** sqlite3_create_function() and UTF-16 for sqlite3_create_function16(). +** +** The first argument is the [sqlite3 | database handle] that holds the +** SQL function or aggregate is to be added or redefined. If a single +** program uses more than one database handle internally, then SQL +** functions or aggregates must be added individually to each database +** handle with which they will be used. +** +** The second parameter is the name of the SQL function to be created +** or redefined. +** The length of the name is limited to 255 bytes, exclusive of the +** zero-terminator. Note that the name length limit is in bytes, not +** characters. Any attempt to create a function with a longer name +** will result in an SQLITE_ERROR error. +** +** The third parameter is the number of arguments that the SQL function or +** aggregate takes. If this parameter is negative, then the SQL function or +** aggregate may take any number of arguments. +** +** The fourth parameter, eTextRep, specifies what +** [SQLITE_UTF8 | text encoding] this SQL function prefers for +** its parameters. Any SQL function implementation should be able to work +** work with UTF-8, UTF-16le, or UTF-16be. But some implementations may be +** more efficient with one encoding than another. It is allowed to +** invoke sqlite3_create_function() or sqlite3_create_function16() multiple +** times with the same function but with different values of eTextRep. +** When multiple implementations of the same function are available, SQLite +** will pick the one that involves the least amount of data conversion. +** If there is only a single implementation which does not care what +** text encoding is used, then the fourth argument should be +** [SQLITE_ANY]. +** +** The fifth parameter is an arbitrary pointer. The implementation +** of the function can gain access to this pointer using +** [sqlite3_user_data()]. +** +** The seventh, eighth and ninth parameters, xFunc, xStep and xFinal, are +** pointers to C-language functions that implement the SQL +** function or aggregate. A scalar SQL function requires an implementation of +** the xFunc callback only, NULL pointers should be passed as the xStep +** and xFinal parameters. An aggregate SQL function requires an implementation +** of xStep and xFinal and NULL should be passed for xFunc. To delete an +** existing SQL function or aggregate, pass NULL for all three function +** callback. +** +** It is permitted to register multiple implementations of the same +** functions with the same name but with either differing numbers of +** arguments or differing perferred text encodings. SQLite will use +** the implementation most closely matches the way in which the +** SQL function is used. +*/ +int sqlite3_create_function( + sqlite3 *, + const char *zFunctionName, + int nArg, + int eTextRep, + void*, + void (*xFunc)(sqlite3_context*,int,sqlite3_value**), + void (*xStep)(sqlite3_context*,int,sqlite3_value**), + void (*xFinal)(sqlite3_context*) +); +int sqlite3_create_function16( + sqlite3*, + const void *zFunctionName, + int nArg, + int eTextRep, + void*, + void (*xFunc)(sqlite3_context*,int,sqlite3_value**), + void (*xStep)(sqlite3_context*,int,sqlite3_value**), + void (*xFinal)(sqlite3_context*) +); + +/* +** CAPI3REF: Text Encodings +** +** These constant define integer codes that represent the various +** text encodings supported by SQLite. +*/ +#define SQLITE_UTF8 1 +#define SQLITE_UTF16LE 2 +#define SQLITE_UTF16BE 3 +#define SQLITE_UTF16 4 /* Use native byte order */ +#define SQLITE_ANY 5 /* sqlite3_create_function only */ +#define SQLITE_UTF16_ALIGNED 8 /* sqlite3_create_collation only */ + +/* +** CAPI3REF: Obsolete Functions +** +** These functions are all now obsolete. In order to maintain +** backwards compatibility with older code, we continue to support +** these functions. However, new development projects should avoid +** the use of these functions. To help encourage people to avoid +** using these functions, we are not going to tell you want they do. +*/ +int sqlite3_aggregate_count(sqlite3_context*); +int sqlite3_expired(sqlite3_stmt*); +int sqlite3_transfer_bindings(sqlite3_stmt*, sqlite3_stmt*); +int sqlite3_global_recover(void); +void sqlite3_thread_cleanup(void); +int sqlite3_memory_alarm(void(*)(void*,sqlite3_int64,int),void*,sqlite3_int64); + +/* +** CAPI3REF: Obtaining SQL Function Parameter Values +** +** The C-language implementation of SQL functions and aggregates uses +** this set of interface routines to access the parameter values on +** the function or aggregate. +** +** The xFunc (for scalar functions) or xStep (for aggregates) parameters +** to [sqlite3_create_function()] and [sqlite3_create_function16()] +** define callbacks that implement the SQL functions and aggregates. +** The 4th parameter to these callbacks is an array of pointers to +** [sqlite3_value] objects. There is one [sqlite3_value] object for +** each parameter to the SQL function. These routines are used to +** extract values from the [sqlite3_value] objects. +** +** These routines work just like the corresponding +** [sqlite3_column_blob | sqlite3_column_* routines] except that +** these routines take a single [sqlite3_value*] pointer instead +** of an [sqlite3_stmt*] pointer and an integer column number. +** +** The sqlite3_value_text16() interface extracts a UTF16 string +** in the native byte-order of the host machine. The +** sqlite3_value_text16be() and sqlite3_value_text16le() interfaces +** extract UTF16 strings as big-endian and little-endian respectively. +** +** The sqlite3_value_numeric_type() interface attempts to apply +** numeric affinity to the value. This means that an attempt is +** made to convert the value to an integer or floating point. If +** such a conversion is possible without loss of information (in order +** words if the value is original a string that looks like a number) +** then it is done. Otherwise no conversion occurs. The +** [SQLITE_INTEGER | datatype] after conversion is returned. +** +** Please pay particular attention to the fact that the pointer that +** is returned from [sqlite3_value_blob()], [sqlite3_value_text()], or +** [sqlite3_value_text16()] can be invalidated by a subsequent call to +** [sqlite3_value_bytes()], [sqlite3_value_bytes16()], [sqlite3_value_text()], +** or [sqlite3_value_text16()]. +** +** These routines must be called from the same thread as +** the SQL function that supplied the sqlite3_value* parameters. +** Or, if the sqlite3_value* argument comes from the [sqlite3_column_value()] +** interface, then these routines should be called from the same thread +** that ran [sqlite3_column_value()]. +*/ +const void *sqlite3_value_blob(sqlite3_value*); +int sqlite3_value_bytes(sqlite3_value*); +int sqlite3_value_bytes16(sqlite3_value*); +double sqlite3_value_double(sqlite3_value*); +int sqlite3_value_int(sqlite3_value*); +sqlite3_int64 sqlite3_value_int64(sqlite3_value*); +const unsigned char *sqlite3_value_text(sqlite3_value*); +const void *sqlite3_value_text16(sqlite3_value*); +const void *sqlite3_value_text16le(sqlite3_value*); +const void *sqlite3_value_text16be(sqlite3_value*); +int sqlite3_value_type(sqlite3_value*); +int sqlite3_value_numeric_type(sqlite3_value*); + +/* +** CAPI3REF: Obtain Aggregate Function Context +** +** The implementation of aggregate SQL functions use this routine to allocate +** a structure for storing their state. The first time this routine +** is called for a particular aggregate, a new structure of size nBytes +** is allocated, zeroed, and returned. On subsequent calls (for the +** same aggregate instance) the same buffer is returned. The implementation +** of the aggregate can use the returned buffer to accumulate data. +** +** The buffer allocated is freed automatically by SQLite whan the aggregate +** query concludes. +** +** The first parameter should be a copy of the +** [sqlite3_context | SQL function context] that is the first +** parameter to the callback routine that implements the aggregate +** function. +** +** This routine must be called from the same thread in which +** the aggregate SQL function is running. +*/ +void *sqlite3_aggregate_context(sqlite3_context*, int nBytes); + +/* +** CAPI3REF: User Data For Functions +** +** The pUserData parameter to the [sqlite3_create_function()] +** and [sqlite3_create_function16()] routines +** used to register user functions is available to +** the implementation of the function using this call. +** +** This routine must be called from the same thread in which +** the SQL function is running. +*/ +void *sqlite3_user_data(sqlite3_context*); + +/* +** CAPI3REF: Function Auxiliary Data +** +** The following two functions may be used by scalar SQL functions to +** associate meta-data with argument values. If the same value is passed to +** multiple invocations of the same SQL function during query execution, under +** some circumstances the associated meta-data may be preserved. This may +** be used, for example, to add a regular-expression matching scalar +** function. The compiled version of the regular expression is stored as +** meta-data associated with the SQL value passed as the regular expression +** pattern. The compiled regular expression can be reused on multiple +** invocations of the same function so that the original pattern string +** does not need to be recompiled on each invocation. +** +** The sqlite3_get_auxdata() interface returns a pointer to the meta-data +** associated with the Nth argument value to the current SQL function +** call, where N is the second parameter. If no meta-data has been set for +** that value, then a NULL pointer is returned. +** +** The sqlite3_set_auxdata() is used to associate meta-data with an SQL +** function argument. The third parameter is a pointer to the meta-data +** to be associated with the Nth user function argument value. The fourth +** parameter specifies a destructor that will be called on the meta- +** data pointer to release it when it is no longer required. If the +** destructor is NULL, it is not invoked. +** +** In practice, meta-data is preserved between function calls for +** expressions that are constant at compile time. This includes literal +** values and SQL variables. +** +** These routines must be called from the same thread in which +** the SQL function is running. +*/ +void *sqlite3_get_auxdata(sqlite3_context*, int); +void sqlite3_set_auxdata(sqlite3_context*, int, void*, void (*)(void*)); + + +/* +** CAPI3REF: Constants Defining Special Destructor Behavior +** +** These are special value for the destructor that is passed in as the +** final argument to routines like [sqlite3_result_blob()]. If the destructor +** argument is SQLITE_STATIC, it means that the content pointer is constant +** and will never change. It does not need to be destroyed. The +** SQLITE_TRANSIENT value means that the content will likely change in +** the near future and that SQLite should make its own private copy of +** the content before returning. +** +** The typedef is necessary to work around problems in certain +** C++ compilers. See ticket #2191. +*/ +typedef void (*sqlite3_destructor_type)(void*); +#define SQLITE_STATIC ((sqlite3_destructor_type)0) +#define SQLITE_TRANSIENT ((sqlite3_destructor_type)-1) + +/* +** CAPI3REF: Setting The Result Of An SQL Function +** +** These routines are used by the xFunc or xFinal callbacks that +** implement SQL functions and aggregates. See +** [sqlite3_create_function()] and [sqlite3_create_function16()] +** for additional information. +** +** These functions work very much like the +** [sqlite3_bind_blob | sqlite3_bind_*] family of functions used +** to bind values to host parameters in prepared statements. +** Refer to the +** [sqlite3_bind_blob | sqlite3_bind_* documentation] for +** additional information. +** +** The sqlite3_result_error() and sqlite3_result_error16() functions +** cause the implemented SQL function to throw an exception. The +** parameter to sqlite3_result_error() or sqlite3_result_error16() +** is the text of an error message. +** +** The sqlite3_result_toobig() cause the function implementation +** to throw and error indicating that a string or BLOB is to long +** to represent. +** +** These routines must be called from within the same thread as +** the SQL function associated with the [sqlite3_context] pointer. +*/ +void sqlite3_result_blob(sqlite3_context*, const void*, int, void(*)(void*)); +void sqlite3_result_double(sqlite3_context*, double); +void sqlite3_result_error(sqlite3_context*, const char*, int); +void sqlite3_result_error16(sqlite3_context*, const void*, int); +void sqlite3_result_error_toobig(sqlite3_context*); +void sqlite3_result_error_nomem(sqlite3_context*); +void sqlite3_result_int(sqlite3_context*, int); +void sqlite3_result_int64(sqlite3_context*, sqlite3_int64); +void sqlite3_result_null(sqlite3_context*); +void sqlite3_result_text(sqlite3_context*, const char*, int, void(*)(void*)); +void sqlite3_result_text16(sqlite3_context*, const void*, int, void(*)(void*)); +void sqlite3_result_text16le(sqlite3_context*, const void*, int,void(*)(void*)); +void sqlite3_result_text16be(sqlite3_context*, const void*, int,void(*)(void*)); +void sqlite3_result_value(sqlite3_context*, sqlite3_value*); +void sqlite3_result_zeroblob(sqlite3_context*, int n); + +/* +** CAPI3REF: Define New Collating Sequences +** +** These functions are used to add new collation sequences to the +** [sqlite3*] handle specified as the first argument. +** +** The name of the new collation sequence is specified as a UTF-8 string +** for sqlite3_create_collation() and sqlite3_create_collation_v2() +** and a UTF-16 string for sqlite3_create_collation16(). In all cases +** the name is passed as the second function argument. +** +** The third argument may be one of the constants [SQLITE_UTF8], +** [SQLITE_UTF16LE] or [SQLITE_UTF16BE], indicating that the user-supplied +** routine expects to be passed pointers to strings encoded using UTF-8, +** UTF-16 little-endian or UTF-16 big-endian respectively. The +** third argument might also be [SQLITE_UTF16_ALIGNED] to indicate that +** the routine expects pointers to 16-bit word aligned strings +** of UTF16 in the native byte order of the host computer. +** +** A pointer to the user supplied routine must be passed as the fifth +** argument. If it is NULL, this is the same as deleting the collation +** sequence (so that SQLite cannot call it anymore). Each time the user +** supplied function is invoked, it is passed a copy of the void* passed as +** the fourth argument to sqlite3_create_collation() or +** sqlite3_create_collation16() as its first parameter. +** +** The remaining arguments to the user-supplied routine are two strings, +** each represented by a [length, data] pair and encoded in the encoding +** that was passed as the third argument when the collation sequence was +** registered. The user routine should return negative, zero or positive if +** the first string is less than, equal to, or greater than the second +** string. i.e. (STRING1 - STRING2). +** +** The sqlite3_create_collation_v2() works like sqlite3_create_collation() +** excapt that it takes an extra argument which is a destructor for +** the collation. The destructor is called when the collation is +** destroyed and is passed a copy of the fourth parameter void* pointer +** of the sqlite3_create_collation_v2(). Collations are destroyed when +** they are overridden by later calls to the collation creation functions +** or when the [sqlite3*] database handle is closed using [sqlite3_close()]. +** +** The sqlite3_create_collation_v2() interface is experimental and +** subject to change in future releases. The other collation creation +** functions are stable. +*/ +int sqlite3_create_collation( + sqlite3*, + const char *zName, + int eTextRep, + void*, + int(*xCompare)(void*,int,const void*,int,const void*) +); +int sqlite3_create_collation_v2( + sqlite3*, + const char *zName, + int eTextRep, + void*, + int(*xCompare)(void*,int,const void*,int,const void*), + void(*xDestroy)(void*) +); +int sqlite3_create_collation16( + sqlite3*, + const char *zName, + int eTextRep, + void*, + int(*xCompare)(void*,int,const void*,int,const void*) +); + +/* +** CAPI3REF: 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 handle to be called whenever an undefined collation sequence is +** required. +** +** If the function is registered using the sqlite3_collation_needed() API, +** then it is passed the names of undefined collation sequences as strings +** encoded in UTF-8. If sqlite3_collation_needed16() is used, the names +** are passed as UTF-16 in machine native byte order. A call to either +** function replaces any existing callback. +** +** When the callback is invoked, the first argument passed is a copy +** of the second argument to sqlite3_collation_needed() or +** sqlite3_collation_needed16(). The second argument is the database +** handle. The third argument is one of [SQLITE_UTF8], [SQLITE_UTF16BE], or +** [SQLITE_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 +** [sqlite3_create_collation()], [sqlite3_create_collation16()], or +** [sqlite3_create_collation_v2()]. +*/ +int sqlite3_collation_needed( + sqlite3*, + void*, + void(*)(void*,sqlite3*,int eTextRep,const char*) +); +int sqlite3_collation_needed16( + sqlite3*, + void*, + void(*)(void*,sqlite3*,int eTextRep,const void*) +); + +/* +** Specify the key for an encrypted database. This routine should be +** called right after sqlite3_open(). +** +** The code to implement this API is not available in the public release +** of SQLite. +*/ +int sqlite3_key( + sqlite3 *db, /* Database to be rekeyed */ + const void *pKey, int nKey /* The key */ +); + +/* +** Change the key on an open database. If the current database is not +** encrypted, this routine will encrypt it. If pNew==0 or nNew==0, the +** database is decrypted. +** +** The code to implement this API is not available in the public release +** of SQLite. +*/ +int sqlite3_rekey( + sqlite3 *db, /* Database to be rekeyed */ + const void *pKey, int nKey /* The new key */ +); + +/* +** CAPI3REF: Suspend Execution For A Short Time +** +** This function causes the current thread to suspend execution +** a number of milliseconds specified in its parameter. +** +** If the operating system does not support sleep requests with +** millisecond time resolution, then the time will be rounded up to +** the nearest second. The number of milliseconds of sleep actually +** requested from the operating system is returned. +** +** SQLite implements this interface by calling the xSleep() +** method of the default [sqlite3_vfs] object. +*/ +int sqlite3_sleep(int); + +/* +** CAPI3REF: Name Of The Folder Holding Temporary Files +** +** If this global variable is made to point to a string which is +** the name of a folder (a.ka. directory), then all temporary files +** created by SQLite will be placed in that directory. If this variable +** is NULL pointer, then SQLite does a search for an appropriate temporary +** file directory. +** +** It is not safe to modify this variable once a database connection +** has been opened. It is intended that this variable be set once +** as part of process initialization and before any SQLite interface +** routines have been call and remain unchanged thereafter. +*/ +SQLITE_EXTERN char *sqlite3_temp_directory; + +/* +** CAPI3REF: Test To See If The Database Is In Auto-Commit Mode +** +** Test to see whether or not the database connection is in autocommit +** mode. Return TRUE if it is and FALSE if not. Autocommit mode is on +** by default. Autocommit is disabled by a BEGIN statement and reenabled +** by the next COMMIT or ROLLBACK. +** +** If certain kinds of errors occur on a statement within a multi-statement +** transactions (errors including [SQLITE_FULL], [SQLITE_IOERR], +** [SQLITE_NOMEM], [SQLITE_BUSY], and [SQLITE_INTERRUPT]) then the +** transaction might be rolled back automatically. The only way to +** find out if SQLite automatically rolled back the transaction after +** an error is to use this function. +** +** If another thread changes the autocommit status of the database +** connection while this routine is running, then the return value +** is undefined. +*/ +int sqlite3_get_autocommit(sqlite3*); + +/* +** CAPI3REF: Find The Database Handle Associated With A Prepared Statement +** +** Return the [sqlite3*] database handle to which a +** [sqlite3_stmt | prepared statement] belongs. +** This is the same database handle that was +** the first argument to the [sqlite3_prepare_v2()] or its variants +** that was used to create the statement in the first place. +*/ +sqlite3 *sqlite3_db_handle(sqlite3_stmt*); + + +/* +** CAPI3REF: Commit And Rollback Notification Callbacks +** +** These routines +** register callback functions to be invoked whenever a transaction +** is committed or rolled back. The pArg argument is passed through +** to the callback. If the callback on a commit hook function +** returns non-zero, then the commit is converted into a rollback. +** +** If another function was previously registered, its pArg value is returned. +** Otherwise NULL is returned. +** +** Registering a NULL function disables the callback. +** +** For the purposes of this API, a transaction is said to have been +** rolled back if an explicit "ROLLBACK" statement is executed, or +** an error or constraint causes an implicit rollback to occur. The +** callback is not invoked if a transaction is automatically rolled +** back because the database connection is closed. +** +** These are experimental interfaces and are subject to change. +*/ +void *sqlite3_commit_hook(sqlite3*, int(*)(void*), void*); +void *sqlite3_rollback_hook(sqlite3*, void(*)(void *), void*); + +/* +** CAPI3REF: Data Change Notification Callbacks +** +** Register a callback function with the database connection identified by the +** first argument to be invoked whenever a row is updated, inserted or deleted. +** Any callback set by a previous call to this function for the same +** database connection is overridden. +** +** The second argument is a pointer to the function to invoke when a +** row is updated, inserted or deleted. The first argument to the callback is +** a copy of the third argument to sqlite3_update_hook(). The second callback +** argument is one of SQLITE_INSERT, SQLITE_DELETE or SQLITE_UPDATE, depending +** on the operation that caused the callback to be invoked. The third and +** fourth arguments to the callback contain pointers to the database and +** table name containing the affected row. The final callback parameter is +** the rowid of the row. In the case of an update, this is the rowid after +** the update takes place. +** +** The update hook is not invoked when internal system tables are +** modified (i.e. sqlite_master and sqlite_sequence). +** +** If another function was previously registered, its pArg value is returned. +** Otherwise NULL is returned. +*/ +void *sqlite3_update_hook( + sqlite3*, + void(*)(void *,int ,char const *,char const *,sqlite3_int64), + void* +); + +/* +** CAPI3REF: Enable Or Disable Shared Pager Cache +** +** This routine enables or disables the sharing of the database cache +** and schema data structures between connections to the same database. +** Sharing is enabled if the argument is true and disabled if the argument +** is false. +** +** Beginning in SQLite version 3.5.0, cache sharing is enabled and disabled +** for an entire process. In prior versions of SQLite, sharing was +** enabled or disabled for each thread separately. +** +** The cache sharing mode set by this interface effects all subsequent +** calls to [sqlite3_open()], [sqlite3_open_v2()], and [sqlite3_open16()]. +** Existing database connections continue use the sharing mode that was +** in effect at the time they were opened. +** +** Virtual tables cannot be used with a shared cache. When shared +** cache is enabled, the [sqlite3_create_module()] API used to register +** virtual tables will always return an error. +** +** This routine returns [SQLITE_OK] if shared cache was +** enabled or disabled successfully. An [SQLITE_ERROR | error code] +** is returned otherwise. +** +** Shared cache is disabled by default. But this might change in +** future releases of SQLite. Applications that care about shared +** cache setting should set it explicitly. +*/ +int sqlite3_enable_shared_cache(int); + +/* +** CAPI3REF: Attempt To Free Heap Memory +** +** Attempt to free N bytes of heap memory by deallocating non-essential +** memory allocations held by the database library (example: memory +** used to cache database pages to improve performance). +*/ +int sqlite3_release_memory(int); + +/* +** CAPI3REF: Impose A Limit On Heap Size +** +** Place a "soft" limit on the amount of heap memory that may be allocated +** by SQLite. If an internal allocation is requested +** that would exceed the specified limit, [sqlite3_release_memory()] is +** invoked one or more times to free up some space before the allocation +** is made. +** +** The limit is called "soft", because if [sqlite3_release_memory()] cannot +** free sufficient memory to prevent the limit from being exceeded, +** the memory is allocated anyway and the current operation proceeds. +** +** A negative or zero value for N means that there is no soft heap limit and +** [sqlite3_release_memory()] will only be called when memory is exhausted. +** The default value for the soft heap limit is zero. +** +** SQLite makes a best effort to honor the soft heap limit. But if it +** is unable to reduce memory usage below the soft limit, execution will +** continue without error or notification. This is why the limit is +** called a "soft" limit. It is advisory only. +** +** Prior to SQLite version 3.5.0, this routine only constrained the memory +** allocated by a single thread - the same thread in which this routine +** runs. Beginning with SQLite version 3.5.0, the soft heap limit is +** applied to all threads. The value specified for the soft heap limit +** is an upper bound on the total memory allocation for all threads. In +** version 3.5.0 there is no mechanism for limiting the heap usage for +** individual threads. +*/ +void sqlite3_soft_heap_limit(int); + +/* +** CAPI3REF: Extract Metadata About A Column Of A Table +** +** This routine +** returns meta-data about a specific column of a specific database +** table accessible using the connection handle passed as the first function +** argument. +** +** The column is identified by the second, third and fourth parameters to +** this function. The second parameter is either the name of the database +** (i.e. "main", "temp" or an attached database) containing the specified +** table or NULL. If it is NULL, then all attached databases are searched +** for the table using the same algorithm as the database engine uses to +** resolve unqualified table references. +** +** The third and fourth parameters to this function are the table and column +** name of the desired column, respectively. Neither of these parameters +** may be NULL. +** +** Meta information is returned by writing to the memory locations passed as +** the 5th and subsequent parameters to this function. Any of these +** arguments may be NULL, in which case the corresponding element of meta +** information is ommitted. +** +** <pre> +** Parameter Output Type Description +** ----------------------------------- +** +** 5th const char* Data type +** 6th const char* Name of the default collation sequence +** 7th int True if the column has a NOT NULL constraint +** 8th int True if the column is part of the PRIMARY KEY +** 9th int True if the column is AUTOINCREMENT +** </pre> +** +** +** The memory pointed to by the character pointers returned for the +** declaration type and collation sequence is valid only until the next +** call to any sqlite API function. +** +** If the specified table is actually a view, then an error is returned. +** +** If the specified column is "rowid", "oid" or "_rowid_" and an +** INTEGER PRIMARY KEY column has been explicitly declared, then the output +** parameters are set for the explicitly declared column. If there is no +** explicitly declared IPK column, then the output parameters are set as +** follows: +** +** <pre> +** data type: "INTEGER" +** collation sequence: "BINARY" +** not null: 0 +** primary key: 1 +** auto increment: 0 +** </pre> +** +** This function may load one or more schemas from database files. If an +** error occurs during this process, or if the requested table or column +** cannot be found, an SQLITE error code is returned and an error message +** left in the database handle (to be retrieved using sqlite3_errmsg()). +** +** This API is only available if the library was compiled with the +** SQLITE_ENABLE_COLUMN_METADATA preprocessor symbol defined. +*/ +int sqlite3_table_column_metadata( + sqlite3 *db, /* Connection handle */ + const char *zDbName, /* Database name or NULL */ + const char *zTableName, /* Table name */ + const char *zColumnName, /* Column name */ + char const **pzDataType, /* OUTPUT: Declared data type */ + char const **pzCollSeq, /* OUTPUT: Collation sequence name */ + int *pNotNull, /* OUTPUT: True if NOT NULL constraint exists */ + int *pPrimaryKey, /* OUTPUT: True if column part of PK */ + int *pAutoinc /* OUTPUT: True if column is auto-increment */ +); + +/* +** CAPI3REF: Load An Extension +** +** Attempt to load an SQLite extension library contained in the file +** zFile. The entry point is zProc. zProc may be 0 in which case the +** name of the entry point defaults to "sqlite3_extension_init". +** +** Return [SQLITE_OK] on success and [SQLITE_ERROR] if something goes wrong. +** +** If an error occurs and pzErrMsg is not 0, then fill *pzErrMsg with +** error message text. The calling function should free this memory +** by calling [sqlite3_free()]. +** +** Extension loading must be enabled using [sqlite3_enable_load_extension()] +** prior to calling this API or an error will be returned. +*/ +int sqlite3_load_extension( + sqlite3 *db, /* Load the extension into this database connection */ + const char *zFile, /* Name of the shared library containing extension */ + const char *zProc, /* Entry point. Derived from zFile if 0 */ + char **pzErrMsg /* Put error message here if not 0 */ +); + +/* +** CAPI3REF: Enable Or Disable Extension Loading +** +** So as not to open security holes in older applications that are +** unprepared to deal with extension loading, and as a means of disabling +** extension loading while evaluating user-entered SQL, the following +** API is provided to turn the [sqlite3_load_extension()] mechanism on and +** off. It is off by default. See ticket #1863. +** +** Call this routine with onoff==1 to turn extension loading on +** and call it with onoff==0 to turn it back off again. +*/ +int sqlite3_enable_load_extension(sqlite3 *db, int onoff); + +/* +** CAPI3REF: Make Arrangements To Automatically Load An Extension +** +** Register an extension entry point that is automatically invoked +** whenever a new database connection is opened using +** [sqlite3_open()], [sqlite3_open16()], or [sqlite3_open_v2()]. +** +** This API can be invoked at program startup in order to register +** one or more statically linked extensions that will be available +** to all new database connections. +** +** Duplicate extensions are detected so calling this routine multiple +** times with the same extension is harmless. +** +** This routine stores a pointer to the extension in an array +** that is obtained from malloc(). If you run a memory leak +** checker on your program and it reports a leak because of this +** array, then invoke [sqlite3_reset_auto_extension()] prior +** to shutdown to free the memory. +** +** Automatic extensions apply across all threads. +** +** This interface is experimental and is subject to change or +** removal in future releases of SQLite. +*/ +int sqlite3_auto_extension(void *xEntryPoint); + + +/* +** CAPI3REF: Reset Automatic Extension Loading +** +** Disable all previously registered automatic extensions. This +** routine undoes the effect of all prior [sqlite3_automatic_extension()] +** calls. +** +** This call disabled automatic extensions in all threads. +** +** This interface is experimental and is subject to change or +** removal in future releases of SQLite. +*/ +void sqlite3_reset_auto_extension(void); + + +/* +****** EXPERIMENTAL - subject to change without notice ************** +** +** The interface to the virtual-table mechanism is currently considered +** to be experimental. The interface might change in incompatible ways. +** If this is a problem for you, do not use the interface at this time. +** +** When the virtual-table mechanism stablizes, we will declare the +** interface fixed, support it indefinitely, and remove this comment. +*/ + +/* +** Structures used by the virtual table interface +*/ +typedef struct sqlite3_vtab sqlite3_vtab; +typedef struct sqlite3_index_info sqlite3_index_info; +typedef struct sqlite3_vtab_cursor sqlite3_vtab_cursor; +typedef struct sqlite3_module sqlite3_module; + +/* +** A module is a class of virtual tables. Each module is defined +** by an instance of the following structure. This structure consists +** mostly of methods for the module. +*/ +struct sqlite3_module { + int iVersion; + int (*xCreate)(sqlite3*, void *pAux, + int argc, const char *const*argv, + sqlite3_vtab **ppVTab, char**); + int (*xConnect)(sqlite3*, void *pAux, + int argc, const char *const*argv, + sqlite3_vtab **ppVTab, char**); + int (*xBestIndex)(sqlite3_vtab *pVTab, sqlite3_index_info*); + int (*xDisconnect)(sqlite3_vtab *pVTab); + int (*xDestroy)(sqlite3_vtab *pVTab); + int (*xOpen)(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor); + int (*xClose)(sqlite3_vtab_cursor*); + int (*xFilter)(sqlite3_vtab_cursor*, int idxNum, const char *idxStr, + int argc, sqlite3_value **argv); + int (*xNext)(sqlite3_vtab_cursor*); + int (*xEof)(sqlite3_vtab_cursor*); + int (*xColumn)(sqlite3_vtab_cursor*, sqlite3_context*, int); + int (*xRowid)(sqlite3_vtab_cursor*, sqlite3_int64 *pRowid); + int (*xUpdate)(sqlite3_vtab *, int, sqlite3_value **, sqlite3_int64 *); + int (*xBegin)(sqlite3_vtab *pVTab); + int (*xSync)(sqlite3_vtab *pVTab); + int (*xCommit)(sqlite3_vtab *pVTab); + int (*xRollback)(sqlite3_vtab *pVTab); + int (*xFindFunction)(sqlite3_vtab *pVtab, int nArg, const char *zName, + void (**pxFunc)(sqlite3_context*,int,sqlite3_value**), + void **ppArg); + + int (*xRename)(sqlite3_vtab *pVtab, const char *zNew); +}; + +/* +** The sqlite3_index_info structure and its substructures is used to +** pass information into and receive the reply from the xBestIndex +** method of an sqlite3_module. The fields under **Inputs** are the +** inputs to xBestIndex and are read-only. xBestIndex inserts its +** results into the **Outputs** fields. +** +** The aConstraint[] array records WHERE clause constraints of the +** form: +** +** column OP expr +** +** Where OP is =, <, <=, >, or >=. The particular operator is stored +** in aConstraint[].op. The index of the column is stored in +** aConstraint[].iColumn. aConstraint[].usable is TRUE if the +** expr on the right-hand side can be evaluated (and thus the constraint +** is usable) and false if it cannot. +** +** The optimizer automatically inverts terms of the form "expr OP column" +** and makes other simplifications to the WHERE clause in an attempt to +** get as many WHERE clause terms into the form shown above as possible. +** The aConstraint[] array only reports WHERE clause terms in the correct +** form that refer to the particular virtual table being queried. +** +** Information about the ORDER BY clause is stored in aOrderBy[]. +** Each term of aOrderBy records a column of the ORDER BY clause. +** +** The xBestIndex method must fill aConstraintUsage[] with information +** about what parameters to pass to xFilter. If argvIndex>0 then +** the right-hand side of the corresponding aConstraint[] is evaluated +** and becomes the argvIndex-th entry in argv. If aConstraintUsage[].omit +** is true, then the constraint is assumed to be fully handled by the +** virtual table and is not checked again by SQLite. +** +** The idxNum and idxPtr values are recorded and passed into xFilter. +** sqlite3_free() is used to free idxPtr if needToFreeIdxPtr is true. +** +** The orderByConsumed means that output from xFilter will occur in +** the correct order to satisfy the ORDER BY clause so that no separate +** sorting step is required. +** +** The estimatedCost value is an estimate of the cost of doing the +** particular lookup. A full scan of a table with N entries should have +** a cost of N. A binary search of a table of N entries should have a +** cost of approximately log(N). +*/ +struct sqlite3_index_info { + /* Inputs */ + int nConstraint; /* Number of entries in aConstraint */ + struct sqlite3_index_constraint { + int iColumn; /* Column on left-hand side of constraint */ + unsigned char op; /* Constraint operator */ + unsigned char usable; /* True if this constraint is usable */ + int iTermOffset; /* Used internally - xBestIndex should ignore */ + } *aConstraint; /* Table of WHERE clause constraints */ + int nOrderBy; /* Number of terms in the ORDER BY clause */ + struct sqlite3_index_orderby { + int iColumn; /* Column number */ + unsigned char desc; /* True for DESC. False for ASC. */ + } *aOrderBy; /* The ORDER BY clause */ + + /* Outputs */ + struct sqlite3_index_constraint_usage { + int argvIndex; /* if >0, constraint is part of argv to xFilter */ + unsigned char omit; /* Do not code a test for this constraint */ + } *aConstraintUsage; + int idxNum; /* Number used to identify the index */ + char *idxStr; /* String, possibly obtained from sqlite3_malloc */ + int needToFreeIdxStr; /* Free idxStr using sqlite3_free() if true */ + int orderByConsumed; /* True if output is already ordered */ + double estimatedCost; /* Estimated cost of using this index */ +}; +#define SQLITE_INDEX_CONSTRAINT_EQ 2 +#define SQLITE_INDEX_CONSTRAINT_GT 4 +#define SQLITE_INDEX_CONSTRAINT_LE 8 +#define SQLITE_INDEX_CONSTRAINT_LT 16 +#define SQLITE_INDEX_CONSTRAINT_GE 32 +#define SQLITE_INDEX_CONSTRAINT_MATCH 64 + +/* +** This routine is used to register a new module name with an SQLite +** connection. Module names must be registered before creating new +** virtual tables on the module, or before using preexisting virtual +** tables of the module. +*/ +int sqlite3_create_module( + sqlite3 *db, /* SQLite connection to register module with */ + const char *zName, /* Name of the module */ + const sqlite3_module *, /* Methods for the module */ + void * /* Client data for xCreate/xConnect */ +); + +/* +** This routine is identical to the sqlite3_create_module() method above, +** except that it allows a destructor function to be specified. It is +** even more experimental than the rest of the virtual tables API. +*/ +int sqlite3_create_module_v2( + sqlite3 *db, /* SQLite connection to register module with */ + const char *zName, /* Name of the module */ + const sqlite3_module *, /* Methods for the module */ + void *, /* Client data for xCreate/xConnect */ + void(*xDestroy)(void*) /* Module destructor function */ +); + +/* +** Every module implementation uses a subclass of the following structure +** to describe a particular instance of the module. Each subclass will +** be tailored to the specific needs of the module implementation. The +** purpose of this superclass is to define certain fields that are common +** to all module implementations. +** +** Virtual tables methods can set an error message by assigning a +** string obtained from sqlite3_mprintf() to zErrMsg. The method should +** take care that any prior string is freed by a call to sqlite3_free() +** prior to assigning a new string to zErrMsg. After the error message +** is delivered up to the client application, the string will be automatically +** freed by sqlite3_free() and the zErrMsg field will be zeroed. Note +** that sqlite3_mprintf() and sqlite3_free() are used on the zErrMsg field +** since virtual tables are commonly implemented in loadable extensions which +** do not have access to sqlite3MPrintf() or sqlite3Free(). +*/ +struct sqlite3_vtab { + const sqlite3_module *pModule; /* The module for this virtual table */ + int nRef; /* Used internally */ + char *zErrMsg; /* Error message from sqlite3_mprintf() */ + /* Virtual table implementations will typically add additional fields */ +}; + +/* Every module implementation uses a subclass of the following structure +** to describe cursors that point into the virtual table and are used +** to loop through the virtual table. Cursors are created using the +** xOpen method of the module. Each module implementation will define +** the content of a cursor structure to suit its own needs. +** +** This superclass exists in order to define fields of the cursor that +** are common to all implementations. +*/ +struct sqlite3_vtab_cursor { + sqlite3_vtab *pVtab; /* Virtual table of this cursor */ + /* Virtual table implementations will typically add additional fields */ +}; + +/* +** The xCreate and xConnect methods of a module use the following API +** to declare the format (the names and datatypes of the columns) of +** the virtual tables they implement. +*/ +int sqlite3_declare_vtab(sqlite3*, const char *zCreateTable); + +/* +** Virtual tables can provide alternative implementations of functions +** using the xFindFunction method. But global versions of those functions +** must exist in order to be overloaded. +** +** This API makes sure a global version of a function with a particular +** name and number of parameters exists. If no such function exists +** before this API is called, a new function is created. The implementation +** of the new function always causes an exception to be thrown. So +** the new function is not good for anything by itself. Its only +** purpose is to be a place-holder function that can be overloaded +** by virtual tables. +** +** This API should be considered part of the virtual table interface, +** which is experimental and subject to change. +*/ +int sqlite3_overload_function(sqlite3*, const char *zFuncName, int nArg); + +/* +** The interface to the virtual-table mechanism defined above (back up +** to a comment remarkably similar to this one) is currently considered +** to be experimental. The interface might change in incompatible ways. +** If this is a problem for you, do not use the interface at this time. +** +** When the virtual-table mechanism stabilizes, we will declare the +** interface fixed, support it indefinitely, and remove this comment. +** +****** EXPERIMENTAL - subject to change without notice ************** +*/ + +/* +** CAPI3REF: A Handle To An Open BLOB +** +** An instance of the following opaque structure is used to +** represent an blob-handle. A blob-handle is created by +** [sqlite3_blob_open()] and destroyed by [sqlite3_blob_close()]. +** The [sqlite3_blob_read()] and [sqlite3_blob_write()] interfaces +** can be used to read or write small subsections of the blob. +** The [sqlite3_blob_bytes()] interface returns the size of the +** blob in bytes. +*/ +typedef struct sqlite3_blob sqlite3_blob; + +/* +** CAPI3REF: Open A BLOB For Incremental I/O +** +** Open a handle to the blob located in row iRow,, column zColumn, +** table zTable in database zDb. i.e. the same blob that would +** be selected by: +** +** <pre> +** SELECT zColumn FROM zDb.zTable WHERE rowid = iRow; +** </pre> +** +** If the flags parameter is non-zero, the blob is opened for +** read and write access. If it is zero, the blob is opened for read +** access. +** +** On success, [SQLITE_OK] is returned and the new +** [sqlite3_blob | blob handle] is written to *ppBlob. +** Otherwise an error code is returned and +** any value written to *ppBlob should not be used by the caller. +** This function sets the database-handle error code and message +** accessible via [sqlite3_errcode()] and [sqlite3_errmsg()]. +*/ +int sqlite3_blob_open( + sqlite3*, + const char *zDb, + const char *zTable, + const char *zColumn, + sqlite3_int64 iRow, + int flags, + sqlite3_blob **ppBlob +); + +/* +** CAPI3REF: Close A BLOB Handle +** +** Close an open [sqlite3_blob | blob handle]. +*/ +int sqlite3_blob_close(sqlite3_blob *); + +/* +** CAPI3REF: Return The Size Of An Open BLOB +** +** Return the size in bytes of the blob accessible via the open +** [sqlite3_blob | blob-handle] passed as an argument. +*/ +int sqlite3_blob_bytes(sqlite3_blob *); + +/* +** CAPI3REF: Read Data From A BLOB Incrementally +** +** This function is used to read data from an open +** [sqlite3_blob | blob-handle] into a caller supplied buffer. +** n bytes of data are copied into buffer +** z from the open blob, starting at offset iOffset. +** +** On success, SQLITE_OK is returned. Otherwise, an +** [SQLITE_ERROR | SQLite error code] or an +** [SQLITE_IOERR_READ | extended error code] is returned. +*/ +int sqlite3_blob_read(sqlite3_blob *, void *z, int n, int iOffset); + +/* +** CAPI3REF: Write Data Into A BLOB Incrementally +** +** This function is used to write data into an open +** [sqlite3_blob | blob-handle] from a user supplied buffer. +** n bytes of data are copied from the buffer +** pointed to by z into the open blob, starting at offset iOffset. +** +** If the [sqlite3_blob | blob-handle] passed as the first argument +** was not opened for writing (the flags parameter to [sqlite3_blob_open()] +*** was zero), this function returns [SQLITE_READONLY]. +** +** This function may only modify the contents of the blob, it is +** not possible to increase the size of a blob using this API. If +** offset iOffset is less than n bytes from the end of the blob, +** [SQLITE_ERROR] is returned and no data is written. +** +** On success, SQLITE_OK is returned. Otherwise, an +** [SQLITE_ERROR | SQLite error code] or an +** [SQLITE_IOERR_READ | extended error code] is returned. +*/ +int sqlite3_blob_write(sqlite3_blob *, const void *z, int n, int iOffset); + +/* +** CAPI3REF: Virtual File System Objects +** +** A virtual filesystem (VFS) is an [sqlite3_vfs] object +** that SQLite uses to interact +** with the underlying operating system. Most builds come with a +** single default VFS that is appropriate for the host computer. +** New VFSes can be registered and existing VFSes can be unregistered. +** The following interfaces are provided. +** +** The sqlite3_vfs_find() interface returns a pointer to a VFS given its +** name. Names are case sensitive. If there is no match, a NULL +** pointer is returned. If zVfsName is NULL then the default +** VFS is returned. +** +** New VFSes are registered with sqlite3_vfs_register(). Each +** new VFS becomes the default VFS if the makeDflt flag is set. +** The same VFS can be registered multiple times without injury. +** To make an existing VFS into the default VFS, register it again +** with the makeDflt flag set. If two different VFSes with the +** same name are registered, the behavior is undefined. If a +** VFS is registered with a name that is NULL or an empty string, +** then the behavior is undefined. +** +** Unregister a VFS with the sqlite3_vfs_unregister() interface. +** If the default VFS is unregistered, another VFS is chosen as +** the default. The choice for the new VFS is arbitrary. +*/ +sqlite3_vfs *sqlite3_vfs_find(const char *zVfsName); +int sqlite3_vfs_register(sqlite3_vfs*, int makeDflt); +int sqlite3_vfs_unregister(sqlite3_vfs*); + +/* +** CAPI3REF: Mutexes +** +** The SQLite core uses these routines for thread +** synchronization. Though they are intended for internal +** use by SQLite, code that links against SQLite is +** permitted to use any of these routines. +** +** The SQLite source code contains multiple implementations +** of these mutex routines. An appropriate implementation +** is selected automatically at compile-time. The following +** implementations are available in the SQLite core: +** +** <ul> +** <li> SQLITE_MUTEX_OS2 +** <li> SQLITE_MUTEX_PTHREAD +** <li> SQLITE_MUTEX_W32 +** <li> SQLITE_MUTEX_NOOP +** </ul> +** +** The SQLITE_MUTEX_NOOP implementation is a set of routines +** that does no real locking and is appropriate for use in +** a single-threaded application. The SQLITE_MUTEX_OS2, +** SQLITE_MUTEX_PTHREAD, and SQLITE_MUTEX_W32 implementations +** are appropriate for use on os/2, unix, and windows. +** +** If SQLite is compiled with the SQLITE_MUTEX_APPDEF preprocessor +** macro defined (with "-DSQLITE_MUTEX_APPDEF=1"), then no mutex +** implementation is included with the library. The +** mutex interface routines defined here become external +** references in the SQLite library for which implementations +** must be provided by the application. This facility allows an +** application that links against SQLite to provide its own mutex +** implementation without having to modify the SQLite core. +** +** The sqlite3_mutex_alloc() routine allocates a new +** mutex and returns a pointer to it. If it returns NULL +** that means that a mutex could not be allocated. SQLite +** will unwind its stack and return an error. The argument +** to sqlite3_mutex_alloc() is one of these integer constants: +** +** <ul> +** <li> SQLITE_MUTEX_FAST +** <li> SQLITE_MUTEX_RECURSIVE +** <li> SQLITE_MUTEX_STATIC_MASTER +** <li> SQLITE_MUTEX_STATIC_MEM +** <li> SQLITE_MUTEX_STATIC_MEM2 +** <li> SQLITE_MUTEX_STATIC_PRNG +** <li> SQLITE_MUTEX_STATIC_LRU +** </ul> +** +** The first two constants cause sqlite3_mutex_alloc() to create +** a new mutex. The new mutex is recursive when SQLITE_MUTEX_RECURSIVE +** is used but not necessarily so when SQLITE_MUTEX_FAST is used. +** The mutex implementation does not need to make a distinction +** between SQLITE_MUTEX_RECURSIVE and SQLITE_MUTEX_FAST if it does +** not want to. But SQLite will only request a recursive mutex in +** cases where it really needs one. If a faster non-recursive mutex +** implementation is available on the host platform, the mutex subsystem +** might return such a mutex in response to SQLITE_MUTEX_FAST. +** +** The other allowed parameters to sqlite3_mutex_alloc() each return +** a pointer to a static preexisting mutex. Four static mutexes are +** used by the current version of SQLite. Future versions of SQLite +** may add additional static mutexes. Static mutexes are for internal +** use by SQLite only. Applications that use SQLite mutexes should +** use only the dynamic mutexes returned by SQLITE_MUTEX_FAST or +** SQLITE_MUTEX_RECURSIVE. +** +** Note that if one of the dynamic mutex parameters (SQLITE_MUTEX_FAST +** or SQLITE_MUTEX_RECURSIVE) is used then sqlite3_mutex_alloc() +** returns a different mutex on every call. But for the static +** mutex types, the same mutex is returned on every call that has +** the same type number. +** +** The sqlite3_mutex_free() routine deallocates a previously +** allocated dynamic mutex. SQLite is careful to deallocate every +** dynamic mutex that it allocates. The dynamic mutexes must not be in +** use when they are deallocated. Attempting to deallocate a static +** mutex results in undefined behavior. SQLite never deallocates +** a static mutex. +** +** The sqlite3_mutex_enter() and sqlite3_mutex_try() routines attempt +** to enter a mutex. If another thread is already within the mutex, +** sqlite3_mutex_enter() will block and sqlite3_mutex_try() will return +** SQLITE_BUSY. The sqlite3_mutex_try() interface returns SQLITE_OK +** upon successful entry. Mutexes created using SQLITE_MUTEX_RECURSIVE can +** be entered multiple times by the same thread. In such cases the, +** mutex must be exited an equal number of times before another thread +** can enter. If the same thread tries to enter any other kind of mutex +** more than once, the behavior is undefined. SQLite will never exhibit +** such behavior in its own use of mutexes. +** +** Some systems (ex: windows95) do not the operation implemented by +** sqlite3_mutex_try(). On those systems, sqlite3_mutex_try() will +** always return SQLITE_BUSY. The SQLite core only ever uses +** sqlite3_mutex_try() as an optimization so this is acceptable behavior. +** +** The sqlite3_mutex_leave() routine exits a mutex that was +** previously entered by the same thread. The behavior +** is undefined if the mutex is not currently entered by the +** calling thread or is not currently allocated. SQLite will +** never do either. +** +** See also: [sqlite3_mutex_held()] and [sqlite3_mutex_notheld()]. +*/ +sqlite3_mutex *sqlite3_mutex_alloc(int); +void sqlite3_mutex_free(sqlite3_mutex*); +void sqlite3_mutex_enter(sqlite3_mutex*); +int sqlite3_mutex_try(sqlite3_mutex*); +void sqlite3_mutex_leave(sqlite3_mutex*); + +/* +** CAPI3REF: Mutex Verifcation Routines +** +** The sqlite3_mutex_held() and sqlite3_mutex_notheld() routines +** are intended for use inside assert() statements. The SQLite core +** never uses these routines except inside an assert() and applications +** are advised to follow the lead of the core. The core only +** provides implementations for these routines when it is compiled +** with the SQLITE_DEBUG flag. External mutex implementations +** are only required to provide these routines if SQLITE_DEBUG is +** defined and if NDEBUG is not defined. +** +** These routines should return true if the mutex in their argument +** is held or not held, respectively, by the calling thread. +** +** The implementation is not required to provided versions of these +** routines that actually work. +** If the implementation does not provide working +** versions of these routines, it should at least provide stubs +** that always return true so that one does not get spurious +** assertion failures. +** +** If the argument to sqlite3_mutex_held() is a NULL pointer then +** the routine should return 1. This seems counter-intuitive since +** clearly the mutex cannot be held if it does not exist. But the +** the reason the mutex does not exist is because the build is not +** using mutexes. And we do not want the assert() containing the +** call to sqlite3_mutex_held() to fail, so a non-zero return is +** the appropriate thing to do. The sqlite3_mutex_notheld() +** interface should also return 1 when given a NULL pointer. +*/ +int sqlite3_mutex_held(sqlite3_mutex*); +int sqlite3_mutex_notheld(sqlite3_mutex*); + +/* +** CAPI3REF: Mutex Types +** +** The [sqlite3_mutex_alloc()] interface takes a single argument +** which is one of these integer constants. +*/ +#define SQLITE_MUTEX_FAST 0 +#define SQLITE_MUTEX_RECURSIVE 1 +#define SQLITE_MUTEX_STATIC_MASTER 2 +#define SQLITE_MUTEX_STATIC_MEM 3 /* sqlite3_malloc() */ +#define SQLITE_MUTEX_STATIC_MEM2 4 /* sqlite3_release_memory() */ +#define SQLITE_MUTEX_STATIC_PRNG 5 /* sqlite3_random() */ +#define SQLITE_MUTEX_STATIC_LRU 6 /* lru page list */ + +/* +** CAPI3REF: Low-Level Control Of Database Files +** +** The [sqlite3_file_control()] interface makes a direct call to the +** xFileControl method for the [sqlite3_io_methods] object associated +** with a particular database identified by the second argument. The +** name of the database is the name assigned to the database by the +** <a href="lang_attach.html">ATTACH</a> SQL command that opened the +** database. To control the main database file, use the name "main" +** or a NULL pointer. The third and fourth parameters to this routine +** are passed directly through to the second and third parameters of +** the xFileControl method. The return value of the xFileControl +** method becomes the return value of this routine. +** +** If the second parameter (zDbName) does not match the name of any +** open database file, then SQLITE_ERROR is returned. This error +** code is not remembered and will not be recalled by [sqlite3_errcode()] +** or [sqlite3_errmsg()]. The underlying xFileControl method might +** also return SQLITE_ERROR. There is no way to distinguish between +** an incorrect zDbName and an SQLITE_ERROR return from the underlying +** xFileControl method. +** +** See also: [SQLITE_FCNTL_LOCKSTATE] +*/ +int sqlite3_file_control(sqlite3*, const char *zDbName, int op, void*); + +/* +** Undo the hack that converts floating point types to integer for +** builds on processors without floating point support. +*/ +#ifdef SQLITE_OMIT_FLOATING_POINT +# undef double +#endif + +#if 0 +} /* End of the 'extern "C"' block */ +#endif +#endif + +/************** End of sqlite3.h *********************************************/ +/************** Continuing where we left off in sqlite3ext.h *****************/ + +typedef struct sqlite3_api_routines sqlite3_api_routines; + +/* +** The following structure hold pointers to all of the SQLite API +** routines. +** +** WARNING: In order to maintain backwards compatibility, add new +** interfaces to the end of this structure only. If you insert new +** interfaces in the middle of this structure, then older different +** versions of SQLite will not be able to load each others shared +** libraries! +*/ +struct sqlite3_api_routines { + void * (*aggregate_context)(sqlite3_context*,int nBytes); + int (*aggregate_count)(sqlite3_context*); + int (*bind_blob)(sqlite3_stmt*,int,const void*,int n,void(*)(void*)); + int (*bind_double)(sqlite3_stmt*,int,double); + int (*bind_int)(sqlite3_stmt*,int,int); + int (*bind_int64)(sqlite3_stmt*,int,sqlite_int64); + int (*bind_null)(sqlite3_stmt*,int); + int (*bind_parameter_count)(sqlite3_stmt*); + int (*bind_parameter_index)(sqlite3_stmt*,const char*zName); + const char * (*bind_parameter_name)(sqlite3_stmt*,int); + int (*bind_text)(sqlite3_stmt*,int,const char*,int n,void(*)(void*)); + int (*bind_text16)(sqlite3_stmt*,int,const void*,int,void(*)(void*)); + int (*bind_value)(sqlite3_stmt*,int,const sqlite3_value*); + int (*busy_handler)(sqlite3*,int(*)(void*,int),void*); + int (*busy_timeout)(sqlite3*,int ms); + int (*changes)(sqlite3*); + int (*close)(sqlite3*); + int (*collation_needed)(sqlite3*,void*,void(*)(void*,sqlite3*,int eTextRep,const char*)); + int (*collation_needed16)(sqlite3*,void*,void(*)(void*,sqlite3*,int eTextRep,const void*)); + const void * (*column_blob)(sqlite3_stmt*,int iCol); + int (*column_bytes)(sqlite3_stmt*,int iCol); + int (*column_bytes16)(sqlite3_stmt*,int iCol); + int (*column_count)(sqlite3_stmt*pStmt); + const char * (*column_database_name)(sqlite3_stmt*,int); + const void * (*column_database_name16)(sqlite3_stmt*,int); + const char * (*column_decltype)(sqlite3_stmt*,int i); + const void * (*column_decltype16)(sqlite3_stmt*,int); + double (*column_double)(sqlite3_stmt*,int iCol); + int (*column_int)(sqlite3_stmt*,int iCol); + sqlite_int64 (*column_int64)(sqlite3_stmt*,int iCol); + const char * (*column_name)(sqlite3_stmt*,int); + const void * (*column_name16)(sqlite3_stmt*,int); + const char * (*column_origin_name)(sqlite3_stmt*,int); + const void * (*column_origin_name16)(sqlite3_stmt*,int); + const char * (*column_table_name)(sqlite3_stmt*,int); + const void * (*column_table_name16)(sqlite3_stmt*,int); + const unsigned char * (*column_text)(sqlite3_stmt*,int iCol); + const void * (*column_text16)(sqlite3_stmt*,int iCol); + int (*column_type)(sqlite3_stmt*,int iCol); + sqlite3_value* (*column_value)(sqlite3_stmt*,int iCol); + void * (*commit_hook)(sqlite3*,int(*)(void*),void*); + int (*complete)(const char*sql); + int (*complete16)(const void*sql); + int (*create_collation)(sqlite3*,const char*,int,void*,int(*)(void*,int,const void*,int,const void*)); + int (*create_collation16)(sqlite3*,const char*,int,void*,int(*)(void*,int,const void*,int,const void*)); + int (*create_function)(sqlite3*,const char*,int,int,void*,void (*xFunc)(sqlite3_context*,int,sqlite3_value**),void (*xStep)(sqlite3_context*,int,sqlite3_value**),void (*xFinal)(sqlite3_context*)); + int (*create_function16)(sqlite3*,const void*,int,int,void*,void (*xFunc)(sqlite3_context*,int,sqlite3_value**),void (*xStep)(sqlite3_context*,int,sqlite3_value**),void (*xFinal)(sqlite3_context*)); + int (*create_module)(sqlite3*,const char*,const sqlite3_module*,void*); + int (*data_count)(sqlite3_stmt*pStmt); + sqlite3 * (*db_handle)(sqlite3_stmt*); + int (*declare_vtab)(sqlite3*,const char*); + int (*enable_shared_cache)(int); + int (*errcode)(sqlite3*db); + const char * (*errmsg)(sqlite3*); + const void * (*errmsg16)(sqlite3*); + int (*exec)(sqlite3*,const char*,sqlite3_callback,void*,char**); + int (*expired)(sqlite3_stmt*); + int (*finalize)(sqlite3_stmt*pStmt); + void (*free)(void*); + void (*free_table)(char**result); + int (*get_autocommit)(sqlite3*); + void * (*get_auxdata)(sqlite3_context*,int); + int (*get_table)(sqlite3*,const char*,char***,int*,int*,char**); + int (*global_recover)(void); + void (*interruptx)(sqlite3*); + sqlite_int64 (*last_insert_rowid)(sqlite3*); + const char * (*libversion)(void); + int (*libversion_number)(void); + void *(*malloc)(int); + char * (*mprintf)(const char*,...); + int (*open)(const char*,sqlite3**); + int (*open16)(const void*,sqlite3**); + int (*prepare)(sqlite3*,const char*,int,sqlite3_stmt**,const char**); + int (*prepare16)(sqlite3*,const void*,int,sqlite3_stmt**,const void**); + void * (*profile)(sqlite3*,void(*)(void*,const char*,sqlite_uint64),void*); + void (*progress_handler)(sqlite3*,int,int(*)(void*),void*); + void *(*realloc)(void*,int); + int (*reset)(sqlite3_stmt*pStmt); + void (*result_blob)(sqlite3_context*,const void*,int,void(*)(void*)); + void (*result_double)(sqlite3_context*,double); + void (*result_error)(sqlite3_context*,const char*,int); + void (*result_error16)(sqlite3_context*,const void*,int); + void (*result_int)(sqlite3_context*,int); + void (*result_int64)(sqlite3_context*,sqlite_int64); + void (*result_null)(sqlite3_context*); + void (*result_text)(sqlite3_context*,const char*,int,void(*)(void*)); + void (*result_text16)(sqlite3_context*,const void*,int,void(*)(void*)); + void (*result_text16be)(sqlite3_context*,const void*,int,void(*)(void*)); + void (*result_text16le)(sqlite3_context*,const void*,int,void(*)(void*)); + void (*result_value)(sqlite3_context*,sqlite3_value*); + void * (*rollback_hook)(sqlite3*,void(*)(void*),void*); + int (*set_authorizer)(sqlite3*,int(*)(void*,int,const char*,const char*,const char*,const char*),void*); + void (*set_auxdata)(sqlite3_context*,int,void*,void (*)(void*)); + char * (*snprintf)(int,char*,const char*,...); + int (*step)(sqlite3_stmt*); + int (*table_column_metadata)(sqlite3*,const char*,const char*,const char*,char const**,char const**,int*,int*,int*); + void (*thread_cleanup)(void); + int (*total_changes)(sqlite3*); + void * (*trace)(sqlite3*,void(*xTrace)(void*,const char*),void*); + int (*transfer_bindings)(sqlite3_stmt*,sqlite3_stmt*); + void * (*update_hook)(sqlite3*,void(*)(void*,int ,char const*,char const*,sqlite_int64),void*); + void * (*user_data)(sqlite3_context*); + const void * (*value_blob)(sqlite3_value*); + int (*value_bytes)(sqlite3_value*); + int (*value_bytes16)(sqlite3_value*); + double (*value_double)(sqlite3_value*); + int (*value_int)(sqlite3_value*); + sqlite_int64 (*value_int64)(sqlite3_value*); + int (*value_numeric_type)(sqlite3_value*); + const unsigned char * (*value_text)(sqlite3_value*); + const void * (*value_text16)(sqlite3_value*); + const void * (*value_text16be)(sqlite3_value*); + const void * (*value_text16le)(sqlite3_value*); + int (*value_type)(sqlite3_value*); + char *(*vmprintf)(const char*,va_list); + /* Added ??? */ + int (*overload_function)(sqlite3*, const char *zFuncName, int nArg); + /* Added by 3.3.13 */ + int (*prepare_v2)(sqlite3*,const char*,int,sqlite3_stmt**,const char**); + int (*prepare16_v2)(sqlite3*,const void*,int,sqlite3_stmt**,const void**); + int (*clear_bindings)(sqlite3_stmt*); + /* Added by 3.4.1 */ + int (*create_module_v2)(sqlite3*,const char*,const sqlite3_module*,void*,void (*xDestroy)(void *)); + /* Added by 3.5.0 */ + int (*bind_zeroblob)(sqlite3_stmt*,int,int); + int (*blob_bytes)(sqlite3_blob*); + int (*blob_close)(sqlite3_blob*); + int (*blob_open)(sqlite3*,const char*,const char*,const char*,sqlite3_int64,int,sqlite3_blob**); + int (*blob_read)(sqlite3_blob*,void*,int,int); + int (*blob_write)(sqlite3_blob*,const void*,int,int); + int (*create_collation_v2)(sqlite3*,const char*,int,void*,int(*)(void*,int,const void*,int,const void*),void(*)(void*)); + int (*file_control)(sqlite3*,const char*,int,void*); + sqlite3_int64 (*memory_highwater)(int); + sqlite3_int64 (*memory_used)(void); + sqlite3_mutex *(*mutex_alloc)(int); + void (*mutex_enter)(sqlite3_mutex*); + void (*mutex_free)(sqlite3_mutex*); + void (*mutex_leave)(sqlite3_mutex*); + int (*mutex_try)(sqlite3_mutex*); + int (*open_v2)(const char*,sqlite3**,int,const char*); + int (*release_memory)(int); + void (*result_error_nomem)(sqlite3_context*); + void (*result_error_toobig)(sqlite3_context*); + int (*sleep)(int); + void (*soft_heap_limit)(int); + sqlite3_vfs *(*vfs_find)(const char*); + int (*vfs_register)(sqlite3_vfs*,int); + int (*vfs_unregister)(sqlite3_vfs*); +}; + +/* +** The following macros redefine the API routines so that they are +** redirected throught the global sqlite3_api structure. +** +** This header file is also used by the loadext.c source file +** (part of the main SQLite library - not an extension) so that +** it can get access to the sqlite3_api_routines structure +** definition. But the main library does not want to redefine +** the API. So the redefinition macros are only valid if the +** SQLITE_CORE macros is undefined. +*/ +#ifndef SQLITE_CORE +#define sqlite3_aggregate_context sqlite3_api->aggregate_context +#define sqlite3_aggregate_count sqlite3_api->aggregate_count +#define sqlite3_bind_blob sqlite3_api->bind_blob +#define sqlite3_bind_double sqlite3_api->bind_double +#define sqlite3_bind_int sqlite3_api->bind_int +#define sqlite3_bind_int64 sqlite3_api->bind_int64 +#define sqlite3_bind_null sqlite3_api->bind_null +#define sqlite3_bind_parameter_count sqlite3_api->bind_parameter_count +#define sqlite3_bind_parameter_index sqlite3_api->bind_parameter_index +#define sqlite3_bind_parameter_name sqlite3_api->bind_parameter_name +#define sqlite3_bind_text sqlite3_api->bind_text +#define sqlite3_bind_text16 sqlite3_api->bind_text16 +#define sqlite3_bind_value sqlite3_api->bind_value +#define sqlite3_busy_handler sqlite3_api->busy_handler +#define sqlite3_busy_timeout sqlite3_api->busy_timeout +#define sqlite3_changes sqlite3_api->changes +#define sqlite3_close sqlite3_api->close +#define sqlite3_collation_needed sqlite3_api->collation_needed +#define sqlite3_collation_needed16 sqlite3_api->collation_needed16 +#define sqlite3_column_blob sqlite3_api->column_blob +#define sqlite3_column_bytes sqlite3_api->column_bytes +#define sqlite3_column_bytes16 sqlite3_api->column_bytes16 +#define sqlite3_column_count sqlite3_api->column_count +#define sqlite3_column_database_name sqlite3_api->column_database_name +#define sqlite3_column_database_name16 sqlite3_api->column_database_name16 +#define sqlite3_column_decltype sqlite3_api->column_decltype +#define sqlite3_column_decltype16 sqlite3_api->column_decltype16 +#define sqlite3_column_double sqlite3_api->column_double +#define sqlite3_column_int sqlite3_api->column_int +#define sqlite3_column_int64 sqlite3_api->column_int64 +#define sqlite3_column_name sqlite3_api->column_name +#define sqlite3_column_name16 sqlite3_api->column_name16 +#define sqlite3_column_origin_name sqlite3_api->column_origin_name +#define sqlite3_column_origin_name16 sqlite3_api->column_origin_name16 +#define sqlite3_column_table_name sqlite3_api->column_table_name +#define sqlite3_column_table_name16 sqlite3_api->column_table_name16 +#define sqlite3_column_text sqlite3_api->column_text +#define sqlite3_column_text16 sqlite3_api->column_text16 +#define sqlite3_column_type sqlite3_api->column_type +#define sqlite3_column_value sqlite3_api->column_value +#define sqlite3_commit_hook sqlite3_api->commit_hook +#define sqlite3_complete sqlite3_api->complete +#define sqlite3_complete16 sqlite3_api->complete16 +#define sqlite3_create_collation sqlite3_api->create_collation +#define sqlite3_create_collation16 sqlite3_api->create_collation16 +#define sqlite3_create_function sqlite3_api->create_function +#define sqlite3_create_function16 sqlite3_api->create_function16 +#define sqlite3_create_module sqlite3_api->create_module +#define sqlite3_create_module_v2 sqlite3_api->create_module_v2 +#define sqlite3_data_count sqlite3_api->data_count +#define sqlite3_db_handle sqlite3_api->db_handle +#define sqlite3_declare_vtab sqlite3_api->declare_vtab +#define sqlite3_enable_shared_cache sqlite3_api->enable_shared_cache +#define sqlite3_errcode sqlite3_api->errcode +#define sqlite3_errmsg sqlite3_api->errmsg +#define sqlite3_errmsg16 sqlite3_api->errmsg16 +#define sqlite3_exec sqlite3_api->exec +#define sqlite3_expired sqlite3_api->expired +#define sqlite3_finalize sqlite3_api->finalize +#define sqlite3_free sqlite3_api->free +#define sqlite3_free_table sqlite3_api->free_table +#define sqlite3_get_autocommit sqlite3_api->get_autocommit +#define sqlite3_get_auxdata sqlite3_api->get_auxdata +#define sqlite3_get_table sqlite3_api->get_table +#define sqlite3_global_recover sqlite3_api->global_recover +#define sqlite3_interrupt sqlite3_api->interruptx +#define sqlite3_last_insert_rowid sqlite3_api->last_insert_rowid +#define sqlite3_libversion sqlite3_api->libversion +#define sqlite3_libversion_number sqlite3_api->libversion_number +#define sqlite3_malloc sqlite3_api->malloc +#define sqlite3_mprintf sqlite3_api->mprintf +#define sqlite3_open sqlite3_api->open +#define sqlite3_open16 sqlite3_api->open16 +#define sqlite3_prepare sqlite3_api->prepare +#define sqlite3_prepare16 sqlite3_api->prepare16 +#define sqlite3_prepare_v2 sqlite3_api->prepare_v2 +#define sqlite3_prepare16_v2 sqlite3_api->prepare16_v2 +#define sqlite3_profile sqlite3_api->profile +#define sqlite3_progress_handler sqlite3_api->progress_handler +#define sqlite3_realloc sqlite3_api->realloc +#define sqlite3_reset sqlite3_api->reset +#define sqlite3_result_blob sqlite3_api->result_blob +#define sqlite3_result_double sqlite3_api->result_double +#define sqlite3_result_error sqlite3_api->result_error +#define sqlite3_result_error16 sqlite3_api->result_error16 +#define sqlite3_result_int sqlite3_api->result_int +#define sqlite3_result_int64 sqlite3_api->result_int64 +#define sqlite3_result_null sqlite3_api->result_null +#define sqlite3_result_text sqlite3_api->result_text +#define sqlite3_result_text16 sqlite3_api->result_text16 +#define sqlite3_result_text16be sqlite3_api->result_text16be +#define sqlite3_result_text16le sqlite3_api->result_text16le +#define sqlite3_result_value sqlite3_api->result_value +#define sqlite3_rollback_hook sqlite3_api->rollback_hook +#define sqlite3_set_authorizer sqlite3_api->set_authorizer +#define sqlite3_set_auxdata sqlite3_api->set_auxdata +#define sqlite3_snprintf sqlite3_api->snprintf +#define sqlite3_step sqlite3_api->step +#define sqlite3_table_column_metadata sqlite3_api->table_column_metadata +#define sqlite3_thread_cleanup sqlite3_api->thread_cleanup +#define sqlite3_total_changes sqlite3_api->total_changes +#define sqlite3_trace sqlite3_api->trace +#define sqlite3_transfer_bindings sqlite3_api->transfer_bindings +#define sqlite3_update_hook sqlite3_api->update_hook +#define sqlite3_user_data sqlite3_api->user_data +#define sqlite3_value_blob sqlite3_api->value_blob +#define sqlite3_value_bytes sqlite3_api->value_bytes +#define sqlite3_value_bytes16 sqlite3_api->value_bytes16 +#define sqlite3_value_double sqlite3_api->value_double +#define sqlite3_value_int sqlite3_api->value_int +#define sqlite3_value_int64 sqlite3_api->value_int64 +#define sqlite3_value_numeric_type sqlite3_api->value_numeric_type +#define sqlite3_value_text sqlite3_api->value_text +#define sqlite3_value_text16 sqlite3_api->value_text16 +#define sqlite3_value_text16be sqlite3_api->value_text16be +#define sqlite3_value_text16le sqlite3_api->value_text16le +#define sqlite3_value_type sqlite3_api->value_type +#define sqlite3_vmprintf sqlite3_api->vmprintf +#define sqlite3_overload_function sqlite3_api->overload_function +#define sqlite3_prepare_v2 sqlite3_api->prepare_v2 +#define sqlite3_prepare16_v2 sqlite3_api->prepare16_v2 +#define sqlite3_clear_bindings sqlite3_api->clear_bindings +#define sqlite3_bind_zeroblob sqlite3_api->bind_zeroblob +#define sqlite3_blob_bytes sqlite3_api->blob_bytes +#define sqlite3_blob_close sqlite3_api->blob_close +#define sqlite3_blob_open sqlite3_api->blob_open +#define sqlite3_blob_read sqlite3_api->blob_read +#define sqlite3_blob_write sqlite3_api->blob_write +#define sqlite3_create_collation_v2 sqlite3_api->create_collation_v2 +#define sqlite3_file_control sqlite3_api->file_control +#define sqlite3_memory_highwater sqlite3_api->memory_highwater +#define sqlite3_memory_used sqlite3_api->memory_used +#define sqlite3_mutex_alloc sqlite3_api->mutex_alloc +#define sqlite3_mutex_enter sqlite3_api->mutex_enter +#define sqlite3_mutex_free sqlite3_api->mutex_free +#define sqlite3_mutex_leave sqlite3_api->mutex_leave +#define sqlite3_mutex_try sqlite3_api->mutex_try +#define sqlite3_open_v2 sqlite3_api->open_v2 +#define sqlite3_release_memory sqlite3_api->release_memory +#define sqlite3_result_error_nomem sqlite3_api->result_error_nomem +#define sqlite3_result_error_toobig sqlite3_api->result_error_toobig +#define sqlite3_sleep sqlite3_api->sleep +#define sqlite3_soft_heap_limit sqlite3_api->soft_heap_limit +#define sqlite3_vfs_find sqlite3_api->vfs_find +#define sqlite3_vfs_register sqlite3_api->vfs_register +#define sqlite3_vfs_unregister sqlite3_api->vfs_unregister +#endif /* SQLITE_CORE */ + +#define SQLITE_EXTENSION_INIT1 const sqlite3_api_routines *sqlite3_api; +#define SQLITE_EXTENSION_INIT2(v) sqlite3_api = v; + +#endif /* _SQLITE3EXT_H_ */ + +/************** End of sqlite3ext.h ******************************************/ +/************** Continuing where we left off in fts3_tokenizer.c *************/ +SQLITE_EXTENSION_INIT1 + +/************** Include fts3_hash.h in the middle of fts3_tokenizer.c ********/ +/************** Begin file fts3_hash.h ***************************************/ +/* +** 2001 September 22 +** +** 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 is the header file for the generic hash-table implemenation +** used in SQLite. We've modified it slightly to serve as a standalone +** hash table implementation for the full-text indexing module. +** +*/ +#ifndef _FTS3_HASH_H_ +#define _FTS3_HASH_H_ + +/* Forward declarations of structures. */ +typedef struct fts3Hash fts3Hash; +typedef struct fts3HashElem fts3HashElem; + +/* A complete hash table is an instance of the following structure. +** The internals of this structure are intended to be opaque -- client +** code should not attempt to access or modify the fields of this structure +** directly. Change this structure only by using the routines below. +** However, many of the "procedures" and "functions" for modifying and +** accessing this structure are really macros, so we can't really make +** this structure opaque. +*/ +struct fts3Hash { + char keyClass; /* HASH_INT, _POINTER, _STRING, _BINARY */ + char copyKey; /* True if copy of key made on insert */ + int count; /* Number of entries in this table */ + fts3HashElem *first; /* The first element of the array */ + int htsize; /* Number of buckets in the hash table */ + struct _fts3ht { /* the hash table */ + int count; /* Number of entries with this hash */ + fts3HashElem *chain; /* Pointer to first entry with this hash */ + } *ht; +}; + +/* Each element in the hash table is an instance of the following +** structure. All elements are stored on a single doubly-linked list. +** +** Again, this structure is intended to be opaque, but it can't really +** be opaque because it is used by macros. +*/ +struct fts3HashElem { + fts3HashElem *next, *prev; /* Next and previous elements in the table */ + void *data; /* Data associated with this element */ + void *pKey; int nKey; /* Key associated with this element */ +}; + +/* +** There are 2 different modes of operation for a hash table: +** +** FTS3_HASH_STRING pKey points to a string that is nKey bytes long +** (including the null-terminator, if any). Case +** is respected in comparisons. +** +** FTS3_HASH_BINARY pKey points to binary data nKey bytes long. +** memcmp() is used to compare keys. +** +** A copy of the key is made if the copyKey parameter to fts3HashInit is 1. +*/ +#define FTS3_HASH_STRING 1 +#define FTS3_HASH_BINARY 2 + +/* +** Access routines. To delete, insert a NULL pointer. +*/ +void sqlite3Fts3HashInit(fts3Hash*, int keytype, int copyKey); +void *sqlite3Fts3HashInsert(fts3Hash*, const void *pKey, int nKey, void *pData); +void *sqlite3Fts3HashFind(const fts3Hash*, const void *pKey, int nKey); +void sqlite3Fts3HashClear(fts3Hash*); + +/* +** Shorthand for the functions above +*/ +#define fts3HashInit sqlite3Fts3HashInit +#define fts3HashInsert sqlite3Fts3HashInsert +#define fts3HashFind sqlite3Fts3HashFind +#define fts3HashClear sqlite3Fts3HashClear + +/* +** Macros for looping over all elements of a hash table. The idiom is +** like this: +** +** fts3Hash h; +** fts3HashElem *p; +** ... +** for(p=fts3HashFirst(&h); p; p=fts3HashNext(p)){ +** SomeStructure *pData = fts3HashData(p); +** // do something with pData +** } +*/ +#define fts3HashFirst(H) ((H)->first) +#define fts3HashNext(E) ((E)->next) +#define fts3HashData(E) ((E)->data) +#define fts3HashKey(E) ((E)->pKey) +#define fts3HashKeysize(E) ((E)->nKey) + +/* +** Number of entries in a hash table +*/ +#define fts3HashCount(H) ((H)->count) + +#endif /* _FTS3_HASH_H_ */ + +/************** End of fts3_hash.h *******************************************/ +/************** Continuing where we left off in fts3_tokenizer.c *************/ +/************** Include fts3_tokenizer.h in the middle of fts3_tokenizer.c ***/ +/************** Begin file fts3_tokenizer.h **********************************/ +/* +** 2006 July 10 +** +** The author disclaims copyright to this source code. +** +************************************************************************* +** Defines the interface to tokenizers used by fulltext-search. There +** are three basic components: +** +** sqlite3_tokenizer_module is a singleton defining the tokenizer +** interface functions. This is essentially the class structure for +** tokenizers. +** +** sqlite3_tokenizer is used to define a particular tokenizer, perhaps +** including customization information defined at creation time. +** +** sqlite3_tokenizer_cursor is generated by a tokenizer to generate +** tokens from a particular input. +*/ +#ifndef _FTS3_TOKENIZER_H_ +#define _FTS3_TOKENIZER_H_ + +/* TODO(shess) Only used for SQLITE_OK and SQLITE_DONE at this time. +** If tokenizers are to be allowed to call sqlite3_*() functions, then +** we will need a way to register the API consistently. +*/ +/************** Include sqlite3.h in the middle of fts3_tokenizer.h **********/ +/************** Begin file sqlite3.h *****************************************/ +/* +** 2001 September 15 +** +** 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 header file defines the interface that the SQLite library +** presents to client programs. If a C-function, structure, datatype, +** or constant definition does not appear in this file, then it is +** not a published API of SQLite, is subject to change without +** notice, and should not be referenced by programs that use SQLite. +** +** Some of the definitions that are in this file are marked as +** "experimental". Experimental interfaces are normally new +** features recently added to SQLite. We do not anticipate changes +** to experimental interfaces but reserve to make minor changes if +** experience from use "in the wild" suggest such changes are prudent. +** +** The official C-language API documentation for SQLite is derived +** from comments in this file. This file is the authoritative source +** on how SQLite interfaces are suppose to operate. +** +** The name of this file under configuration management is "sqlite.h.in". +** The makefile makes some minor changes to this file (such as inserting +** the version number) and changes its name to "sqlite3.h" as +** part of the build process. +** +** @(#) $Id: sqlite.h.in,v 1.271 2007/11/21 15:24:01 drh Exp $ +*/ +#ifndef _SQLITE3_H_ +#define _SQLITE3_H_ + +/* +** Make sure we can call this stuff from C++. +*/ +#if 0 +extern "C" { +#endif + + +/* +** Add the ability to override 'extern' +*/ +#ifndef SQLITE_EXTERN +# define SQLITE_EXTERN extern +#endif + +/* +** Make sure these symbols where not defined by some previous header +** file. +*/ +#ifdef SQLITE_VERSION +# undef SQLITE_VERSION +#endif +#ifdef SQLITE_VERSION_NUMBER +# undef SQLITE_VERSION_NUMBER +#endif + +/* +** CAPI3REF: Compile-Time Library Version Numbers +** +** The version of the SQLite library is contained in the sqlite3.h +** header file in a #define named SQLITE_VERSION. The SQLITE_VERSION +** macro resolves to a string constant. +** +** The format of the version string is "X.Y.Z", where +** X is the major version number, Y is the minor version number and Z +** is the release number. The X.Y.Z might be followed by "alpha" or "beta". +** For example "3.1.1beta". +** +** The X value is always 3 in SQLite. The X value only changes when +** backwards compatibility is broken and we intend to never break +** backwards compatibility. The Y value only changes when +** there are major feature enhancements that are forwards compatible +** but not backwards compatible. The Z value is incremented with +** each release but resets back to 0 when Y is incremented. +** +** The SQLITE_VERSION_NUMBER is an integer with the value +** (X*1000000 + Y*1000 + Z). For example, for version "3.1.1beta", +** SQLITE_VERSION_NUMBER is set to 3001001. To detect if they are using +** version 3.1.1 or greater at compile time, programs may use the test +** (SQLITE_VERSION_NUMBER>=3001001). +** +** See also: [sqlite3_libversion()] and [sqlite3_libversion_number()]. +*/ +#define SQLITE_VERSION "3.5.2" +#define SQLITE_VERSION_NUMBER 3005002 + +/* +** CAPI3REF: Run-Time Library Version Numbers +** +** These routines return values equivalent to the header constants +** [SQLITE_VERSION] and [SQLITE_VERSION_NUMBER]. The values returned +** by this routines should only be different from the header values +** if you compile your program using an sqlite3.h header from a +** different version of SQLite that the version of the library you +** link against. +** +** The sqlite3_version[] string constant contains the text of the +** [SQLITE_VERSION] string. The sqlite3_libversion() function returns +** a poiner to the sqlite3_version[] string constant. The function +** is provided for DLL users who can only access functions and not +** constants within the DLL. +*/ +SQLITE_EXTERN const char sqlite3_version[]; +const char *sqlite3_libversion(void); +int sqlite3_libversion_number(void); + +/* +** CAPI3REF: Test To See If The Library Is Threadsafe +** +** This routine returns TRUE (nonzero) if SQLite was compiled with +** all of its mutexes enabled and is thus threadsafe. It returns +** zero if the particular build is for single-threaded operation +** only. +** +** Really all this routine does is return true if SQLite was compiled +** with the -DSQLITE_THREADSAFE=1 option and false if +** compiled with -DSQLITE_THREADSAFE=0. If SQLite uses an +** application-defined mutex subsystem, malloc subsystem, collating +** sequence, VFS, SQL function, progress callback, commit hook, +** extension, or other accessories and these add-ons are not +** threadsafe, then clearly the combination will not be threadsafe +** either. Hence, this routine never reports that the library +** is guaranteed to be threadsafe, only when it is guaranteed not +** to be. +** +** This is an experimental API and may go away or change in future +** releases. +*/ +int sqlite3_threadsafe(void); + +/* +** CAPI3REF: Database Connection Handle +** +** Each open SQLite database is represented by pointer to an instance of the +** opaque structure named "sqlite3". It is useful to think of an sqlite3 +** pointer as an object. The [sqlite3_open()], [sqlite3_open16()], and +** [sqlite3_open_v2()] interfaces are its constructors +** and [sqlite3_close()] is its destructor. There are many other interfaces +** (such as [sqlite3_prepare_v2()], [sqlite3_create_function()], and +** [sqlite3_busy_timeout()] to name but three) that are methods on this +** object. +*/ +typedef struct sqlite3 sqlite3; + + +/* +** CAPI3REF: 64-Bit Integer Types +** +** Some compilers do not support the "long long" datatype. So we have +** to do compiler-specific typedefs for 64-bit signed and unsigned integers. +** +** Many SQLite interface functions require a 64-bit integer arguments. +** Those interfaces are declared using this typedef. +*/ +#ifdef SQLITE_INT64_TYPE + typedef SQLITE_INT64_TYPE sqlite_int64; + typedef unsigned SQLITE_INT64_TYPE sqlite_uint64; +#elif defined(_MSC_VER) || defined(__BORLANDC__) + typedef __int64 sqlite_int64; + typedef unsigned __int64 sqlite_uint64; +#else + typedef long long int sqlite_int64; + typedef unsigned long long int sqlite_uint64; +#endif +typedef sqlite_int64 sqlite3_int64; +typedef sqlite_uint64 sqlite3_uint64; + +/* +** If compiling for a processor that lacks floating point support, +** substitute integer for floating-point +*/ +#ifdef SQLITE_OMIT_FLOATING_POINT +# define double sqlite3_int64 +#endif + +/* +** CAPI3REF: Closing A Database Connection +** +** Call this function with a pointer to a structure that was previously +** returned from [sqlite3_open()], [sqlite3_open16()], or +** [sqlite3_open_v2()] and the corresponding database will by +** closed. +** +** All SQL statements prepared using [sqlite3_prepare_v2()] or +** [sqlite3_prepare16_v2()] must be destroyed using [sqlite3_finalize()] +** before this routine is called. Otherwise, SQLITE_BUSY is returned and the +** database connection remains open. +** +** Passing this routine a database connection that has already been +** closed results in undefined behavior. If other interfaces that +** reference the same database connection are pending (either in the +** same thread or in different threads) when this routine is called, +** then the behavior is undefined and is almost certainly undesirable. +*/ +int sqlite3_close(sqlite3 *); + +/* +** The type for a callback function. +** This is legacy and deprecated. It is included for historical +** compatibility and is not documented. +*/ +typedef int (*sqlite3_callback)(void*,int,char**, char**); + +/* +** CAPI3REF: One-Step Query Execution Interface +** +** This interface is used to do a one-time evaluatation of zero +** or more SQL statements. UTF-8 text of the SQL statements to +** be evaluted is passed in as the second parameter. The statements +** are prepared one by one using [sqlite3_prepare()], evaluated +** using [sqlite3_step()], then destroyed using [sqlite3_finalize()]. +** +** If one or more of the SQL statements are queries, then +** the callback function specified by the 3rd parameter is +** invoked once for each row of the query result. This callback +** should normally return 0. If the callback returns a non-zero +** value then the query is aborted, all subsequent SQL statements +** are skipped and the sqlite3_exec() function returns the [SQLITE_ABORT]. +** +** The 4th parameter to this interface is an arbitrary pointer that is +** passed through to the callback function as its first parameter. +** +** The 2nd parameter to the callback function is the number of +** columns in the query result. The 3rd parameter to the callback +** is an array of strings holding the values for each column +** as extracted using [sqlite3_column_text()]. +** The 4th parameter to the callback is an array of strings +** obtained using [sqlite3_column_name()] and holding +** the names of each column. +** +** The callback function may be NULL, even for queries. A NULL +** callback is not an error. It just means that no callback +** will be invoked. +** +** If an error occurs while parsing or evaluating the SQL (but +** not while executing the callback) then an appropriate error +** message is written into memory obtained from [sqlite3_malloc()] and +** *errmsg is made to point to that message. The calling function +** is responsible for freeing the memory using [sqlite3_free()]. +** If errmsg==NULL, then no error message is ever written. +** +** The return value is is SQLITE_OK if there are no errors and +** some other [SQLITE_OK | return code] if there is an error. +** The particular return value depends on the type of error. +** +*/ +int sqlite3_exec( + sqlite3*, /* An open database */ + const char *sql, /* SQL to be evaluted */ + int (*callback)(void*,int,char**,char**), /* Callback function */ + void *, /* 1st argument to callback */ + char **errmsg /* Error msg written here */ +); + +/* +** CAPI3REF: Result Codes +** KEYWORDS: SQLITE_OK +** +** Many SQLite functions return an integer result code from the set shown +** above in order to indicates success or failure. +** +** The result codes above are the only ones returned by SQLite in its +** default configuration. However, the [sqlite3_extended_result_codes()] +** API can be used to set a database connectoin to return more detailed +** result codes. +** +** See also: [SQLITE_IOERR_READ | extended result codes] +** +*/ +#define SQLITE_OK 0 /* Successful result */ +/* beginning-of-error-codes */ +#define SQLITE_ERROR 1 /* SQL error or missing database */ +#define SQLITE_INTERNAL 2 /* NOT USED. Internal logic error in SQLite */ +#define SQLITE_PERM 3 /* Access permission denied */ +#define SQLITE_ABORT 4 /* Callback routine requested an abort */ +#define SQLITE_BUSY 5 /* The database file is locked */ +#define SQLITE_LOCKED 6 /* A table in the database is locked */ +#define SQLITE_NOMEM 7 /* A malloc() failed */ +#define SQLITE_READONLY 8 /* Attempt to write a readonly database */ +#define SQLITE_INTERRUPT 9 /* Operation terminated by sqlite3_interrupt()*/ +#define SQLITE_IOERR 10 /* Some kind of disk I/O error occurred */ +#define SQLITE_CORRUPT 11 /* The database disk image is malformed */ +#define SQLITE_NOTFOUND 12 /* NOT USED. Table or record not found */ +#define SQLITE_FULL 13 /* Insertion failed because database is full */ +#define SQLITE_CANTOPEN 14 /* Unable to open the database file */ +#define SQLITE_PROTOCOL 15 /* NOT USED. Database lock protocol error */ +#define SQLITE_EMPTY 16 /* Database is empty */ +#define SQLITE_SCHEMA 17 /* The database schema changed */ +#define SQLITE_TOOBIG 18 /* String or BLOB exceeds size limit */ +#define SQLITE_CONSTRAINT 19 /* Abort due to constraint violation */ +#define SQLITE_MISMATCH 20 /* Data type mismatch */ +#define SQLITE_MISUSE 21 /* Library used incorrectly */ +#define SQLITE_NOLFS 22 /* Uses OS features not supported on host */ +#define SQLITE_AUTH 23 /* Authorization denied */ +#define SQLITE_FORMAT 24 /* Auxiliary database format error */ +#define SQLITE_RANGE 25 /* 2nd parameter to sqlite3_bind out of range */ +#define SQLITE_NOTADB 26 /* File opened that is not a database file */ +#define SQLITE_ROW 100 /* sqlite3_step() has another row ready */ +#define SQLITE_DONE 101 /* sqlite3_step() has finished executing */ +/* end-of-error-codes */ + +/* +** CAPI3REF: Extended Result Codes +** +** In its default configuration, SQLite API routines return one of 26 integer +** result codes described at result-codes. However, experience has shown that +** many of these result codes are too course-grained. They do not provide as +** much information about problems as users might like. In an effort to +** address this, newer versions of SQLite (version 3.3.8 and later) include +** support for additional result codes that provide more detailed information +** about errors. The extended result codes are enabled (or disabled) for +** each database +** connection using the [sqlite3_extended_result_codes()] API. +** +** Some of the available extended result codes are listed above. +** We expect the number of extended result codes will be expand +** over time. Software that uses extended result codes should expect +** to see new result codes in future releases of SQLite. +** +** The symbolic name for an extended result code always contains a related +** primary result code as a prefix. Primary result codes contain a single +** "_" character. Extended result codes contain two or more "_" characters. +** The numeric value of an extended result code can be converted to its +** corresponding primary result code by masking off the lower 8 bytes. +** +** The SQLITE_OK result code will never be extended. It will always +** be exactly zero. +*/ +#define SQLITE_IOERR_READ (SQLITE_IOERR | (1<<8)) +#define SQLITE_IOERR_SHORT_READ (SQLITE_IOERR | (2<<8)) +#define SQLITE_IOERR_WRITE (SQLITE_IOERR | (3<<8)) +#define SQLITE_IOERR_FSYNC (SQLITE_IOERR | (4<<8)) +#define SQLITE_IOERR_DIR_FSYNC (SQLITE_IOERR | (5<<8)) +#define SQLITE_IOERR_TRUNCATE (SQLITE_IOERR | (6<<8)) +#define SQLITE_IOERR_FSTAT (SQLITE_IOERR | (7<<8)) +#define SQLITE_IOERR_UNLOCK (SQLITE_IOERR | (8<<8)) +#define SQLITE_IOERR_RDLOCK (SQLITE_IOERR | (9<<8)) +#define SQLITE_IOERR_DELETE (SQLITE_IOERR | (10<<8)) +#define SQLITE_IOERR_BLOCKED (SQLITE_IOERR | (11<<8)) +#define SQLITE_IOERR_NOMEM (SQLITE_IOERR | (12<<8)) + +/* +** CAPI3REF: Flags For File Open Operations +** +** Combination of the following bit values are used as the +** third argument to the [sqlite3_open_v2()] interface and +** as fourth argument to the xOpen method of the +** [sqlite3_vfs] object. +** +*/ +#define SQLITE_OPEN_READONLY 0x00000001 +#define SQLITE_OPEN_READWRITE 0x00000002 +#define SQLITE_OPEN_CREATE 0x00000004 +#define SQLITE_OPEN_DELETEONCLOSE 0x00000008 +#define SQLITE_OPEN_EXCLUSIVE 0x00000010 +#define SQLITE_OPEN_MAIN_DB 0x00000100 +#define SQLITE_OPEN_TEMP_DB 0x00000200 +#define SQLITE_OPEN_TRANSIENT_DB 0x00000400 +#define SQLITE_OPEN_MAIN_JOURNAL 0x00000800 +#define SQLITE_OPEN_TEMP_JOURNAL 0x00001000 +#define SQLITE_OPEN_SUBJOURNAL 0x00002000 +#define SQLITE_OPEN_MASTER_JOURNAL 0x00004000 + +/* +** CAPI3REF: Device Characteristics +** +** The xDeviceCapabilities method of the [sqlite3_io_methods] +** object returns an integer which is a vector of the following +** bit values expressing I/O characteristics of the mass storage +** device that holds the file that the [sqlite3_io_methods] +** refers to. +** +** The SQLITE_IOCAP_ATOMIC property means that all writes of +** any size are atomic. The SQLITE_IOCAP_ATOMICnnn values +** mean that writes of blocks that are nnn bytes in size and +** are aligned to an address which is an integer multiple of +** nnn are atomic. The SQLITE_IOCAP_SAFE_APPEND value means +** that when data is appended to a file, the data is appended +** first then the size of the file is extended, never the other +** way around. The SQLITE_IOCAP_SEQUENTIAL property means that +** information is written to disk in the same order as calls +** to xWrite(). +*/ +#define SQLITE_IOCAP_ATOMIC 0x00000001 +#define SQLITE_IOCAP_ATOMIC512 0x00000002 +#define SQLITE_IOCAP_ATOMIC1K 0x00000004 +#define SQLITE_IOCAP_ATOMIC2K 0x00000008 +#define SQLITE_IOCAP_ATOMIC4K 0x00000010 +#define SQLITE_IOCAP_ATOMIC8K 0x00000020 +#define SQLITE_IOCAP_ATOMIC16K 0x00000040 +#define SQLITE_IOCAP_ATOMIC32K 0x00000080 +#define SQLITE_IOCAP_ATOMIC64K 0x00000100 +#define SQLITE_IOCAP_SAFE_APPEND 0x00000200 +#define SQLITE_IOCAP_SEQUENTIAL 0x00000400 + +/* +** CAPI3REF: File Locking Levels +** +** SQLite uses one of the following integer values as the second +** argument to calls it makes to the xLock() and xUnlock() methods +** of an [sqlite3_io_methods] object. +*/ +#define SQLITE_LOCK_NONE 0 +#define SQLITE_LOCK_SHARED 1 +#define SQLITE_LOCK_RESERVED 2 +#define SQLITE_LOCK_PENDING 3 +#define SQLITE_LOCK_EXCLUSIVE 4 + +/* +** CAPI3REF: Synchronization Type Flags +** +** When SQLite invokes the xSync() method of an [sqlite3_io_methods] +** object it uses a combination of the following integer values as +** the second argument. +** +** When the SQLITE_SYNC_DATAONLY flag is used, it means that the +** sync operation only needs to flush data to mass storage. Inode +** information need not be flushed. The SQLITE_SYNC_NORMAL means +** to use normal fsync() semantics. The SQLITE_SYNC_FULL flag means +** to use Mac OS-X style fullsync instead of fsync(). +*/ +#define SQLITE_SYNC_NORMAL 0x00002 +#define SQLITE_SYNC_FULL 0x00003 +#define SQLITE_SYNC_DATAONLY 0x00010 + + +/* +** CAPI3REF: OS Interface Open File Handle +** +** An [sqlite3_file] object represents an open file in the OS +** interface layer. Individual OS interface implementations will +** want to subclass this object by appending additional fields +** for their own use. The pMethods entry is a pointer to an +** [sqlite3_io_methods] object that defines methods for performing +** I/O operations on the open file. +*/ +typedef struct sqlite3_file sqlite3_file; +struct sqlite3_file { + const struct sqlite3_io_methods *pMethods; /* Methods for an open file */ +}; + +/* +** CAPI3REF: OS Interface File Virtual Methods Object +** +** Every file opened by the [sqlite3_vfs] xOpen method contains a pointer to +** an instance of the this object. This object defines the +** methods used to perform various operations against the open file. +** +** The flags argument to xSync may be one of [SQLITE_SYNC_NORMAL] or +** [SQLITE_SYNC_FULL]. The first choice is the normal fsync(). +* The second choice is an +** OS-X style fullsync. The SQLITE_SYNC_DATA flag may be ORed in to +** indicate that only the data of the file and not its inode needs to be +** synced. +** +** The integer values to xLock() and xUnlock() are one of +** <ul> +** <li> [SQLITE_LOCK_NONE], +** <li> [SQLITE_LOCK_SHARED], +** <li> [SQLITE_LOCK_RESERVED], +** <li> [SQLITE_LOCK_PENDING], or +** <li> [SQLITE_LOCK_EXCLUSIVE]. +** </ul> +** xLock() increases the lock. xUnlock() decreases the lock. +** The xCheckReservedLock() method looks +** to see if any database connection, either in this +** process or in some other process, is holding an RESERVED, +** PENDING, or EXCLUSIVE lock on the file. It returns true +** if such a lock exists and false if not. +** +** The xFileControl() method is a generic interface that allows custom +** VFS implementations to directly control an open file using the +** [sqlite3_file_control()] interface. The second "op" argument +** is an integer opcode. The third +** argument is a generic pointer which is intended to be a pointer +** to a structure that may contain arguments or space in which to +** write return values. Potential uses for xFileControl() might be +** functions to enable blocking locks with timeouts, to change the +** locking strategy (for example to use dot-file locks), to inquire +** about the status of a lock, or to break stale locks. The SQLite +** core reserves opcodes less than 100 for its own use. +** A [SQLITE_FCNTL_LOCKSTATE | list of opcodes] less than 100 is available. +** Applications that define a custom xFileControl method should use opcodes +** greater than 100 to avoid conflicts. +** +** The xSectorSize() method returns the sector size of the +** device that underlies the file. The sector size is the +** minimum write that can be performed without disturbing +** other bytes in the file. The xDeviceCharacteristics() +** method returns a bit vector describing behaviors of the +** underlying device: +** +** <ul> +** <li> [SQLITE_IOCAP_ATOMIC] +** <li> [SQLITE_IOCAP_ATOMIC512] +** <li> [SQLITE_IOCAP_ATOMIC1K] +** <li> [SQLITE_IOCAP_ATOMIC2K] +** <li> [SQLITE_IOCAP_ATOMIC4K] +** <li> [SQLITE_IOCAP_ATOMIC8K] +** <li> [SQLITE_IOCAP_ATOMIC16K] +** <li> [SQLITE_IOCAP_ATOMIC32K] +** <li> [SQLITE_IOCAP_ATOMIC64K] +** <li> [SQLITE_IOCAP_SAFE_APPEND] +** <li> [SQLITE_IOCAP_SEQUENTIAL] +** </ul> +** +** The SQLITE_IOCAP_ATOMIC property means that all writes of +** any size are atomic. The SQLITE_IOCAP_ATOMICnnn values +** mean that writes of blocks that are nnn bytes in size and +** are aligned to an address which is an integer multiple of +** nnn are atomic. The SQLITE_IOCAP_SAFE_APPEND value means +** that when data is appended to a file, the data is appended +** first then the size of the file is extended, never the other +** way around. The SQLITE_IOCAP_SEQUENTIAL property means that +** information is written to disk in the same order as calls +** to xWrite(). +*/ +typedef struct sqlite3_io_methods sqlite3_io_methods; +struct sqlite3_io_methods { + int iVersion; + int (*xClose)(sqlite3_file*); + int (*xRead)(sqlite3_file*, void*, int iAmt, sqlite3_int64 iOfst); + int (*xWrite)(sqlite3_file*, const void*, int iAmt, sqlite3_int64 iOfst); + int (*xTruncate)(sqlite3_file*, sqlite3_int64 size); + int (*xSync)(sqlite3_file*, int flags); + int (*xFileSize)(sqlite3_file*, sqlite3_int64 *pSize); + int (*xLock)(sqlite3_file*, int); + int (*xUnlock)(sqlite3_file*, int); + int (*xCheckReservedLock)(sqlite3_file*); + int (*xFileControl)(sqlite3_file*, int op, void *pArg); + int (*xSectorSize)(sqlite3_file*); + int (*xDeviceCharacteristics)(sqlite3_file*); + /* Additional methods may be added in future releases */ +}; + +/* +** CAPI3REF: Standard File Control Opcodes +** +** These integer constants are opcodes for the xFileControl method +** of the [sqlite3_io_methods] object and to the [sqlite3_file_control()] +** interface. +** +** The [SQLITE_FCNTL_LOCKSTATE] opcode is used for debugging. This +** opcode cases the xFileControl method to write the current state of +** the lock (one of [SQLITE_LOCK_NONE], [SQLITE_LOCK_SHARED], +** [SQLITE_LOCK_RESERVED], [SQLITE_LOCK_PENDING], or [SQLITE_LOCK_EXCLUSIVE]) +** into an integer that the pArg argument points to. This capability +** is used during testing and only needs to be supported when SQLITE_TEST +** is defined. +*/ +#define SQLITE_FCNTL_LOCKSTATE 1 + +/* +** CAPI3REF: Mutex Handle +** +** The mutex module within SQLite defines [sqlite3_mutex] to be an +** abstract type for a mutex object. The SQLite core never looks +** at the internal representation of an [sqlite3_mutex]. It only +** deals with pointers to the [sqlite3_mutex] object. +** +** Mutexes are created using [sqlite3_mutex_alloc()]. +*/ +typedef struct sqlite3_mutex sqlite3_mutex; + +/* +** CAPI3REF: OS Interface Object +** +** An instance of this object defines the interface between the +** SQLite core and the underlying operating system. The "vfs" +** in the name of the object stands for "virtual file system". +** +** The iVersion field is initially 1 but may be larger for future +** versions of SQLite. Additional fields may be appended to this +** object when the iVersion value is increased. +** +** The szOsFile field is the size of the subclassed [sqlite3_file] +** structure used by this VFS. mxPathname is the maximum length of +** a pathname in this VFS. +** +** Registered vfs modules are kept on a linked list formed by +** the pNext pointer. The [sqlite3_vfs_register()] +** and [sqlite3_vfs_unregister()] interfaces manage this list +** in a thread-safe way. The [sqlite3_vfs_find()] interface +** searches the list. +** +** The pNext field is the only fields in the sqlite3_vfs +** structure that SQLite will ever modify. SQLite will only access +** or modify this field while holding a particular static mutex. +** The application should never modify anything within the sqlite3_vfs +** object once the object has been registered. +** +** The zName field holds the name of the VFS module. The name must +** be unique across all VFS modules. +** +** SQLite will guarantee that the zFilename string passed to +** xOpen() is a full pathname as generated by xFullPathname() and +** that the string will be valid and unchanged until xClose() is +** called. So the [sqlite3_file] can store a pointer to the +** filename if it needs to remember the filename for some reason. +** +** The flags argument to xOpen() is a copy of the flags argument +** to [sqlite3_open_v2()]. If [sqlite3_open()] or [sqlite3_open16()] +** is used, then flags is [SQLITE_OPEN_READWRITE] | [SQLITE_OPEN_CREATE]. +** If xOpen() opens a file read-only then it sets *pOutFlags to +** include [SQLITE_OPEN_READONLY]. Other bits in *pOutFlags may be +** set. +** +** SQLite will also add one of the following flags to the xOpen() +** call, depending on the object being opened: +** +** <ul> +** <li> [SQLITE_OPEN_MAIN_DB] +** <li> [SQLITE_OPEN_MAIN_JOURNAL] +** <li> [SQLITE_OPEN_TEMP_DB] +** <li> [SQLITE_OPEN_TEMP_JOURNAL] +** <li> [SQLITE_OPEN_TRANSIENT_DB] +** <li> [SQLITE_OPEN_SUBJOURNAL] +** <li> [SQLITE_OPEN_MASTER_JOURNAL] +** </ul> +** +** The file I/O implementation can use the object type flags to +** changes the way it deals with files. For example, an application +** that does not care about crash recovery or rollback, might make +** the open of a journal file a no-op. Writes to this journal are +** also a no-op. Any attempt to read the journal return SQLITE_IOERR. +** Or the implementation might recognize the a database file will +** be doing page-aligned sector reads and writes in a random order +** and set up its I/O subsystem accordingly. +** +** SQLite might also add one of the following flags to the xOpen +** method: +** +** <ul> +** <li> [SQLITE_OPEN_DELETEONCLOSE] +** <li> [SQLITE_OPEN_EXCLUSIVE] +** </ul> +** +** The [SQLITE_OPEN_DELETEONCLOSE] flag means the file should be +** deleted when it is closed. This will always be set for TEMP +** databases and journals and for subjournals. The +** [SQLITE_OPEN_EXCLUSIVE] flag means the file should be opened +** for exclusive access. This flag is set for all files except +** for the main database file. +** +** Space to hold the [sqlite3_file] structure passed as the third +** argument to xOpen is allocated by caller (the SQLite core). +** szOsFile bytes are allocated for this object. The xOpen method +** fills in the allocated space. +** +** The flags argument to xAccess() may be [SQLITE_ACCESS_EXISTS] +** to test for the existance of a file, +** or [SQLITE_ACCESS_READWRITE] to test to see +** if a file is readable and writable, or [SQLITE_ACCESS_READ] +** to test to see if a file is at least readable. The file can be a +** directory. +** +** SQLite will always allocate at least mxPathname+1 byte for +** the output buffers for xGetTempname and xFullPathname. The exact +** size of the output buffer is also passed as a parameter to both +** methods. If the output buffer is not large enough, SQLITE_CANTOPEN +** should be returned. As this is handled as a fatal error by SQLite, +** vfs implementations should endevour to prevent this by setting +** mxPathname to a sufficiently large value. +** +** The xRandomness(), xSleep(), and xCurrentTime() interfaces +** are not strictly a part of the filesystem, but they are +** included in the VFS structure for completeness. +** The xRandomness() function attempts to return nBytes bytes +** of good-quality randomness into zOut. The return value is +** the actual number of bytes of randomness obtained. The +** xSleep() method cause the calling thread to sleep for at +** least the number of microseconds given. The xCurrentTime() +** method returns a Julian Day Number for the current date and +** time. +*/ +typedef struct sqlite3_vfs sqlite3_vfs; +struct sqlite3_vfs { + int iVersion; /* Structure version number */ + int szOsFile; /* Size of subclassed sqlite3_file */ + int mxPathname; /* Maximum file pathname length */ + sqlite3_vfs *pNext; /* Next registered VFS */ + const char *zName; /* Name of this virtual file system */ + void *pAppData; /* Pointer to application-specific data */ + int (*xOpen)(sqlite3_vfs*, const char *zName, sqlite3_file*, + int flags, int *pOutFlags); + int (*xDelete)(sqlite3_vfs*, const char *zName, int syncDir); + int (*xAccess)(sqlite3_vfs*, const char *zName, int flags); + int (*xGetTempname)(sqlite3_vfs*, int nOut, char *zOut); + int (*xFullPathname)(sqlite3_vfs*, const char *zName, int nOut, char *zOut); + void *(*xDlOpen)(sqlite3_vfs*, const char *zFilename); + void (*xDlError)(sqlite3_vfs*, int nByte, char *zErrMsg); + void *(*xDlSym)(sqlite3_vfs*,void*, const char *zSymbol); + void (*xDlClose)(sqlite3_vfs*, void*); + int (*xRandomness)(sqlite3_vfs*, int nByte, char *zOut); + int (*xSleep)(sqlite3_vfs*, int microseconds); + int (*xCurrentTime)(sqlite3_vfs*, double*); + /* New fields may be appended in figure versions. The iVersion + ** value will increment whenever this happens. */ +}; + +/* +** CAPI3REF: Flags for the xAccess VFS method +** +** These integer constants can be used as the third parameter to +** the xAccess method of an [sqlite3_vfs] object. They determine +** the kind of what kind of permissions the xAccess method is +** looking for. With SQLITE_ACCESS_EXISTS, the xAccess method +** simply checks to see if the file exists. With SQLITE_ACCESS_READWRITE, +** the xAccess method checks to see if the file is both readable +** and writable. With SQLITE_ACCESS_READ the xAccess method +** checks to see if the file is readable. +*/ +#define SQLITE_ACCESS_EXISTS 0 +#define SQLITE_ACCESS_READWRITE 1 +#define SQLITE_ACCESS_READ 2 + +/* +** CAPI3REF: Enable Or Disable Extended Result Codes +** +** This routine enables or disables the +** [SQLITE_IOERR_READ | extended result codes] feature. +** By default, SQLite API routines return one of only 26 integer +** [SQLITE_OK | result codes]. When extended result codes +** are enabled by this routine, the repetoire of result codes can be +** much larger and can (hopefully) provide more detailed information +** about the cause of an error. +** +** The second argument is a boolean value that turns extended result +** codes on and off. Extended result codes are off by default for +** backwards compatibility with older versions of SQLite. +*/ +int sqlite3_extended_result_codes(sqlite3*, int onoff); + +/* +** CAPI3REF: Last Insert Rowid +** +** Each entry in an SQLite table has a unique 64-bit signed integer key +** called the "rowid". The rowid is always available as an undeclared +** column named ROWID, OID, or _ROWID_. If the table has a column of +** type INTEGER PRIMARY KEY then that column is another an alias for the +** rowid. +** +** This routine returns the rowid of the most recent successful INSERT into +** the database from the database connection given in the first +** argument. If no successful inserts have ever occurred on this database +** connection, zero is returned. +** +** If an INSERT occurs within a trigger, then the rowid of the +** inserted row is returned by this routine as long as the trigger +** is running. But once the trigger terminates, the value returned +** by this routine reverts to the last value inserted before the +** trigger fired. +** +** An INSERT that fails due to a constraint violation is not a +** successful insert and does not change the value returned by this +** routine. Thus INSERT OR FAIL, INSERT OR IGNORE, INSERT OR ROLLBACK, +** and INSERT OR ABORT make no changes to the return value of this +** routine when their insertion fails. When INSERT OR REPLACE +** encounters a constraint violation, it does not fail. The +** INSERT continues to completion after deleting rows that caused +** the constraint problem so INSERT OR REPLACE will always change +** the return value of this interface. +** +** If another thread does a new insert on the same database connection +** while this routine is running and thus changes the last insert rowid, +** then the return value of this routine is undefined. +*/ +sqlite3_int64 sqlite3_last_insert_rowid(sqlite3*); + +/* +** CAPI3REF: Count The Number Of Rows Modified +** +** This function returns the number of database rows that were changed +** (or inserted or deleted) by the most recent SQL statement. Only +** changes that are directly specified by the INSERT, UPDATE, or +** DELETE statement are counted. Auxiliary changes caused by +** triggers are not counted. Use the [sqlite3_total_changes()] function +** to find the total number of changes including changes caused by triggers. +** +** Within the body of a trigger, the sqlite3_changes() interface can be +** called to find the number of +** changes in the most recently completed INSERT, UPDATE, or DELETE +** statement within the body of the trigger. +** +** All changes are counted, even if they were later undone by a +** ROLLBACK or ABORT. Except, changes associated with creating and +** dropping tables are not counted. +** +** If a callback invokes [sqlite3_exec()] or [sqlite3_step()] recursively, +** then the changes in the inner, recursive call are counted together +** with the changes in the outer call. +** +** SQLite implements the command "DELETE FROM table" without a WHERE clause +** by dropping and recreating the table. (This is much faster than going +** through and deleting individual elements from the table.) Because of +** this optimization, the change count for "DELETE FROM table" will be +** zero regardless of the number of elements that were originally in the +** table. To get an accurate count of the number of rows deleted, use +** "DELETE FROM table WHERE 1" instead. +** +** If another thread makes changes on the same database connection +** while this routine is running then the return value of this routine +** is undefined. +*/ +int sqlite3_changes(sqlite3*); + +/* +** CAPI3REF: Total Number Of Rows Modified +*** +** This function returns the number of database rows that have been +** modified by INSERT, UPDATE or DELETE statements since the database handle +** was opened. This includes UPDATE, INSERT and DELETE statements executed +** as part of trigger programs. All changes are counted as soon as the +** statement that makes them is completed (when the statement handle is +** passed to [sqlite3_reset()] or [sqlite3_finalize()]). +** +** See also the [sqlite3_change()] interface. +** +** SQLite implements the command "DELETE FROM table" without a WHERE clause +** by dropping and recreating the table. (This is much faster than going +** through and deleting individual elements form the table.) Because of +** this optimization, the change count for "DELETE FROM table" will be +** zero regardless of the number of elements that were originally in the +** table. To get an accurate count of the number of rows deleted, use +** "DELETE FROM table WHERE 1" instead. +** +** If another thread makes changes on the same database connection +** while this routine is running then the return value of this routine +** is undefined. +*/ +int sqlite3_total_changes(sqlite3*); + +/* +** CAPI3REF: Interrupt A Long-Running Query +** +** This function causes any pending database operation to abort and +** return at its earliest opportunity. This routine is typically +** called in response to a user action such as pressing "Cancel" +** or Ctrl-C where the user wants a long query operation to halt +** immediately. +** +** It is safe to call this routine from a thread different from the +** thread that is currently running the database operation. But it +** is not safe to call this routine with a database connection that +** is closed or might close before sqlite3_interrupt() returns. +** +** The SQL operation that is interrupted will return [SQLITE_INTERRUPT]. +** If an interrupted operation was an update that is inside an +** explicit transaction, then the entire transaction will be rolled +** back automatically. +*/ +void sqlite3_interrupt(sqlite3*); + +/* +** CAPI3REF: Determine If An SQL Statement Is Complete +** +** These functions return true if the given input string comprises +** one or more complete SQL statements. For the sqlite3_complete() call, +** the parameter must be a nul-terminated UTF-8 string. For +** sqlite3_complete16(), a nul-terminated machine byte order UTF-16 string +** is required. +** +** These routines are useful for command-line input to determine if the +** currently entered text forms one or more complete SQL statements or +** if additional input is needed before sending the statements into +** SQLite for parsing. The algorithm is simple. If the +** last token other than spaces and comments is a semicolon, then return +** true. Actually, the algorithm is a little more complicated than that +** in order to deal with triggers, but the basic idea is the same: the +** statement is not complete unless it ends in a semicolon. +*/ +int sqlite3_complete(const char *sql); +int sqlite3_complete16(const void *sql); + +/* +** CAPI3REF: Register A Callback To Handle SQLITE_BUSY Errors +** +** This routine identifies a callback function that might be invoked +** whenever an attempt is made to open a database table +** that another thread or process has locked. +** If the busy callback is NULL, then [SQLITE_BUSY] +** (or sometimes [SQLITE_IOERR_BLOCKED]) +** is returned immediately upon encountering the lock. +** If the busy callback is not NULL, then the +** callback will be invoked with two arguments. The +** first argument to the handler is a copy of the void* pointer which +** is the third argument to this routine. The second argument to +** the handler is the number of times that the busy handler has +** been invoked for this locking event. If the +** busy callback returns 0, then no additional attempts are made to +** access the database and [SQLITE_BUSY] or [SQLITE_IOERR_BLOCKED] is returned. +** If the callback returns non-zero, then another attempt is made to open the +** database for reading and the cycle repeats. +** +** The presence of a busy handler does not guarantee that +** it will be invoked when there is lock contention. +** If SQLite determines that invoking the busy handler could result in +** a deadlock, it will return [SQLITE_BUSY] instead. +** Consider a scenario where one process is holding a read lock that +** it is trying to promote to a reserved lock and +** a second process is holding a reserved lock that it is trying +** to promote to an exclusive lock. The first process cannot proceed +** because it is blocked by the second and the second process cannot +** proceed because it is blocked by the first. If both processes +** invoke the busy handlers, neither will make any progress. Therefore, +** SQLite returns [SQLITE_BUSY] for the first process, hoping that this +** will induce the first process to release its read lock and allow +** the second process to proceed. +** +** The default busy callback is NULL. +** +** The [SQLITE_BUSY] error is converted to [SQLITE_IOERR_BLOCKED] when +** SQLite is in the middle of a large transaction where all the +** changes will not fit into the in-memory cache. SQLite will +** already hold a RESERVED lock on the database file, but it needs +** to promote this lock to EXCLUSIVE so that it can spill cache +** pages into the database file without harm to concurrent +** readers. If it is unable to promote the lock, then the in-memory +** cache will be left in an inconsistent state and so the error +** code is promoted from the relatively benign [SQLITE_BUSY] to +** the more severe [SQLITE_IOERR_BLOCKED]. This error code promotion +** forces an automatic rollback of the changes. See the +** <a href="http://www.sqlite.org/cvstrac/wiki?p=CorruptionFollowingBusyError"> +** CorruptionFollowingBusyError</a> wiki page for a discussion of why +** this is important. +** +** Sqlite is re-entrant, so the busy handler may start a new query. +** (It is not clear why anyone would every want to do this, but it +** is allowed, in theory.) But the busy handler may not close the +** database. Closing the database from a busy handler will delete +** data structures out from under the executing query and will +** probably result in a segmentation fault or other runtime error. +** +** There can only be a single busy handler defined for each database +** connection. Setting a new busy handler clears any previous one. +** Note that calling [sqlite3_busy_timeout()] will also set or clear +** the busy handler. +** +** When operating in [sqlite3_enable_shared_cache | shared cache mode], +** only a single busy handler can be defined for each database file. +** So if two database connections share a single cache, then changing +** the busy handler on one connection will also change the busy +** handler in the other connection. The busy handler is invoked +** in the thread that was running when the SQLITE_BUSY was hit. +*/ +int sqlite3_busy_handler(sqlite3*, int(*)(void*,int), void*); + +/* +** CAPI3REF: Set A Busy Timeout +** +** This routine sets a busy handler that sleeps for a while when a +** table is locked. The handler will sleep multiple times until +** at least "ms" milliseconds of sleeping have been done. After +** "ms" milliseconds of sleeping, the handler returns 0 which +** causes [sqlite3_step()] to return [SQLITE_BUSY] or [SQLITE_IOERR_BLOCKED]. +** +** Calling this routine with an argument less than or equal to zero +** turns off all busy handlers. +** +** There can only be a single busy handler for a particular database +** connection. If another busy handler was defined +** (using [sqlite3_busy_handler()]) prior to calling +** this routine, that other busy handler is cleared. +*/ +int sqlite3_busy_timeout(sqlite3*, int ms); + +/* +** CAPI3REF: Convenience Routines For Running Queries +** +** This next routine is a convenience wrapper around [sqlite3_exec()]. +** Instead of invoking a user-supplied callback for each row of the +** result, this routine remembers each row of the result in memory +** obtained from [sqlite3_malloc()], then returns all of the result after the +** query has finished. +** +** As an example, suppose the query result where this table: +** +** <blockquote><pre> +** Name | Age +** ----------------------- +** Alice | 43 +** Bob | 28 +** Cindy | 21 +** </pre></blockquote> +** +** If the 3rd argument were &azResult then after the function returns +** azResult will contain the following data: +** +** <blockquote><pre> +** azResult[0] = "Name"; +** azResult[1] = "Age"; +** azResult[2] = "Alice"; +** azResult[3] = "43"; +** azResult[4] = "Bob"; +** azResult[5] = "28"; +** azResult[6] = "Cindy"; +** azResult[7] = "21"; +** </pre></blockquote> +** +** Notice that there is an extra row of data containing the column +** headers. But the *nrow return value is still 3. *ncolumn is +** set to 2. In general, the number of values inserted into azResult +** will be ((*nrow) + 1)*(*ncolumn). +** +** After the calling function has finished using the result, it should +** pass the result data pointer to sqlite3_free_table() in order to +** release the memory that was malloc-ed. Because of the way the +** [sqlite3_malloc()] happens, the calling function must not try to call +** [sqlite3_free()] directly. Only [sqlite3_free_table()] is able to release +** the memory properly and safely. +** +** The return value of this routine is the same as from [sqlite3_exec()]. +*/ +int sqlite3_get_table( + sqlite3*, /* An open database */ + const char *sql, /* SQL to be executed */ + char ***resultp, /* Result written to a char *[] that this points to */ + int *nrow, /* Number of result rows written here */ + int *ncolumn, /* Number of result columns written here */ + char **errmsg /* Error msg written here */ +); +void sqlite3_free_table(char **result); + +/* +** CAPI3REF: Formatted String Printing Functions +** +** These routines are workalikes of the "printf()" family of functions +** from the standard C library. +** +** The sqlite3_mprintf() and sqlite3_vmprintf() routines write their +** results into memory obtained from [sqlite3_malloc()]. +** The strings returned by these two routines should be +** released by [sqlite3_free()]. Both routines return a +** NULL pointer if [sqlite3_malloc()] is unable to allocate enough +** memory to hold the resulting string. +** +** In sqlite3_snprintf() routine is similar to "snprintf()" from +** the standard C library. The result is written into the +** buffer supplied as the second parameter whose size is given by +** the first parameter. Note that the order of the +** first two parameters is reversed from snprintf(). This is an +** historical accident that cannot be fixed without breaking +** backwards compatibility. Note also that sqlite3_snprintf() +** returns a pointer to its buffer instead of the number of +** characters actually written into the buffer. We admit that +** the number of characters written would be a more useful return +** value but we cannot change the implementation of sqlite3_snprintf() +** now without breaking compatibility. +** +** As long as the buffer size is greater than zero, sqlite3_snprintf() +** guarantees that the buffer is always zero-terminated. The first +** parameter "n" is the total size of the buffer, including space for +** the zero terminator. So the longest string that can be completely +** written will be n-1 characters. +** +** These routines all implement some additional formatting +** options that are useful for constructing SQL statements. +** All of the usual printf formatting options apply. In addition, there +** is are "%q", "%Q", and "%z" options. +** +** The %q option works like %s in that it substitutes a null-terminated +** string from the argument list. But %q also doubles every '\'' character. +** %q is designed for use inside a string literal. By doubling each '\'' +** character it escapes that character and allows it to be inserted into +** the string. +** +** For example, so some string variable contains text as follows: +** +** <blockquote><pre> +** char *zText = "It's a happy day!"; +** </pre></blockquote> +** +** One can use this text in an SQL statement as follows: +** +** <blockquote><pre> +** char *zSQL = sqlite3_mprintf("INSERT INTO table VALUES('%q')", zText); +** sqlite3_exec(db, zSQL, 0, 0, 0); +** sqlite3_free(zSQL); +** </pre></blockquote> +** +** Because the %q format string is used, the '\'' character in zText +** is escaped and the SQL generated is as follows: +** +** <blockquote><pre> +** INSERT INTO table1 VALUES('It''s a happy day!') +** </pre></blockquote> +** +** This is correct. Had we used %s instead of %q, the generated SQL +** would have looked like this: +** +** <blockquote><pre> +** INSERT INTO table1 VALUES('It's a happy day!'); +** </pre></blockquote> +** +** This second example is an SQL syntax error. As a general rule you +** should always use %q instead of %s when inserting text into a string +** literal. +** +** The %Q option works like %q except it also adds single quotes around +** the outside of the total string. Or if the parameter in the argument +** list is a NULL pointer, %Q substitutes the text "NULL" (without single +** quotes) in place of the %Q option. So, for example, one could say: +** +** <blockquote><pre> +** char *zSQL = sqlite3_mprintf("INSERT INTO table VALUES(%Q)", zText); +** sqlite3_exec(db, zSQL, 0, 0, 0); +** sqlite3_free(zSQL); +** </pre></blockquote> +** +** The code above will render a correct SQL statement in the zSQL +** variable even if the zText variable is a NULL pointer. +** +** The "%z" formatting option works exactly like "%s" with the +** addition that after the string has been read and copied into +** the result, [sqlite3_free()] is called on the input string. +*/ +char *sqlite3_mprintf(const char*,...); +char *sqlite3_vmprintf(const char*, va_list); +char *sqlite3_snprintf(int,char*,const char*, ...); + +/* +** CAPI3REF: Memory Allocation Subsystem +** +** The SQLite core uses these three routines for all of its own +** internal memory allocation needs. (See the exception below.) +** +** The default implementation +** of the memory allocation subsystem uses the malloc(), realloc() +** and free() provided by the standard C library. However, if +** SQLite is compiled with the following C preprocessor macro +** +** <blockquote> SQLITE_MEMORY_SIZE=<i>NNN</i> </blockquote> +** +** where <i>NNN</i> is an integer, then SQLite create a static +** array of at least <i>NNN</i> bytes in size and use that array +** for all of its dynamic memory allocation needs. +** +** In SQLite version 3.5.0 and 3.5.1, it was possible to define +** the SQLITE_OMIT_MEMORY_ALLOCATION which would cause the built-in +** implementation of these routines to be omitted. That capability +** is no longer provided. Only built-in memory allocators can be +** used. +** +** <b>Exception:</b> The windows OS interface layer calls +** the system malloc() and free() directly when converting +** filenames between the UTF-8 encoding used by SQLite +** and whatever filename encoding is used by the particular windows +** installation. Memory allocation errors are detected, but +** they are reported back as [SQLITE_CANTOPEN] or +** [SQLITE_IOERR] rather than [SQLITE_NOMEM]. +*/ +void *sqlite3_malloc(int); +void *sqlite3_realloc(void*, int); +void sqlite3_free(void*); + +/* +** CAPI3REF: Memory Allocator Statistics +** +** In addition to the basic three allocation routines +** [sqlite3_malloc()], [sqlite3_free()], and [sqlite3_realloc()], +** the memory allocation subsystem included with the SQLite +** sources provides the interfaces shown below. +** +** The first of these two routines returns the amount of memory +** currently outstanding (malloced but not freed). The second +** returns the largest instantaneous amount of outstanding +** memory. The highwater mark is reset if the argument is +** true. +** +** The value returned may or may not include allocation +** overhead, depending on which built-in memory allocator +** implementation is used. +*/ +sqlite3_int64 sqlite3_memory_used(void); +sqlite3_int64 sqlite3_memory_highwater(int resetFlag); + +/* +** CAPI3REF: Compile-Time Authorization Callbacks +*** +** This routine registers a authorizer callback with the SQLite library. +** The authorizer callback is invoked as SQL statements are being compiled +** by [sqlite3_prepare()] or its variants [sqlite3_prepare_v2()], +** [sqlite3_prepare16()] and [sqlite3_prepare16_v2()]. At various +** points during the compilation process, as logic is being created +** to perform various actions, the authorizer callback is invoked to +** see if those actions are allowed. The authorizer callback should +** return SQLITE_OK to allow the action, [SQLITE_IGNORE] to disallow the +** specific action but allow the SQL statement to continue to be +** compiled, or [SQLITE_DENY] to cause the entire SQL statement to be +** rejected with an error. +** +** Depending on the action, the [SQLITE_IGNORE] and [SQLITE_DENY] return +** codes might mean something different or they might mean the same +** thing. If the action is, for example, to perform a delete opertion, +** then [SQLITE_IGNORE] and [SQLITE_DENY] both cause the statement compilation +** to fail with an error. But if the action is to read a specific column +** from a specific table, then [SQLITE_DENY] will cause the entire +** statement to fail but [SQLITE_IGNORE] will cause a NULL value to be +** read instead of the actual column value. +** +** The first parameter to the authorizer callback is a copy of +** the third parameter to the sqlite3_set_authorizer() interface. +** The second parameter to the callback is an integer +** [SQLITE_COPY | action code] that specifies the particular action +** to be authorized. The available action codes are +** [SQLITE_COPY | documented separately]. The third through sixth +** parameters to the callback are strings that contain additional +** details about the action to be authorized. +** +** An authorizer is used when preparing SQL statements from an untrusted +** source, to ensure that the SQL statements do not try to access data +** that they are not allowed to see, or that they do not try to +** execute malicious statements that damage the database. For +** example, an application may allow a user to enter arbitrary +** SQL queries for evaluation by a database. But the application does +** not want the user to be able to make arbitrary changes to the +** database. An authorizer could then be put in place while the +** user-entered SQL is being prepared that disallows everything +** except SELECT statements. +** +** Only a single authorizer can be in place on a database connection +** at a time. Each call to sqlite3_set_authorizer overrides the +** previous call. A NULL authorizer means that no authorization +** callback is invoked. The default authorizer is NULL. +** +** Note that the authorizer callback is invoked only during +** [sqlite3_prepare()] or its variants. Authorization is not +** performed during statement evaluation in [sqlite3_step()]. +*/ +int sqlite3_set_authorizer( + sqlite3*, + int (*xAuth)(void*,int,const char*,const char*,const char*,const char*), + void *pUserData +); + +/* +** CAPI3REF: Authorizer Return Codes +** +** The [sqlite3_set_authorizer | authorizer callback function] must +** return either [SQLITE_OK] or one of these two constants in order +** to signal SQLite whether or not the action is permitted. See the +** [sqlite3_set_authorizer | authorizer documentation] for additional +** information. +*/ +#define SQLITE_DENY 1 /* Abort the SQL statement with an error */ +#define SQLITE_IGNORE 2 /* Don't allow access, but don't generate an error */ + +/* +** CAPI3REF: Authorizer Action Codes +** +** The [sqlite3_set_authorizer()] interface registers a callback function +** that is invoked to authorizer certain SQL statement actions. The +** second parameter to the callback is an integer code that specifies +** what action is being authorized. These are the integer action codes that +** the authorizer callback may be passed. +** +** These action code values signify what kind of operation is to be +** authorized. The 3rd and 4th parameters to the authorization callback +** function will be parameters or NULL depending on which of these +** codes is used as the second parameter. The 5th parameter to the +** authorizer callback is the name of the database ("main", "temp", +** etc.) if applicable. The 6th parameter to the authorizer callback +** is the name of the inner-most trigger or view that is responsible for +** the access attempt or NULL if this access attempt is directly from +** top-level SQL code. +*/ +/******************************************* 3rd ************ 4th ***********/ +#define SQLITE_CREATE_INDEX 1 /* Index Name Table Name */ +#define SQLITE_CREATE_TABLE 2 /* Table Name NULL */ +#define SQLITE_CREATE_TEMP_INDEX 3 /* Index Name Table Name */ +#define SQLITE_CREATE_TEMP_TABLE 4 /* Table Name NULL */ +#define SQLITE_CREATE_TEMP_TRIGGER 5 /* Trigger Name Table Name */ +#define SQLITE_CREATE_TEMP_VIEW 6 /* View Name NULL */ +#define SQLITE_CREATE_TRIGGER 7 /* Trigger Name Table Name */ +#define SQLITE_CREATE_VIEW 8 /* View Name NULL */ +#define SQLITE_DELETE 9 /* Table Name NULL */ +#define SQLITE_DROP_INDEX 10 /* Index Name Table Name */ +#define SQLITE_DROP_TABLE 11 /* Table Name NULL */ +#define SQLITE_DROP_TEMP_INDEX 12 /* Index Name Table Name */ +#define SQLITE_DROP_TEMP_TABLE 13 /* Table Name NULL */ +#define SQLITE_DROP_TEMP_TRIGGER 14 /* Trigger Name Table Name */ +#define SQLITE_DROP_TEMP_VIEW 15 /* View Name NULL */ +#define SQLITE_DROP_TRIGGER 16 /* Trigger Name Table Name */ +#define SQLITE_DROP_VIEW 17 /* View Name NULL */ +#define SQLITE_INSERT 18 /* Table Name NULL */ +#define SQLITE_PRAGMA 19 /* Pragma Name 1st arg or NULL */ +#define SQLITE_READ 20 /* Table Name Column Name */ +#define SQLITE_SELECT 21 /* NULL NULL */ +#define SQLITE_TRANSACTION 22 /* NULL NULL */ +#define SQLITE_UPDATE 23 /* Table Name Column Name */ +#define SQLITE_ATTACH 24 /* Filename NULL */ +#define SQLITE_DETACH 25 /* Database Name NULL */ +#define SQLITE_ALTER_TABLE 26 /* Database Name Table Name */ +#define SQLITE_REINDEX 27 /* Index Name NULL */ +#define SQLITE_ANALYZE 28 /* Table Name NULL */ +#define SQLITE_CREATE_VTABLE 29 /* Table Name Module Name */ +#define SQLITE_DROP_VTABLE 30 /* Table Name Module Name */ +#define SQLITE_FUNCTION 31 /* Function Name NULL */ +#define SQLITE_COPY 0 /* No longer used */ + +/* +** CAPI3REF: Tracing And Profiling Functions +** +** These routines register callback functions that can be used for +** tracing and profiling the execution of SQL statements. +** The callback function registered by sqlite3_trace() is invoked +** at the first [sqlite3_step()] for the evaluation of an SQL statement. +** The callback function registered by sqlite3_profile() is invoked +** as each SQL statement finishes and includes +** information on how long that statement ran. +** +** The sqlite3_profile() API is currently considered experimental and +** is subject to change. +*/ +void *sqlite3_trace(sqlite3*, void(*xTrace)(void*,const char*), void*); +void *sqlite3_profile(sqlite3*, + void(*xProfile)(void*,const char*,sqlite3_uint64), void*); + +/* +** CAPI3REF: Query Progress Callbacks +** +** This routine configures a callback function - the progress callback - that +** is invoked periodically during long running calls to [sqlite3_exec()], +** [sqlite3_step()] and [sqlite3_get_table()]. An example use for this +** interface is to keep a GUI updated during a large query. +** +** The progress callback is invoked once for every N virtual machine opcodes, +** where N is the second argument to this function. The progress callback +** itself is identified by the third argument to this function. The fourth +** argument to this function is a void pointer passed to the progress callback +** function each time it is invoked. +** +** If a call to [sqlite3_exec()], [sqlite3_step()], or [sqlite3_get_table()] +** results in fewer than N opcodes being executed, then the progress +** callback is never invoked. +** +** Only a single progress callback function may be registered for each +** open database connection. Every call to sqlite3_progress_handler() +** overwrites the results of the previous call. +** To remove the progress callback altogether, pass NULL as the third +** argument to this function. +** +** If the progress callback returns a result other than 0, then the current +** query is immediately terminated and any database changes rolled back. +** The containing [sqlite3_exec()], [sqlite3_step()], or +** [sqlite3_get_table()] call returns SQLITE_INTERRUPT. This feature +** can be used, for example, to implement the "Cancel" button on a +** progress dialog box in a GUI. +*/ +void sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*); + +/* +** CAPI3REF: Opening A New Database Connection +** +** Open the sqlite database file "filename". The "filename" is UTF-8 +** encoded for [sqlite3_open()] and [sqlite3_open_v2()] and UTF-16 encoded +** in the native byte order for [sqlite3_open16()]. +** An [sqlite3*] handle is returned in *ppDb, even +** if an error occurs. If the database is opened (or created) successfully, +** then [SQLITE_OK] is returned. Otherwise an error code is returned. The +** [sqlite3_errmsg()] or [sqlite3_errmsg16()] routines can be used to obtain +** an English language description of the error. +** +** The default encoding for the database will be UTF-8 if +** [sqlite3_open()] or [sqlite3_open_v2()] is called and +** UTF-16 if [sqlite3_open16()] is used. +** +** Whether or not an error occurs when it is opened, resources associated +** with the [sqlite3*] handle should be released by passing it to +** [sqlite3_close()] when it is no longer required. +** +** The [sqlite3_open_v2()] interface works like [sqlite3_open()] except that +** provides two additional parameters for additional control over the +** new database connection. The flags parameter can be one of: +** +** <ol> +** <li> [SQLITE_OPEN_READONLY] +** <li> [SQLITE_OPEN_READWRITE] +** <li> [SQLITE_OPEN_READWRITE] | [SQLITE_OPEN_CREATE] +** </ol> +** +** The first value opens the database read-only. If the database does +** not previously exist, an error is returned. The second option opens +** the database for reading and writing if possible, or reading only if +** if the file is write protected. In either case the database must already +** exist or an error is returned. The third option opens the database +** for reading and writing and creates it if it does not already exist. +** The third options is behavior that is always used for [sqlite3_open()] +** and [sqlite3_open16()]. +** +** If the filename is ":memory:", then an private +** in-memory database is created for the connection. This in-memory +** database will vanish when the database connection is closed. Future +** version of SQLite might make use of additional special filenames +** that begin with the ":" character. It is recommended that +** when a database filename really does begin with +** ":" that you prefix the filename with a pathname like "./" to +** avoid ambiguity. +** +** If the filename is an empty string, then a private temporary +** on-disk database will be created. This private database will be +** automatically deleted as soon as the database connection is closed. +** +** The fourth parameter to sqlite3_open_v2() is the name of the +** [sqlite3_vfs] object that defines the operating system +** interface that the new database connection should use. If the +** fourth parameter is a NULL pointer then the default [sqlite3_vfs] +** object is used. +** +** <b>Note to windows users:</b> The encoding used for the filename argument +** of [sqlite3_open()] and [sqlite3_open_v2()] must be UTF-8, not whatever +** codepage is currently defined. Filenames containing international +** characters must be converted to UTF-8 prior to passing them into +** [sqlite3_open()] or [sqlite3_open_v2()]. +*/ +int sqlite3_open( + const char *filename, /* Database filename (UTF-8) */ + sqlite3 **ppDb /* OUT: SQLite db handle */ +); +int sqlite3_open16( + const void *filename, /* Database filename (UTF-16) */ + sqlite3 **ppDb /* OUT: SQLite db handle */ +); +int sqlite3_open_v2( + const char *filename, /* Database filename (UTF-8) */ + sqlite3 **ppDb, /* OUT: SQLite db handle */ + int flags, /* Flags */ + const char *zVfs /* Name of VFS module to use */ +); + +/* +** CAPI3REF: Error Codes And Messages +** +** The sqlite3_errcode() interface returns the numeric +** [SQLITE_OK | result code] or [SQLITE_IOERR_READ | extended result code] +** for the most recent failed sqlite3_* API call associated +** with [sqlite3] handle 'db'. If a prior API call failed but the +** most recent API call succeeded, the return value from sqlite3_errcode() +** is undefined. +** +** The sqlite3_errmsg() and sqlite3_errmsg16() return English-language +** text that describes the error, as either UTF8 or UTF16 respectively. +** Memory to hold the error message string is managed internally. The +** string may be overwritten or deallocated by subsequent calls to SQLite +** interface functions. +** +** Calls to many sqlite3_* functions set the error code and string returned +** by [sqlite3_errcode()], [sqlite3_errmsg()], and [sqlite3_errmsg16()] +** (overwriting the previous values). Note that calls to [sqlite3_errcode()], +** [sqlite3_errmsg()], and [sqlite3_errmsg16()] themselves do not affect the +** results of future invocations. Calls to API routines that do not return +** an error code (example: [sqlite3_data_count()]) do not +** change the error code returned by this routine. Interfaces that are +** not associated with a specific database connection (examples: +** [sqlite3_mprintf()] or [sqlite3_enable_shared_cache()] do not change +** the return code. +** +** Assuming no other intervening sqlite3_* API calls are made, the error +** code returned by this function is associated with the same error as +** the strings returned by [sqlite3_errmsg()] and [sqlite3_errmsg16()]. +*/ +int sqlite3_errcode(sqlite3 *db); +const char *sqlite3_errmsg(sqlite3*); +const void *sqlite3_errmsg16(sqlite3*); + +/* +** CAPI3REF: SQL Statement Object +** +** Instance of this object represent single SQL statements. This +** is variously known as a "prepared statement" or a +** "compiled SQL statement" or simply as a "statement". +** +** The life of a statement object goes something like this: +** +** <ol> +** <li> Create the object using [sqlite3_prepare_v2()] or a related +** function. +** <li> Bind values to host parameters using +** [sqlite3_bind_blob | sqlite3_bind_* interfaces]. +** <li> Run the SQL by calling [sqlite3_step()] one or more times. +** <li> Reset the statement using [sqlite3_reset()] then go back +** to step 2. Do this zero or more times. +** <li> Destroy the object using [sqlite3_finalize()]. +** </ol> +** +** Refer to documentation on individual methods above for additional +** information. +*/ +typedef struct sqlite3_stmt sqlite3_stmt; + +/* +** CAPI3REF: Compiling An SQL Statement +** +** To execute an SQL query, it must first be compiled into a byte-code +** program using one of these routines. +** +** The first argument "db" is an [sqlite3 | SQLite database handle] +** obtained from a prior call to [sqlite3_open()], [sqlite3_open_v2()] +** or [sqlite3_open16()]. +** The second argument "zSql" is the statement to be compiled, encoded +** as either UTF-8 or UTF-16. The sqlite3_prepare() and sqlite3_prepare_v2() +** interfaces uses UTF-8 and sqlite3_prepare16() and sqlite3_prepare16_v2() +** use UTF-16. +** +** If the nByte argument is less +** than zero, then zSql is read up to the first zero terminator. If +** nByte is non-negative, then it is the maximum number of +** bytes read from zSql. When nByte is non-negative, the +** zSql string ends at either the first '\000' character or +** until the nByte-th byte, whichever comes first. +** +** *pzTail is made to point to the first byte past the end of the first +** SQL statement in zSql. This routine only compiles the first statement +** in zSql, so *pzTail is left pointing to what remains uncompiled. +** +** *ppStmt is left pointing to a compiled +** [sqlite3_stmt | SQL statement structure] that can be +** executed using [sqlite3_step()]. Or if there is an error, *ppStmt may be +** set to NULL. If the input text contained no SQL (if the input is and +** empty string or a comment) then *ppStmt is set to NULL. The calling +** procedure is responsible for deleting the compiled SQL statement +** using [sqlite3_finalize()] after it has finished with it. +** +** On success, [SQLITE_OK] is returned. Otherwise an +** [SQLITE_ERROR | error code] is returned. +** +** The sqlite3_prepare_v2() and sqlite3_prepare16_v2() interfaces are +** recommended for all new programs. The two older interfaces are retained +** for backwards compatibility, but their use is discouraged. +** In the "v2" interfaces, the prepared statement +** that is returned (the [sqlite3_stmt] object) contains a copy of the +** original SQL text. This causes the [sqlite3_step()] interface to +** behave a differently in two ways: +** +** <ol> +** <li> +** If the database schema changes, instead of returning [SQLITE_SCHEMA] as it +** always used to do, [sqlite3_step()] will automatically recompile the SQL +** statement and try to run it again. If the schema has changed in a way +** that makes the statement no longer valid, [sqlite3_step()] will still +** return [SQLITE_SCHEMA]. But unlike the legacy behavior, [SQLITE_SCHEMA] is +** now a fatal error. Calling [sqlite3_prepare_v2()] again will not make the +** error go away. Note: use [sqlite3_errmsg()] to find the text of the parsing +** error that results in an [SQLITE_SCHEMA] return. +** </li> +** +** <li> +** When an error occurs, +** [sqlite3_step()] will return one of the detailed +** [SQLITE_ERROR | result codes] or +** [SQLITE_IOERR_READ | extended result codes] such as directly. +** The legacy behavior was that [sqlite3_step()] would only return a generic +** [SQLITE_ERROR] result code and you would have to make a second call to +** [sqlite3_reset()] in order to find the underlying cause of the problem. +** With the "v2" prepare interfaces, the underlying reason for the error is +** returned immediately. +** </li> +** </ol> +*/ +int sqlite3_prepare( + sqlite3 *db, /* Database handle */ + const char *zSql, /* SQL statement, UTF-8 encoded */ + int nByte, /* Maximum length of zSql in bytes. */ + sqlite3_stmt **ppStmt, /* OUT: Statement handle */ + const char **pzTail /* OUT: Pointer to unused portion of zSql */ +); +int sqlite3_prepare_v2( + sqlite3 *db, /* Database handle */ + const char *zSql, /* SQL statement, UTF-8 encoded */ + int nByte, /* Maximum length of zSql in bytes. */ + sqlite3_stmt **ppStmt, /* OUT: Statement handle */ + const char **pzTail /* OUT: Pointer to unused portion of zSql */ +); +int sqlite3_prepare16( + sqlite3 *db, /* Database handle */ + const void *zSql, /* SQL statement, UTF-16 encoded */ + int nByte, /* Maximum length of zSql in bytes. */ + sqlite3_stmt **ppStmt, /* OUT: Statement handle */ + const void **pzTail /* OUT: Pointer to unused portion of zSql */ +); +int sqlite3_prepare16_v2( + sqlite3 *db, /* Database handle */ + const void *zSql, /* SQL statement, UTF-16 encoded */ + int nByte, /* Maximum length of zSql in bytes. */ + sqlite3_stmt **ppStmt, /* OUT: Statement handle */ + const void **pzTail /* OUT: Pointer to unused portion of zSql */ +); + +/* +** Retrieve the original SQL statement associated with a compiled statement +** in UTF-8 encoding. +** +** If the compiled SQL statement passed as an argument was compiled using +** either sqlite3_prepare_v2 or sqlite3_prepare16_v2, then this function +** returns a pointer to a nul-terminated string containing a copy of +** the original SQL statement. The pointer is valid until the statement +** is deleted using sqlite3_finalize(). +** +** If the statement was compiled using either of the legacy interfaces +** sqlite3_prepare() or sqlite3_prepare16(), this function returns NULL. +** +****** EXPERIMENTAL - subject to change without notice ************** +*/ +const char *sqlite3_sql(sqlite3_stmt *pStmt); + +/* +** CAPI3REF: Dynamically Typed Value Object +** +** SQLite uses dynamic typing for the values it stores. Values can +** be integers, floating point values, strings, BLOBs, or NULL. When +** passing around values internally, each value is represented as +** an instance of the sqlite3_value object. +*/ +typedef struct Mem sqlite3_value; + +/* +** CAPI3REF: SQL Function Context Object +** +** The context in which an SQL function executes is stored in an +** sqlite3_context object. A pointer to such an object is the +** first parameter to user-defined SQL functions. +*/ +typedef struct sqlite3_context sqlite3_context; + +/* +** CAPI3REF: Binding Values To Prepared Statements +** +** In the SQL strings input to [sqlite3_prepare_v2()] and its variants, +** one or more literals can be replace by a parameter in one of these +** forms: +** +** <ul> +** <li> ? +** <li> ?NNN +** <li> :AAA +** <li> @AAA +** <li> $VVV +** </ul> +** +** In the parameter forms shown above NNN is an integer literal, +** AAA is an alphanumeric identifier and VVV is a variable name according +** to the syntax rules of the TCL programming language. +** The values of these parameters (also called "host parameter names") +** can be set using the sqlite3_bind_*() routines defined here. +** +** The first argument to the sqlite3_bind_*() routines always is a pointer +** to the [sqlite3_stmt] object returned from [sqlite3_prepare_v2()] or +** its variants. The second +** argument is the index of the parameter to be set. The first parameter has +** an index of 1. When the same named parameter is used more than once, second +** and subsequent +** occurrences have the same index as the first occurrence. The index for +** named parameters can be looked up using the +** [sqlite3_bind_parameter_name()] API if desired. The index for "?NNN" +** parametes is the value of NNN. +** The NNN value must be between 1 and the compile-time +** parameter SQLITE_MAX_VARIABLE_NUMBER (default value: 999). +** See <a href="limits.html">limits.html</a> for additional information. +** +** The third argument is the value to bind to the parameter. +** +** In those +** routines that have a fourth argument, its value is the number of bytes +** in the parameter. To be clear: the value is the number of bytes in the +** string, not the number of characters. The number +** of bytes does not include the zero-terminator at the end of strings. +** If the fourth parameter is negative, the length of the string is +** number of bytes up to the first zero terminator. +** +** The fifth argument to sqlite3_bind_blob(), sqlite3_bind_text(), and +** sqlite3_bind_text16() is a destructor used to dispose of the BLOB or +** text after SQLite has finished with it. If the fifth argument is the +** special value [SQLITE_STATIC], then the library assumes that the information +** is in static, unmanaged space and does not need to be freed. If the +** fifth argument has the value [SQLITE_TRANSIENT], then SQLite makes its +** own private copy of the data immediately, before the sqlite3_bind_*() +** routine returns. +** +** The sqlite3_bind_zeroblob() routine binds a BLOB of length n that +** is filled with zeros. A zeroblob uses a fixed amount of memory +** (just an integer to hold it size) while it is being processed. +** Zeroblobs are intended to serve as place-holders for BLOBs whose +** content is later written using +** [sqlite3_blob_open | increment BLOB I/O] routines. A negative +** value for the zeroblob results in a zero-length BLOB. +** +** The sqlite3_bind_*() routines must be called after +** [sqlite3_prepare_v2()] (and its variants) or [sqlite3_reset()] and +** before [sqlite3_step()]. +** Bindings are not cleared by the [sqlite3_reset()] routine. +** Unbound parameters are interpreted as NULL. +** +** These routines return [SQLITE_OK] on success or an error code if +** anything goes wrong. [SQLITE_RANGE] is returned if the parameter +** index is out of range. [SQLITE_NOMEM] is returned if malloc fails. +** [SQLITE_MISUSE] is returned if these routines are called on a virtual +** machine that is the wrong state or which has already been finalized. +*/ +int sqlite3_bind_blob(sqlite3_stmt*, int, const void*, int n, void(*)(void*)); +int sqlite3_bind_double(sqlite3_stmt*, int, double); +int sqlite3_bind_int(sqlite3_stmt*, int, int); +int sqlite3_bind_int64(sqlite3_stmt*, int, sqlite3_int64); +int sqlite3_bind_null(sqlite3_stmt*, int); +int sqlite3_bind_text(sqlite3_stmt*, int, const char*, int n, void(*)(void*)); +int sqlite3_bind_text16(sqlite3_stmt*, int, const void*, int, void(*)(void*)); +int sqlite3_bind_value(sqlite3_stmt*, int, const sqlite3_value*); +int sqlite3_bind_zeroblob(sqlite3_stmt*, int, int n); + +/* +** CAPI3REF: Number Of Host Parameters +** +** Return the largest host parameter index in the precompiled statement given +** as the argument. When the host parameters are of the forms like ":AAA" +** or "?", then they are assigned sequential increasing numbers beginning +** with one, so the value returned is the number of parameters. However +** if the same host parameter name is used multiple times, each occurrance +** is given the same number, so the value returned in that case is the number +** of unique host parameter names. If host parameters of the form "?NNN" +** are used (where NNN is an integer) then there might be gaps in the +** numbering and the value returned by this interface is the index of the +** host parameter with the largest index value. +** +** The prepared statement must not be [sqlite3_finalize | finalized] +** prior to this routine returnning. Otherwise the results are undefined +** and probably undesirable. +*/ +int sqlite3_bind_parameter_count(sqlite3_stmt*); + +/* +** CAPI3REF: Name Of A Host Parameter +** +** This routine returns a pointer to the name of the n-th parameter in a +** [sqlite3_stmt | prepared statement]. +** Host parameters of the form ":AAA" or "@AAA" or "$VVV" have a name +** which is the string ":AAA" or "@AAA" or "$VVV". +** In other words, the initial ":" or "$" or "@" +** is included as part of the name. +** Parameters of the form "?" or "?NNN" have no name. +** +** The first bound parameter has an index of 1, not 0. +** +** If the value n is out of range or if the n-th parameter is nameless, +** then NULL is returned. The returned string is always in the +** UTF-8 encoding even if the named parameter was originally specified +** as UTF-16 in [sqlite3_prepare16()] or [sqlite3_prepare16_v2()]. +*/ +const char *sqlite3_bind_parameter_name(sqlite3_stmt*, int); + +/* +** CAPI3REF: Index Of A Parameter With A Given Name +** +** This routine returns the index of a host parameter with the given name. +** The name must match exactly. If no parameter with the given name is +** found, return 0. Parameter names must be UTF8. +*/ +int sqlite3_bind_parameter_index(sqlite3_stmt*, const char *zName); + +/* +** CAPI3REF: Reset All Bindings On A Prepared Statement +** +** Contrary to the intuition of many, [sqlite3_reset()] does not +** reset the [sqlite3_bind_blob | bindings] on a +** [sqlite3_stmt | prepared statement]. Use this routine to +** reset all host parameters to NULL. +*/ +int sqlite3_clear_bindings(sqlite3_stmt*); + +/* +** CAPI3REF: Number Of Columns In A Result Set +** +** Return the number of columns in the result set returned by the +** [sqlite3_stmt | compiled SQL statement]. This routine returns 0 +** if pStmt is an SQL statement that does not return data (for +** example an UPDATE). +*/ +int sqlite3_column_count(sqlite3_stmt *pStmt); + +/* +** CAPI3REF: Column Names In A Result Set +** +** These routines return the name assigned to a particular column +** in the result set of a SELECT statement. The sqlite3_column_name() +** interface returns a pointer to a UTF8 string and sqlite3_column_name16() +** returns a pointer to a UTF16 string. The first parameter is the +** [sqlite3_stmt | prepared statement] that implements the SELECT statement. +** The second parameter is the column number. The left-most column is +** number 0. +** +** The returned string pointer is valid until either the +** [sqlite3_stmt | prepared statement] is destroyed by [sqlite3_finalize()] +** or until the next call sqlite3_column_name() or sqlite3_column_name16() +** on the same column. +** +** If sqlite3_malloc() fails during the processing of either routine +** (for example during a conversion from UTF-8 to UTF-16) then a +** NULL pointer is returned. +*/ +const char *sqlite3_column_name(sqlite3_stmt*, int N); +const void *sqlite3_column_name16(sqlite3_stmt*, int N); + +/* +** CAPI3REF: Source Of Data In A Query Result +** +** These routines provide a means to determine what column of what +** table in which database a result of a SELECT statement comes from. +** The name of the database or table or column can be returned as +** either a UTF8 or UTF16 string. The _database_ routines return +** the database name, the _table_ routines return the table name, and +** the origin_ routines return the column name. +** The returned string is valid until +** the [sqlite3_stmt | prepared statement] is destroyed using +** [sqlite3_finalize()] or until the same information is requested +** again in a different encoding. +** +** The names returned are the original un-aliased names of the +** database, table, and column. +** +** The first argument to the following calls is a +** [sqlite3_stmt | compiled SQL statement]. +** These functions return information about the Nth column returned by +** the statement, where N is the second function argument. +** +** If the Nth column returned by the statement is an expression +** or subquery and is not a column value, then all of these functions +** return NULL. Otherwise, they return the +** name of the attached database, table and column that query result +** column was extracted from. +** +** As with all other SQLite APIs, those postfixed with "16" return UTF-16 +** encoded strings, the other functions return UTF-8. +** +** These APIs are only available if the library was compiled with the +** SQLITE_ENABLE_COLUMN_METADATA preprocessor symbol defined. +** +** If two or more threads call one or more of these routines against the same +** prepared statement and column at the same time then the results are +** undefined. +*/ +const char *sqlite3_column_database_name(sqlite3_stmt*,int); +const void *sqlite3_column_database_name16(sqlite3_stmt*,int); +const char *sqlite3_column_table_name(sqlite3_stmt*,int); +const void *sqlite3_column_table_name16(sqlite3_stmt*,int); +const char *sqlite3_column_origin_name(sqlite3_stmt*,int); +const void *sqlite3_column_origin_name16(sqlite3_stmt*,int); + +/* +** CAPI3REF: Declared Datatype Of A Query Result +** +** The first parameter is a [sqlite3_stmt | compiled SQL statement]. +** If this statement is a SELECT statement and the Nth column of the +** returned result set of that SELECT is a table column (not an +** expression or subquery) then the declared type of the table +** column is returned. If the Nth column of the result set is an +** expression or subquery, then a NULL pointer is returned. +** The returned string is always UTF-8 encoded. For example, in +** the database schema: +** +** CREATE TABLE t1(c1 VARIANT); +** +** And the following statement compiled: +** +** SELECT c1 + 1, c1 FROM t1; +** +** Then this routine would return the string "VARIANT" for the second +** result column (i==1), and a NULL pointer for the first result column +** (i==0). +** +** SQLite uses dynamic run-time typing. So just because a column +** is declared to contain a particular type does not mean that the +** data stored in that column is of the declared type. SQLite is +** strongly typed, but the typing is dynamic not static. Type +** is associated with individual values, not with the containers +** used to hold those values. +*/ +const char *sqlite3_column_decltype(sqlite3_stmt *, int i); +const void *sqlite3_column_decltype16(sqlite3_stmt*,int); + +/* +** CAPI3REF: Evaluate An SQL Statement +** +** After an [sqlite3_stmt | SQL statement] has been prepared with a call +** to either [sqlite3_prepare_v2()] or [sqlite3_prepare16_v2()] or to one of +** the legacy interfaces [sqlite3_prepare()] or [sqlite3_prepare16()], +** then this function must be called one or more times to evaluate the +** statement. +** +** The details of the behavior of this sqlite3_step() interface depend +** on whether the statement was prepared using the newer "v2" interface +** [sqlite3_prepare_v2()] and [sqlite3_prepare16_v2()] or the older legacy +** interface [sqlite3_prepare()] and [sqlite3_prepare16()]. The use of the +** new "v2" interface is recommended for new applications but the legacy +** interface will continue to be supported. +** +** In the lagacy interface, the return value will be either [SQLITE_BUSY], +** [SQLITE_DONE], [SQLITE_ROW], [SQLITE_ERROR], or [SQLITE_MISUSE]. +** With the "v2" interface, any of the other [SQLITE_OK | result code] +** or [SQLITE_IOERR_READ | extended result code] might be returned as +** well. +** +** [SQLITE_BUSY] means that the database engine was unable to acquire the +** database locks it needs to do its job. If the statement is a COMMIT +** or occurs outside of an explicit transaction, then you can retry the +** statement. If the statement is not a COMMIT and occurs within a +** explicit transaction then you should rollback the transaction before +** continuing. +** +** [SQLITE_DONE] means that the statement has finished executing +** successfully. sqlite3_step() should not be called again on this virtual +** machine without first calling [sqlite3_reset()] to reset the virtual +** machine back to its initial state. +** +** If the SQL statement being executed returns any data, then +** [SQLITE_ROW] is returned each time a new row of data is ready +** for processing by the caller. The values may be accessed using +** the [sqlite3_column_int | column access functions]. +** sqlite3_step() is called again to retrieve the next row of data. +** +** [SQLITE_ERROR] means that a run-time error (such as a constraint +** violation) has occurred. sqlite3_step() should not be called again on +** the VM. More information may be found by calling [sqlite3_errmsg()]. +** With the legacy interface, a more specific error code (example: +** [SQLITE_INTERRUPT], [SQLITE_SCHEMA], [SQLITE_CORRUPT], and so forth) +** can be obtained by calling [sqlite3_reset()] on the +** [sqlite3_stmt | prepared statement]. In the "v2" interface, +** the more specific error code is returned directly by sqlite3_step(). +** +** [SQLITE_MISUSE] means that the this routine was called inappropriately. +** Perhaps it was called on a [sqlite3_stmt | prepared statement] that has +** already been [sqlite3_finalize | finalized] or on one that had +** previously returned [SQLITE_ERROR] or [SQLITE_DONE]. Or it could +** be the case that the same database connection is being used by two or +** more threads at the same moment in time. +** +** <b>Goofy Interface Alert:</b> +** In the legacy interface, +** the sqlite3_step() API always returns a generic error code, +** [SQLITE_ERROR], following any error other than [SQLITE_BUSY] +** and [SQLITE_MISUSE]. You must call [sqlite3_reset()] or +** [sqlite3_finalize()] in order to find one of the specific +** [SQLITE_ERROR | result codes] that better describes the error. +** We admit that this is a goofy design. The problem has been fixed +** with the "v2" interface. If you prepare all of your SQL statements +** using either [sqlite3_prepare_v2()] or [sqlite3_prepare16_v2()] instead +** of the legacy [sqlite3_prepare()] and [sqlite3_prepare16()], then the +** more specific [SQLITE_ERROR | result codes] are returned directly +** by sqlite3_step(). The use of the "v2" interface is recommended. +*/ +int sqlite3_step(sqlite3_stmt*); + +/* +** CAPI3REF: +** +** Return the number of values in the current row of the result set. +** +** After a call to [sqlite3_step()] that returns [SQLITE_ROW], this routine +** will return the same value as the [sqlite3_column_count()] function. +** After [sqlite3_step()] has returned an [SQLITE_DONE], [SQLITE_BUSY], or +** a [SQLITE_ERROR | error code], or before [sqlite3_step()] has been +** called on the [sqlite3_stmt | prepared statement] for the first time, +** this routine returns zero. +*/ +int sqlite3_data_count(sqlite3_stmt *pStmt); + +/* +** CAPI3REF: Fundamental Datatypes +** +** Every value in SQLite has one of five fundamental datatypes: +** +** <ul> +** <li> 64-bit signed integer +** <li> 64-bit IEEE floating point number +** <li> string +** <li> BLOB +** <li> NULL +** </ul> +** +** These constants are codes for each of those types. +** +** Note that the SQLITE_TEXT constant was also used in SQLite version 2 +** for a completely different meaning. Software that links against both +** SQLite version 2 and SQLite version 3 should use SQLITE3_TEXT not +** SQLITE_TEXT. +*/ +#define SQLITE_INTEGER 1 +#define SQLITE_FLOAT 2 +#define SQLITE_BLOB 4 +#define SQLITE_NULL 5 +#ifdef SQLITE_TEXT +# undef SQLITE_TEXT +#else +# define SQLITE_TEXT 3 +#endif +#define SQLITE3_TEXT 3 + +/* +** CAPI3REF: Results Values From A Query +** +** These routines return information about +** a single column of the current result row of a query. In every +** case the first argument is a pointer to the +** [sqlite3_stmt | SQL statement] that is being +** evaluated (the [sqlite3_stmt*] that was returned from +** [sqlite3_prepare_v2()] or one of its variants) and +** the second argument is the index of the column for which information +** should be returned. The left-most column of the result set +** has an index of 0. +** +** If the SQL statement is not currently point to a valid row, or if the +** the column index is out of range, the result is undefined. +** These routines may only be called when the most recent call to +** [sqlite3_step()] has returned [SQLITE_ROW] and neither +** [sqlite3_reset()] nor [sqlite3_finalize()] has been call subsequently. +** If any of these routines are called after [sqlite3_reset()] or +** [sqlite3_finalize()] or after [sqlite3_step()] has returned +** something other than [SQLITE_ROW], the results are undefined. +** If [sqlite3_step()] or [sqlite3_reset()] or [sqlite3_finalize()] +** are called from a different thread while any of these routines +** are pending, then the results are undefined. +** +** The sqlite3_column_type() routine returns +** [SQLITE_INTEGER | datatype code] for the initial data type +** of the result column. The returned value is one of [SQLITE_INTEGER], +** [SQLITE_FLOAT], [SQLITE_TEXT], [SQLITE_BLOB], or [SQLITE_NULL]. The value +** returned by sqlite3_column_type() is only meaningful if no type +** conversions have occurred as described below. After a type conversion, +** the value returned by sqlite3_column_type() is undefined. Future +** versions of SQLite may change the behavior of sqlite3_column_type() +** following a type conversion. +** +** If the result is a BLOB or UTF-8 string then the sqlite3_column_bytes() +** routine returns the number of bytes in that BLOB or string. +** If the result is a UTF-16 string, then sqlite3_column_bytes() converts +** the string to UTF-8 and then returns the number of bytes. +** If the result is a numeric value then sqlite3_column_bytes() uses +** [sqlite3_snprintf()] to convert that value to a UTF-8 string and returns +** the number of bytes in that string. +** The value returned does not include the zero terminator at the end +** of the string. For clarity: the value returned is the number of +** bytes in the string, not the number of characters. +** +** Strings returned by sqlite3_column_text() and sqlite3_column_text16(), +** even zero-length strings, are always zero terminated. The return +** value from sqlite3_column_blob() for a zero-length blob is an arbitrary +** pointer, possibly even a NULL pointer. +** +** The sqlite3_column_bytes16() routine is similar to sqlite3_column_bytes() +** but leaves the result in UTF-16 instead of UTF-8. +** The zero terminator is not included in this count. +** +** These routines attempt to convert the value where appropriate. For +** example, if the internal representation is FLOAT and a text result +** is requested, [sqlite3_snprintf()] is used internally to do the conversion +** automatically. The following table details the conversions that +** are applied: +** +** <blockquote> +** <table border="1"> +** <tr><th> Internal<br>Type <th> Requested<br>Type <th> Conversion +** +** <tr><td> NULL <td> INTEGER <td> Result is 0 +** <tr><td> NULL <td> FLOAT <td> Result is 0.0 +** <tr><td> NULL <td> TEXT <td> Result is NULL pointer +** <tr><td> NULL <td> BLOB <td> Result is NULL pointer +** <tr><td> INTEGER <td> FLOAT <td> Convert from integer to float +** <tr><td> INTEGER <td> TEXT <td> ASCII rendering of the integer +** <tr><td> INTEGER <td> BLOB <td> Same as for INTEGER->TEXT +** <tr><td> FLOAT <td> INTEGER <td> Convert from float to integer +** <tr><td> FLOAT <td> TEXT <td> ASCII rendering of the float +** <tr><td> FLOAT <td> BLOB <td> Same as FLOAT->TEXT +** <tr><td> TEXT <td> INTEGER <td> Use atoi() +** <tr><td> TEXT <td> FLOAT <td> Use atof() +** <tr><td> TEXT <td> BLOB <td> No change +** <tr><td> BLOB <td> INTEGER <td> Convert to TEXT then use atoi() +** <tr><td> BLOB <td> FLOAT <td> Convert to TEXT then use atof() +** <tr><td> BLOB <td> TEXT <td> Add a zero terminator if needed +** </table> +** </blockquote> +** +** The table above makes reference to standard C library functions atoi() +** and atof(). SQLite does not really use these functions. It has its +** on equavalent internal routines. The atoi() and atof() names are +** used in the table for brevity and because they are familiar to most +** C programmers. +** +** Note that when type conversions occur, pointers returned by prior +** calls to sqlite3_column_blob(), sqlite3_column_text(), and/or +** sqlite3_column_text16() may be invalidated. +** Type conversions and pointer invalidations might occur +** in the following cases: +** +** <ul> +** <li><p> The initial content is a BLOB and sqlite3_column_text() +** or sqlite3_column_text16() is called. A zero-terminator might +** need to be added to the string.</p></li> +** +** <li><p> The initial content is UTF-8 text and sqlite3_column_bytes16() or +** sqlite3_column_text16() is called. The content must be converted +** to UTF-16.</p></li> +** +** <li><p> The initial content is UTF-16 text and sqlite3_column_bytes() or +** sqlite3_column_text() is called. The content must be converted +** to UTF-8.</p></li> +** </ul> +** +** Conversions between UTF-16be and UTF-16le are always done in place and do +** not invalidate a prior pointer, though of course the content of the buffer +** that the prior pointer points to will have been modified. Other kinds +** of conversion are done in place when it is possible, but sometime it is +** not possible and in those cases prior pointers are invalidated. +** +** The safest and easiest to remember policy is to invoke these routines +** in one of the following ways: +** +** <ul> +** <li>sqlite3_column_text() followed by sqlite3_column_bytes()</li> +** <li>sqlite3_column_blob() followed by sqlite3_column_bytes()</li> +** <li>sqlite3_column_text16() followed by sqlite3_column_bytes16()</li> +** </ul> +** +** In other words, you should call sqlite3_column_text(), sqlite3_column_blob(), +** or sqlite3_column_text16() first to force the result into the desired +** format, then invoke sqlite3_column_bytes() or sqlite3_column_bytes16() to +** find the size of the result. Do not mix call to sqlite3_column_text() or +** sqlite3_column_blob() with calls to sqlite3_column_bytes16(). And do not +** mix calls to sqlite3_column_text16() with calls to sqlite3_column_bytes(). +** +** The pointers returned are valid until a type conversion occurs as +** described above, or until [sqlite3_step()] or [sqlite3_reset()] or +** [sqlite3_finalize()] is called. The memory space used to hold strings +** and blobs is freed automatically. Do <b>not</b> pass the pointers returned +** [sqlite3_column_blob()], [sqlite3_column_text()], etc. into +** [sqlite3_free()]. +** +** If a memory allocation error occurs during the evaluation of any +** of these routines, a default value is returned. The default value +** is either the integer 0, the floating point number 0.0, or a NULL +** pointer. Subsequent calls to [sqlite3_errcode()] will return +** [SQLITE_NOMEM]. +*/ +const void *sqlite3_column_blob(sqlite3_stmt*, int iCol); +int sqlite3_column_bytes(sqlite3_stmt*, int iCol); +int sqlite3_column_bytes16(sqlite3_stmt*, int iCol); +double sqlite3_column_double(sqlite3_stmt*, int iCol); +int sqlite3_column_int(sqlite3_stmt*, int iCol); +sqlite3_int64 sqlite3_column_int64(sqlite3_stmt*, int iCol); +const unsigned char *sqlite3_column_text(sqlite3_stmt*, int iCol); +const void *sqlite3_column_text16(sqlite3_stmt*, int iCol); +int sqlite3_column_type(sqlite3_stmt*, int iCol); +sqlite3_value *sqlite3_column_value(sqlite3_stmt*, int iCol); + +/* +** CAPI3REF: Destroy A Prepared Statement Object +** +** The sqlite3_finalize() function is called to delete a +** [sqlite3_stmt | compiled SQL statement]. If the statement was +** executed successfully, or not executed at all, then SQLITE_OK is returned. +** If execution of the statement failed then an +** [SQLITE_ERROR | error code] or [SQLITE_IOERR_READ | extended error code] +** is returned. +** +** This routine can be called at any point during the execution of the +** [sqlite3_stmt | virtual machine]. If the virtual machine has not +** completed execution when this routine is called, that is like +** encountering an error or an interrupt. (See [sqlite3_interrupt()].) +** Incomplete updates may be rolled back and transactions cancelled, +** depending on the circumstances, and the +** [SQLITE_ERROR | result code] returned will be [SQLITE_ABORT]. +*/ +int sqlite3_finalize(sqlite3_stmt *pStmt); + +/* +** CAPI3REF: Reset A Prepared Statement Object +** +** The sqlite3_reset() function is called to reset a +** [sqlite3_stmt | compiled SQL statement] object. +** back to it's initial state, ready to be re-executed. +** Any SQL statement variables that had values bound to them using +** the [sqlite3_bind_blob | sqlite3_bind_*() API] retain their values. +** Use [sqlite3_clear_bindings()] to reset the bindings. +*/ +int sqlite3_reset(sqlite3_stmt *pStmt); + +/* +** CAPI3REF: Create Or Redefine SQL Functions +** +** The following two functions are used to add SQL functions or aggregates +** or to redefine the behavior of existing SQL functions or aggregates. The +** difference only between the two is that the second parameter, the +** name of the (scalar) function or aggregate, is encoded in UTF-8 for +** sqlite3_create_function() and UTF-16 for sqlite3_create_function16(). +** +** The first argument is the [sqlite3 | database handle] that holds the +** SQL function or aggregate is to be added or redefined. If a single +** program uses more than one database handle internally, then SQL +** functions or aggregates must be added individually to each database +** handle with which they will be used. +** +** The second parameter is the name of the SQL function to be created +** or redefined. +** The length of the name is limited to 255 bytes, exclusive of the +** zero-terminator. Note that the name length limit is in bytes, not +** characters. Any attempt to create a function with a longer name +** will result in an SQLITE_ERROR error. +** +** The third parameter is the number of arguments that the SQL function or +** aggregate takes. If this parameter is negative, then the SQL function or +** aggregate may take any number of arguments. +** +** The fourth parameter, eTextRep, specifies what +** [SQLITE_UTF8 | text encoding] this SQL function prefers for +** its parameters. Any SQL function implementation should be able to work +** work with UTF-8, UTF-16le, or UTF-16be. But some implementations may be +** more efficient with one encoding than another. It is allowed to +** invoke sqlite3_create_function() or sqlite3_create_function16() multiple +** times with the same function but with different values of eTextRep. +** When multiple implementations of the same function are available, SQLite +** will pick the one that involves the least amount of data conversion. +** If there is only a single implementation which does not care what +** text encoding is used, then the fourth argument should be +** [SQLITE_ANY]. +** +** The fifth parameter is an arbitrary pointer. The implementation +** of the function can gain access to this pointer using +** [sqlite3_user_data()]. +** +** The seventh, eighth and ninth parameters, xFunc, xStep and xFinal, are +** pointers to C-language functions that implement the SQL +** function or aggregate. A scalar SQL function requires an implementation of +** the xFunc callback only, NULL pointers should be passed as the xStep +** and xFinal parameters. An aggregate SQL function requires an implementation +** of xStep and xFinal and NULL should be passed for xFunc. To delete an +** existing SQL function or aggregate, pass NULL for all three function +** callback. +** +** It is permitted to register multiple implementations of the same +** functions with the same name but with either differing numbers of +** arguments or differing perferred text encodings. SQLite will use +** the implementation most closely matches the way in which the +** SQL function is used. +*/ +int sqlite3_create_function( + sqlite3 *, + const char *zFunctionName, + int nArg, + int eTextRep, + void*, + void (*xFunc)(sqlite3_context*,int,sqlite3_value**), + void (*xStep)(sqlite3_context*,int,sqlite3_value**), + void (*xFinal)(sqlite3_context*) +); +int sqlite3_create_function16( + sqlite3*, + const void *zFunctionName, + int nArg, + int eTextRep, + void*, + void (*xFunc)(sqlite3_context*,int,sqlite3_value**), + void (*xStep)(sqlite3_context*,int,sqlite3_value**), + void (*xFinal)(sqlite3_context*) +); + +/* +** CAPI3REF: Text Encodings +** +** These constant define integer codes that represent the various +** text encodings supported by SQLite. +*/ +#define SQLITE_UTF8 1 +#define SQLITE_UTF16LE 2 +#define SQLITE_UTF16BE 3 +#define SQLITE_UTF16 4 /* Use native byte order */ +#define SQLITE_ANY 5 /* sqlite3_create_function only */ +#define SQLITE_UTF16_ALIGNED 8 /* sqlite3_create_collation only */ + +/* +** CAPI3REF: Obsolete Functions +** +** These functions are all now obsolete. In order to maintain +** backwards compatibility with older code, we continue to support +** these functions. However, new development projects should avoid +** the use of these functions. To help encourage people to avoid +** using these functions, we are not going to tell you want they do. +*/ +int sqlite3_aggregate_count(sqlite3_context*); +int sqlite3_expired(sqlite3_stmt*); +int sqlite3_transfer_bindings(sqlite3_stmt*, sqlite3_stmt*); +int sqlite3_global_recover(void); +void sqlite3_thread_cleanup(void); +int sqlite3_memory_alarm(void(*)(void*,sqlite3_int64,int),void*,sqlite3_int64); + +/* +** CAPI3REF: Obtaining SQL Function Parameter Values +** +** The C-language implementation of SQL functions and aggregates uses +** this set of interface routines to access the parameter values on +** the function or aggregate. +** +** The xFunc (for scalar functions) or xStep (for aggregates) parameters +** to [sqlite3_create_function()] and [sqlite3_create_function16()] +** define callbacks that implement the SQL functions and aggregates. +** The 4th parameter to these callbacks is an array of pointers to +** [sqlite3_value] objects. There is one [sqlite3_value] object for +** each parameter to the SQL function. These routines are used to +** extract values from the [sqlite3_value] objects. +** +** These routines work just like the corresponding +** [sqlite3_column_blob | sqlite3_column_* routines] except that +** these routines take a single [sqlite3_value*] pointer instead +** of an [sqlite3_stmt*] pointer and an integer column number. +** +** The sqlite3_value_text16() interface extracts a UTF16 string +** in the native byte-order of the host machine. The +** sqlite3_value_text16be() and sqlite3_value_text16le() interfaces +** extract UTF16 strings as big-endian and little-endian respectively. +** +** The sqlite3_value_numeric_type() interface attempts to apply +** numeric affinity to the value. This means that an attempt is +** made to convert the value to an integer or floating point. If +** such a conversion is possible without loss of information (in order +** words if the value is original a string that looks like a number) +** then it is done. Otherwise no conversion occurs. The +** [SQLITE_INTEGER | datatype] after conversion is returned. +** +** Please pay particular attention to the fact that the pointer that +** is returned from [sqlite3_value_blob()], [sqlite3_value_text()], or +** [sqlite3_value_text16()] can be invalidated by a subsequent call to +** [sqlite3_value_bytes()], [sqlite3_value_bytes16()], [sqlite3_value_text()], +** or [sqlite3_value_text16()]. +** +** These routines must be called from the same thread as +** the SQL function that supplied the sqlite3_value* parameters. +** Or, if the sqlite3_value* argument comes from the [sqlite3_column_value()] +** interface, then these routines should be called from the same thread +** that ran [sqlite3_column_value()]. +*/ +const void *sqlite3_value_blob(sqlite3_value*); +int sqlite3_value_bytes(sqlite3_value*); +int sqlite3_value_bytes16(sqlite3_value*); +double sqlite3_value_double(sqlite3_value*); +int sqlite3_value_int(sqlite3_value*); +sqlite3_int64 sqlite3_value_int64(sqlite3_value*); +const unsigned char *sqlite3_value_text(sqlite3_value*); +const void *sqlite3_value_text16(sqlite3_value*); +const void *sqlite3_value_text16le(sqlite3_value*); +const void *sqlite3_value_text16be(sqlite3_value*); +int sqlite3_value_type(sqlite3_value*); +int sqlite3_value_numeric_type(sqlite3_value*); + +/* +** CAPI3REF: Obtain Aggregate Function Context +** +** The implementation of aggregate SQL functions use this routine to allocate +** a structure for storing their state. The first time this routine +** is called for a particular aggregate, a new structure of size nBytes +** is allocated, zeroed, and returned. On subsequent calls (for the +** same aggregate instance) the same buffer is returned. The implementation +** of the aggregate can use the returned buffer to accumulate data. +** +** The buffer allocated is freed automatically by SQLite whan the aggregate +** query concludes. +** +** The first parameter should be a copy of the +** [sqlite3_context | SQL function context] that is the first +** parameter to the callback routine that implements the aggregate +** function. +** +** This routine must be called from the same thread in which +** the aggregate SQL function is running. +*/ +void *sqlite3_aggregate_context(sqlite3_context*, int nBytes); + +/* +** CAPI3REF: User Data For Functions +** +** The pUserData parameter to the [sqlite3_create_function()] +** and [sqlite3_create_function16()] routines +** used to register user functions is available to +** the implementation of the function using this call. +** +** This routine must be called from the same thread in which +** the SQL function is running. +*/ +void *sqlite3_user_data(sqlite3_context*); + +/* +** CAPI3REF: Function Auxiliary Data +** +** The following two functions may be used by scalar SQL functions to +** associate meta-data with argument values. If the same value is passed to +** multiple invocations of the same SQL function during query execution, under +** some circumstances the associated meta-data may be preserved. This may +** be used, for example, to add a regular-expression matching scalar +** function. The compiled version of the regular expression is stored as +** meta-data associated with the SQL value passed as the regular expression +** pattern. The compiled regular expression can be reused on multiple +** invocations of the same function so that the original pattern string +** does not need to be recompiled on each invocation. +** +** The sqlite3_get_auxdata() interface returns a pointer to the meta-data +** associated with the Nth argument value to the current SQL function +** call, where N is the second parameter. If no meta-data has been set for +** that value, then a NULL pointer is returned. +** +** The sqlite3_set_auxdata() is used to associate meta-data with an SQL +** function argument. The third parameter is a pointer to the meta-data +** to be associated with the Nth user function argument value. The fourth +** parameter specifies a destructor that will be called on the meta- +** data pointer to release it when it is no longer required. If the +** destructor is NULL, it is not invoked. +** +** In practice, meta-data is preserved between function calls for +** expressions that are constant at compile time. This includes literal +** values and SQL variables. +** +** These routines must be called from the same thread in which +** the SQL function is running. +*/ +void *sqlite3_get_auxdata(sqlite3_context*, int); +void sqlite3_set_auxdata(sqlite3_context*, int, void*, void (*)(void*)); + + +/* +** CAPI3REF: Constants Defining Special Destructor Behavior +** +** These are special value for the destructor that is passed in as the +** final argument to routines like [sqlite3_result_blob()]. If the destructor +** argument is SQLITE_STATIC, it means that the content pointer is constant +** and will never change. It does not need to be destroyed. The +** SQLITE_TRANSIENT value means that the content will likely change in +** the near future and that SQLite should make its own private copy of +** the content before returning. +** +** The typedef is necessary to work around problems in certain +** C++ compilers. See ticket #2191. +*/ +typedef void (*sqlite3_destructor_type)(void*); +#define SQLITE_STATIC ((sqlite3_destructor_type)0) +#define SQLITE_TRANSIENT ((sqlite3_destructor_type)-1) + +/* +** CAPI3REF: Setting The Result Of An SQL Function +** +** These routines are used by the xFunc or xFinal callbacks that +** implement SQL functions and aggregates. See +** [sqlite3_create_function()] and [sqlite3_create_function16()] +** for additional information. +** +** These functions work very much like the +** [sqlite3_bind_blob | sqlite3_bind_*] family of functions used +** to bind values to host parameters in prepared statements. +** Refer to the +** [sqlite3_bind_blob | sqlite3_bind_* documentation] for +** additional information. +** +** The sqlite3_result_error() and sqlite3_result_error16() functions +** cause the implemented SQL function to throw an exception. The +** parameter to sqlite3_result_error() or sqlite3_result_error16() +** is the text of an error message. +** +** The sqlite3_result_toobig() cause the function implementation +** to throw and error indicating that a string or BLOB is to long +** to represent. +** +** These routines must be called from within the same thread as +** the SQL function associated with the [sqlite3_context] pointer. +*/ +void sqlite3_result_blob(sqlite3_context*, const void*, int, void(*)(void*)); +void sqlite3_result_double(sqlite3_context*, double); +void sqlite3_result_error(sqlite3_context*, const char*, int); +void sqlite3_result_error16(sqlite3_context*, const void*, int); +void sqlite3_result_error_toobig(sqlite3_context*); +void sqlite3_result_error_nomem(sqlite3_context*); +void sqlite3_result_int(sqlite3_context*, int); +void sqlite3_result_int64(sqlite3_context*, sqlite3_int64); +void sqlite3_result_null(sqlite3_context*); +void sqlite3_result_text(sqlite3_context*, const char*, int, void(*)(void*)); +void sqlite3_result_text16(sqlite3_context*, const void*, int, void(*)(void*)); +void sqlite3_result_text16le(sqlite3_context*, const void*, int,void(*)(void*)); +void sqlite3_result_text16be(sqlite3_context*, const void*, int,void(*)(void*)); +void sqlite3_result_value(sqlite3_context*, sqlite3_value*); +void sqlite3_result_zeroblob(sqlite3_context*, int n); + +/* +** CAPI3REF: Define New Collating Sequences +** +** These functions are used to add new collation sequences to the +** [sqlite3*] handle specified as the first argument. +** +** The name of the new collation sequence is specified as a UTF-8 string +** for sqlite3_create_collation() and sqlite3_create_collation_v2() +** and a UTF-16 string for sqlite3_create_collation16(). In all cases +** the name is passed as the second function argument. +** +** The third argument may be one of the constants [SQLITE_UTF8], +** [SQLITE_UTF16LE] or [SQLITE_UTF16BE], indicating that the user-supplied +** routine expects to be passed pointers to strings encoded using UTF-8, +** UTF-16 little-endian or UTF-16 big-endian respectively. The +** third argument might also be [SQLITE_UTF16_ALIGNED] to indicate that +** the routine expects pointers to 16-bit word aligned strings +** of UTF16 in the native byte order of the host computer. +** +** A pointer to the user supplied routine must be passed as the fifth +** argument. If it is NULL, this is the same as deleting the collation +** sequence (so that SQLite cannot call it anymore). Each time the user +** supplied function is invoked, it is passed a copy of the void* passed as +** the fourth argument to sqlite3_create_collation() or +** sqlite3_create_collation16() as its first parameter. +** +** The remaining arguments to the user-supplied routine are two strings, +** each represented by a [length, data] pair and encoded in the encoding +** that was passed as the third argument when the collation sequence was +** registered. The user routine should return negative, zero or positive if +** the first string is less than, equal to, or greater than the second +** string. i.e. (STRING1 - STRING2). +** +** The sqlite3_create_collation_v2() works like sqlite3_create_collation() +** excapt that it takes an extra argument which is a destructor for +** the collation. The destructor is called when the collation is +** destroyed and is passed a copy of the fourth parameter void* pointer +** of the sqlite3_create_collation_v2(). Collations are destroyed when +** they are overridden by later calls to the collation creation functions +** or when the [sqlite3*] database handle is closed using [sqlite3_close()]. +** +** The sqlite3_create_collation_v2() interface is experimental and +** subject to change in future releases. The other collation creation +** functions are stable. +*/ +int sqlite3_create_collation( + sqlite3*, + const char *zName, + int eTextRep, + void*, + int(*xCompare)(void*,int,const void*,int,const void*) +); +int sqlite3_create_collation_v2( + sqlite3*, + const char *zName, + int eTextRep, + void*, + int(*xCompare)(void*,int,const void*,int,const void*), + void(*xDestroy)(void*) +); +int sqlite3_create_collation16( + sqlite3*, + const char *zName, + int eTextRep, + void*, + int(*xCompare)(void*,int,const void*,int,const void*) +); + +/* +** CAPI3REF: 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 handle to be called whenever an undefined collation sequence is +** required. +** +** If the function is registered using the sqlite3_collation_needed() API, +** then it is passed the names of undefined collation sequences as strings +** encoded in UTF-8. If sqlite3_collation_needed16() is used, the names +** are passed as UTF-16 in machine native byte order. A call to either +** function replaces any existing callback. +** +** When the callback is invoked, the first argument passed is a copy +** of the second argument to sqlite3_collation_needed() or +** sqlite3_collation_needed16(). The second argument is the database +** handle. The third argument is one of [SQLITE_UTF8], [SQLITE_UTF16BE], or +** [SQLITE_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 +** [sqlite3_create_collation()], [sqlite3_create_collation16()], or +** [sqlite3_create_collation_v2()]. +*/ +int sqlite3_collation_needed( + sqlite3*, + void*, + void(*)(void*,sqlite3*,int eTextRep,const char*) +); +int sqlite3_collation_needed16( + sqlite3*, + void*, + void(*)(void*,sqlite3*,int eTextRep,const void*) +); + +/* +** Specify the key for an encrypted database. This routine should be +** called right after sqlite3_open(). +** +** The code to implement this API is not available in the public release +** of SQLite. +*/ +int sqlite3_key( + sqlite3 *db, /* Database to be rekeyed */ + const void *pKey, int nKey /* The key */ +); + +/* +** Change the key on an open database. If the current database is not +** encrypted, this routine will encrypt it. If pNew==0 or nNew==0, the +** database is decrypted. +** +** The code to implement this API is not available in the public release +** of SQLite. +*/ +int sqlite3_rekey( + sqlite3 *db, /* Database to be rekeyed */ + const void *pKey, int nKey /* The new key */ +); + +/* +** CAPI3REF: Suspend Execution For A Short Time +** +** This function causes the current thread to suspend execution +** a number of milliseconds specified in its parameter. +** +** If the operating system does not support sleep requests with +** millisecond time resolution, then the time will be rounded up to +** the nearest second. The number of milliseconds of sleep actually +** requested from the operating system is returned. +** +** SQLite implements this interface by calling the xSleep() +** method of the default [sqlite3_vfs] object. +*/ +int sqlite3_sleep(int); + +/* +** CAPI3REF: Name Of The Folder Holding Temporary Files +** +** If this global variable is made to point to a string which is +** the name of a folder (a.ka. directory), then all temporary files +** created by SQLite will be placed in that directory. If this variable +** is NULL pointer, then SQLite does a search for an appropriate temporary +** file directory. +** +** It is not safe to modify this variable once a database connection +** has been opened. It is intended that this variable be set once +** as part of process initialization and before any SQLite interface +** routines have been call and remain unchanged thereafter. +*/ +SQLITE_EXTERN char *sqlite3_temp_directory; + +/* +** CAPI3REF: Test To See If The Database Is In Auto-Commit Mode +** +** Test to see whether or not the database connection is in autocommit +** mode. Return TRUE if it is and FALSE if not. Autocommit mode is on +** by default. Autocommit is disabled by a BEGIN statement and reenabled +** by the next COMMIT or ROLLBACK. +** +** If certain kinds of errors occur on a statement within a multi-statement +** transactions (errors including [SQLITE_FULL], [SQLITE_IOERR], +** [SQLITE_NOMEM], [SQLITE_BUSY], and [SQLITE_INTERRUPT]) then the +** transaction might be rolled back automatically. The only way to +** find out if SQLite automatically rolled back the transaction after +** an error is to use this function. +** +** If another thread changes the autocommit status of the database +** connection while this routine is running, then the return value +** is undefined. +*/ +int sqlite3_get_autocommit(sqlite3*); + +/* +** CAPI3REF: Find The Database Handle Associated With A Prepared Statement +** +** Return the [sqlite3*] database handle to which a +** [sqlite3_stmt | prepared statement] belongs. +** This is the same database handle that was +** the first argument to the [sqlite3_prepare_v2()] or its variants +** that was used to create the statement in the first place. +*/ +sqlite3 *sqlite3_db_handle(sqlite3_stmt*); + + +/* +** CAPI3REF: Commit And Rollback Notification Callbacks +** +** These routines +** register callback functions to be invoked whenever a transaction +** is committed or rolled back. The pArg argument is passed through +** to the callback. If the callback on a commit hook function +** returns non-zero, then the commit is converted into a rollback. +** +** If another function was previously registered, its pArg value is returned. +** Otherwise NULL is returned. +** +** Registering a NULL function disables the callback. +** +** For the purposes of this API, a transaction is said to have been +** rolled back if an explicit "ROLLBACK" statement is executed, or +** an error or constraint causes an implicit rollback to occur. The +** callback is not invoked if a transaction is automatically rolled +** back because the database connection is closed. +** +** These are experimental interfaces and are subject to change. +*/ +void *sqlite3_commit_hook(sqlite3*, int(*)(void*), void*); +void *sqlite3_rollback_hook(sqlite3*, void(*)(void *), void*); + +/* +** CAPI3REF: Data Change Notification Callbacks +** +** Register a callback function with the database connection identified by the +** first argument to be invoked whenever a row is updated, inserted or deleted. +** Any callback set by a previous call to this function for the same +** database connection is overridden. +** +** The second argument is a pointer to the function to invoke when a +** row is updated, inserted or deleted. The first argument to the callback is +** a copy of the third argument to sqlite3_update_hook(). The second callback +** argument is one of SQLITE_INSERT, SQLITE_DELETE or SQLITE_UPDATE, depending +** on the operation that caused the callback to be invoked. The third and +** fourth arguments to the callback contain pointers to the database and +** table name containing the affected row. The final callback parameter is +** the rowid of the row. In the case of an update, this is the rowid after +** the update takes place. +** +** The update hook is not invoked when internal system tables are +** modified (i.e. sqlite_master and sqlite_sequence). +** +** If another function was previously registered, its pArg value is returned. +** Otherwise NULL is returned. +*/ +void *sqlite3_update_hook( + sqlite3*, + void(*)(void *,int ,char const *,char const *,sqlite3_int64), + void* +); + +/* +** CAPI3REF: Enable Or Disable Shared Pager Cache +** +** This routine enables or disables the sharing of the database cache +** and schema data structures between connections to the same database. +** Sharing is enabled if the argument is true and disabled if the argument +** is false. +** +** Beginning in SQLite version 3.5.0, cache sharing is enabled and disabled +** for an entire process. In prior versions of SQLite, sharing was +** enabled or disabled for each thread separately. +** +** The cache sharing mode set by this interface effects all subsequent +** calls to [sqlite3_open()], [sqlite3_open_v2()], and [sqlite3_open16()]. +** Existing database connections continue use the sharing mode that was +** in effect at the time they were opened. +** +** Virtual tables cannot be used with a shared cache. When shared +** cache is enabled, the [sqlite3_create_module()] API used to register +** virtual tables will always return an error. +** +** This routine returns [SQLITE_OK] if shared cache was +** enabled or disabled successfully. An [SQLITE_ERROR | error code] +** is returned otherwise. +** +** Shared cache is disabled by default. But this might change in +** future releases of SQLite. Applications that care about shared +** cache setting should set it explicitly. +*/ +int sqlite3_enable_shared_cache(int); + +/* +** CAPI3REF: Attempt To Free Heap Memory +** +** Attempt to free N bytes of heap memory by deallocating non-essential +** memory allocations held by the database library (example: memory +** used to cache database pages to improve performance). +*/ +int sqlite3_release_memory(int); + +/* +** CAPI3REF: Impose A Limit On Heap Size +** +** Place a "soft" limit on the amount of heap memory that may be allocated +** by SQLite. If an internal allocation is requested +** that would exceed the specified limit, [sqlite3_release_memory()] is +** invoked one or more times to free up some space before the allocation +** is made. +** +** The limit is called "soft", because if [sqlite3_release_memory()] cannot +** free sufficient memory to prevent the limit from being exceeded, +** the memory is allocated anyway and the current operation proceeds. +** +** A negative or zero value for N means that there is no soft heap limit and +** [sqlite3_release_memory()] will only be called when memory is exhausted. +** The default value for the soft heap limit is zero. +** +** SQLite makes a best effort to honor the soft heap limit. But if it +** is unable to reduce memory usage below the soft limit, execution will +** continue without error or notification. This is why the limit is +** called a "soft" limit. It is advisory only. +** +** Prior to SQLite version 3.5.0, this routine only constrained the memory +** allocated by a single thread - the same thread in which this routine +** runs. Beginning with SQLite version 3.5.0, the soft heap limit is +** applied to all threads. The value specified for the soft heap limit +** is an upper bound on the total memory allocation for all threads. In +** version 3.5.0 there is no mechanism for limiting the heap usage for +** individual threads. +*/ +void sqlite3_soft_heap_limit(int); + +/* +** CAPI3REF: Extract Metadata About A Column Of A Table +** +** This routine +** returns meta-data about a specific column of a specific database +** table accessible using the connection handle passed as the first function +** argument. +** +** The column is identified by the second, third and fourth parameters to +** this function. The second parameter is either the name of the database +** (i.e. "main", "temp" or an attached database) containing the specified +** table or NULL. If it is NULL, then all attached databases are searched +** for the table using the same algorithm as the database engine uses to +** resolve unqualified table references. +** +** The third and fourth parameters to this function are the table and column +** name of the desired column, respectively. Neither of these parameters +** may be NULL. +** +** Meta information is returned by writing to the memory locations passed as +** the 5th and subsequent parameters to this function. Any of these +** arguments may be NULL, in which case the corresponding element of meta +** information is ommitted. +** +** <pre> +** Parameter Output Type Description +** ----------------------------------- +** +** 5th const char* Data type +** 6th const char* Name of the default collation sequence +** 7th int True if the column has a NOT NULL constraint +** 8th int True if the column is part of the PRIMARY KEY +** 9th int True if the column is AUTOINCREMENT +** </pre> +** +** +** The memory pointed to by the character pointers returned for the +** declaration type and collation sequence is valid only until the next +** call to any sqlite API function. +** +** If the specified table is actually a view, then an error is returned. +** +** If the specified column is "rowid", "oid" or "_rowid_" and an +** INTEGER PRIMARY KEY column has been explicitly declared, then the output +** parameters are set for the explicitly declared column. If there is no +** explicitly declared IPK column, then the output parameters are set as +** follows: +** +** <pre> +** data type: "INTEGER" +** collation sequence: "BINARY" +** not null: 0 +** primary key: 1 +** auto increment: 0 +** </pre> +** +** This function may load one or more schemas from database files. If an +** error occurs during this process, or if the requested table or column +** cannot be found, an SQLITE error code is returned and an error message +** left in the database handle (to be retrieved using sqlite3_errmsg()). +** +** This API is only available if the library was compiled with the +** SQLITE_ENABLE_COLUMN_METADATA preprocessor symbol defined. +*/ +int sqlite3_table_column_metadata( + sqlite3 *db, /* Connection handle */ + const char *zDbName, /* Database name or NULL */ + const char *zTableName, /* Table name */ + const char *zColumnName, /* Column name */ + char const **pzDataType, /* OUTPUT: Declared data type */ + char const **pzCollSeq, /* OUTPUT: Collation sequence name */ + int *pNotNull, /* OUTPUT: True if NOT NULL constraint exists */ + int *pPrimaryKey, /* OUTPUT: True if column part of PK */ + int *pAutoinc /* OUTPUT: True if column is auto-increment */ +); + +/* +** CAPI3REF: Load An Extension +** +** Attempt to load an SQLite extension library contained in the file +** zFile. The entry point is zProc. zProc may be 0 in which case the +** name of the entry point defaults to "sqlite3_extension_init". +** +** Return [SQLITE_OK] on success and [SQLITE_ERROR] if something goes wrong. +** +** If an error occurs and pzErrMsg is not 0, then fill *pzErrMsg with +** error message text. The calling function should free this memory +** by calling [sqlite3_free()]. +** +** Extension loading must be enabled using [sqlite3_enable_load_extension()] +** prior to calling this API or an error will be returned. +*/ +int sqlite3_load_extension( + sqlite3 *db, /* Load the extension into this database connection */ + const char *zFile, /* Name of the shared library containing extension */ + const char *zProc, /* Entry point. Derived from zFile if 0 */ + char **pzErrMsg /* Put error message here if not 0 */ +); + +/* +** CAPI3REF: Enable Or Disable Extension Loading +** +** So as not to open security holes in older applications that are +** unprepared to deal with extension loading, and as a means of disabling +** extension loading while evaluating user-entered SQL, the following +** API is provided to turn the [sqlite3_load_extension()] mechanism on and +** off. It is off by default. See ticket #1863. +** +** Call this routine with onoff==1 to turn extension loading on +** and call it with onoff==0 to turn it back off again. +*/ +int sqlite3_enable_load_extension(sqlite3 *db, int onoff); + +/* +** CAPI3REF: Make Arrangements To Automatically Load An Extension +** +** Register an extension entry point that is automatically invoked +** whenever a new database connection is opened using +** [sqlite3_open()], [sqlite3_open16()], or [sqlite3_open_v2()]. +** +** This API can be invoked at program startup in order to register +** one or more statically linked extensions that will be available +** to all new database connections. +** +** Duplicate extensions are detected so calling this routine multiple +** times with the same extension is harmless. +** +** This routine stores a pointer to the extension in an array +** that is obtained from malloc(). If you run a memory leak +** checker on your program and it reports a leak because of this +** array, then invoke [sqlite3_reset_auto_extension()] prior +** to shutdown to free the memory. +** +** Automatic extensions apply across all threads. +** +** This interface is experimental and is subject to change or +** removal in future releases of SQLite. +*/ +int sqlite3_auto_extension(void *xEntryPoint); + + +/* +** CAPI3REF: Reset Automatic Extension Loading +** +** Disable all previously registered automatic extensions. This +** routine undoes the effect of all prior [sqlite3_automatic_extension()] +** calls. +** +** This call disabled automatic extensions in all threads. +** +** This interface is experimental and is subject to change or +** removal in future releases of SQLite. +*/ +void sqlite3_reset_auto_extension(void); + + +/* +****** EXPERIMENTAL - subject to change without notice ************** +** +** The interface to the virtual-table mechanism is currently considered +** to be experimental. The interface might change in incompatible ways. +** If this is a problem for you, do not use the interface at this time. +** +** When the virtual-table mechanism stablizes, we will declare the +** interface fixed, support it indefinitely, and remove this comment. +*/ + +/* +** Structures used by the virtual table interface +*/ +typedef struct sqlite3_vtab sqlite3_vtab; +typedef struct sqlite3_index_info sqlite3_index_info; +typedef struct sqlite3_vtab_cursor sqlite3_vtab_cursor; +typedef struct sqlite3_module sqlite3_module; + +/* +** A module is a class of virtual tables. Each module is defined +** by an instance of the following structure. This structure consists +** mostly of methods for the module. +*/ +struct sqlite3_module { + int iVersion; + int (*xCreate)(sqlite3*, void *pAux, + int argc, const char *const*argv, + sqlite3_vtab **ppVTab, char**); + int (*xConnect)(sqlite3*, void *pAux, + int argc, const char *const*argv, + sqlite3_vtab **ppVTab, char**); + int (*xBestIndex)(sqlite3_vtab *pVTab, sqlite3_index_info*); + int (*xDisconnect)(sqlite3_vtab *pVTab); + int (*xDestroy)(sqlite3_vtab *pVTab); + int (*xOpen)(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor); + int (*xClose)(sqlite3_vtab_cursor*); + int (*xFilter)(sqlite3_vtab_cursor*, int idxNum, const char *idxStr, + int argc, sqlite3_value **argv); + int (*xNext)(sqlite3_vtab_cursor*); + int (*xEof)(sqlite3_vtab_cursor*); + int (*xColumn)(sqlite3_vtab_cursor*, sqlite3_context*, int); + int (*xRowid)(sqlite3_vtab_cursor*, sqlite3_int64 *pRowid); + int (*xUpdate)(sqlite3_vtab *, int, sqlite3_value **, sqlite3_int64 *); + int (*xBegin)(sqlite3_vtab *pVTab); + int (*xSync)(sqlite3_vtab *pVTab); + int (*xCommit)(sqlite3_vtab *pVTab); + int (*xRollback)(sqlite3_vtab *pVTab); + int (*xFindFunction)(sqlite3_vtab *pVtab, int nArg, const char *zName, + void (**pxFunc)(sqlite3_context*,int,sqlite3_value**), + void **ppArg); + + int (*xRename)(sqlite3_vtab *pVtab, const char *zNew); +}; + +/* +** The sqlite3_index_info structure and its substructures is used to +** pass information into and receive the reply from the xBestIndex +** method of an sqlite3_module. The fields under **Inputs** are the +** inputs to xBestIndex and are read-only. xBestIndex inserts its +** results into the **Outputs** fields. +** +** The aConstraint[] array records WHERE clause constraints of the +** form: +** +** column OP expr +** +** Where OP is =, <, <=, >, or >=. The particular operator is stored +** in aConstraint[].op. The index of the column is stored in +** aConstraint[].iColumn. aConstraint[].usable is TRUE if the +** expr on the right-hand side can be evaluated (and thus the constraint +** is usable) and false if it cannot. +** +** The optimizer automatically inverts terms of the form "expr OP column" +** and makes other simplifications to the WHERE clause in an attempt to +** get as many WHERE clause terms into the form shown above as possible. +** The aConstraint[] array only reports WHERE clause terms in the correct +** form that refer to the particular virtual table being queried. +** +** Information about the ORDER BY clause is stored in aOrderBy[]. +** Each term of aOrderBy records a column of the ORDER BY clause. +** +** The xBestIndex method must fill aConstraintUsage[] with information +** about what parameters to pass to xFilter. If argvIndex>0 then +** the right-hand side of the corresponding aConstraint[] is evaluated +** and becomes the argvIndex-th entry in argv. If aConstraintUsage[].omit +** is true, then the constraint is assumed to be fully handled by the +** virtual table and is not checked again by SQLite. +** +** The idxNum and idxPtr values are recorded and passed into xFilter. +** sqlite3_free() is used to free idxPtr if needToFreeIdxPtr is true. +** +** The orderByConsumed means that output from xFilter will occur in +** the correct order to satisfy the ORDER BY clause so that no separate +** sorting step is required. +** +** The estimatedCost value is an estimate of the cost of doing the +** particular lookup. A full scan of a table with N entries should have +** a cost of N. A binary search of a table of N entries should have a +** cost of approximately log(N). +*/ +struct sqlite3_index_info { + /* Inputs */ + int nConstraint; /* Number of entries in aConstraint */ + struct sqlite3_index_constraint { + int iColumn; /* Column on left-hand side of constraint */ + unsigned char op; /* Constraint operator */ + unsigned char usable; /* True if this constraint is usable */ + int iTermOffset; /* Used internally - xBestIndex should ignore */ + } *aConstraint; /* Table of WHERE clause constraints */ + int nOrderBy; /* Number of terms in the ORDER BY clause */ + struct sqlite3_index_orderby { + int iColumn; /* Column number */ + unsigned char desc; /* True for DESC. False for ASC. */ + } *aOrderBy; /* The ORDER BY clause */ + + /* Outputs */ + struct sqlite3_index_constraint_usage { + int argvIndex; /* if >0, constraint is part of argv to xFilter */ + unsigned char omit; /* Do not code a test for this constraint */ + } *aConstraintUsage; + int idxNum; /* Number used to identify the index */ + char *idxStr; /* String, possibly obtained from sqlite3_malloc */ + int needToFreeIdxStr; /* Free idxStr using sqlite3_free() if true */ + int orderByConsumed; /* True if output is already ordered */ + double estimatedCost; /* Estimated cost of using this index */ +}; +#define SQLITE_INDEX_CONSTRAINT_EQ 2 +#define SQLITE_INDEX_CONSTRAINT_GT 4 +#define SQLITE_INDEX_CONSTRAINT_LE 8 +#define SQLITE_INDEX_CONSTRAINT_LT 16 +#define SQLITE_INDEX_CONSTRAINT_GE 32 +#define SQLITE_INDEX_CONSTRAINT_MATCH 64 + +/* +** This routine is used to register a new module name with an SQLite +** connection. Module names must be registered before creating new +** virtual tables on the module, or before using preexisting virtual +** tables of the module. +*/ +int sqlite3_create_module( + sqlite3 *db, /* SQLite connection to register module with */ + const char *zName, /* Name of the module */ + const sqlite3_module *, /* Methods for the module */ + void * /* Client data for xCreate/xConnect */ +); + +/* +** This routine is identical to the sqlite3_create_module() method above, +** except that it allows a destructor function to be specified. It is +** even more experimental than the rest of the virtual tables API. +*/ +int sqlite3_create_module_v2( + sqlite3 *db, /* SQLite connection to register module with */ + const char *zName, /* Name of the module */ + const sqlite3_module *, /* Methods for the module */ + void *, /* Client data for xCreate/xConnect */ + void(*xDestroy)(void*) /* Module destructor function */ +); + +/* +** Every module implementation uses a subclass of the following structure +** to describe a particular instance of the module. Each subclass will +** be tailored to the specific needs of the module implementation. The +** purpose of this superclass is to define certain fields that are common +** to all module implementations. +** +** Virtual tables methods can set an error message by assigning a +** string obtained from sqlite3_mprintf() to zErrMsg. The method should +** take care that any prior string is freed by a call to sqlite3_free() +** prior to assigning a new string to zErrMsg. After the error message +** is delivered up to the client application, the string will be automatically +** freed by sqlite3_free() and the zErrMsg field will be zeroed. Note +** that sqlite3_mprintf() and sqlite3_free() are used on the zErrMsg field +** since virtual tables are commonly implemented in loadable extensions which +** do not have access to sqlite3MPrintf() or sqlite3Free(). +*/ +struct sqlite3_vtab { + const sqlite3_module *pModule; /* The module for this virtual table */ + int nRef; /* Used internally */ + char *zErrMsg; /* Error message from sqlite3_mprintf() */ + /* Virtual table implementations will typically add additional fields */ +}; + +/* Every module implementation uses a subclass of the following structure +** to describe cursors that point into the virtual table and are used +** to loop through the virtual table. Cursors are created using the +** xOpen method of the module. Each module implementation will define +** the content of a cursor structure to suit its own needs. +** +** This superclass exists in order to define fields of the cursor that +** are common to all implementations. +*/ +struct sqlite3_vtab_cursor { + sqlite3_vtab *pVtab; /* Virtual table of this cursor */ + /* Virtual table implementations will typically add additional fields */ +}; + +/* +** The xCreate and xConnect methods of a module use the following API +** to declare the format (the names and datatypes of the columns) of +** the virtual tables they implement. +*/ +int sqlite3_declare_vtab(sqlite3*, const char *zCreateTable); + +/* +** Virtual tables can provide alternative implementations of functions +** using the xFindFunction method. But global versions of those functions +** must exist in order to be overloaded. +** +** This API makes sure a global version of a function with a particular +** name and number of parameters exists. If no such function exists +** before this API is called, a new function is created. The implementation +** of the new function always causes an exception to be thrown. So +** the new function is not good for anything by itself. Its only +** purpose is to be a place-holder function that can be overloaded +** by virtual tables. +** +** This API should be considered part of the virtual table interface, +** which is experimental and subject to change. +*/ +int sqlite3_overload_function(sqlite3*, const char *zFuncName, int nArg); + +/* +** The interface to the virtual-table mechanism defined above (back up +** to a comment remarkably similar to this one) is currently considered +** to be experimental. The interface might change in incompatible ways. +** If this is a problem for you, do not use the interface at this time. +** +** When the virtual-table mechanism stabilizes, we will declare the +** interface fixed, support it indefinitely, and remove this comment. +** +****** EXPERIMENTAL - subject to change without notice ************** +*/ + +/* +** CAPI3REF: A Handle To An Open BLOB +** +** An instance of the following opaque structure is used to +** represent an blob-handle. A blob-handle is created by +** [sqlite3_blob_open()] and destroyed by [sqlite3_blob_close()]. +** The [sqlite3_blob_read()] and [sqlite3_blob_write()] interfaces +** can be used to read or write small subsections of the blob. +** The [sqlite3_blob_bytes()] interface returns the size of the +** blob in bytes. +*/ +typedef struct sqlite3_blob sqlite3_blob; + +/* +** CAPI3REF: Open A BLOB For Incremental I/O +** +** Open a handle to the blob located in row iRow,, column zColumn, +** table zTable in database zDb. i.e. the same blob that would +** be selected by: +** +** <pre> +** SELECT zColumn FROM zDb.zTable WHERE rowid = iRow; +** </pre> +** +** If the flags parameter is non-zero, the blob is opened for +** read and write access. If it is zero, the blob is opened for read +** access. +** +** On success, [SQLITE_OK] is returned and the new +** [sqlite3_blob | blob handle] is written to *ppBlob. +** Otherwise an error code is returned and +** any value written to *ppBlob should not be used by the caller. +** This function sets the database-handle error code and message +** accessible via [sqlite3_errcode()] and [sqlite3_errmsg()]. +*/ +int sqlite3_blob_open( + sqlite3*, + const char *zDb, + const char *zTable, + const char *zColumn, + sqlite3_int64 iRow, + int flags, + sqlite3_blob **ppBlob +); + +/* +** CAPI3REF: Close A BLOB Handle +** +** Close an open [sqlite3_blob | blob handle]. +*/ +int sqlite3_blob_close(sqlite3_blob *); + +/* +** CAPI3REF: Return The Size Of An Open BLOB +** +** Return the size in bytes of the blob accessible via the open +** [sqlite3_blob | blob-handle] passed as an argument. +*/ +int sqlite3_blob_bytes(sqlite3_blob *); + +/* +** CAPI3REF: Read Data From A BLOB Incrementally +** +** This function is used to read data from an open +** [sqlite3_blob | blob-handle] into a caller supplied buffer. +** n bytes of data are copied into buffer +** z from the open blob, starting at offset iOffset. +** +** On success, SQLITE_OK is returned. Otherwise, an +** [SQLITE_ERROR | SQLite error code] or an +** [SQLITE_IOERR_READ | extended error code] is returned. +*/ +int sqlite3_blob_read(sqlite3_blob *, void *z, int n, int iOffset); + +/* +** CAPI3REF: Write Data Into A BLOB Incrementally +** +** This function is used to write data into an open +** [sqlite3_blob | blob-handle] from a user supplied buffer. +** n bytes of data are copied from the buffer +** pointed to by z into the open blob, starting at offset iOffset. +** +** If the [sqlite3_blob | blob-handle] passed as the first argument +** was not opened for writing (the flags parameter to [sqlite3_blob_open()] +*** was zero), this function returns [SQLITE_READONLY]. +** +** This function may only modify the contents of the blob, it is +** not possible to increase the size of a blob using this API. If +** offset iOffset is less than n bytes from the end of the blob, +** [SQLITE_ERROR] is returned and no data is written. +** +** On success, SQLITE_OK is returned. Otherwise, an +** [SQLITE_ERROR | SQLite error code] or an +** [SQLITE_IOERR_READ | extended error code] is returned. +*/ +int sqlite3_blob_write(sqlite3_blob *, const void *z, int n, int iOffset); + +/* +** CAPI3REF: Virtual File System Objects +** +** A virtual filesystem (VFS) is an [sqlite3_vfs] object +** that SQLite uses to interact +** with the underlying operating system. Most builds come with a +** single default VFS that is appropriate for the host computer. +** New VFSes can be registered and existing VFSes can be unregistered. +** The following interfaces are provided. +** +** The sqlite3_vfs_find() interface returns a pointer to a VFS given its +** name. Names are case sensitive. If there is no match, a NULL +** pointer is returned. If zVfsName is NULL then the default +** VFS is returned. +** +** New VFSes are registered with sqlite3_vfs_register(). Each +** new VFS becomes the default VFS if the makeDflt flag is set. +** The same VFS can be registered multiple times without injury. +** To make an existing VFS into the default VFS, register it again +** with the makeDflt flag set. If two different VFSes with the +** same name are registered, the behavior is undefined. If a +** VFS is registered with a name that is NULL or an empty string, +** then the behavior is undefined. +** +** Unregister a VFS with the sqlite3_vfs_unregister() interface. +** If the default VFS is unregistered, another VFS is chosen as +** the default. The choice for the new VFS is arbitrary. +*/ +sqlite3_vfs *sqlite3_vfs_find(const char *zVfsName); +int sqlite3_vfs_register(sqlite3_vfs*, int makeDflt); +int sqlite3_vfs_unregister(sqlite3_vfs*); + +/* +** CAPI3REF: Mutexes +** +** The SQLite core uses these routines for thread +** synchronization. Though they are intended for internal +** use by SQLite, code that links against SQLite is +** permitted to use any of these routines. +** +** The SQLite source code contains multiple implementations +** of these mutex routines. An appropriate implementation +** is selected automatically at compile-time. The following +** implementations are available in the SQLite core: +** +** <ul> +** <li> SQLITE_MUTEX_OS2 +** <li> SQLITE_MUTEX_PTHREAD +** <li> SQLITE_MUTEX_W32 +** <li> SQLITE_MUTEX_NOOP +** </ul> +** +** The SQLITE_MUTEX_NOOP implementation is a set of routines +** that does no real locking and is appropriate for use in +** a single-threaded application. The SQLITE_MUTEX_OS2, +** SQLITE_MUTEX_PTHREAD, and SQLITE_MUTEX_W32 implementations +** are appropriate for use on os/2, unix, and windows. +** +** If SQLite is compiled with the SQLITE_MUTEX_APPDEF preprocessor +** macro defined (with "-DSQLITE_MUTEX_APPDEF=1"), then no mutex +** implementation is included with the library. The +** mutex interface routines defined here become external +** references in the SQLite library for which implementations +** must be provided by the application. This facility allows an +** application that links against SQLite to provide its own mutex +** implementation without having to modify the SQLite core. +** +** The sqlite3_mutex_alloc() routine allocates a new +** mutex and returns a pointer to it. If it returns NULL +** that means that a mutex could not be allocated. SQLite +** will unwind its stack and return an error. The argument +** to sqlite3_mutex_alloc() is one of these integer constants: +** +** <ul> +** <li> SQLITE_MUTEX_FAST +** <li> SQLITE_MUTEX_RECURSIVE +** <li> SQLITE_MUTEX_STATIC_MASTER +** <li> SQLITE_MUTEX_STATIC_MEM +** <li> SQLITE_MUTEX_STATIC_MEM2 +** <li> SQLITE_MUTEX_STATIC_PRNG +** <li> SQLITE_MUTEX_STATIC_LRU +** </ul> +** +** The first two constants cause sqlite3_mutex_alloc() to create +** a new mutex. The new mutex is recursive when SQLITE_MUTEX_RECURSIVE +** is used but not necessarily so when SQLITE_MUTEX_FAST is used. +** The mutex implementation does not need to make a distinction +** between SQLITE_MUTEX_RECURSIVE and SQLITE_MUTEX_FAST if it does +** not want to. But SQLite will only request a recursive mutex in +** cases where it really needs one. If a faster non-recursive mutex +** implementation is available on the host platform, the mutex subsystem +** might return such a mutex in response to SQLITE_MUTEX_FAST. +** +** The other allowed parameters to sqlite3_mutex_alloc() each return +** a pointer to a static preexisting mutex. Four static mutexes are +** used by the current version of SQLite. Future versions of SQLite +** may add additional static mutexes. Static mutexes are for internal +** use by SQLite only. Applications that use SQLite mutexes should +** use only the dynamic mutexes returned by SQLITE_MUTEX_FAST or +** SQLITE_MUTEX_RECURSIVE. +** +** Note that if one of the dynamic mutex parameters (SQLITE_MUTEX_FAST +** or SQLITE_MUTEX_RECURSIVE) is used then sqlite3_mutex_alloc() +** returns a different mutex on every call. But for the static +** mutex types, the same mutex is returned on every call that has +** the same type number. +** +** The sqlite3_mutex_free() routine deallocates a previously +** allocated dynamic mutex. SQLite is careful to deallocate every +** dynamic mutex that it allocates. The dynamic mutexes must not be in +** use when they are deallocated. Attempting to deallocate a static +** mutex results in undefined behavior. SQLite never deallocates +** a static mutex. +** +** The sqlite3_mutex_enter() and sqlite3_mutex_try() routines attempt +** to enter a mutex. If another thread is already within the mutex, +** sqlite3_mutex_enter() will block and sqlite3_mutex_try() will return +** SQLITE_BUSY. The sqlite3_mutex_try() interface returns SQLITE_OK +** upon successful entry. Mutexes created using SQLITE_MUTEX_RECURSIVE can +** be entered multiple times by the same thread. In such cases the, +** mutex must be exited an equal number of times before another thread +** can enter. If the same thread tries to enter any other kind of mutex +** more than once, the behavior is undefined. SQLite will never exhibit +** such behavior in its own use of mutexes. +** +** Some systems (ex: windows95) do not the operation implemented by +** sqlite3_mutex_try(). On those systems, sqlite3_mutex_try() will +** always return SQLITE_BUSY. The SQLite core only ever uses +** sqlite3_mutex_try() as an optimization so this is acceptable behavior. +** +** The sqlite3_mutex_leave() routine exits a mutex that was +** previously entered by the same thread. The behavior +** is undefined if the mutex is not currently entered by the +** calling thread or is not currently allocated. SQLite will +** never do either. +** +** See also: [sqlite3_mutex_held()] and [sqlite3_mutex_notheld()]. +*/ +sqlite3_mutex *sqlite3_mutex_alloc(int); +void sqlite3_mutex_free(sqlite3_mutex*); +void sqlite3_mutex_enter(sqlite3_mutex*); +int sqlite3_mutex_try(sqlite3_mutex*); +void sqlite3_mutex_leave(sqlite3_mutex*); + +/* +** CAPI3REF: Mutex Verifcation Routines +** +** The sqlite3_mutex_held() and sqlite3_mutex_notheld() routines +** are intended for use inside assert() statements. The SQLite core +** never uses these routines except inside an assert() and applications +** are advised to follow the lead of the core. The core only +** provides implementations for these routines when it is compiled +** with the SQLITE_DEBUG flag. External mutex implementations +** are only required to provide these routines if SQLITE_DEBUG is +** defined and if NDEBUG is not defined. +** +** These routines should return true if the mutex in their argument +** is held or not held, respectively, by the calling thread. +** +** The implementation is not required to provided versions of these +** routines that actually work. +** If the implementation does not provide working +** versions of these routines, it should at least provide stubs +** that always return true so that one does not get spurious +** assertion failures. +** +** If the argument to sqlite3_mutex_held() is a NULL pointer then +** the routine should return 1. This seems counter-intuitive since +** clearly the mutex cannot be held if it does not exist. But the +** the reason the mutex does not exist is because the build is not +** using mutexes. And we do not want the assert() containing the +** call to sqlite3_mutex_held() to fail, so a non-zero return is +** the appropriate thing to do. The sqlite3_mutex_notheld() +** interface should also return 1 when given a NULL pointer. +*/ +int sqlite3_mutex_held(sqlite3_mutex*); +int sqlite3_mutex_notheld(sqlite3_mutex*); + +/* +** CAPI3REF: Mutex Types +** +** The [sqlite3_mutex_alloc()] interface takes a single argument +** which is one of these integer constants. +*/ +#define SQLITE_MUTEX_FAST 0 +#define SQLITE_MUTEX_RECURSIVE 1 +#define SQLITE_MUTEX_STATIC_MASTER 2 +#define SQLITE_MUTEX_STATIC_MEM 3 /* sqlite3_malloc() */ +#define SQLITE_MUTEX_STATIC_MEM2 4 /* sqlite3_release_memory() */ +#define SQLITE_MUTEX_STATIC_PRNG 5 /* sqlite3_random() */ +#define SQLITE_MUTEX_STATIC_LRU 6 /* lru page list */ + +/* +** CAPI3REF: Low-Level Control Of Database Files +** +** The [sqlite3_file_control()] interface makes a direct call to the +** xFileControl method for the [sqlite3_io_methods] object associated +** with a particular database identified by the second argument. The +** name of the database is the name assigned to the database by the +** <a href="lang_attach.html">ATTACH</a> SQL command that opened the +** database. To control the main database file, use the name "main" +** or a NULL pointer. The third and fourth parameters to this routine +** are passed directly through to the second and third parameters of +** the xFileControl method. The return value of the xFileControl +** method becomes the return value of this routine. +** +** If the second parameter (zDbName) does not match the name of any +** open database file, then SQLITE_ERROR is returned. This error +** code is not remembered and will not be recalled by [sqlite3_errcode()] +** or [sqlite3_errmsg()]. The underlying xFileControl method might +** also return SQLITE_ERROR. There is no way to distinguish between +** an incorrect zDbName and an SQLITE_ERROR return from the underlying +** xFileControl method. +** +** See also: [SQLITE_FCNTL_LOCKSTATE] +*/ +int sqlite3_file_control(sqlite3*, const char *zDbName, int op, void*); + +/* +** Undo the hack that converts floating point types to integer for +** builds on processors without floating point support. +*/ +#ifdef SQLITE_OMIT_FLOATING_POINT +# undef double +#endif + +#if 0 +} /* End of the 'extern "C"' block */ +#endif +#endif + +/************** End of sqlite3.h *********************************************/ +/************** Continuing where we left off in fts3_tokenizer.h *************/ + +/* +** Structures used by the tokenizer interface. When a new tokenizer +** implementation is registered, the caller provides a pointer to +** an sqlite3_tokenizer_module containing pointers to the callback +** functions that make up an implementation. +** +** When an fts3 table is created, it passes any arguments passed to +** the tokenizer clause of the CREATE VIRTUAL TABLE statement to the +** sqlite3_tokenizer_module.xCreate() function of the requested tokenizer +** implementation. The xCreate() function in turn returns an +** sqlite3_tokenizer structure representing the specific tokenizer to +** be used for the fts3 table (customized by the tokenizer clause arguments). +** +** To tokenize an input buffer, the sqlite3_tokenizer_module.xOpen() +** method is called. It returns an sqlite3_tokenizer_cursor object +** that may be used to tokenize a specific input buffer based on +** the tokenization rules supplied by a specific sqlite3_tokenizer +** object. +*/ +typedef struct sqlite3_tokenizer_module sqlite3_tokenizer_module; +typedef struct sqlite3_tokenizer sqlite3_tokenizer; +typedef struct sqlite3_tokenizer_cursor sqlite3_tokenizer_cursor; + +struct sqlite3_tokenizer_module { + + /* + ** Structure version. Should always be set to 0. + */ + int iVersion; + + /* + ** Create a new tokenizer. The values in the argv[] array are the + ** arguments passed to the "tokenizer" clause of the CREATE VIRTUAL + ** TABLE statement that created the fts3 table. For example, if + ** the following SQL is executed: + ** + ** CREATE .. USING fts3( ... , tokenizer <tokenizer-name> arg1 arg2) + ** + ** then argc is set to 2, and the argv[] array contains pointers + ** to the strings "arg1" and "arg2". + ** + ** This method should return either SQLITE_OK (0), or an SQLite error + ** code. If SQLITE_OK is returned, then *ppTokenizer should be set + ** to point at the newly created tokenizer structure. The generic + ** sqlite3_tokenizer.pModule variable should not be initialised by + ** this callback. The caller will do so. + */ + int (*xCreate)( + int argc, /* Size of argv array */ + const char *const*argv, /* Tokenizer argument strings */ + sqlite3_tokenizer **ppTokenizer /* OUT: Created tokenizer */ + ); + + /* + ** Destroy an existing tokenizer. The fts3 module calls this method + ** exactly once for each successful call to xCreate(). + */ + int (*xDestroy)(sqlite3_tokenizer *pTokenizer); + + /* + ** Create a tokenizer cursor to tokenize an input buffer. The caller + ** is responsible for ensuring that the input buffer remains valid + ** until the cursor is closed (using the xClose() method). + */ + int (*xOpen)( + sqlite3_tokenizer *pTokenizer, /* Tokenizer object */ + const char *pInput, int nBytes, /* Input buffer */ + sqlite3_tokenizer_cursor **ppCursor /* OUT: Created tokenizer cursor */ + ); + + /* + ** Destroy an existing tokenizer cursor. The fts3 module calls this + ** method exactly once for each successful call to xOpen(). + */ + int (*xClose)(sqlite3_tokenizer_cursor *pCursor); + + /* + ** Retrieve the next token from the tokenizer cursor pCursor. This + ** method should either return SQLITE_OK and set the values of the + ** "OUT" variables identified below, or SQLITE_DONE to indicate that + ** the end of the buffer has been reached, or an SQLite error code. + ** + ** *ppToken should be set to point at a buffer containing the + ** normalized version of the token (i.e. after any case-folding and/or + ** stemming has been performed). *pnBytes should be set to the length + ** of this buffer in bytes. The input text that generated the token is + ** identified by the byte offsets returned in *piStartOffset and + ** *piEndOffset. + ** + ** The buffer *ppToken is set to point at is managed by the tokenizer + ** implementation. It is only required to be valid until the next call + ** to xNext() or xClose(). + */ + /* TODO(shess) current implementation requires pInput to be + ** nul-terminated. This should either be fixed, or pInput/nBytes + ** should be converted to zInput. + */ + int (*xNext)( + sqlite3_tokenizer_cursor *pCursor, /* Tokenizer cursor */ + const char **ppToken, int *pnBytes, /* OUT: Normalized text for token */ + int *piStartOffset, /* OUT: Byte offset of token in input buffer */ + int *piEndOffset, /* OUT: Byte offset of end of token in input buffer */ + int *piPosition /* OUT: Number of tokens returned before this one */ + ); +}; + +struct sqlite3_tokenizer { + const sqlite3_tokenizer_module *pModule; /* The module for this tokenizer */ + /* Tokenizer implementations will typically add additional fields */ +}; + +struct sqlite3_tokenizer_cursor { + sqlite3_tokenizer *pTokenizer; /* Tokenizer for this cursor. */ + /* Tokenizer implementations will typically add additional fields */ +}; + +#endif /* _FTS3_TOKENIZER_H_ */ + +/************** End of fts3_tokenizer.h **************************************/ +/************** Continuing where we left off in fts3_tokenizer.c *************/ + +/* +** Implementation of the SQL scalar function for accessing the underlying +** hash table. This function may be called as follows: +** +** SELECT <function-name>(<key-name>); +** SELECT <function-name>(<key-name>, <pointer>); +** +** where <function-name> is the name passed as the second argument +** to the sqlite3Fts3InitHashTable() function (e.g. 'fts3_tokenizer'). +** +** If the <pointer> argument is specified, it must be a blob value +** containing a pointer to be stored as the hash data corresponding +** to the string <key-name>. If <pointer> is not specified, then +** the string <key-name> must already exist in the has table. Otherwise, +** an error is returned. +** +** Whether or not the <pointer> argument is specified, the value returned +** is a blob containing the pointer stored as the hash data corresponding +** to string <key-name> (after the hash-table is updated, if applicable). +*/ +static void scalarFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + fts3Hash *pHash; + void *pPtr = 0; + const unsigned char *zName; + int nName; + + assert( argc==1 || argc==2 ); + + pHash = (fts3Hash *)sqlite3_user_data(context); + + zName = sqlite3_value_text(argv[0]); + nName = sqlite3_value_bytes(argv[0])+1; + + if( argc==2 ){ + void *pOld; + int n = sqlite3_value_bytes(argv[1]); + if( n!=sizeof(pPtr) ){ + sqlite3_result_error(context, "argument type mismatch", -1); + return; + } + pPtr = *(void **)sqlite3_value_blob(argv[1]); + pOld = sqlite3Fts3HashInsert(pHash, (void *)zName, nName, pPtr); + if( pOld==pPtr ){ + sqlite3_result_error(context, "out of memory", -1); + return; + } + }else{ + pPtr = sqlite3Fts3HashFind(pHash, zName, nName); + if( !pPtr ){ + char *zErr = sqlite3_mprintf("unknown tokenizer: %s", zName); + sqlite3_result_error(context, zErr, -1); + sqlite3_free(zErr); + return; + } + } + + sqlite3_result_blob(context, (void *)&pPtr, sizeof(pPtr), SQLITE_TRANSIENT); +} + +#ifdef SQLITE_TEST + +#include <tcl.h> + +/* +** Implementation of a special SQL scalar function for testing tokenizers +** designed to be used in concert with the Tcl testing framework. This +** function must be called with two arguments: +** +** SELECT <function-name>(<key-name>, <input-string>); +** SELECT <function-name>(<key-name>, <pointer>); +** +** where <function-name> is the name passed as the second argument +** to the sqlite3Fts3InitHashTable() function (e.g. 'fts3_tokenizer') +** concatenated with the string '_test' (e.g. 'fts3_tokenizer_test'). +** +** The return value is a string that may be interpreted as a Tcl +** list. For each token in the <input-string>, three elements are +** added to the returned list. The first is the token position, the +** second is the token text (folded, stemmed, etc.) and the third is the +** substring of <input-string> associated with the token. For example, +** using the built-in "simple" tokenizer: +** +** SELECT fts_tokenizer_test('simple', 'I don't see how'); +** +** will return the string: +** +** "{0 i I 1 dont don't 2 see see 3 how how}" +** +*/ +static void testFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + fts3Hash *pHash; + sqlite3_tokenizer_module *p; + sqlite3_tokenizer *pTokenizer = 0; + sqlite3_tokenizer_cursor *pCsr = 0; + + const char *zErr = 0; + + const char *zName; + int nName; + const char *zInput; + int nInput; + + const char *zArg = 0; + + const char *zToken; + int nToken; + int iStart; + int iEnd; + int iPos; + + Tcl_Obj *pRet; + + assert( argc==2 || argc==3 ); + + nName = sqlite3_value_bytes(argv[0]); + zName = (const char *)sqlite3_value_text(argv[0]); + nInput = sqlite3_value_bytes(argv[argc-1]); + zInput = (const char *)sqlite3_value_text(argv[argc-1]); + + if( argc==3 ){ + zArg = (const char *)sqlite3_value_text(argv[1]); + } + + pHash = (fts3Hash *)sqlite3_user_data(context); + p = (sqlite3_tokenizer_module *)sqlite3Fts3HashFind(pHash, zName, nName+1); + + if( !p ){ + char *zErr = sqlite3_mprintf("unknown tokenizer: %s", zName); + sqlite3_result_error(context, zErr, -1); + sqlite3_free(zErr); + return; + } + + pRet = Tcl_NewObj(); + Tcl_IncrRefCount(pRet); + + if( SQLITE_OK!=p->xCreate(zArg ? 1 : 0, &zArg, &pTokenizer) ){ + zErr = "error in xCreate()"; + goto finish; + } + pTokenizer->pModule = p; + if( SQLITE_OK!=p->xOpen(pTokenizer, zInput, nInput, &pCsr) ){ + zErr = "error in xOpen()"; + goto finish; + } + pCsr->pTokenizer = pTokenizer; + + while( SQLITE_OK==p->xNext(pCsr, &zToken, &nToken, &iStart, &iEnd, &iPos) ){ + Tcl_ListObjAppendElement(0, pRet, Tcl_NewIntObj(iPos)); + Tcl_ListObjAppendElement(0, pRet, Tcl_NewStringObj(zToken, nToken)); + zToken = &zInput[iStart]; + nToken = iEnd-iStart; + Tcl_ListObjAppendElement(0, pRet, Tcl_NewStringObj(zToken, nToken)); + } + + if( SQLITE_OK!=p->xClose(pCsr) ){ + zErr = "error in xClose()"; + goto finish; + } + if( SQLITE_OK!=p->xDestroy(pTokenizer) ){ + zErr = "error in xDestroy()"; + goto finish; + } + +finish: + if( zErr ){ + sqlite3_result_error(context, zErr, -1); + }else{ + sqlite3_result_text(context, Tcl_GetString(pRet), -1, SQLITE_TRANSIENT); + } + Tcl_DecrRefCount(pRet); +} + +static +int registerTokenizer( + sqlite3 *db, + char *zName, + const sqlite3_tokenizer_module *p +){ + int rc; + sqlite3_stmt *pStmt; + const char zSql[] = "SELECT fts3_tokenizer(?, ?)"; + + rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0); + if( rc!=SQLITE_OK ){ + return rc; + } + + sqlite3_bind_text(pStmt, 1, zName, -1, SQLITE_STATIC); + sqlite3_bind_blob(pStmt, 2, &p, sizeof(p), SQLITE_STATIC); + sqlite3_step(pStmt); + + return sqlite3_finalize(pStmt); +} + +static +int queryTokenizer( + sqlite3 *db, + char *zName, + const sqlite3_tokenizer_module **pp +){ + int rc; + sqlite3_stmt *pStmt; + const char zSql[] = "SELECT fts3_tokenizer(?)"; + + *pp = 0; + rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0); + if( rc!=SQLITE_OK ){ + return rc; + } + + sqlite3_bind_text(pStmt, 1, zName, -1, SQLITE_STATIC); + if( SQLITE_ROW==sqlite3_step(pStmt) ){ + if( sqlite3_column_type(pStmt, 0)==SQLITE_BLOB ){ + memcpy(pp, sqlite3_column_blob(pStmt, 0), sizeof(*pp)); + } + } + + return sqlite3_finalize(pStmt); +} + +void sqlite3Fts3SimpleTokenizerModule(sqlite3_tokenizer_module const**ppModule); + +/* +** Implementation of the scalar function fts3_tokenizer_internal_test(). +** This function is used for testing only, it is not included in the +** build unless SQLITE_TEST is defined. +** +** The purpose of this is to test that the fts3_tokenizer() function +** can be used as designed by the C-code in the queryTokenizer and +** registerTokenizer() functions above. These two functions are repeated +** in the README.tokenizer file as an example, so it is important to +** test them. +** +** To run the tests, evaluate the fts3_tokenizer_internal_test() scalar +** function with no arguments. An assert() will fail if a problem is +** detected. i.e.: +** +** SELECT fts3_tokenizer_internal_test(); +** +*/ +static void intTestFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + int rc; + const sqlite3_tokenizer_module *p1; + const sqlite3_tokenizer_module *p2; + sqlite3 *db = (sqlite3 *)sqlite3_user_data(context); + + /* Test the query function */ + sqlite3Fts3SimpleTokenizerModule(&p1); + rc = queryTokenizer(db, "simple", &p2); + assert( rc==SQLITE_OK ); + assert( p1==p2 ); + rc = queryTokenizer(db, "nosuchtokenizer", &p2); + assert( rc==SQLITE_ERROR ); + assert( p2==0 ); + assert( 0==strcmp(sqlite3_errmsg(db), "unknown tokenizer: nosuchtokenizer") ); + + /* Test the storage function */ + rc = registerTokenizer(db, "nosuchtokenizer", p1); + assert( rc==SQLITE_OK ); + rc = queryTokenizer(db, "nosuchtokenizer", &p2); + assert( rc==SQLITE_OK ); + assert( p2==p1 ); + + sqlite3_result_text(context, "ok", -1, SQLITE_STATIC); +} + +#endif + +/* +** Set up SQL objects in database db used to access the contents of +** the hash table pointed to by argument pHash. The hash table must +** been initialised to use string keys, and to take a private copy +** of the key when a value is inserted. i.e. by a call similar to: +** +** sqlite3Fts3HashInit(pHash, FTS3_HASH_STRING, 1); +** +** This function adds a scalar function (see header comment above +** scalarFunc() in this file for details) and, if ENABLE_TABLE is +** defined at compilation time, a temporary virtual table (see header +** comment above struct HashTableVtab) to the database schema. Both +** provide read/write access to the contents of *pHash. +** +** The third argument to this function, zName, is used as the name +** of both the scalar and, if created, the virtual table. +*/ +int sqlite3Fts3InitHashTable( + sqlite3 *db, + fts3Hash *pHash, + const char *zName +){ + int rc = SQLITE_OK; + void *p = (void *)pHash; + const int any = SQLITE_ANY; + char *zTest = 0; + char *zTest2 = 0; + +#ifdef SQLITE_TEST + void *pdb = (void *)db; + zTest = sqlite3_mprintf("%s_test", zName); + zTest2 = sqlite3_mprintf("%s_internal_test", zName); + if( !zTest || !zTest2 ){ + rc = SQLITE_NOMEM; + } +#endif + + if( rc!=SQLITE_OK + || (rc = sqlite3_create_function(db, zName, 1, any, p, scalarFunc, 0, 0)) + || (rc = sqlite3_create_function(db, zName, 2, any, p, scalarFunc, 0, 0)) +#ifdef SQLITE_TEST + || (rc = sqlite3_create_function(db, zTest, 2, any, p, testFunc, 0, 0)) + || (rc = sqlite3_create_function(db, zTest, 3, any, p, testFunc, 0, 0)) + || (rc = sqlite3_create_function(db, zTest2, 0, any, pdb, intTestFunc, 0, 0)) +#endif + ); + + sqlite3_free(zTest); + sqlite3_free(zTest2); + return rc; +} + +#endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) */ + +/************** End of fts3_tokenizer.c **************************************/ +/************** Begin file fts3_tokenizer1.c *********************************/ +/* +** 2006 Oct 10 +** +** 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. +** +****************************************************************************** +** +** Implementation of the "simple" full-text-search tokenizer. +*/ + +/* +** The code in this file is only compiled if: +** +** * The FTS3 module is being built as an extension +** (in which case SQLITE_CORE is not defined), or +** +** * The FTS3 module is being built into the core of +** SQLite (in which case SQLITE_ENABLE_FTS3 is defined). +*/ +#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) + + + +/************** Include fts3_tokenizer.h in the middle of fts3_tokenizer1.c **/ +/************** Begin file fts3_tokenizer.h **********************************/ +/* +** 2006 July 10 +** +** The author disclaims copyright to this source code. +** +************************************************************************* +** Defines the interface to tokenizers used by fulltext-search. There +** are three basic components: +** +** sqlite3_tokenizer_module is a singleton defining the tokenizer +** interface functions. This is essentially the class structure for +** tokenizers. +** +** sqlite3_tokenizer is used to define a particular tokenizer, perhaps +** including customization information defined at creation time. +** +** sqlite3_tokenizer_cursor is generated by a tokenizer to generate +** tokens from a particular input. +*/ +#ifndef _FTS3_TOKENIZER_H_ +#define _FTS3_TOKENIZER_H_ + +/* TODO(shess) Only used for SQLITE_OK and SQLITE_DONE at this time. +** If tokenizers are to be allowed to call sqlite3_*() functions, then +** we will need a way to register the API consistently. +*/ +/************** Include sqlite3.h in the middle of fts3_tokenizer.h **********/ +/************** Begin file sqlite3.h *****************************************/ +/* +** 2001 September 15 +** +** 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 header file defines the interface that the SQLite library +** presents to client programs. If a C-function, structure, datatype, +** or constant definition does not appear in this file, then it is +** not a published API of SQLite, is subject to change without +** notice, and should not be referenced by programs that use SQLite. +** +** Some of the definitions that are in this file are marked as +** "experimental". Experimental interfaces are normally new +** features recently added to SQLite. We do not anticipate changes +** to experimental interfaces but reserve to make minor changes if +** experience from use "in the wild" suggest such changes are prudent. +** +** The official C-language API documentation for SQLite is derived +** from comments in this file. This file is the authoritative source +** on how SQLite interfaces are suppose to operate. +** +** The name of this file under configuration management is "sqlite.h.in". +** The makefile makes some minor changes to this file (such as inserting +** the version number) and changes its name to "sqlite3.h" as +** part of the build process. +** +** @(#) $Id: sqlite.h.in,v 1.271 2007/11/21 15:24:01 drh Exp $ +*/ +#ifndef _SQLITE3_H_ +#define _SQLITE3_H_ + +/* +** Make sure we can call this stuff from C++. +*/ +#if 0 +extern "C" { +#endif + + +/* +** Add the ability to override 'extern' +*/ +#ifndef SQLITE_EXTERN +# define SQLITE_EXTERN extern +#endif + +/* +** Make sure these symbols where not defined by some previous header +** file. +*/ +#ifdef SQLITE_VERSION +# undef SQLITE_VERSION +#endif +#ifdef SQLITE_VERSION_NUMBER +# undef SQLITE_VERSION_NUMBER +#endif + +/* +** CAPI3REF: Compile-Time Library Version Numbers +** +** The version of the SQLite library is contained in the sqlite3.h +** header file in a #define named SQLITE_VERSION. The SQLITE_VERSION +** macro resolves to a string constant. +** +** The format of the version string is "X.Y.Z", where +** X is the major version number, Y is the minor version number and Z +** is the release number. The X.Y.Z might be followed by "alpha" or "beta". +** For example "3.1.1beta". +** +** The X value is always 3 in SQLite. The X value only changes when +** backwards compatibility is broken and we intend to never break +** backwards compatibility. The Y value only changes when +** there are major feature enhancements that are forwards compatible +** but not backwards compatible. The Z value is incremented with +** each release but resets back to 0 when Y is incremented. +** +** The SQLITE_VERSION_NUMBER is an integer with the value +** (X*1000000 + Y*1000 + Z). For example, for version "3.1.1beta", +** SQLITE_VERSION_NUMBER is set to 3001001. To detect if they are using +** version 3.1.1 or greater at compile time, programs may use the test +** (SQLITE_VERSION_NUMBER>=3001001). +** +** See also: [sqlite3_libversion()] and [sqlite3_libversion_number()]. +*/ +#define SQLITE_VERSION "3.5.2" +#define SQLITE_VERSION_NUMBER 3005002 + +/* +** CAPI3REF: Run-Time Library Version Numbers +** +** These routines return values equivalent to the header constants +** [SQLITE_VERSION] and [SQLITE_VERSION_NUMBER]. The values returned +** by this routines should only be different from the header values +** if you compile your program using an sqlite3.h header from a +** different version of SQLite that the version of the library you +** link against. +** +** The sqlite3_version[] string constant contains the text of the +** [SQLITE_VERSION] string. The sqlite3_libversion() function returns +** a poiner to the sqlite3_version[] string constant. The function +** is provided for DLL users who can only access functions and not +** constants within the DLL. +*/ +SQLITE_EXTERN const char sqlite3_version[]; +const char *sqlite3_libversion(void); +int sqlite3_libversion_number(void); + +/* +** CAPI3REF: Test To See If The Library Is Threadsafe +** +** This routine returns TRUE (nonzero) if SQLite was compiled with +** all of its mutexes enabled and is thus threadsafe. It returns +** zero if the particular build is for single-threaded operation +** only. +** +** Really all this routine does is return true if SQLite was compiled +** with the -DSQLITE_THREADSAFE=1 option and false if +** compiled with -DSQLITE_THREADSAFE=0. If SQLite uses an +** application-defined mutex subsystem, malloc subsystem, collating +** sequence, VFS, SQL function, progress callback, commit hook, +** extension, or other accessories and these add-ons are not +** threadsafe, then clearly the combination will not be threadsafe +** either. Hence, this routine never reports that the library +** is guaranteed to be threadsafe, only when it is guaranteed not +** to be. +** +** This is an experimental API and may go away or change in future +** releases. +*/ +int sqlite3_threadsafe(void); + +/* +** CAPI3REF: Database Connection Handle +** +** Each open SQLite database is represented by pointer to an instance of the +** opaque structure named "sqlite3". It is useful to think of an sqlite3 +** pointer as an object. The [sqlite3_open()], [sqlite3_open16()], and +** [sqlite3_open_v2()] interfaces are its constructors +** and [sqlite3_close()] is its destructor. There are many other interfaces +** (such as [sqlite3_prepare_v2()], [sqlite3_create_function()], and +** [sqlite3_busy_timeout()] to name but three) that are methods on this +** object. +*/ +typedef struct sqlite3 sqlite3; + + +/* +** CAPI3REF: 64-Bit Integer Types +** +** Some compilers do not support the "long long" datatype. So we have +** to do compiler-specific typedefs for 64-bit signed and unsigned integers. +** +** Many SQLite interface functions require a 64-bit integer arguments. +** Those interfaces are declared using this typedef. +*/ +#ifdef SQLITE_INT64_TYPE + typedef SQLITE_INT64_TYPE sqlite_int64; + typedef unsigned SQLITE_INT64_TYPE sqlite_uint64; +#elif defined(_MSC_VER) || defined(__BORLANDC__) + typedef __int64 sqlite_int64; + typedef unsigned __int64 sqlite_uint64; +#else + typedef long long int sqlite_int64; + typedef unsigned long long int sqlite_uint64; +#endif +typedef sqlite_int64 sqlite3_int64; +typedef sqlite_uint64 sqlite3_uint64; + +/* +** If compiling for a processor that lacks floating point support, +** substitute integer for floating-point +*/ +#ifdef SQLITE_OMIT_FLOATING_POINT +# define double sqlite3_int64 +#endif + +/* +** CAPI3REF: Closing A Database Connection +** +** Call this function with a pointer to a structure that was previously +** returned from [sqlite3_open()], [sqlite3_open16()], or +** [sqlite3_open_v2()] and the corresponding database will by +** closed. +** +** All SQL statements prepared using [sqlite3_prepare_v2()] or +** [sqlite3_prepare16_v2()] must be destroyed using [sqlite3_finalize()] +** before this routine is called. Otherwise, SQLITE_BUSY is returned and the +** database connection remains open. +** +** Passing this routine a database connection that has already been +** closed results in undefined behavior. If other interfaces that +** reference the same database connection are pending (either in the +** same thread or in different threads) when this routine is called, +** then the behavior is undefined and is almost certainly undesirable. +*/ +int sqlite3_close(sqlite3 *); + +/* +** The type for a callback function. +** This is legacy and deprecated. It is included for historical +** compatibility and is not documented. +*/ +typedef int (*sqlite3_callback)(void*,int,char**, char**); + +/* +** CAPI3REF: One-Step Query Execution Interface +** +** This interface is used to do a one-time evaluatation of zero +** or more SQL statements. UTF-8 text of the SQL statements to +** be evaluted is passed in as the second parameter. The statements +** are prepared one by one using [sqlite3_prepare()], evaluated +** using [sqlite3_step()], then destroyed using [sqlite3_finalize()]. +** +** If one or more of the SQL statements are queries, then +** the callback function specified by the 3rd parameter is +** invoked once for each row of the query result. This callback +** should normally return 0. If the callback returns a non-zero +** value then the query is aborted, all subsequent SQL statements +** are skipped and the sqlite3_exec() function returns the [SQLITE_ABORT]. +** +** The 4th parameter to this interface is an arbitrary pointer that is +** passed through to the callback function as its first parameter. +** +** The 2nd parameter to the callback function is the number of +** columns in the query result. The 3rd parameter to the callback +** is an array of strings holding the values for each column +** as extracted using [sqlite3_column_text()]. +** The 4th parameter to the callback is an array of strings +** obtained using [sqlite3_column_name()] and holding +** the names of each column. +** +** The callback function may be NULL, even for queries. A NULL +** callback is not an error. It just means that no callback +** will be invoked. +** +** If an error occurs while parsing or evaluating the SQL (but +** not while executing the callback) then an appropriate error +** message is written into memory obtained from [sqlite3_malloc()] and +** *errmsg is made to point to that message. The calling function +** is responsible for freeing the memory using [sqlite3_free()]. +** If errmsg==NULL, then no error message is ever written. +** +** The return value is is SQLITE_OK if there are no errors and +** some other [SQLITE_OK | return code] if there is an error. +** The particular return value depends on the type of error. +** +*/ +int sqlite3_exec( + sqlite3*, /* An open database */ + const char *sql, /* SQL to be evaluted */ + int (*callback)(void*,int,char**,char**), /* Callback function */ + void *, /* 1st argument to callback */ + char **errmsg /* Error msg written here */ +); + +/* +** CAPI3REF: Result Codes +** KEYWORDS: SQLITE_OK +** +** Many SQLite functions return an integer result code from the set shown +** above in order to indicates success or failure. +** +** The result codes above are the only ones returned by SQLite in its +** default configuration. However, the [sqlite3_extended_result_codes()] +** API can be used to set a database connectoin to return more detailed +** result codes. +** +** See also: [SQLITE_IOERR_READ | extended result codes] +** +*/ +#define SQLITE_OK 0 /* Successful result */ +/* beginning-of-error-codes */ +#define SQLITE_ERROR 1 /* SQL error or missing database */ +#define SQLITE_INTERNAL 2 /* NOT USED. Internal logic error in SQLite */ +#define SQLITE_PERM 3 /* Access permission denied */ +#define SQLITE_ABORT 4 /* Callback routine requested an abort */ +#define SQLITE_BUSY 5 /* The database file is locked */ +#define SQLITE_LOCKED 6 /* A table in the database is locked */ +#define SQLITE_NOMEM 7 /* A malloc() failed */ +#define SQLITE_READONLY 8 /* Attempt to write a readonly database */ +#define SQLITE_INTERRUPT 9 /* Operation terminated by sqlite3_interrupt()*/ +#define SQLITE_IOERR 10 /* Some kind of disk I/O error occurred */ +#define SQLITE_CORRUPT 11 /* The database disk image is malformed */ +#define SQLITE_NOTFOUND 12 /* NOT USED. Table or record not found */ +#define SQLITE_FULL 13 /* Insertion failed because database is full */ +#define SQLITE_CANTOPEN 14 /* Unable to open the database file */ +#define SQLITE_PROTOCOL 15 /* NOT USED. Database lock protocol error */ +#define SQLITE_EMPTY 16 /* Database is empty */ +#define SQLITE_SCHEMA 17 /* The database schema changed */ +#define SQLITE_TOOBIG 18 /* String or BLOB exceeds size limit */ +#define SQLITE_CONSTRAINT 19 /* Abort due to constraint violation */ +#define SQLITE_MISMATCH 20 /* Data type mismatch */ +#define SQLITE_MISUSE 21 /* Library used incorrectly */ +#define SQLITE_NOLFS 22 /* Uses OS features not supported on host */ +#define SQLITE_AUTH 23 /* Authorization denied */ +#define SQLITE_FORMAT 24 /* Auxiliary database format error */ +#define SQLITE_RANGE 25 /* 2nd parameter to sqlite3_bind out of range */ +#define SQLITE_NOTADB 26 /* File opened that is not a database file */ +#define SQLITE_ROW 100 /* sqlite3_step() has another row ready */ +#define SQLITE_DONE 101 /* sqlite3_step() has finished executing */ +/* end-of-error-codes */ + +/* +** CAPI3REF: Extended Result Codes +** +** In its default configuration, SQLite API routines return one of 26 integer +** result codes described at result-codes. However, experience has shown that +** many of these result codes are too course-grained. They do not provide as +** much information about problems as users might like. In an effort to +** address this, newer versions of SQLite (version 3.3.8 and later) include +** support for additional result codes that provide more detailed information +** about errors. The extended result codes are enabled (or disabled) for +** each database +** connection using the [sqlite3_extended_result_codes()] API. +** +** Some of the available extended result codes are listed above. +** We expect the number of extended result codes will be expand +** over time. Software that uses extended result codes should expect +** to see new result codes in future releases of SQLite. +** +** The symbolic name for an extended result code always contains a related +** primary result code as a prefix. Primary result codes contain a single +** "_" character. Extended result codes contain two or more "_" characters. +** The numeric value of an extended result code can be converted to its +** corresponding primary result code by masking off the lower 8 bytes. +** +** The SQLITE_OK result code will never be extended. It will always +** be exactly zero. +*/ +#define SQLITE_IOERR_READ (SQLITE_IOERR | (1<<8)) +#define SQLITE_IOERR_SHORT_READ (SQLITE_IOERR | (2<<8)) +#define SQLITE_IOERR_WRITE (SQLITE_IOERR | (3<<8)) +#define SQLITE_IOERR_FSYNC (SQLITE_IOERR | (4<<8)) +#define SQLITE_IOERR_DIR_FSYNC (SQLITE_IOERR | (5<<8)) +#define SQLITE_IOERR_TRUNCATE (SQLITE_IOERR | (6<<8)) +#define SQLITE_IOERR_FSTAT (SQLITE_IOERR | (7<<8)) +#define SQLITE_IOERR_UNLOCK (SQLITE_IOERR | (8<<8)) +#define SQLITE_IOERR_RDLOCK (SQLITE_IOERR | (9<<8)) +#define SQLITE_IOERR_DELETE (SQLITE_IOERR | (10<<8)) +#define SQLITE_IOERR_BLOCKED (SQLITE_IOERR | (11<<8)) +#define SQLITE_IOERR_NOMEM (SQLITE_IOERR | (12<<8)) + +/* +** CAPI3REF: Flags For File Open Operations +** +** Combination of the following bit values are used as the +** third argument to the [sqlite3_open_v2()] interface and +** as fourth argument to the xOpen method of the +** [sqlite3_vfs] object. +** +*/ +#define SQLITE_OPEN_READONLY 0x00000001 +#define SQLITE_OPEN_READWRITE 0x00000002 +#define SQLITE_OPEN_CREATE 0x00000004 +#define SQLITE_OPEN_DELETEONCLOSE 0x00000008 +#define SQLITE_OPEN_EXCLUSIVE 0x00000010 +#define SQLITE_OPEN_MAIN_DB 0x00000100 +#define SQLITE_OPEN_TEMP_DB 0x00000200 +#define SQLITE_OPEN_TRANSIENT_DB 0x00000400 +#define SQLITE_OPEN_MAIN_JOURNAL 0x00000800 +#define SQLITE_OPEN_TEMP_JOURNAL 0x00001000 +#define SQLITE_OPEN_SUBJOURNAL 0x00002000 +#define SQLITE_OPEN_MASTER_JOURNAL 0x00004000 + +/* +** CAPI3REF: Device Characteristics +** +** The xDeviceCapabilities method of the [sqlite3_io_methods] +** object returns an integer which is a vector of the following +** bit values expressing I/O characteristics of the mass storage +** device that holds the file that the [sqlite3_io_methods] +** refers to. +** +** The SQLITE_IOCAP_ATOMIC property means that all writes of +** any size are atomic. The SQLITE_IOCAP_ATOMICnnn values +** mean that writes of blocks that are nnn bytes in size and +** are aligned to an address which is an integer multiple of +** nnn are atomic. The SQLITE_IOCAP_SAFE_APPEND value means +** that when data is appended to a file, the data is appended +** first then the size of the file is extended, never the other +** way around. The SQLITE_IOCAP_SEQUENTIAL property means that +** information is written to disk in the same order as calls +** to xWrite(). +*/ +#define SQLITE_IOCAP_ATOMIC 0x00000001 +#define SQLITE_IOCAP_ATOMIC512 0x00000002 +#define SQLITE_IOCAP_ATOMIC1K 0x00000004 +#define SQLITE_IOCAP_ATOMIC2K 0x00000008 +#define SQLITE_IOCAP_ATOMIC4K 0x00000010 +#define SQLITE_IOCAP_ATOMIC8K 0x00000020 +#define SQLITE_IOCAP_ATOMIC16K 0x00000040 +#define SQLITE_IOCAP_ATOMIC32K 0x00000080 +#define SQLITE_IOCAP_ATOMIC64K 0x00000100 +#define SQLITE_IOCAP_SAFE_APPEND 0x00000200 +#define SQLITE_IOCAP_SEQUENTIAL 0x00000400 + +/* +** CAPI3REF: File Locking Levels +** +** SQLite uses one of the following integer values as the second +** argument to calls it makes to the xLock() and xUnlock() methods +** of an [sqlite3_io_methods] object. +*/ +#define SQLITE_LOCK_NONE 0 +#define SQLITE_LOCK_SHARED 1 +#define SQLITE_LOCK_RESERVED 2 +#define SQLITE_LOCK_PENDING 3 +#define SQLITE_LOCK_EXCLUSIVE 4 + +/* +** CAPI3REF: Synchronization Type Flags +** +** When SQLite invokes the xSync() method of an [sqlite3_io_methods] +** object it uses a combination of the following integer values as +** the second argument. +** +** When the SQLITE_SYNC_DATAONLY flag is used, it means that the +** sync operation only needs to flush data to mass storage. Inode +** information need not be flushed. The SQLITE_SYNC_NORMAL means +** to use normal fsync() semantics. The SQLITE_SYNC_FULL flag means +** to use Mac OS-X style fullsync instead of fsync(). +*/ +#define SQLITE_SYNC_NORMAL 0x00002 +#define SQLITE_SYNC_FULL 0x00003 +#define SQLITE_SYNC_DATAONLY 0x00010 + + +/* +** CAPI3REF: OS Interface Open File Handle +** +** An [sqlite3_file] object represents an open file in the OS +** interface layer. Individual OS interface implementations will +** want to subclass this object by appending additional fields +** for their own use. The pMethods entry is a pointer to an +** [sqlite3_io_methods] object that defines methods for performing +** I/O operations on the open file. +*/ +typedef struct sqlite3_file sqlite3_file; +struct sqlite3_file { + const struct sqlite3_io_methods *pMethods; /* Methods for an open file */ +}; + +/* +** CAPI3REF: OS Interface File Virtual Methods Object +** +** Every file opened by the [sqlite3_vfs] xOpen method contains a pointer to +** an instance of the this object. This object defines the +** methods used to perform various operations against the open file. +** +** The flags argument to xSync may be one of [SQLITE_SYNC_NORMAL] or +** [SQLITE_SYNC_FULL]. The first choice is the normal fsync(). +* The second choice is an +** OS-X style fullsync. The SQLITE_SYNC_DATA flag may be ORed in to +** indicate that only the data of the file and not its inode needs to be +** synced. +** +** The integer values to xLock() and xUnlock() are one of +** <ul> +** <li> [SQLITE_LOCK_NONE], +** <li> [SQLITE_LOCK_SHARED], +** <li> [SQLITE_LOCK_RESERVED], +** <li> [SQLITE_LOCK_PENDING], or +** <li> [SQLITE_LOCK_EXCLUSIVE]. +** </ul> +** xLock() increases the lock. xUnlock() decreases the lock. +** The xCheckReservedLock() method looks +** to see if any database connection, either in this +** process or in some other process, is holding an RESERVED, +** PENDING, or EXCLUSIVE lock on the file. It returns true +** if such a lock exists and false if not. +** +** The xFileControl() method is a generic interface that allows custom +** VFS implementations to directly control an open file using the +** [sqlite3_file_control()] interface. The second "op" argument +** is an integer opcode. The third +** argument is a generic pointer which is intended to be a pointer +** to a structure that may contain arguments or space in which to +** write return values. Potential uses for xFileControl() might be +** functions to enable blocking locks with timeouts, to change the +** locking strategy (for example to use dot-file locks), to inquire +** about the status of a lock, or to break stale locks. The SQLite +** core reserves opcodes less than 100 for its own use. +** A [SQLITE_FCNTL_LOCKSTATE | list of opcodes] less than 100 is available. +** Applications that define a custom xFileControl method should use opcodes +** greater than 100 to avoid conflicts. +** +** The xSectorSize() method returns the sector size of the +** device that underlies the file. The sector size is the +** minimum write that can be performed without disturbing +** other bytes in the file. The xDeviceCharacteristics() +** method returns a bit vector describing behaviors of the +** underlying device: +** +** <ul> +** <li> [SQLITE_IOCAP_ATOMIC] +** <li> [SQLITE_IOCAP_ATOMIC512] +** <li> [SQLITE_IOCAP_ATOMIC1K] +** <li> [SQLITE_IOCAP_ATOMIC2K] +** <li> [SQLITE_IOCAP_ATOMIC4K] +** <li> [SQLITE_IOCAP_ATOMIC8K] +** <li> [SQLITE_IOCAP_ATOMIC16K] +** <li> [SQLITE_IOCAP_ATOMIC32K] +** <li> [SQLITE_IOCAP_ATOMIC64K] +** <li> [SQLITE_IOCAP_SAFE_APPEND] +** <li> [SQLITE_IOCAP_SEQUENTIAL] +** </ul> +** +** The SQLITE_IOCAP_ATOMIC property means that all writes of +** any size are atomic. The SQLITE_IOCAP_ATOMICnnn values +** mean that writes of blocks that are nnn bytes in size and +** are aligned to an address which is an integer multiple of +** nnn are atomic. The SQLITE_IOCAP_SAFE_APPEND value means +** that when data is appended to a file, the data is appended +** first then the size of the file is extended, never the other +** way around. The SQLITE_IOCAP_SEQUENTIAL property means that +** information is written to disk in the same order as calls +** to xWrite(). +*/ +typedef struct sqlite3_io_methods sqlite3_io_methods; +struct sqlite3_io_methods { + int iVersion; + int (*xClose)(sqlite3_file*); + int (*xRead)(sqlite3_file*, void*, int iAmt, sqlite3_int64 iOfst); + int (*xWrite)(sqlite3_file*, const void*, int iAmt, sqlite3_int64 iOfst); + int (*xTruncate)(sqlite3_file*, sqlite3_int64 size); + int (*xSync)(sqlite3_file*, int flags); + int (*xFileSize)(sqlite3_file*, sqlite3_int64 *pSize); + int (*xLock)(sqlite3_file*, int); + int (*xUnlock)(sqlite3_file*, int); + int (*xCheckReservedLock)(sqlite3_file*); + int (*xFileControl)(sqlite3_file*, int op, void *pArg); + int (*xSectorSize)(sqlite3_file*); + int (*xDeviceCharacteristics)(sqlite3_file*); + /* Additional methods may be added in future releases */ +}; + +/* +** CAPI3REF: Standard File Control Opcodes +** +** These integer constants are opcodes for the xFileControl method +** of the [sqlite3_io_methods] object and to the [sqlite3_file_control()] +** interface. +** +** The [SQLITE_FCNTL_LOCKSTATE] opcode is used for debugging. This +** opcode cases the xFileControl method to write the current state of +** the lock (one of [SQLITE_LOCK_NONE], [SQLITE_LOCK_SHARED], +** [SQLITE_LOCK_RESERVED], [SQLITE_LOCK_PENDING], or [SQLITE_LOCK_EXCLUSIVE]) +** into an integer that the pArg argument points to. This capability +** is used during testing and only needs to be supported when SQLITE_TEST +** is defined. +*/ +#define SQLITE_FCNTL_LOCKSTATE 1 + +/* +** CAPI3REF: Mutex Handle +** +** The mutex module within SQLite defines [sqlite3_mutex] to be an +** abstract type for a mutex object. The SQLite core never looks +** at the internal representation of an [sqlite3_mutex]. It only +** deals with pointers to the [sqlite3_mutex] object. +** +** Mutexes are created using [sqlite3_mutex_alloc()]. +*/ +typedef struct sqlite3_mutex sqlite3_mutex; + +/* +** CAPI3REF: OS Interface Object +** +** An instance of this object defines the interface between the +** SQLite core and the underlying operating system. The "vfs" +** in the name of the object stands for "virtual file system". +** +** The iVersion field is initially 1 but may be larger for future +** versions of SQLite. Additional fields may be appended to this +** object when the iVersion value is increased. +** +** The szOsFile field is the size of the subclassed [sqlite3_file] +** structure used by this VFS. mxPathname is the maximum length of +** a pathname in this VFS. +** +** Registered vfs modules are kept on a linked list formed by +** the pNext pointer. The [sqlite3_vfs_register()] +** and [sqlite3_vfs_unregister()] interfaces manage this list +** in a thread-safe way. The [sqlite3_vfs_find()] interface +** searches the list. +** +** The pNext field is the only fields in the sqlite3_vfs +** structure that SQLite will ever modify. SQLite will only access +** or modify this field while holding a particular static mutex. +** The application should never modify anything within the sqlite3_vfs +** object once the object has been registered. +** +** The zName field holds the name of the VFS module. The name must +** be unique across all VFS modules. +** +** SQLite will guarantee that the zFilename string passed to +** xOpen() is a full pathname as generated by xFullPathname() and +** that the string will be valid and unchanged until xClose() is +** called. So the [sqlite3_file] can store a pointer to the +** filename if it needs to remember the filename for some reason. +** +** The flags argument to xOpen() is a copy of the flags argument +** to [sqlite3_open_v2()]. If [sqlite3_open()] or [sqlite3_open16()] +** is used, then flags is [SQLITE_OPEN_READWRITE] | [SQLITE_OPEN_CREATE]. +** If xOpen() opens a file read-only then it sets *pOutFlags to +** include [SQLITE_OPEN_READONLY]. Other bits in *pOutFlags may be +** set. +** +** SQLite will also add one of the following flags to the xOpen() +** call, depending on the object being opened: +** +** <ul> +** <li> [SQLITE_OPEN_MAIN_DB] +** <li> [SQLITE_OPEN_MAIN_JOURNAL] +** <li> [SQLITE_OPEN_TEMP_DB] +** <li> [SQLITE_OPEN_TEMP_JOURNAL] +** <li> [SQLITE_OPEN_TRANSIENT_DB] +** <li> [SQLITE_OPEN_SUBJOURNAL] +** <li> [SQLITE_OPEN_MASTER_JOURNAL] +** </ul> +** +** The file I/O implementation can use the object type flags to +** changes the way it deals with files. For example, an application +** that does not care about crash recovery or rollback, might make +** the open of a journal file a no-op. Writes to this journal are +** also a no-op. Any attempt to read the journal return SQLITE_IOERR. +** Or the implementation might recognize the a database file will +** be doing page-aligned sector reads and writes in a random order +** and set up its I/O subsystem accordingly. +** +** SQLite might also add one of the following flags to the xOpen +** method: +** +** <ul> +** <li> [SQLITE_OPEN_DELETEONCLOSE] +** <li> [SQLITE_OPEN_EXCLUSIVE] +** </ul> +** +** The [SQLITE_OPEN_DELETEONCLOSE] flag means the file should be +** deleted when it is closed. This will always be set for TEMP +** databases and journals and for subjournals. The +** [SQLITE_OPEN_EXCLUSIVE] flag means the file should be opened +** for exclusive access. This flag is set for all files except +** for the main database file. +** +** Space to hold the [sqlite3_file] structure passed as the third +** argument to xOpen is allocated by caller (the SQLite core). +** szOsFile bytes are allocated for this object. The xOpen method +** fills in the allocated space. +** +** The flags argument to xAccess() may be [SQLITE_ACCESS_EXISTS] +** to test for the existance of a file, +** or [SQLITE_ACCESS_READWRITE] to test to see +** if a file is readable and writable, or [SQLITE_ACCESS_READ] +** to test to see if a file is at least readable. The file can be a +** directory. +** +** SQLite will always allocate at least mxPathname+1 byte for +** the output buffers for xGetTempname and xFullPathname. The exact +** size of the output buffer is also passed as a parameter to both +** methods. If the output buffer is not large enough, SQLITE_CANTOPEN +** should be returned. As this is handled as a fatal error by SQLite, +** vfs implementations should endevour to prevent this by setting +** mxPathname to a sufficiently large value. +** +** The xRandomness(), xSleep(), and xCurrentTime() interfaces +** are not strictly a part of the filesystem, but they are +** included in the VFS structure for completeness. +** The xRandomness() function attempts to return nBytes bytes +** of good-quality randomness into zOut. The return value is +** the actual number of bytes of randomness obtained. The +** xSleep() method cause the calling thread to sleep for at +** least the number of microseconds given. The xCurrentTime() +** method returns a Julian Day Number for the current date and +** time. +*/ +typedef struct sqlite3_vfs sqlite3_vfs; +struct sqlite3_vfs { + int iVersion; /* Structure version number */ + int szOsFile; /* Size of subclassed sqlite3_file */ + int mxPathname; /* Maximum file pathname length */ + sqlite3_vfs *pNext; /* Next registered VFS */ + const char *zName; /* Name of this virtual file system */ + void *pAppData; /* Pointer to application-specific data */ + int (*xOpen)(sqlite3_vfs*, const char *zName, sqlite3_file*, + int flags, int *pOutFlags); + int (*xDelete)(sqlite3_vfs*, const char *zName, int syncDir); + int (*xAccess)(sqlite3_vfs*, const char *zName, int flags); + int (*xGetTempname)(sqlite3_vfs*, int nOut, char *zOut); + int (*xFullPathname)(sqlite3_vfs*, const char *zName, int nOut, char *zOut); + void *(*xDlOpen)(sqlite3_vfs*, const char *zFilename); + void (*xDlError)(sqlite3_vfs*, int nByte, char *zErrMsg); + void *(*xDlSym)(sqlite3_vfs*,void*, const char *zSymbol); + void (*xDlClose)(sqlite3_vfs*, void*); + int (*xRandomness)(sqlite3_vfs*, int nByte, char *zOut); + int (*xSleep)(sqlite3_vfs*, int microseconds); + int (*xCurrentTime)(sqlite3_vfs*, double*); + /* New fields may be appended in figure versions. The iVersion + ** value will increment whenever this happens. */ +}; + +/* +** CAPI3REF: Flags for the xAccess VFS method +** +** These integer constants can be used as the third parameter to +** the xAccess method of an [sqlite3_vfs] object. They determine +** the kind of what kind of permissions the xAccess method is +** looking for. With SQLITE_ACCESS_EXISTS, the xAccess method +** simply checks to see if the file exists. With SQLITE_ACCESS_READWRITE, +** the xAccess method checks to see if the file is both readable +** and writable. With SQLITE_ACCESS_READ the xAccess method +** checks to see if the file is readable. +*/ +#define SQLITE_ACCESS_EXISTS 0 +#define SQLITE_ACCESS_READWRITE 1 +#define SQLITE_ACCESS_READ 2 + +/* +** CAPI3REF: Enable Or Disable Extended Result Codes +** +** This routine enables or disables the +** [SQLITE_IOERR_READ | extended result codes] feature. +** By default, SQLite API routines return one of only 26 integer +** [SQLITE_OK | result codes]. When extended result codes +** are enabled by this routine, the repetoire of result codes can be +** much larger and can (hopefully) provide more detailed information +** about the cause of an error. +** +** The second argument is a boolean value that turns extended result +** codes on and off. Extended result codes are off by default for +** backwards compatibility with older versions of SQLite. +*/ +int sqlite3_extended_result_codes(sqlite3*, int onoff); + +/* +** CAPI3REF: Last Insert Rowid +** +** Each entry in an SQLite table has a unique 64-bit signed integer key +** called the "rowid". The rowid is always available as an undeclared +** column named ROWID, OID, or _ROWID_. If the table has a column of +** type INTEGER PRIMARY KEY then that column is another an alias for the +** rowid. +** +** This routine returns the rowid of the most recent successful INSERT into +** the database from the database connection given in the first +** argument. If no successful inserts have ever occurred on this database +** connection, zero is returned. +** +** If an INSERT occurs within a trigger, then the rowid of the +** inserted row is returned by this routine as long as the trigger +** is running. But once the trigger terminates, the value returned +** by this routine reverts to the last value inserted before the +** trigger fired. +** +** An INSERT that fails due to a constraint violation is not a +** successful insert and does not change the value returned by this +** routine. Thus INSERT OR FAIL, INSERT OR IGNORE, INSERT OR ROLLBACK, +** and INSERT OR ABORT make no changes to the return value of this +** routine when their insertion fails. When INSERT OR REPLACE +** encounters a constraint violation, it does not fail. The +** INSERT continues to completion after deleting rows that caused +** the constraint problem so INSERT OR REPLACE will always change +** the return value of this interface. +** +** If another thread does a new insert on the same database connection +** while this routine is running and thus changes the last insert rowid, +** then the return value of this routine is undefined. +*/ +sqlite3_int64 sqlite3_last_insert_rowid(sqlite3*); + +/* +** CAPI3REF: Count The Number Of Rows Modified +** +** This function returns the number of database rows that were changed +** (or inserted or deleted) by the most recent SQL statement. Only +** changes that are directly specified by the INSERT, UPDATE, or +** DELETE statement are counted. Auxiliary changes caused by +** triggers are not counted. Use the [sqlite3_total_changes()] function +** to find the total number of changes including changes caused by triggers. +** +** Within the body of a trigger, the sqlite3_changes() interface can be +** called to find the number of +** changes in the most recently completed INSERT, UPDATE, or DELETE +** statement within the body of the trigger. +** +** All changes are counted, even if they were later undone by a +** ROLLBACK or ABORT. Except, changes associated with creating and +** dropping tables are not counted. +** +** If a callback invokes [sqlite3_exec()] or [sqlite3_step()] recursively, +** then the changes in the inner, recursive call are counted together +** with the changes in the outer call. +** +** SQLite implements the command "DELETE FROM table" without a WHERE clause +** by dropping and recreating the table. (This is much faster than going +** through and deleting individual elements from the table.) Because of +** this optimization, the change count for "DELETE FROM table" will be +** zero regardless of the number of elements that were originally in the +** table. To get an accurate count of the number of rows deleted, use +** "DELETE FROM table WHERE 1" instead. +** +** If another thread makes changes on the same database connection +** while this routine is running then the return value of this routine +** is undefined. +*/ +int sqlite3_changes(sqlite3*); + +/* +** CAPI3REF: Total Number Of Rows Modified +*** +** This function returns the number of database rows that have been +** modified by INSERT, UPDATE or DELETE statements since the database handle +** was opened. This includes UPDATE, INSERT and DELETE statements executed +** as part of trigger programs. All changes are counted as soon as the +** statement that makes them is completed (when the statement handle is +** passed to [sqlite3_reset()] or [sqlite3_finalize()]). +** +** See also the [sqlite3_change()] interface. +** +** SQLite implements the command "DELETE FROM table" without a WHERE clause +** by dropping and recreating the table. (This is much faster than going +** through and deleting individual elements form the table.) Because of +** this optimization, the change count for "DELETE FROM table" will be +** zero regardless of the number of elements that were originally in the +** table. To get an accurate count of the number of rows deleted, use +** "DELETE FROM table WHERE 1" instead. +** +** If another thread makes changes on the same database connection +** while this routine is running then the return value of this routine +** is undefined. +*/ +int sqlite3_total_changes(sqlite3*); + +/* +** CAPI3REF: Interrupt A Long-Running Query +** +** This function causes any pending database operation to abort and +** return at its earliest opportunity. This routine is typically +** called in response to a user action such as pressing "Cancel" +** or Ctrl-C where the user wants a long query operation to halt +** immediately. +** +** It is safe to call this routine from a thread different from the +** thread that is currently running the database operation. But it +** is not safe to call this routine with a database connection that +** is closed or might close before sqlite3_interrupt() returns. +** +** The SQL operation that is interrupted will return [SQLITE_INTERRUPT]. +** If an interrupted operation was an update that is inside an +** explicit transaction, then the entire transaction will be rolled +** back automatically. +*/ +void sqlite3_interrupt(sqlite3*); + +/* +** CAPI3REF: Determine If An SQL Statement Is Complete +** +** These functions return true if the given input string comprises +** one or more complete SQL statements. For the sqlite3_complete() call, +** the parameter must be a nul-terminated UTF-8 string. For +** sqlite3_complete16(), a nul-terminated machine byte order UTF-16 string +** is required. +** +** These routines are useful for command-line input to determine if the +** currently entered text forms one or more complete SQL statements or +** if additional input is needed before sending the statements into +** SQLite for parsing. The algorithm is simple. If the +** last token other than spaces and comments is a semicolon, then return +** true. Actually, the algorithm is a little more complicated than that +** in order to deal with triggers, but the basic idea is the same: the +** statement is not complete unless it ends in a semicolon. +*/ +int sqlite3_complete(const char *sql); +int sqlite3_complete16(const void *sql); + +/* +** CAPI3REF: Register A Callback To Handle SQLITE_BUSY Errors +** +** This routine identifies a callback function that might be invoked +** whenever an attempt is made to open a database table +** that another thread or process has locked. +** If the busy callback is NULL, then [SQLITE_BUSY] +** (or sometimes [SQLITE_IOERR_BLOCKED]) +** is returned immediately upon encountering the lock. +** If the busy callback is not NULL, then the +** callback will be invoked with two arguments. The +** first argument to the handler is a copy of the void* pointer which +** is the third argument to this routine. The second argument to +** the handler is the number of times that the busy handler has +** been invoked for this locking event. If the +** busy callback returns 0, then no additional attempts are made to +** access the database and [SQLITE_BUSY] or [SQLITE_IOERR_BLOCKED] is returned. +** If the callback returns non-zero, then another attempt is made to open the +** database for reading and the cycle repeats. +** +** The presence of a busy handler does not guarantee that +** it will be invoked when there is lock contention. +** If SQLite determines that invoking the busy handler could result in +** a deadlock, it will return [SQLITE_BUSY] instead. +** Consider a scenario where one process is holding a read lock that +** it is trying to promote to a reserved lock and +** a second process is holding a reserved lock that it is trying +** to promote to an exclusive lock. The first process cannot proceed +** because it is blocked by the second and the second process cannot +** proceed because it is blocked by the first. If both processes +** invoke the busy handlers, neither will make any progress. Therefore, +** SQLite returns [SQLITE_BUSY] for the first process, hoping that this +** will induce the first process to release its read lock and allow +** the second process to proceed. +** +** The default busy callback is NULL. +** +** The [SQLITE_BUSY] error is converted to [SQLITE_IOERR_BLOCKED] when +** SQLite is in the middle of a large transaction where all the +** changes will not fit into the in-memory cache. SQLite will +** already hold a RESERVED lock on the database file, but it needs +** to promote this lock to EXCLUSIVE so that it can spill cache +** pages into the database file without harm to concurrent +** readers. If it is unable to promote the lock, then the in-memory +** cache will be left in an inconsistent state and so the error +** code is promoted from the relatively benign [SQLITE_BUSY] to +** the more severe [SQLITE_IOERR_BLOCKED]. This error code promotion +** forces an automatic rollback of the changes. See the +** <a href="http://www.sqlite.org/cvstrac/wiki?p=CorruptionFollowingBusyError"> +** CorruptionFollowingBusyError</a> wiki page for a discussion of why +** this is important. +** +** Sqlite is re-entrant, so the busy handler may start a new query. +** (It is not clear why anyone would every want to do this, but it +** is allowed, in theory.) But the busy handler may not close the +** database. Closing the database from a busy handler will delete +** data structures out from under the executing query and will +** probably result in a segmentation fault or other runtime error. +** +** There can only be a single busy handler defined for each database +** connection. Setting a new busy handler clears any previous one. +** Note that calling [sqlite3_busy_timeout()] will also set or clear +** the busy handler. +** +** When operating in [sqlite3_enable_shared_cache | shared cache mode], +** only a single busy handler can be defined for each database file. +** So if two database connections share a single cache, then changing +** the busy handler on one connection will also change the busy +** handler in the other connection. The busy handler is invoked +** in the thread that was running when the SQLITE_BUSY was hit. +*/ +int sqlite3_busy_handler(sqlite3*, int(*)(void*,int), void*); + +/* +** CAPI3REF: Set A Busy Timeout +** +** This routine sets a busy handler that sleeps for a while when a +** table is locked. The handler will sleep multiple times until +** at least "ms" milliseconds of sleeping have been done. After +** "ms" milliseconds of sleeping, the handler returns 0 which +** causes [sqlite3_step()] to return [SQLITE_BUSY] or [SQLITE_IOERR_BLOCKED]. +** +** Calling this routine with an argument less than or equal to zero +** turns off all busy handlers. +** +** There can only be a single busy handler for a particular database +** connection. If another busy handler was defined +** (using [sqlite3_busy_handler()]) prior to calling +** this routine, that other busy handler is cleared. +*/ +int sqlite3_busy_timeout(sqlite3*, int ms); + +/* +** CAPI3REF: Convenience Routines For Running Queries +** +** This next routine is a convenience wrapper around [sqlite3_exec()]. +** Instead of invoking a user-supplied callback for each row of the +** result, this routine remembers each row of the result in memory +** obtained from [sqlite3_malloc()], then returns all of the result after the +** query has finished. +** +** As an example, suppose the query result where this table: +** +** <blockquote><pre> +** Name | Age +** ----------------------- +** Alice | 43 +** Bob | 28 +** Cindy | 21 +** </pre></blockquote> +** +** If the 3rd argument were &azResult then after the function returns +** azResult will contain the following data: +** +** <blockquote><pre> +** azResult[0] = "Name"; +** azResult[1] = "Age"; +** azResult[2] = "Alice"; +** azResult[3] = "43"; +** azResult[4] = "Bob"; +** azResult[5] = "28"; +** azResult[6] = "Cindy"; +** azResult[7] = "21"; +** </pre></blockquote> +** +** Notice that there is an extra row of data containing the column +** headers. But the *nrow return value is still 3. *ncolumn is +** set to 2. In general, the number of values inserted into azResult +** will be ((*nrow) + 1)*(*ncolumn). +** +** After the calling function has finished using the result, it should +** pass the result data pointer to sqlite3_free_table() in order to +** release the memory that was malloc-ed. Because of the way the +** [sqlite3_malloc()] happens, the calling function must not try to call +** [sqlite3_free()] directly. Only [sqlite3_free_table()] is able to release +** the memory properly and safely. +** +** The return value of this routine is the same as from [sqlite3_exec()]. +*/ +int sqlite3_get_table( + sqlite3*, /* An open database */ + const char *sql, /* SQL to be executed */ + char ***resultp, /* Result written to a char *[] that this points to */ + int *nrow, /* Number of result rows written here */ + int *ncolumn, /* Number of result columns written here */ + char **errmsg /* Error msg written here */ +); +void sqlite3_free_table(char **result); + +/* +** CAPI3REF: Formatted String Printing Functions +** +** These routines are workalikes of the "printf()" family of functions +** from the standard C library. +** +** The sqlite3_mprintf() and sqlite3_vmprintf() routines write their +** results into memory obtained from [sqlite3_malloc()]. +** The strings returned by these two routines should be +** released by [sqlite3_free()]. Both routines return a +** NULL pointer if [sqlite3_malloc()] is unable to allocate enough +** memory to hold the resulting string. +** +** In sqlite3_snprintf() routine is similar to "snprintf()" from +** the standard C library. The result is written into the +** buffer supplied as the second parameter whose size is given by +** the first parameter. Note that the order of the +** first two parameters is reversed from snprintf(). This is an +** historical accident that cannot be fixed without breaking +** backwards compatibility. Note also that sqlite3_snprintf() +** returns a pointer to its buffer instead of the number of +** characters actually written into the buffer. We admit that +** the number of characters written would be a more useful return +** value but we cannot change the implementation of sqlite3_snprintf() +** now without breaking compatibility. +** +** As long as the buffer size is greater than zero, sqlite3_snprintf() +** guarantees that the buffer is always zero-terminated. The first +** parameter "n" is the total size of the buffer, including space for +** the zero terminator. So the longest string that can be completely +** written will be n-1 characters. +** +** These routines all implement some additional formatting +** options that are useful for constructing SQL statements. +** All of the usual printf formatting options apply. In addition, there +** is are "%q", "%Q", and "%z" options. +** +** The %q option works like %s in that it substitutes a null-terminated +** string from the argument list. But %q also doubles every '\'' character. +** %q is designed for use inside a string literal. By doubling each '\'' +** character it escapes that character and allows it to be inserted into +** the string. +** +** For example, so some string variable contains text as follows: +** +** <blockquote><pre> +** char *zText = "It's a happy day!"; +** </pre></blockquote> +** +** One can use this text in an SQL statement as follows: +** +** <blockquote><pre> +** char *zSQL = sqlite3_mprintf("INSERT INTO table VALUES('%q')", zText); +** sqlite3_exec(db, zSQL, 0, 0, 0); +** sqlite3_free(zSQL); +** </pre></blockquote> +** +** Because the %q format string is used, the '\'' character in zText +** is escaped and the SQL generated is as follows: +** +** <blockquote><pre> +** INSERT INTO table1 VALUES('It''s a happy day!') +** </pre></blockquote> +** +** This is correct. Had we used %s instead of %q, the generated SQL +** would have looked like this: +** +** <blockquote><pre> +** INSERT INTO table1 VALUES('It's a happy day!'); +** </pre></blockquote> +** +** This second example is an SQL syntax error. As a general rule you +** should always use %q instead of %s when inserting text into a string +** literal. +** +** The %Q option works like %q except it also adds single quotes around +** the outside of the total string. Or if the parameter in the argument +** list is a NULL pointer, %Q substitutes the text "NULL" (without single +** quotes) in place of the %Q option. So, for example, one could say: +** +** <blockquote><pre> +** char *zSQL = sqlite3_mprintf("INSERT INTO table VALUES(%Q)", zText); +** sqlite3_exec(db, zSQL, 0, 0, 0); +** sqlite3_free(zSQL); +** </pre></blockquote> +** +** The code above will render a correct SQL statement in the zSQL +** variable even if the zText variable is a NULL pointer. +** +** The "%z" formatting option works exactly like "%s" with the +** addition that after the string has been read and copied into +** the result, [sqlite3_free()] is called on the input string. +*/ +char *sqlite3_mprintf(const char*,...); +char *sqlite3_vmprintf(const char*, va_list); +char *sqlite3_snprintf(int,char*,const char*, ...); + +/* +** CAPI3REF: Memory Allocation Subsystem +** +** The SQLite core uses these three routines for all of its own +** internal memory allocation needs. (See the exception below.) +** +** The default implementation +** of the memory allocation subsystem uses the malloc(), realloc() +** and free() provided by the standard C library. However, if +** SQLite is compiled with the following C preprocessor macro +** +** <blockquote> SQLITE_MEMORY_SIZE=<i>NNN</i> </blockquote> +** +** where <i>NNN</i> is an integer, then SQLite create a static +** array of at least <i>NNN</i> bytes in size and use that array +** for all of its dynamic memory allocation needs. +** +** In SQLite version 3.5.0 and 3.5.1, it was possible to define +** the SQLITE_OMIT_MEMORY_ALLOCATION which would cause the built-in +** implementation of these routines to be omitted. That capability +** is no longer provided. Only built-in memory allocators can be +** used. +** +** <b>Exception:</b> The windows OS interface layer calls +** the system malloc() and free() directly when converting +** filenames between the UTF-8 encoding used by SQLite +** and whatever filename encoding is used by the particular windows +** installation. Memory allocation errors are detected, but +** they are reported back as [SQLITE_CANTOPEN] or +** [SQLITE_IOERR] rather than [SQLITE_NOMEM]. +*/ +void *sqlite3_malloc(int); +void *sqlite3_realloc(void*, int); +void sqlite3_free(void*); + +/* +** CAPI3REF: Memory Allocator Statistics +** +** In addition to the basic three allocation routines +** [sqlite3_malloc()], [sqlite3_free()], and [sqlite3_realloc()], +** the memory allocation subsystem included with the SQLite +** sources provides the interfaces shown below. +** +** The first of these two routines returns the amount of memory +** currently outstanding (malloced but not freed). The second +** returns the largest instantaneous amount of outstanding +** memory. The highwater mark is reset if the argument is +** true. +** +** The value returned may or may not include allocation +** overhead, depending on which built-in memory allocator +** implementation is used. +*/ +sqlite3_int64 sqlite3_memory_used(void); +sqlite3_int64 sqlite3_memory_highwater(int resetFlag); + +/* +** CAPI3REF: Compile-Time Authorization Callbacks +*** +** This routine registers a authorizer callback with the SQLite library. +** The authorizer callback is invoked as SQL statements are being compiled +** by [sqlite3_prepare()] or its variants [sqlite3_prepare_v2()], +** [sqlite3_prepare16()] and [sqlite3_prepare16_v2()]. At various +** points during the compilation process, as logic is being created +** to perform various actions, the authorizer callback is invoked to +** see if those actions are allowed. The authorizer callback should +** return SQLITE_OK to allow the action, [SQLITE_IGNORE] to disallow the +** specific action but allow the SQL statement to continue to be +** compiled, or [SQLITE_DENY] to cause the entire SQL statement to be +** rejected with an error. +** +** Depending on the action, the [SQLITE_IGNORE] and [SQLITE_DENY] return +** codes might mean something different or they might mean the same +** thing. If the action is, for example, to perform a delete opertion, +** then [SQLITE_IGNORE] and [SQLITE_DENY] both cause the statement compilation +** to fail with an error. But if the action is to read a specific column +** from a specific table, then [SQLITE_DENY] will cause the entire +** statement to fail but [SQLITE_IGNORE] will cause a NULL value to be +** read instead of the actual column value. +** +** The first parameter to the authorizer callback is a copy of +** the third parameter to the sqlite3_set_authorizer() interface. +** The second parameter to the callback is an integer +** [SQLITE_COPY | action code] that specifies the particular action +** to be authorized. The available action codes are +** [SQLITE_COPY | documented separately]. The third through sixth +** parameters to the callback are strings that contain additional +** details about the action to be authorized. +** +** An authorizer is used when preparing SQL statements from an untrusted +** source, to ensure that the SQL statements do not try to access data +** that they are not allowed to see, or that they do not try to +** execute malicious statements that damage the database. For +** example, an application may allow a user to enter arbitrary +** SQL queries for evaluation by a database. But the application does +** not want the user to be able to make arbitrary changes to the +** database. An authorizer could then be put in place while the +** user-entered SQL is being prepared that disallows everything +** except SELECT statements. +** +** Only a single authorizer can be in place on a database connection +** at a time. Each call to sqlite3_set_authorizer overrides the +** previous call. A NULL authorizer means that no authorization +** callback is invoked. The default authorizer is NULL. +** +** Note that the authorizer callback is invoked only during +** [sqlite3_prepare()] or its variants. Authorization is not +** performed during statement evaluation in [sqlite3_step()]. +*/ +int sqlite3_set_authorizer( + sqlite3*, + int (*xAuth)(void*,int,const char*,const char*,const char*,const char*), + void *pUserData +); + +/* +** CAPI3REF: Authorizer Return Codes +** +** The [sqlite3_set_authorizer | authorizer callback function] must +** return either [SQLITE_OK] or one of these two constants in order +** to signal SQLite whether or not the action is permitted. See the +** [sqlite3_set_authorizer | authorizer documentation] for additional +** information. +*/ +#define SQLITE_DENY 1 /* Abort the SQL statement with an error */ +#define SQLITE_IGNORE 2 /* Don't allow access, but don't generate an error */ + +/* +** CAPI3REF: Authorizer Action Codes +** +** The [sqlite3_set_authorizer()] interface registers a callback function +** that is invoked to authorizer certain SQL statement actions. The +** second parameter to the callback is an integer code that specifies +** what action is being authorized. These are the integer action codes that +** the authorizer callback may be passed. +** +** These action code values signify what kind of operation is to be +** authorized. The 3rd and 4th parameters to the authorization callback +** function will be parameters or NULL depending on which of these +** codes is used as the second parameter. The 5th parameter to the +** authorizer callback is the name of the database ("main", "temp", +** etc.) if applicable. The 6th parameter to the authorizer callback +** is the name of the inner-most trigger or view that is responsible for +** the access attempt or NULL if this access attempt is directly from +** top-level SQL code. +*/ +/******************************************* 3rd ************ 4th ***********/ +#define SQLITE_CREATE_INDEX 1 /* Index Name Table Name */ +#define SQLITE_CREATE_TABLE 2 /* Table Name NULL */ +#define SQLITE_CREATE_TEMP_INDEX 3 /* Index Name Table Name */ +#define SQLITE_CREATE_TEMP_TABLE 4 /* Table Name NULL */ +#define SQLITE_CREATE_TEMP_TRIGGER 5 /* Trigger Name Table Name */ +#define SQLITE_CREATE_TEMP_VIEW 6 /* View Name NULL */ +#define SQLITE_CREATE_TRIGGER 7 /* Trigger Name Table Name */ +#define SQLITE_CREATE_VIEW 8 /* View Name NULL */ +#define SQLITE_DELETE 9 /* Table Name NULL */ +#define SQLITE_DROP_INDEX 10 /* Index Name Table Name */ +#define SQLITE_DROP_TABLE 11 /* Table Name NULL */ +#define SQLITE_DROP_TEMP_INDEX 12 /* Index Name Table Name */ +#define SQLITE_DROP_TEMP_TABLE 13 /* Table Name NULL */ +#define SQLITE_DROP_TEMP_TRIGGER 14 /* Trigger Name Table Name */ +#define SQLITE_DROP_TEMP_VIEW 15 /* View Name NULL */ +#define SQLITE_DROP_TRIGGER 16 /* Trigger Name Table Name */ +#define SQLITE_DROP_VIEW 17 /* View Name NULL */ +#define SQLITE_INSERT 18 /* Table Name NULL */ +#define SQLITE_PRAGMA 19 /* Pragma Name 1st arg or NULL */ +#define SQLITE_READ 20 /* Table Name Column Name */ +#define SQLITE_SELECT 21 /* NULL NULL */ +#define SQLITE_TRANSACTION 22 /* NULL NULL */ +#define SQLITE_UPDATE 23 /* Table Name Column Name */ +#define SQLITE_ATTACH 24 /* Filename NULL */ +#define SQLITE_DETACH 25 /* Database Name NULL */ +#define SQLITE_ALTER_TABLE 26 /* Database Name Table Name */ +#define SQLITE_REINDEX 27 /* Index Name NULL */ +#define SQLITE_ANALYZE 28 /* Table Name NULL */ +#define SQLITE_CREATE_VTABLE 29 /* Table Name Module Name */ +#define SQLITE_DROP_VTABLE 30 /* Table Name Module Name */ +#define SQLITE_FUNCTION 31 /* Function Name NULL */ +#define SQLITE_COPY 0 /* No longer used */ + +/* +** CAPI3REF: Tracing And Profiling Functions +** +** These routines register callback functions that can be used for +** tracing and profiling the execution of SQL statements. +** The callback function registered by sqlite3_trace() is invoked +** at the first [sqlite3_step()] for the evaluation of an SQL statement. +** The callback function registered by sqlite3_profile() is invoked +** as each SQL statement finishes and includes +** information on how long that statement ran. +** +** The sqlite3_profile() API is currently considered experimental and +** is subject to change. +*/ +void *sqlite3_trace(sqlite3*, void(*xTrace)(void*,const char*), void*); +void *sqlite3_profile(sqlite3*, + void(*xProfile)(void*,const char*,sqlite3_uint64), void*); + +/* +** CAPI3REF: Query Progress Callbacks +** +** This routine configures a callback function - the progress callback - that +** is invoked periodically during long running calls to [sqlite3_exec()], +** [sqlite3_step()] and [sqlite3_get_table()]. An example use for this +** interface is to keep a GUI updated during a large query. +** +** The progress callback is invoked once for every N virtual machine opcodes, +** where N is the second argument to this function. The progress callback +** itself is identified by the third argument to this function. The fourth +** argument to this function is a void pointer passed to the progress callback +** function each time it is invoked. +** +** If a call to [sqlite3_exec()], [sqlite3_step()], or [sqlite3_get_table()] +** results in fewer than N opcodes being executed, then the progress +** callback is never invoked. +** +** Only a single progress callback function may be registered for each +** open database connection. Every call to sqlite3_progress_handler() +** overwrites the results of the previous call. +** To remove the progress callback altogether, pass NULL as the third +** argument to this function. +** +** If the progress callback returns a result other than 0, then the current +** query is immediately terminated and any database changes rolled back. +** The containing [sqlite3_exec()], [sqlite3_step()], or +** [sqlite3_get_table()] call returns SQLITE_INTERRUPT. This feature +** can be used, for example, to implement the "Cancel" button on a +** progress dialog box in a GUI. +*/ +void sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*); + +/* +** CAPI3REF: Opening A New Database Connection +** +** Open the sqlite database file "filename". The "filename" is UTF-8 +** encoded for [sqlite3_open()] and [sqlite3_open_v2()] and UTF-16 encoded +** in the native byte order for [sqlite3_open16()]. +** An [sqlite3*] handle is returned in *ppDb, even +** if an error occurs. If the database is opened (or created) successfully, +** then [SQLITE_OK] is returned. Otherwise an error code is returned. The +** [sqlite3_errmsg()] or [sqlite3_errmsg16()] routines can be used to obtain +** an English language description of the error. +** +** The default encoding for the database will be UTF-8 if +** [sqlite3_open()] or [sqlite3_open_v2()] is called and +** UTF-16 if [sqlite3_open16()] is used. +** +** Whether or not an error occurs when it is opened, resources associated +** with the [sqlite3*] handle should be released by passing it to +** [sqlite3_close()] when it is no longer required. +** +** The [sqlite3_open_v2()] interface works like [sqlite3_open()] except that +** provides two additional parameters for additional control over the +** new database connection. The flags parameter can be one of: +** +** <ol> +** <li> [SQLITE_OPEN_READONLY] +** <li> [SQLITE_OPEN_READWRITE] +** <li> [SQLITE_OPEN_READWRITE] | [SQLITE_OPEN_CREATE] +** </ol> +** +** The first value opens the database read-only. If the database does +** not previously exist, an error is returned. The second option opens +** the database for reading and writing if possible, or reading only if +** if the file is write protected. In either case the database must already +** exist or an error is returned. The third option opens the database +** for reading and writing and creates it if it does not already exist. +** The third options is behavior that is always used for [sqlite3_open()] +** and [sqlite3_open16()]. +** +** If the filename is ":memory:", then an private +** in-memory database is created for the connection. This in-memory +** database will vanish when the database connection is closed. Future +** version of SQLite might make use of additional special filenames +** that begin with the ":" character. It is recommended that +** when a database filename really does begin with +** ":" that you prefix the filename with a pathname like "./" to +** avoid ambiguity. +** +** If the filename is an empty string, then a private temporary +** on-disk database will be created. This private database will be +** automatically deleted as soon as the database connection is closed. +** +** The fourth parameter to sqlite3_open_v2() is the name of the +** [sqlite3_vfs] object that defines the operating system +** interface that the new database connection should use. If the +** fourth parameter is a NULL pointer then the default [sqlite3_vfs] +** object is used. +** +** <b>Note to windows users:</b> The encoding used for the filename argument +** of [sqlite3_open()] and [sqlite3_open_v2()] must be UTF-8, not whatever +** codepage is currently defined. Filenames containing international +** characters must be converted to UTF-8 prior to passing them into +** [sqlite3_open()] or [sqlite3_open_v2()]. +*/ +int sqlite3_open( + const char *filename, /* Database filename (UTF-8) */ + sqlite3 **ppDb /* OUT: SQLite db handle */ +); +int sqlite3_open16( + const void *filename, /* Database filename (UTF-16) */ + sqlite3 **ppDb /* OUT: SQLite db handle */ +); +int sqlite3_open_v2( + const char *filename, /* Database filename (UTF-8) */ + sqlite3 **ppDb, /* OUT: SQLite db handle */ + int flags, /* Flags */ + const char *zVfs /* Name of VFS module to use */ +); + +/* +** CAPI3REF: Error Codes And Messages +** +** The sqlite3_errcode() interface returns the numeric +** [SQLITE_OK | result code] or [SQLITE_IOERR_READ | extended result code] +** for the most recent failed sqlite3_* API call associated +** with [sqlite3] handle 'db'. If a prior API call failed but the +** most recent API call succeeded, the return value from sqlite3_errcode() +** is undefined. +** +** The sqlite3_errmsg() and sqlite3_errmsg16() return English-language +** text that describes the error, as either UTF8 or UTF16 respectively. +** Memory to hold the error message string is managed internally. The +** string may be overwritten or deallocated by subsequent calls to SQLite +** interface functions. +** +** Calls to many sqlite3_* functions set the error code and string returned +** by [sqlite3_errcode()], [sqlite3_errmsg()], and [sqlite3_errmsg16()] +** (overwriting the previous values). Note that calls to [sqlite3_errcode()], +** [sqlite3_errmsg()], and [sqlite3_errmsg16()] themselves do not affect the +** results of future invocations. Calls to API routines that do not return +** an error code (example: [sqlite3_data_count()]) do not +** change the error code returned by this routine. Interfaces that are +** not associated with a specific database connection (examples: +** [sqlite3_mprintf()] or [sqlite3_enable_shared_cache()] do not change +** the return code. +** +** Assuming no other intervening sqlite3_* API calls are made, the error +** code returned by this function is associated with the same error as +** the strings returned by [sqlite3_errmsg()] and [sqlite3_errmsg16()]. +*/ +int sqlite3_errcode(sqlite3 *db); +const char *sqlite3_errmsg(sqlite3*); +const void *sqlite3_errmsg16(sqlite3*); + +/* +** CAPI3REF: SQL Statement Object +** +** Instance of this object represent single SQL statements. This +** is variously known as a "prepared statement" or a +** "compiled SQL statement" or simply as a "statement". +** +** The life of a statement object goes something like this: +** +** <ol> +** <li> Create the object using [sqlite3_prepare_v2()] or a related +** function. +** <li> Bind values to host parameters using +** [sqlite3_bind_blob | sqlite3_bind_* interfaces]. +** <li> Run the SQL by calling [sqlite3_step()] one or more times. +** <li> Reset the statement using [sqlite3_reset()] then go back +** to step 2. Do this zero or more times. +** <li> Destroy the object using [sqlite3_finalize()]. +** </ol> +** +** Refer to documentation on individual methods above for additional +** information. +*/ +typedef struct sqlite3_stmt sqlite3_stmt; + +/* +** CAPI3REF: Compiling An SQL Statement +** +** To execute an SQL query, it must first be compiled into a byte-code +** program using one of these routines. +** +** The first argument "db" is an [sqlite3 | SQLite database handle] +** obtained from a prior call to [sqlite3_open()], [sqlite3_open_v2()] +** or [sqlite3_open16()]. +** The second argument "zSql" is the statement to be compiled, encoded +** as either UTF-8 or UTF-16. The sqlite3_prepare() and sqlite3_prepare_v2() +** interfaces uses UTF-8 and sqlite3_prepare16() and sqlite3_prepare16_v2() +** use UTF-16. +** +** If the nByte argument is less +** than zero, then zSql is read up to the first zero terminator. If +** nByte is non-negative, then it is the maximum number of +** bytes read from zSql. When nByte is non-negative, the +** zSql string ends at either the first '\000' character or +** until the nByte-th byte, whichever comes first. +** +** *pzTail is made to point to the first byte past the end of the first +** SQL statement in zSql. This routine only compiles the first statement +** in zSql, so *pzTail is left pointing to what remains uncompiled. +** +** *ppStmt is left pointing to a compiled +** [sqlite3_stmt | SQL statement structure] that can be +** executed using [sqlite3_step()]. Or if there is an error, *ppStmt may be +** set to NULL. If the input text contained no SQL (if the input is and +** empty string or a comment) then *ppStmt is set to NULL. The calling +** procedure is responsible for deleting the compiled SQL statement +** using [sqlite3_finalize()] after it has finished with it. +** +** On success, [SQLITE_OK] is returned. Otherwise an +** [SQLITE_ERROR | error code] is returned. +** +** The sqlite3_prepare_v2() and sqlite3_prepare16_v2() interfaces are +** recommended for all new programs. The two older interfaces are retained +** for backwards compatibility, but their use is discouraged. +** In the "v2" interfaces, the prepared statement +** that is returned (the [sqlite3_stmt] object) contains a copy of the +** original SQL text. This causes the [sqlite3_step()] interface to +** behave a differently in two ways: +** +** <ol> +** <li> +** If the database schema changes, instead of returning [SQLITE_SCHEMA] as it +** always used to do, [sqlite3_step()] will automatically recompile the SQL +** statement and try to run it again. If the schema has changed in a way +** that makes the statement no longer valid, [sqlite3_step()] will still +** return [SQLITE_SCHEMA]. But unlike the legacy behavior, [SQLITE_SCHEMA] is +** now a fatal error. Calling [sqlite3_prepare_v2()] again will not make the +** error go away. Note: use [sqlite3_errmsg()] to find the text of the parsing +** error that results in an [SQLITE_SCHEMA] return. +** </li> +** +** <li> +** When an error occurs, +** [sqlite3_step()] will return one of the detailed +** [SQLITE_ERROR | result codes] or +** [SQLITE_IOERR_READ | extended result codes] such as directly. +** The legacy behavior was that [sqlite3_step()] would only return a generic +** [SQLITE_ERROR] result code and you would have to make a second call to +** [sqlite3_reset()] in order to find the underlying cause of the problem. +** With the "v2" prepare interfaces, the underlying reason for the error is +** returned immediately. +** </li> +** </ol> +*/ +int sqlite3_prepare( + sqlite3 *db, /* Database handle */ + const char *zSql, /* SQL statement, UTF-8 encoded */ + int nByte, /* Maximum length of zSql in bytes. */ + sqlite3_stmt **ppStmt, /* OUT: Statement handle */ + const char **pzTail /* OUT: Pointer to unused portion of zSql */ +); +int sqlite3_prepare_v2( + sqlite3 *db, /* Database handle */ + const char *zSql, /* SQL statement, UTF-8 encoded */ + int nByte, /* Maximum length of zSql in bytes. */ + sqlite3_stmt **ppStmt, /* OUT: Statement handle */ + const char **pzTail /* OUT: Pointer to unused portion of zSql */ +); +int sqlite3_prepare16( + sqlite3 *db, /* Database handle */ + const void *zSql, /* SQL statement, UTF-16 encoded */ + int nByte, /* Maximum length of zSql in bytes. */ + sqlite3_stmt **ppStmt, /* OUT: Statement handle */ + const void **pzTail /* OUT: Pointer to unused portion of zSql */ +); +int sqlite3_prepare16_v2( + sqlite3 *db, /* Database handle */ + const void *zSql, /* SQL statement, UTF-16 encoded */ + int nByte, /* Maximum length of zSql in bytes. */ + sqlite3_stmt **ppStmt, /* OUT: Statement handle */ + const void **pzTail /* OUT: Pointer to unused portion of zSql */ +); + +/* +** Retrieve the original SQL statement associated with a compiled statement +** in UTF-8 encoding. +** +** If the compiled SQL statement passed as an argument was compiled using +** either sqlite3_prepare_v2 or sqlite3_prepare16_v2, then this function +** returns a pointer to a nul-terminated string containing a copy of +** the original SQL statement. The pointer is valid until the statement +** is deleted using sqlite3_finalize(). +** +** If the statement was compiled using either of the legacy interfaces +** sqlite3_prepare() or sqlite3_prepare16(), this function returns NULL. +** +****** EXPERIMENTAL - subject to change without notice ************** +*/ +const char *sqlite3_sql(sqlite3_stmt *pStmt); + +/* +** CAPI3REF: Dynamically Typed Value Object +** +** SQLite uses dynamic typing for the values it stores. Values can +** be integers, floating point values, strings, BLOBs, or NULL. When +** passing around values internally, each value is represented as +** an instance of the sqlite3_value object. +*/ +typedef struct Mem sqlite3_value; + +/* +** CAPI3REF: SQL Function Context Object +** +** The context in which an SQL function executes is stored in an +** sqlite3_context object. A pointer to such an object is the +** first parameter to user-defined SQL functions. +*/ +typedef struct sqlite3_context sqlite3_context; + +/* +** CAPI3REF: Binding Values To Prepared Statements +** +** In the SQL strings input to [sqlite3_prepare_v2()] and its variants, +** one or more literals can be replace by a parameter in one of these +** forms: +** +** <ul> +** <li> ? +** <li> ?NNN +** <li> :AAA +** <li> @AAA +** <li> $VVV +** </ul> +** +** In the parameter forms shown above NNN is an integer literal, +** AAA is an alphanumeric identifier and VVV is a variable name according +** to the syntax rules of the TCL programming language. +** The values of these parameters (also called "host parameter names") +** can be set using the sqlite3_bind_*() routines defined here. +** +** The first argument to the sqlite3_bind_*() routines always is a pointer +** to the [sqlite3_stmt] object returned from [sqlite3_prepare_v2()] or +** its variants. The second +** argument is the index of the parameter to be set. The first parameter has +** an index of 1. When the same named parameter is used more than once, second +** and subsequent +** occurrences have the same index as the first occurrence. The index for +** named parameters can be looked up using the +** [sqlite3_bind_parameter_name()] API if desired. The index for "?NNN" +** parametes is the value of NNN. +** The NNN value must be between 1 and the compile-time +** parameter SQLITE_MAX_VARIABLE_NUMBER (default value: 999). +** See <a href="limits.html">limits.html</a> for additional information. +** +** The third argument is the value to bind to the parameter. +** +** In those +** routines that have a fourth argument, its value is the number of bytes +** in the parameter. To be clear: the value is the number of bytes in the +** string, not the number of characters. The number +** of bytes does not include the zero-terminator at the end of strings. +** If the fourth parameter is negative, the length of the string is +** number of bytes up to the first zero terminator. +** +** The fifth argument to sqlite3_bind_blob(), sqlite3_bind_text(), and +** sqlite3_bind_text16() is a destructor used to dispose of the BLOB or +** text after SQLite has finished with it. If the fifth argument is the +** special value [SQLITE_STATIC], then the library assumes that the information +** is in static, unmanaged space and does not need to be freed. If the +** fifth argument has the value [SQLITE_TRANSIENT], then SQLite makes its +** own private copy of the data immediately, before the sqlite3_bind_*() +** routine returns. +** +** The sqlite3_bind_zeroblob() routine binds a BLOB of length n that +** is filled with zeros. A zeroblob uses a fixed amount of memory +** (just an integer to hold it size) while it is being processed. +** Zeroblobs are intended to serve as place-holders for BLOBs whose +** content is later written using +** [sqlite3_blob_open | increment BLOB I/O] routines. A negative +** value for the zeroblob results in a zero-length BLOB. +** +** The sqlite3_bind_*() routines must be called after +** [sqlite3_prepare_v2()] (and its variants) or [sqlite3_reset()] and +** before [sqlite3_step()]. +** Bindings are not cleared by the [sqlite3_reset()] routine. +** Unbound parameters are interpreted as NULL. +** +** These routines return [SQLITE_OK] on success or an error code if +** anything goes wrong. [SQLITE_RANGE] is returned if the parameter +** index is out of range. [SQLITE_NOMEM] is returned if malloc fails. +** [SQLITE_MISUSE] is returned if these routines are called on a virtual +** machine that is the wrong state or which has already been finalized. +*/ +int sqlite3_bind_blob(sqlite3_stmt*, int, const void*, int n, void(*)(void*)); +int sqlite3_bind_double(sqlite3_stmt*, int, double); +int sqlite3_bind_int(sqlite3_stmt*, int, int); +int sqlite3_bind_int64(sqlite3_stmt*, int, sqlite3_int64); +int sqlite3_bind_null(sqlite3_stmt*, int); +int sqlite3_bind_text(sqlite3_stmt*, int, const char*, int n, void(*)(void*)); +int sqlite3_bind_text16(sqlite3_stmt*, int, const void*, int, void(*)(void*)); +int sqlite3_bind_value(sqlite3_stmt*, int, const sqlite3_value*); +int sqlite3_bind_zeroblob(sqlite3_stmt*, int, int n); + +/* +** CAPI3REF: Number Of Host Parameters +** +** Return the largest host parameter index in the precompiled statement given +** as the argument. When the host parameters are of the forms like ":AAA" +** or "?", then they are assigned sequential increasing numbers beginning +** with one, so the value returned is the number of parameters. However +** if the same host parameter name is used multiple times, each occurrance +** is given the same number, so the value returned in that case is the number +** of unique host parameter names. If host parameters of the form "?NNN" +** are used (where NNN is an integer) then there might be gaps in the +** numbering and the value returned by this interface is the index of the +** host parameter with the largest index value. +** +** The prepared statement must not be [sqlite3_finalize | finalized] +** prior to this routine returnning. Otherwise the results are undefined +** and probably undesirable. +*/ +int sqlite3_bind_parameter_count(sqlite3_stmt*); + +/* +** CAPI3REF: Name Of A Host Parameter +** +** This routine returns a pointer to the name of the n-th parameter in a +** [sqlite3_stmt | prepared statement]. +** Host parameters of the form ":AAA" or "@AAA" or "$VVV" have a name +** which is the string ":AAA" or "@AAA" or "$VVV". +** In other words, the initial ":" or "$" or "@" +** is included as part of the name. +** Parameters of the form "?" or "?NNN" have no name. +** +** The first bound parameter has an index of 1, not 0. +** +** If the value n is out of range or if the n-th parameter is nameless, +** then NULL is returned. The returned string is always in the +** UTF-8 encoding even if the named parameter was originally specified +** as UTF-16 in [sqlite3_prepare16()] or [sqlite3_prepare16_v2()]. +*/ +const char *sqlite3_bind_parameter_name(sqlite3_stmt*, int); + +/* +** CAPI3REF: Index Of A Parameter With A Given Name +** +** This routine returns the index of a host parameter with the given name. +** The name must match exactly. If no parameter with the given name is +** found, return 0. Parameter names must be UTF8. +*/ +int sqlite3_bind_parameter_index(sqlite3_stmt*, const char *zName); + +/* +** CAPI3REF: Reset All Bindings On A Prepared Statement +** +** Contrary to the intuition of many, [sqlite3_reset()] does not +** reset the [sqlite3_bind_blob | bindings] on a +** [sqlite3_stmt | prepared statement]. Use this routine to +** reset all host parameters to NULL. +*/ +int sqlite3_clear_bindings(sqlite3_stmt*); + +/* +** CAPI3REF: Number Of Columns In A Result Set +** +** Return the number of columns in the result set returned by the +** [sqlite3_stmt | compiled SQL statement]. This routine returns 0 +** if pStmt is an SQL statement that does not return data (for +** example an UPDATE). +*/ +int sqlite3_column_count(sqlite3_stmt *pStmt); + +/* +** CAPI3REF: Column Names In A Result Set +** +** These routines return the name assigned to a particular column +** in the result set of a SELECT statement. The sqlite3_column_name() +** interface returns a pointer to a UTF8 string and sqlite3_column_name16() +** returns a pointer to a UTF16 string. The first parameter is the +** [sqlite3_stmt | prepared statement] that implements the SELECT statement. +** The second parameter is the column number. The left-most column is +** number 0. +** +** The returned string pointer is valid until either the +** [sqlite3_stmt | prepared statement] is destroyed by [sqlite3_finalize()] +** or until the next call sqlite3_column_name() or sqlite3_column_name16() +** on the same column. +** +** If sqlite3_malloc() fails during the processing of either routine +** (for example during a conversion from UTF-8 to UTF-16) then a +** NULL pointer is returned. +*/ +const char *sqlite3_column_name(sqlite3_stmt*, int N); +const void *sqlite3_column_name16(sqlite3_stmt*, int N); + +/* +** CAPI3REF: Source Of Data In A Query Result +** +** These routines provide a means to determine what column of what +** table in which database a result of a SELECT statement comes from. +** The name of the database or table or column can be returned as +** either a UTF8 or UTF16 string. The _database_ routines return +** the database name, the _table_ routines return the table name, and +** the origin_ routines return the column name. +** The returned string is valid until +** the [sqlite3_stmt | prepared statement] is destroyed using +** [sqlite3_finalize()] or until the same information is requested +** again in a different encoding. +** +** The names returned are the original un-aliased names of the +** database, table, and column. +** +** The first argument to the following calls is a +** [sqlite3_stmt | compiled SQL statement]. +** These functions return information about the Nth column returned by +** the statement, where N is the second function argument. +** +** If the Nth column returned by the statement is an expression +** or subquery and is not a column value, then all of these functions +** return NULL. Otherwise, they return the +** name of the attached database, table and column that query result +** column was extracted from. +** +** As with all other SQLite APIs, those postfixed with "16" return UTF-16 +** encoded strings, the other functions return UTF-8. +** +** These APIs are only available if the library was compiled with the +** SQLITE_ENABLE_COLUMN_METADATA preprocessor symbol defined. +** +** If two or more threads call one or more of these routines against the same +** prepared statement and column at the same time then the results are +** undefined. +*/ +const char *sqlite3_column_database_name(sqlite3_stmt*,int); +const void *sqlite3_column_database_name16(sqlite3_stmt*,int); +const char *sqlite3_column_table_name(sqlite3_stmt*,int); +const void *sqlite3_column_table_name16(sqlite3_stmt*,int); +const char *sqlite3_column_origin_name(sqlite3_stmt*,int); +const void *sqlite3_column_origin_name16(sqlite3_stmt*,int); + +/* +** CAPI3REF: Declared Datatype Of A Query Result +** +** The first parameter is a [sqlite3_stmt | compiled SQL statement]. +** If this statement is a SELECT statement and the Nth column of the +** returned result set of that SELECT is a table column (not an +** expression or subquery) then the declared type of the table +** column is returned. If the Nth column of the result set is an +** expression or subquery, then a NULL pointer is returned. +** The returned string is always UTF-8 encoded. For example, in +** the database schema: +** +** CREATE TABLE t1(c1 VARIANT); +** +** And the following statement compiled: +** +** SELECT c1 + 1, c1 FROM t1; +** +** Then this routine would return the string "VARIANT" for the second +** result column (i==1), and a NULL pointer for the first result column +** (i==0). +** +** SQLite uses dynamic run-time typing. So just because a column +** is declared to contain a particular type does not mean that the +** data stored in that column is of the declared type. SQLite is +** strongly typed, but the typing is dynamic not static. Type +** is associated with individual values, not with the containers +** used to hold those values. +*/ +const char *sqlite3_column_decltype(sqlite3_stmt *, int i); +const void *sqlite3_column_decltype16(sqlite3_stmt*,int); + +/* +** CAPI3REF: Evaluate An SQL Statement +** +** After an [sqlite3_stmt | SQL statement] has been prepared with a call +** to either [sqlite3_prepare_v2()] or [sqlite3_prepare16_v2()] or to one of +** the legacy interfaces [sqlite3_prepare()] or [sqlite3_prepare16()], +** then this function must be called one or more times to evaluate the +** statement. +** +** The details of the behavior of this sqlite3_step() interface depend +** on whether the statement was prepared using the newer "v2" interface +** [sqlite3_prepare_v2()] and [sqlite3_prepare16_v2()] or the older legacy +** interface [sqlite3_prepare()] and [sqlite3_prepare16()]. The use of the +** new "v2" interface is recommended for new applications but the legacy +** interface will continue to be supported. +** +** In the lagacy interface, the return value will be either [SQLITE_BUSY], +** [SQLITE_DONE], [SQLITE_ROW], [SQLITE_ERROR], or [SQLITE_MISUSE]. +** With the "v2" interface, any of the other [SQLITE_OK | result code] +** or [SQLITE_IOERR_READ | extended result code] might be returned as +** well. +** +** [SQLITE_BUSY] means that the database engine was unable to acquire the +** database locks it needs to do its job. If the statement is a COMMIT +** or occurs outside of an explicit transaction, then you can retry the +** statement. If the statement is not a COMMIT and occurs within a +** explicit transaction then you should rollback the transaction before +** continuing. +** +** [SQLITE_DONE] means that the statement has finished executing +** successfully. sqlite3_step() should not be called again on this virtual +** machine without first calling [sqlite3_reset()] to reset the virtual +** machine back to its initial state. +** +** If the SQL statement being executed returns any data, then +** [SQLITE_ROW] is returned each time a new row of data is ready +** for processing by the caller. The values may be accessed using +** the [sqlite3_column_int | column access functions]. +** sqlite3_step() is called again to retrieve the next row of data. +** +** [SQLITE_ERROR] means that a run-time error (such as a constraint +** violation) has occurred. sqlite3_step() should not be called again on +** the VM. More information may be found by calling [sqlite3_errmsg()]. +** With the legacy interface, a more specific error code (example: +** [SQLITE_INTERRUPT], [SQLITE_SCHEMA], [SQLITE_CORRUPT], and so forth) +** can be obtained by calling [sqlite3_reset()] on the +** [sqlite3_stmt | prepared statement]. In the "v2" interface, +** the more specific error code is returned directly by sqlite3_step(). +** +** [SQLITE_MISUSE] means that the this routine was called inappropriately. +** Perhaps it was called on a [sqlite3_stmt | prepared statement] that has +** already been [sqlite3_finalize | finalized] or on one that had +** previously returned [SQLITE_ERROR] or [SQLITE_DONE]. Or it could +** be the case that the same database connection is being used by two or +** more threads at the same moment in time. +** +** <b>Goofy Interface Alert:</b> +** In the legacy interface, +** the sqlite3_step() API always returns a generic error code, +** [SQLITE_ERROR], following any error other than [SQLITE_BUSY] +** and [SQLITE_MISUSE]. You must call [sqlite3_reset()] or +** [sqlite3_finalize()] in order to find one of the specific +** [SQLITE_ERROR | result codes] that better describes the error. +** We admit that this is a goofy design. The problem has been fixed +** with the "v2" interface. If you prepare all of your SQL statements +** using either [sqlite3_prepare_v2()] or [sqlite3_prepare16_v2()] instead +** of the legacy [sqlite3_prepare()] and [sqlite3_prepare16()], then the +** more specific [SQLITE_ERROR | result codes] are returned directly +** by sqlite3_step(). The use of the "v2" interface is recommended. +*/ +int sqlite3_step(sqlite3_stmt*); + +/* +** CAPI3REF: +** +** Return the number of values in the current row of the result set. +** +** After a call to [sqlite3_step()] that returns [SQLITE_ROW], this routine +** will return the same value as the [sqlite3_column_count()] function. +** After [sqlite3_step()] has returned an [SQLITE_DONE], [SQLITE_BUSY], or +** a [SQLITE_ERROR | error code], or before [sqlite3_step()] has been +** called on the [sqlite3_stmt | prepared statement] for the first time, +** this routine returns zero. +*/ +int sqlite3_data_count(sqlite3_stmt *pStmt); + +/* +** CAPI3REF: Fundamental Datatypes +** +** Every value in SQLite has one of five fundamental datatypes: +** +** <ul> +** <li> 64-bit signed integer +** <li> 64-bit IEEE floating point number +** <li> string +** <li> BLOB +** <li> NULL +** </ul> +** +** These constants are codes for each of those types. +** +** Note that the SQLITE_TEXT constant was also used in SQLite version 2 +** for a completely different meaning. Software that links against both +** SQLite version 2 and SQLite version 3 should use SQLITE3_TEXT not +** SQLITE_TEXT. +*/ +#define SQLITE_INTEGER 1 +#define SQLITE_FLOAT 2 +#define SQLITE_BLOB 4 +#define SQLITE_NULL 5 +#ifdef SQLITE_TEXT +# undef SQLITE_TEXT +#else +# define SQLITE_TEXT 3 +#endif +#define SQLITE3_TEXT 3 + +/* +** CAPI3REF: Results Values From A Query +** +** These routines return information about +** a single column of the current result row of a query. In every +** case the first argument is a pointer to the +** [sqlite3_stmt | SQL statement] that is being +** evaluated (the [sqlite3_stmt*] that was returned from +** [sqlite3_prepare_v2()] or one of its variants) and +** the second argument is the index of the column for which information +** should be returned. The left-most column of the result set +** has an index of 0. +** +** If the SQL statement is not currently point to a valid row, or if the +** the column index is out of range, the result is undefined. +** These routines may only be called when the most recent call to +** [sqlite3_step()] has returned [SQLITE_ROW] and neither +** [sqlite3_reset()] nor [sqlite3_finalize()] has been call subsequently. +** If any of these routines are called after [sqlite3_reset()] or +** [sqlite3_finalize()] or after [sqlite3_step()] has returned +** something other than [SQLITE_ROW], the results are undefined. +** If [sqlite3_step()] or [sqlite3_reset()] or [sqlite3_finalize()] +** are called from a different thread while any of these routines +** are pending, then the results are undefined. +** +** The sqlite3_column_type() routine returns +** [SQLITE_INTEGER | datatype code] for the initial data type +** of the result column. The returned value is one of [SQLITE_INTEGER], +** [SQLITE_FLOAT], [SQLITE_TEXT], [SQLITE_BLOB], or [SQLITE_NULL]. The value +** returned by sqlite3_column_type() is only meaningful if no type +** conversions have occurred as described below. After a type conversion, +** the value returned by sqlite3_column_type() is undefined. Future +** versions of SQLite may change the behavior of sqlite3_column_type() +** following a type conversion. +** +** If the result is a BLOB or UTF-8 string then the sqlite3_column_bytes() +** routine returns the number of bytes in that BLOB or string. +** If the result is a UTF-16 string, then sqlite3_column_bytes() converts +** the string to UTF-8 and then returns the number of bytes. +** If the result is a numeric value then sqlite3_column_bytes() uses +** [sqlite3_snprintf()] to convert that value to a UTF-8 string and returns +** the number of bytes in that string. +** The value returned does not include the zero terminator at the end +** of the string. For clarity: the value returned is the number of +** bytes in the string, not the number of characters. +** +** Strings returned by sqlite3_column_text() and sqlite3_column_text16(), +** even zero-length strings, are always zero terminated. The return +** value from sqlite3_column_blob() for a zero-length blob is an arbitrary +** pointer, possibly even a NULL pointer. +** +** The sqlite3_column_bytes16() routine is similar to sqlite3_column_bytes() +** but leaves the result in UTF-16 instead of UTF-8. +** The zero terminator is not included in this count. +** +** These routines attempt to convert the value where appropriate. For +** example, if the internal representation is FLOAT and a text result +** is requested, [sqlite3_snprintf()] is used internally to do the conversion +** automatically. The following table details the conversions that +** are applied: +** +** <blockquote> +** <table border="1"> +** <tr><th> Internal<br>Type <th> Requested<br>Type <th> Conversion +** +** <tr><td> NULL <td> INTEGER <td> Result is 0 +** <tr><td> NULL <td> FLOAT <td> Result is 0.0 +** <tr><td> NULL <td> TEXT <td> Result is NULL pointer +** <tr><td> NULL <td> BLOB <td> Result is NULL pointer +** <tr><td> INTEGER <td> FLOAT <td> Convert from integer to float +** <tr><td> INTEGER <td> TEXT <td> ASCII rendering of the integer +** <tr><td> INTEGER <td> BLOB <td> Same as for INTEGER->TEXT +** <tr><td> FLOAT <td> INTEGER <td> Convert from float to integer +** <tr><td> FLOAT <td> TEXT <td> ASCII rendering of the float +** <tr><td> FLOAT <td> BLOB <td> Same as FLOAT->TEXT +** <tr><td> TEXT <td> INTEGER <td> Use atoi() +** <tr><td> TEXT <td> FLOAT <td> Use atof() +** <tr><td> TEXT <td> BLOB <td> No change +** <tr><td> BLOB <td> INTEGER <td> Convert to TEXT then use atoi() +** <tr><td> BLOB <td> FLOAT <td> Convert to TEXT then use atof() +** <tr><td> BLOB <td> TEXT <td> Add a zero terminator if needed +** </table> +** </blockquote> +** +** The table above makes reference to standard C library functions atoi() +** and atof(). SQLite does not really use these functions. It has its +** on equavalent internal routines. The atoi() and atof() names are +** used in the table for brevity and because they are familiar to most +** C programmers. +** +** Note that when type conversions occur, pointers returned by prior +** calls to sqlite3_column_blob(), sqlite3_column_text(), and/or +** sqlite3_column_text16() may be invalidated. +** Type conversions and pointer invalidations might occur +** in the following cases: +** +** <ul> +** <li><p> The initial content is a BLOB and sqlite3_column_text() +** or sqlite3_column_text16() is called. A zero-terminator might +** need to be added to the string.</p></li> +** +** <li><p> The initial content is UTF-8 text and sqlite3_column_bytes16() or +** sqlite3_column_text16() is called. The content must be converted +** to UTF-16.</p></li> +** +** <li><p> The initial content is UTF-16 text and sqlite3_column_bytes() or +** sqlite3_column_text() is called. The content must be converted +** to UTF-8.</p></li> +** </ul> +** +** Conversions between UTF-16be and UTF-16le are always done in place and do +** not invalidate a prior pointer, though of course the content of the buffer +** that the prior pointer points to will have been modified. Other kinds +** of conversion are done in place when it is possible, but sometime it is +** not possible and in those cases prior pointers are invalidated. +** +** The safest and easiest to remember policy is to invoke these routines +** in one of the following ways: +** +** <ul> +** <li>sqlite3_column_text() followed by sqlite3_column_bytes()</li> +** <li>sqlite3_column_blob() followed by sqlite3_column_bytes()</li> +** <li>sqlite3_column_text16() followed by sqlite3_column_bytes16()</li> +** </ul> +** +** In other words, you should call sqlite3_column_text(), sqlite3_column_blob(), +** or sqlite3_column_text16() first to force the result into the desired +** format, then invoke sqlite3_column_bytes() or sqlite3_column_bytes16() to +** find the size of the result. Do not mix call to sqlite3_column_text() or +** sqlite3_column_blob() with calls to sqlite3_column_bytes16(). And do not +** mix calls to sqlite3_column_text16() with calls to sqlite3_column_bytes(). +** +** The pointers returned are valid until a type conversion occurs as +** described above, or until [sqlite3_step()] or [sqlite3_reset()] or +** [sqlite3_finalize()] is called. The memory space used to hold strings +** and blobs is freed automatically. Do <b>not</b> pass the pointers returned +** [sqlite3_column_blob()], [sqlite3_column_text()], etc. into +** [sqlite3_free()]. +** +** If a memory allocation error occurs during the evaluation of any +** of these routines, a default value is returned. The default value +** is either the integer 0, the floating point number 0.0, or a NULL +** pointer. Subsequent calls to [sqlite3_errcode()] will return +** [SQLITE_NOMEM]. +*/ +const void *sqlite3_column_blob(sqlite3_stmt*, int iCol); +int sqlite3_column_bytes(sqlite3_stmt*, int iCol); +int sqlite3_column_bytes16(sqlite3_stmt*, int iCol); +double sqlite3_column_double(sqlite3_stmt*, int iCol); +int sqlite3_column_int(sqlite3_stmt*, int iCol); +sqlite3_int64 sqlite3_column_int64(sqlite3_stmt*, int iCol); +const unsigned char *sqlite3_column_text(sqlite3_stmt*, int iCol); +const void *sqlite3_column_text16(sqlite3_stmt*, int iCol); +int sqlite3_column_type(sqlite3_stmt*, int iCol); +sqlite3_value *sqlite3_column_value(sqlite3_stmt*, int iCol); + +/* +** CAPI3REF: Destroy A Prepared Statement Object +** +** The sqlite3_finalize() function is called to delete a +** [sqlite3_stmt | compiled SQL statement]. If the statement was +** executed successfully, or not executed at all, then SQLITE_OK is returned. +** If execution of the statement failed then an +** [SQLITE_ERROR | error code] or [SQLITE_IOERR_READ | extended error code] +** is returned. +** +** This routine can be called at any point during the execution of the +** [sqlite3_stmt | virtual machine]. If the virtual machine has not +** completed execution when this routine is called, that is like +** encountering an error or an interrupt. (See [sqlite3_interrupt()].) +** Incomplete updates may be rolled back and transactions cancelled, +** depending on the circumstances, and the +** [SQLITE_ERROR | result code] returned will be [SQLITE_ABORT]. +*/ +int sqlite3_finalize(sqlite3_stmt *pStmt); + +/* +** CAPI3REF: Reset A Prepared Statement Object +** +** The sqlite3_reset() function is called to reset a +** [sqlite3_stmt | compiled SQL statement] object. +** back to it's initial state, ready to be re-executed. +** Any SQL statement variables that had values bound to them using +** the [sqlite3_bind_blob | sqlite3_bind_*() API] retain their values. +** Use [sqlite3_clear_bindings()] to reset the bindings. +*/ +int sqlite3_reset(sqlite3_stmt *pStmt); + +/* +** CAPI3REF: Create Or Redefine SQL Functions +** +** The following two functions are used to add SQL functions or aggregates +** or to redefine the behavior of existing SQL functions or aggregates. The +** difference only between the two is that the second parameter, the +** name of the (scalar) function or aggregate, is encoded in UTF-8 for +** sqlite3_create_function() and UTF-16 for sqlite3_create_function16(). +** +** The first argument is the [sqlite3 | database handle] that holds the +** SQL function or aggregate is to be added or redefined. If a single +** program uses more than one database handle internally, then SQL +** functions or aggregates must be added individually to each database +** handle with which they will be used. +** +** The second parameter is the name of the SQL function to be created +** or redefined. +** The length of the name is limited to 255 bytes, exclusive of the +** zero-terminator. Note that the name length limit is in bytes, not +** characters. Any attempt to create a function with a longer name +** will result in an SQLITE_ERROR error. +** +** The third parameter is the number of arguments that the SQL function or +** aggregate takes. If this parameter is negative, then the SQL function or +** aggregate may take any number of arguments. +** +** The fourth parameter, eTextRep, specifies what +** [SQLITE_UTF8 | text encoding] this SQL function prefers for +** its parameters. Any SQL function implementation should be able to work +** work with UTF-8, UTF-16le, or UTF-16be. But some implementations may be +** more efficient with one encoding than another. It is allowed to +** invoke sqlite3_create_function() or sqlite3_create_function16() multiple +** times with the same function but with different values of eTextRep. +** When multiple implementations of the same function are available, SQLite +** will pick the one that involves the least amount of data conversion. +** If there is only a single implementation which does not care what +** text encoding is used, then the fourth argument should be +** [SQLITE_ANY]. +** +** The fifth parameter is an arbitrary pointer. The implementation +** of the function can gain access to this pointer using +** [sqlite3_user_data()]. +** +** The seventh, eighth and ninth parameters, xFunc, xStep and xFinal, are +** pointers to C-language functions that implement the SQL +** function or aggregate. A scalar SQL function requires an implementation of +** the xFunc callback only, NULL pointers should be passed as the xStep +** and xFinal parameters. An aggregate SQL function requires an implementation +** of xStep and xFinal and NULL should be passed for xFunc. To delete an +** existing SQL function or aggregate, pass NULL for all three function +** callback. +** +** It is permitted to register multiple implementations of the same +** functions with the same name but with either differing numbers of +** arguments or differing perferred text encodings. SQLite will use +** the implementation most closely matches the way in which the +** SQL function is used. +*/ +int sqlite3_create_function( + sqlite3 *, + const char *zFunctionName, + int nArg, + int eTextRep, + void*, + void (*xFunc)(sqlite3_context*,int,sqlite3_value**), + void (*xStep)(sqlite3_context*,int,sqlite3_value**), + void (*xFinal)(sqlite3_context*) +); +int sqlite3_create_function16( + sqlite3*, + const void *zFunctionName, + int nArg, + int eTextRep, + void*, + void (*xFunc)(sqlite3_context*,int,sqlite3_value**), + void (*xStep)(sqlite3_context*,int,sqlite3_value**), + void (*xFinal)(sqlite3_context*) +); + +/* +** CAPI3REF: Text Encodings +** +** These constant define integer codes that represent the various +** text encodings supported by SQLite. +*/ +#define SQLITE_UTF8 1 +#define SQLITE_UTF16LE 2 +#define SQLITE_UTF16BE 3 +#define SQLITE_UTF16 4 /* Use native byte order */ +#define SQLITE_ANY 5 /* sqlite3_create_function only */ +#define SQLITE_UTF16_ALIGNED 8 /* sqlite3_create_collation only */ + +/* +** CAPI3REF: Obsolete Functions +** +** These functions are all now obsolete. In order to maintain +** backwards compatibility with older code, we continue to support +** these functions. However, new development projects should avoid +** the use of these functions. To help encourage people to avoid +** using these functions, we are not going to tell you want they do. +*/ +int sqlite3_aggregate_count(sqlite3_context*); +int sqlite3_expired(sqlite3_stmt*); +int sqlite3_transfer_bindings(sqlite3_stmt*, sqlite3_stmt*); +int sqlite3_global_recover(void); +void sqlite3_thread_cleanup(void); +int sqlite3_memory_alarm(void(*)(void*,sqlite3_int64,int),void*,sqlite3_int64); + +/* +** CAPI3REF: Obtaining SQL Function Parameter Values +** +** The C-language implementation of SQL functions and aggregates uses +** this set of interface routines to access the parameter values on +** the function or aggregate. +** +** The xFunc (for scalar functions) or xStep (for aggregates) parameters +** to [sqlite3_create_function()] and [sqlite3_create_function16()] +** define callbacks that implement the SQL functions and aggregates. +** The 4th parameter to these callbacks is an array of pointers to +** [sqlite3_value] objects. There is one [sqlite3_value] object for +** each parameter to the SQL function. These routines are used to +** extract values from the [sqlite3_value] objects. +** +** These routines work just like the corresponding +** [sqlite3_column_blob | sqlite3_column_* routines] except that +** these routines take a single [sqlite3_value*] pointer instead +** of an [sqlite3_stmt*] pointer and an integer column number. +** +** The sqlite3_value_text16() interface extracts a UTF16 string +** in the native byte-order of the host machine. The +** sqlite3_value_text16be() and sqlite3_value_text16le() interfaces +** extract UTF16 strings as big-endian and little-endian respectively. +** +** The sqlite3_value_numeric_type() interface attempts to apply +** numeric affinity to the value. This means that an attempt is +** made to convert the value to an integer or floating point. If +** such a conversion is possible without loss of information (in order +** words if the value is original a string that looks like a number) +** then it is done. Otherwise no conversion occurs. The +** [SQLITE_INTEGER | datatype] after conversion is returned. +** +** Please pay particular attention to the fact that the pointer that +** is returned from [sqlite3_value_blob()], [sqlite3_value_text()], or +** [sqlite3_value_text16()] can be invalidated by a subsequent call to +** [sqlite3_value_bytes()], [sqlite3_value_bytes16()], [sqlite3_value_text()], +** or [sqlite3_value_text16()]. +** +** These routines must be called from the same thread as +** the SQL function that supplied the sqlite3_value* parameters. +** Or, if the sqlite3_value* argument comes from the [sqlite3_column_value()] +** interface, then these routines should be called from the same thread +** that ran [sqlite3_column_value()]. +*/ +const void *sqlite3_value_blob(sqlite3_value*); +int sqlite3_value_bytes(sqlite3_value*); +int sqlite3_value_bytes16(sqlite3_value*); +double sqlite3_value_double(sqlite3_value*); +int sqlite3_value_int(sqlite3_value*); +sqlite3_int64 sqlite3_value_int64(sqlite3_value*); +const unsigned char *sqlite3_value_text(sqlite3_value*); +const void *sqlite3_value_text16(sqlite3_value*); +const void *sqlite3_value_text16le(sqlite3_value*); +const void *sqlite3_value_text16be(sqlite3_value*); +int sqlite3_value_type(sqlite3_value*); +int sqlite3_value_numeric_type(sqlite3_value*); + +/* +** CAPI3REF: Obtain Aggregate Function Context +** +** The implementation of aggregate SQL functions use this routine to allocate +** a structure for storing their state. The first time this routine +** is called for a particular aggregate, a new structure of size nBytes +** is allocated, zeroed, and returned. On subsequent calls (for the +** same aggregate instance) the same buffer is returned. The implementation +** of the aggregate can use the returned buffer to accumulate data. +** +** The buffer allocated is freed automatically by SQLite whan the aggregate +** query concludes. +** +** The first parameter should be a copy of the +** [sqlite3_context | SQL function context] that is the first +** parameter to the callback routine that implements the aggregate +** function. +** +** This routine must be called from the same thread in which +** the aggregate SQL function is running. +*/ +void *sqlite3_aggregate_context(sqlite3_context*, int nBytes); + +/* +** CAPI3REF: User Data For Functions +** +** The pUserData parameter to the [sqlite3_create_function()] +** and [sqlite3_create_function16()] routines +** used to register user functions is available to +** the implementation of the function using this call. +** +** This routine must be called from the same thread in which +** the SQL function is running. +*/ +void *sqlite3_user_data(sqlite3_context*); + +/* +** CAPI3REF: Function Auxiliary Data +** +** The following two functions may be used by scalar SQL functions to +** associate meta-data with argument values. If the same value is passed to +** multiple invocations of the same SQL function during query execution, under +** some circumstances the associated meta-data may be preserved. This may +** be used, for example, to add a regular-expression matching scalar +** function. The compiled version of the regular expression is stored as +** meta-data associated with the SQL value passed as the regular expression +** pattern. The compiled regular expression can be reused on multiple +** invocations of the same function so that the original pattern string +** does not need to be recompiled on each invocation. +** +** The sqlite3_get_auxdata() interface returns a pointer to the meta-data +** associated with the Nth argument value to the current SQL function +** call, where N is the second parameter. If no meta-data has been set for +** that value, then a NULL pointer is returned. +** +** The sqlite3_set_auxdata() is used to associate meta-data with an SQL +** function argument. The third parameter is a pointer to the meta-data +** to be associated with the Nth user function argument value. The fourth +** parameter specifies a destructor that will be called on the meta- +** data pointer to release it when it is no longer required. If the +** destructor is NULL, it is not invoked. +** +** In practice, meta-data is preserved between function calls for +** expressions that are constant at compile time. This includes literal +** values and SQL variables. +** +** These routines must be called from the same thread in which +** the SQL function is running. +*/ +void *sqlite3_get_auxdata(sqlite3_context*, int); +void sqlite3_set_auxdata(sqlite3_context*, int, void*, void (*)(void*)); + + +/* +** CAPI3REF: Constants Defining Special Destructor Behavior +** +** These are special value for the destructor that is passed in as the +** final argument to routines like [sqlite3_result_blob()]. If the destructor +** argument is SQLITE_STATIC, it means that the content pointer is constant +** and will never change. It does not need to be destroyed. The +** SQLITE_TRANSIENT value means that the content will likely change in +** the near future and that SQLite should make its own private copy of +** the content before returning. +** +** The typedef is necessary to work around problems in certain +** C++ compilers. See ticket #2191. +*/ +typedef void (*sqlite3_destructor_type)(void*); +#define SQLITE_STATIC ((sqlite3_destructor_type)0) +#define SQLITE_TRANSIENT ((sqlite3_destructor_type)-1) + +/* +** CAPI3REF: Setting The Result Of An SQL Function +** +** These routines are used by the xFunc or xFinal callbacks that +** implement SQL functions and aggregates. See +** [sqlite3_create_function()] and [sqlite3_create_function16()] +** for additional information. +** +** These functions work very much like the +** [sqlite3_bind_blob | sqlite3_bind_*] family of functions used +** to bind values to host parameters in prepared statements. +** Refer to the +** [sqlite3_bind_blob | sqlite3_bind_* documentation] for +** additional information. +** +** The sqlite3_result_error() and sqlite3_result_error16() functions +** cause the implemented SQL function to throw an exception. The +** parameter to sqlite3_result_error() or sqlite3_result_error16() +** is the text of an error message. +** +** The sqlite3_result_toobig() cause the function implementation +** to throw and error indicating that a string or BLOB is to long +** to represent. +** +** These routines must be called from within the same thread as +** the SQL function associated with the [sqlite3_context] pointer. +*/ +void sqlite3_result_blob(sqlite3_context*, const void*, int, void(*)(void*)); +void sqlite3_result_double(sqlite3_context*, double); +void sqlite3_result_error(sqlite3_context*, const char*, int); +void sqlite3_result_error16(sqlite3_context*, const void*, int); +void sqlite3_result_error_toobig(sqlite3_context*); +void sqlite3_result_error_nomem(sqlite3_context*); +void sqlite3_result_int(sqlite3_context*, int); +void sqlite3_result_int64(sqlite3_context*, sqlite3_int64); +void sqlite3_result_null(sqlite3_context*); +void sqlite3_result_text(sqlite3_context*, const char*, int, void(*)(void*)); +void sqlite3_result_text16(sqlite3_context*, const void*, int, void(*)(void*)); +void sqlite3_result_text16le(sqlite3_context*, const void*, int,void(*)(void*)); +void sqlite3_result_text16be(sqlite3_context*, const void*, int,void(*)(void*)); +void sqlite3_result_value(sqlite3_context*, sqlite3_value*); +void sqlite3_result_zeroblob(sqlite3_context*, int n); + +/* +** CAPI3REF: Define New Collating Sequences +** +** These functions are used to add new collation sequences to the +** [sqlite3*] handle specified as the first argument. +** +** The name of the new collation sequence is specified as a UTF-8 string +** for sqlite3_create_collation() and sqlite3_create_collation_v2() +** and a UTF-16 string for sqlite3_create_collation16(). In all cases +** the name is passed as the second function argument. +** +** The third argument may be one of the constants [SQLITE_UTF8], +** [SQLITE_UTF16LE] or [SQLITE_UTF16BE], indicating that the user-supplied +** routine expects to be passed pointers to strings encoded using UTF-8, +** UTF-16 little-endian or UTF-16 big-endian respectively. The +** third argument might also be [SQLITE_UTF16_ALIGNED] to indicate that +** the routine expects pointers to 16-bit word aligned strings +** of UTF16 in the native byte order of the host computer. +** +** A pointer to the user supplied routine must be passed as the fifth +** argument. If it is NULL, this is the same as deleting the collation +** sequence (so that SQLite cannot call it anymore). Each time the user +** supplied function is invoked, it is passed a copy of the void* passed as +** the fourth argument to sqlite3_create_collation() or +** sqlite3_create_collation16() as its first parameter. +** +** The remaining arguments to the user-supplied routine are two strings, +** each represented by a [length, data] pair and encoded in the encoding +** that was passed as the third argument when the collation sequence was +** registered. The user routine should return negative, zero or positive if +** the first string is less than, equal to, or greater than the second +** string. i.e. (STRING1 - STRING2). +** +** The sqlite3_create_collation_v2() works like sqlite3_create_collation() +** excapt that it takes an extra argument which is a destructor for +** the collation. The destructor is called when the collation is +** destroyed and is passed a copy of the fourth parameter void* pointer +** of the sqlite3_create_collation_v2(). Collations are destroyed when +** they are overridden by later calls to the collation creation functions +** or when the [sqlite3*] database handle is closed using [sqlite3_close()]. +** +** The sqlite3_create_collation_v2() interface is experimental and +** subject to change in future releases. The other collation creation +** functions are stable. +*/ +int sqlite3_create_collation( + sqlite3*, + const char *zName, + int eTextRep, + void*, + int(*xCompare)(void*,int,const void*,int,const void*) +); +int sqlite3_create_collation_v2( + sqlite3*, + const char *zName, + int eTextRep, + void*, + int(*xCompare)(void*,int,const void*,int,const void*), + void(*xDestroy)(void*) +); +int sqlite3_create_collation16( + sqlite3*, + const char *zName, + int eTextRep, + void*, + int(*xCompare)(void*,int,const void*,int,const void*) +); + +/* +** CAPI3REF: 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 handle to be called whenever an undefined collation sequence is +** required. +** +** If the function is registered using the sqlite3_collation_needed() API, +** then it is passed the names of undefined collation sequences as strings +** encoded in UTF-8. If sqlite3_collation_needed16() is used, the names +** are passed as UTF-16 in machine native byte order. A call to either +** function replaces any existing callback. +** +** When the callback is invoked, the first argument passed is a copy +** of the second argument to sqlite3_collation_needed() or +** sqlite3_collation_needed16(). The second argument is the database +** handle. The third argument is one of [SQLITE_UTF8], [SQLITE_UTF16BE], or +** [SQLITE_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 +** [sqlite3_create_collation()], [sqlite3_create_collation16()], or +** [sqlite3_create_collation_v2()]. +*/ +int sqlite3_collation_needed( + sqlite3*, + void*, + void(*)(void*,sqlite3*,int eTextRep,const char*) +); +int sqlite3_collation_needed16( + sqlite3*, + void*, + void(*)(void*,sqlite3*,int eTextRep,const void*) +); + +/* +** Specify the key for an encrypted database. This routine should be +** called right after sqlite3_open(). +** +** The code to implement this API is not available in the public release +** of SQLite. +*/ +int sqlite3_key( + sqlite3 *db, /* Database to be rekeyed */ + const void *pKey, int nKey /* The key */ +); + +/* +** Change the key on an open database. If the current database is not +** encrypted, this routine will encrypt it. If pNew==0 or nNew==0, the +** database is decrypted. +** +** The code to implement this API is not available in the public release +** of SQLite. +*/ +int sqlite3_rekey( + sqlite3 *db, /* Database to be rekeyed */ + const void *pKey, int nKey /* The new key */ +); + +/* +** CAPI3REF: Suspend Execution For A Short Time +** +** This function causes the current thread to suspend execution +** a number of milliseconds specified in its parameter. +** +** If the operating system does not support sleep requests with +** millisecond time resolution, then the time will be rounded up to +** the nearest second. The number of milliseconds of sleep actually +** requested from the operating system is returned. +** +** SQLite implements this interface by calling the xSleep() +** method of the default [sqlite3_vfs] object. +*/ +int sqlite3_sleep(int); + +/* +** CAPI3REF: Name Of The Folder Holding Temporary Files +** +** If this global variable is made to point to a string which is +** the name of a folder (a.ka. directory), then all temporary files +** created by SQLite will be placed in that directory. If this variable +** is NULL pointer, then SQLite does a search for an appropriate temporary +** file directory. +** +** It is not safe to modify this variable once a database connection +** has been opened. It is intended that this variable be set once +** as part of process initialization and before any SQLite interface +** routines have been call and remain unchanged thereafter. +*/ +SQLITE_EXTERN char *sqlite3_temp_directory; + +/* +** CAPI3REF: Test To See If The Database Is In Auto-Commit Mode +** +** Test to see whether or not the database connection is in autocommit +** mode. Return TRUE if it is and FALSE if not. Autocommit mode is on +** by default. Autocommit is disabled by a BEGIN statement and reenabled +** by the next COMMIT or ROLLBACK. +** +** If certain kinds of errors occur on a statement within a multi-statement +** transactions (errors including [SQLITE_FULL], [SQLITE_IOERR], +** [SQLITE_NOMEM], [SQLITE_BUSY], and [SQLITE_INTERRUPT]) then the +** transaction might be rolled back automatically. The only way to +** find out if SQLite automatically rolled back the transaction after +** an error is to use this function. +** +** If another thread changes the autocommit status of the database +** connection while this routine is running, then the return value +** is undefined. +*/ +int sqlite3_get_autocommit(sqlite3*); + +/* +** CAPI3REF: Find The Database Handle Associated With A Prepared Statement +** +** Return the [sqlite3*] database handle to which a +** [sqlite3_stmt | prepared statement] belongs. +** This is the same database handle that was +** the first argument to the [sqlite3_prepare_v2()] or its variants +** that was used to create the statement in the first place. +*/ +sqlite3 *sqlite3_db_handle(sqlite3_stmt*); + + +/* +** CAPI3REF: Commit And Rollback Notification Callbacks +** +** These routines +** register callback functions to be invoked whenever a transaction +** is committed or rolled back. The pArg argument is passed through +** to the callback. If the callback on a commit hook function +** returns non-zero, then the commit is converted into a rollback. +** +** If another function was previously registered, its pArg value is returned. +** Otherwise NULL is returned. +** +** Registering a NULL function disables the callback. +** +** For the purposes of this API, a transaction is said to have been +** rolled back if an explicit "ROLLBACK" statement is executed, or +** an error or constraint causes an implicit rollback to occur. The +** callback is not invoked if a transaction is automatically rolled +** back because the database connection is closed. +** +** These are experimental interfaces and are subject to change. +*/ +void *sqlite3_commit_hook(sqlite3*, int(*)(void*), void*); +void *sqlite3_rollback_hook(sqlite3*, void(*)(void *), void*); + +/* +** CAPI3REF: Data Change Notification Callbacks +** +** Register a callback function with the database connection identified by the +** first argument to be invoked whenever a row is updated, inserted or deleted. +** Any callback set by a previous call to this function for the same +** database connection is overridden. +** +** The second argument is a pointer to the function to invoke when a +** row is updated, inserted or deleted. The first argument to the callback is +** a copy of the third argument to sqlite3_update_hook(). The second callback +** argument is one of SQLITE_INSERT, SQLITE_DELETE or SQLITE_UPDATE, depending +** on the operation that caused the callback to be invoked. The third and +** fourth arguments to the callback contain pointers to the database and +** table name containing the affected row. The final callback parameter is +** the rowid of the row. In the case of an update, this is the rowid after +** the update takes place. +** +** The update hook is not invoked when internal system tables are +** modified (i.e. sqlite_master and sqlite_sequence). +** +** If another function was previously registered, its pArg value is returned. +** Otherwise NULL is returned. +*/ +void *sqlite3_update_hook( + sqlite3*, + void(*)(void *,int ,char const *,char const *,sqlite3_int64), + void* +); + +/* +** CAPI3REF: Enable Or Disable Shared Pager Cache +** +** This routine enables or disables the sharing of the database cache +** and schema data structures between connections to the same database. +** Sharing is enabled if the argument is true and disabled if the argument +** is false. +** +** Beginning in SQLite version 3.5.0, cache sharing is enabled and disabled +** for an entire process. In prior versions of SQLite, sharing was +** enabled or disabled for each thread separately. +** +** The cache sharing mode set by this interface effects all subsequent +** calls to [sqlite3_open()], [sqlite3_open_v2()], and [sqlite3_open16()]. +** Existing database connections continue use the sharing mode that was +** in effect at the time they were opened. +** +** Virtual tables cannot be used with a shared cache. When shared +** cache is enabled, the [sqlite3_create_module()] API used to register +** virtual tables will always return an error. +** +** This routine returns [SQLITE_OK] if shared cache was +** enabled or disabled successfully. An [SQLITE_ERROR | error code] +** is returned otherwise. +** +** Shared cache is disabled by default. But this might change in +** future releases of SQLite. Applications that care about shared +** cache setting should set it explicitly. +*/ +int sqlite3_enable_shared_cache(int); + +/* +** CAPI3REF: Attempt To Free Heap Memory +** +** Attempt to free N bytes of heap memory by deallocating non-essential +** memory allocations held by the database library (example: memory +** used to cache database pages to improve performance). +*/ +int sqlite3_release_memory(int); + +/* +** CAPI3REF: Impose A Limit On Heap Size +** +** Place a "soft" limit on the amount of heap memory that may be allocated +** by SQLite. If an internal allocation is requested +** that would exceed the specified limit, [sqlite3_release_memory()] is +** invoked one or more times to free up some space before the allocation +** is made. +** +** The limit is called "soft", because if [sqlite3_release_memory()] cannot +** free sufficient memory to prevent the limit from being exceeded, +** the memory is allocated anyway and the current operation proceeds. +** +** A negative or zero value for N means that there is no soft heap limit and +** [sqlite3_release_memory()] will only be called when memory is exhausted. +** The default value for the soft heap limit is zero. +** +** SQLite makes a best effort to honor the soft heap limit. But if it +** is unable to reduce memory usage below the soft limit, execution will +** continue without error or notification. This is why the limit is +** called a "soft" limit. It is advisory only. +** +** Prior to SQLite version 3.5.0, this routine only constrained the memory +** allocated by a single thread - the same thread in which this routine +** runs. Beginning with SQLite version 3.5.0, the soft heap limit is +** applied to all threads. The value specified for the soft heap limit +** is an upper bound on the total memory allocation for all threads. In +** version 3.5.0 there is no mechanism for limiting the heap usage for +** individual threads. +*/ +void sqlite3_soft_heap_limit(int); + +/* +** CAPI3REF: Extract Metadata About A Column Of A Table +** +** This routine +** returns meta-data about a specific column of a specific database +** table accessible using the connection handle passed as the first function +** argument. +** +** The column is identified by the second, third and fourth parameters to +** this function. The second parameter is either the name of the database +** (i.e. "main", "temp" or an attached database) containing the specified +** table or NULL. If it is NULL, then all attached databases are searched +** for the table using the same algorithm as the database engine uses to +** resolve unqualified table references. +** +** The third and fourth parameters to this function are the table and column +** name of the desired column, respectively. Neither of these parameters +** may be NULL. +** +** Meta information is returned by writing to the memory locations passed as +** the 5th and subsequent parameters to this function. Any of these +** arguments may be NULL, in which case the corresponding element of meta +** information is ommitted. +** +** <pre> +** Parameter Output Type Description +** ----------------------------------- +** +** 5th const char* Data type +** 6th const char* Name of the default collation sequence +** 7th int True if the column has a NOT NULL constraint +** 8th int True if the column is part of the PRIMARY KEY +** 9th int True if the column is AUTOINCREMENT +** </pre> +** +** +** The memory pointed to by the character pointers returned for the +** declaration type and collation sequence is valid only until the next +** call to any sqlite API function. +** +** If the specified table is actually a view, then an error is returned. +** +** If the specified column is "rowid", "oid" or "_rowid_" and an +** INTEGER PRIMARY KEY column has been explicitly declared, then the output +** parameters are set for the explicitly declared column. If there is no +** explicitly declared IPK column, then the output parameters are set as +** follows: +** +** <pre> +** data type: "INTEGER" +** collation sequence: "BINARY" +** not null: 0 +** primary key: 1 +** auto increment: 0 +** </pre> +** +** This function may load one or more schemas from database files. If an +** error occurs during this process, or if the requested table or column +** cannot be found, an SQLITE error code is returned and an error message +** left in the database handle (to be retrieved using sqlite3_errmsg()). +** +** This API is only available if the library was compiled with the +** SQLITE_ENABLE_COLUMN_METADATA preprocessor symbol defined. +*/ +int sqlite3_table_column_metadata( + sqlite3 *db, /* Connection handle */ + const char *zDbName, /* Database name or NULL */ + const char *zTableName, /* Table name */ + const char *zColumnName, /* Column name */ + char const **pzDataType, /* OUTPUT: Declared data type */ + char const **pzCollSeq, /* OUTPUT: Collation sequence name */ + int *pNotNull, /* OUTPUT: True if NOT NULL constraint exists */ + int *pPrimaryKey, /* OUTPUT: True if column part of PK */ + int *pAutoinc /* OUTPUT: True if column is auto-increment */ +); + +/* +** CAPI3REF: Load An Extension +** +** Attempt to load an SQLite extension library contained in the file +** zFile. The entry point is zProc. zProc may be 0 in which case the +** name of the entry point defaults to "sqlite3_extension_init". +** +** Return [SQLITE_OK] on success and [SQLITE_ERROR] if something goes wrong. +** +** If an error occurs and pzErrMsg is not 0, then fill *pzErrMsg with +** error message text. The calling function should free this memory +** by calling [sqlite3_free()]. +** +** Extension loading must be enabled using [sqlite3_enable_load_extension()] +** prior to calling this API or an error will be returned. +*/ +int sqlite3_load_extension( + sqlite3 *db, /* Load the extension into this database connection */ + const char *zFile, /* Name of the shared library containing extension */ + const char *zProc, /* Entry point. Derived from zFile if 0 */ + char **pzErrMsg /* Put error message here if not 0 */ +); + +/* +** CAPI3REF: Enable Or Disable Extension Loading +** +** So as not to open security holes in older applications that are +** unprepared to deal with extension loading, and as a means of disabling +** extension loading while evaluating user-entered SQL, the following +** API is provided to turn the [sqlite3_load_extension()] mechanism on and +** off. It is off by default. See ticket #1863. +** +** Call this routine with onoff==1 to turn extension loading on +** and call it with onoff==0 to turn it back off again. +*/ +int sqlite3_enable_load_extension(sqlite3 *db, int onoff); + +/* +** CAPI3REF: Make Arrangements To Automatically Load An Extension +** +** Register an extension entry point that is automatically invoked +** whenever a new database connection is opened using +** [sqlite3_open()], [sqlite3_open16()], or [sqlite3_open_v2()]. +** +** This API can be invoked at program startup in order to register +** one or more statically linked extensions that will be available +** to all new database connections. +** +** Duplicate extensions are detected so calling this routine multiple +** times with the same extension is harmless. +** +** This routine stores a pointer to the extension in an array +** that is obtained from malloc(). If you run a memory leak +** checker on your program and it reports a leak because of this +** array, then invoke [sqlite3_reset_auto_extension()] prior +** to shutdown to free the memory. +** +** Automatic extensions apply across all threads. +** +** This interface is experimental and is subject to change or +** removal in future releases of SQLite. +*/ +int sqlite3_auto_extension(void *xEntryPoint); + + +/* +** CAPI3REF: Reset Automatic Extension Loading +** +** Disable all previously registered automatic extensions. This +** routine undoes the effect of all prior [sqlite3_automatic_extension()] +** calls. +** +** This call disabled automatic extensions in all threads. +** +** This interface is experimental and is subject to change or +** removal in future releases of SQLite. +*/ +void sqlite3_reset_auto_extension(void); + + +/* +****** EXPERIMENTAL - subject to change without notice ************** +** +** The interface to the virtual-table mechanism is currently considered +** to be experimental. The interface might change in incompatible ways. +** If this is a problem for you, do not use the interface at this time. +** +** When the virtual-table mechanism stablizes, we will declare the +** interface fixed, support it indefinitely, and remove this comment. +*/ + +/* +** Structures used by the virtual table interface +*/ +typedef struct sqlite3_vtab sqlite3_vtab; +typedef struct sqlite3_index_info sqlite3_index_info; +typedef struct sqlite3_vtab_cursor sqlite3_vtab_cursor; +typedef struct sqlite3_module sqlite3_module; + +/* +** A module is a class of virtual tables. Each module is defined +** by an instance of the following structure. This structure consists +** mostly of methods for the module. +*/ +struct sqlite3_module { + int iVersion; + int (*xCreate)(sqlite3*, void *pAux, + int argc, const char *const*argv, + sqlite3_vtab **ppVTab, char**); + int (*xConnect)(sqlite3*, void *pAux, + int argc, const char *const*argv, + sqlite3_vtab **ppVTab, char**); + int (*xBestIndex)(sqlite3_vtab *pVTab, sqlite3_index_info*); + int (*xDisconnect)(sqlite3_vtab *pVTab); + int (*xDestroy)(sqlite3_vtab *pVTab); + int (*xOpen)(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor); + int (*xClose)(sqlite3_vtab_cursor*); + int (*xFilter)(sqlite3_vtab_cursor*, int idxNum, const char *idxStr, + int argc, sqlite3_value **argv); + int (*xNext)(sqlite3_vtab_cursor*); + int (*xEof)(sqlite3_vtab_cursor*); + int (*xColumn)(sqlite3_vtab_cursor*, sqlite3_context*, int); + int (*xRowid)(sqlite3_vtab_cursor*, sqlite3_int64 *pRowid); + int (*xUpdate)(sqlite3_vtab *, int, sqlite3_value **, sqlite3_int64 *); + int (*xBegin)(sqlite3_vtab *pVTab); + int (*xSync)(sqlite3_vtab *pVTab); + int (*xCommit)(sqlite3_vtab *pVTab); + int (*xRollback)(sqlite3_vtab *pVTab); + int (*xFindFunction)(sqlite3_vtab *pVtab, int nArg, const char *zName, + void (**pxFunc)(sqlite3_context*,int,sqlite3_value**), + void **ppArg); + + int (*xRename)(sqlite3_vtab *pVtab, const char *zNew); +}; + +/* +** The sqlite3_index_info structure and its substructures is used to +** pass information into and receive the reply from the xBestIndex +** method of an sqlite3_module. The fields under **Inputs** are the +** inputs to xBestIndex and are read-only. xBestIndex inserts its +** results into the **Outputs** fields. +** +** The aConstraint[] array records WHERE clause constraints of the +** form: +** +** column OP expr +** +** Where OP is =, <, <=, >, or >=. The particular operator is stored +** in aConstraint[].op. The index of the column is stored in +** aConstraint[].iColumn. aConstraint[].usable is TRUE if the +** expr on the right-hand side can be evaluated (and thus the constraint +** is usable) and false if it cannot. +** +** The optimizer automatically inverts terms of the form "expr OP column" +** and makes other simplifications to the WHERE clause in an attempt to +** get as many WHERE clause terms into the form shown above as possible. +** The aConstraint[] array only reports WHERE clause terms in the correct +** form that refer to the particular virtual table being queried. +** +** Information about the ORDER BY clause is stored in aOrderBy[]. +** Each term of aOrderBy records a column of the ORDER BY clause. +** +** The xBestIndex method must fill aConstraintUsage[] with information +** about what parameters to pass to xFilter. If argvIndex>0 then +** the right-hand side of the corresponding aConstraint[] is evaluated +** and becomes the argvIndex-th entry in argv. If aConstraintUsage[].omit +** is true, then the constraint is assumed to be fully handled by the +** virtual table and is not checked again by SQLite. +** +** The idxNum and idxPtr values are recorded and passed into xFilter. +** sqlite3_free() is used to free idxPtr if needToFreeIdxPtr is true. +** +** The orderByConsumed means that output from xFilter will occur in +** the correct order to satisfy the ORDER BY clause so that no separate +** sorting step is required. +** +** The estimatedCost value is an estimate of the cost of doing the +** particular lookup. A full scan of a table with N entries should have +** a cost of N. A binary search of a table of N entries should have a +** cost of approximately log(N). +*/ +struct sqlite3_index_info { + /* Inputs */ + int nConstraint; /* Number of entries in aConstraint */ + struct sqlite3_index_constraint { + int iColumn; /* Column on left-hand side of constraint */ + unsigned char op; /* Constraint operator */ + unsigned char usable; /* True if this constraint is usable */ + int iTermOffset; /* Used internally - xBestIndex should ignore */ + } *aConstraint; /* Table of WHERE clause constraints */ + int nOrderBy; /* Number of terms in the ORDER BY clause */ + struct sqlite3_index_orderby { + int iColumn; /* Column number */ + unsigned char desc; /* True for DESC. False for ASC. */ + } *aOrderBy; /* The ORDER BY clause */ + + /* Outputs */ + struct sqlite3_index_constraint_usage { + int argvIndex; /* if >0, constraint is part of argv to xFilter */ + unsigned char omit; /* Do not code a test for this constraint */ + } *aConstraintUsage; + int idxNum; /* Number used to identify the index */ + char *idxStr; /* String, possibly obtained from sqlite3_malloc */ + int needToFreeIdxStr; /* Free idxStr using sqlite3_free() if true */ + int orderByConsumed; /* True if output is already ordered */ + double estimatedCost; /* Estimated cost of using this index */ +}; +#define SQLITE_INDEX_CONSTRAINT_EQ 2 +#define SQLITE_INDEX_CONSTRAINT_GT 4 +#define SQLITE_INDEX_CONSTRAINT_LE 8 +#define SQLITE_INDEX_CONSTRAINT_LT 16 +#define SQLITE_INDEX_CONSTRAINT_GE 32 +#define SQLITE_INDEX_CONSTRAINT_MATCH 64 + +/* +** This routine is used to register a new module name with an SQLite +** connection. Module names must be registered before creating new +** virtual tables on the module, or before using preexisting virtual +** tables of the module. +*/ +int sqlite3_create_module( + sqlite3 *db, /* SQLite connection to register module with */ + const char *zName, /* Name of the module */ + const sqlite3_module *, /* Methods for the module */ + void * /* Client data for xCreate/xConnect */ +); + +/* +** This routine is identical to the sqlite3_create_module() method above, +** except that it allows a destructor function to be specified. It is +** even more experimental than the rest of the virtual tables API. +*/ +int sqlite3_create_module_v2( + sqlite3 *db, /* SQLite connection to register module with */ + const char *zName, /* Name of the module */ + const sqlite3_module *, /* Methods for the module */ + void *, /* Client data for xCreate/xConnect */ + void(*xDestroy)(void*) /* Module destructor function */ +); + +/* +** Every module implementation uses a subclass of the following structure +** to describe a particular instance of the module. Each subclass will +** be tailored to the specific needs of the module implementation. The +** purpose of this superclass is to define certain fields that are common +** to all module implementations. +** +** Virtual tables methods can set an error message by assigning a +** string obtained from sqlite3_mprintf() to zErrMsg. The method should +** take care that any prior string is freed by a call to sqlite3_free() +** prior to assigning a new string to zErrMsg. After the error message +** is delivered up to the client application, the string will be automatically +** freed by sqlite3_free() and the zErrMsg field will be zeroed. Note +** that sqlite3_mprintf() and sqlite3_free() are used on the zErrMsg field +** since virtual tables are commonly implemented in loadable extensions which +** do not have access to sqlite3MPrintf() or sqlite3Free(). +*/ +struct sqlite3_vtab { + const sqlite3_module *pModule; /* The module for this virtual table */ + int nRef; /* Used internally */ + char *zErrMsg; /* Error message from sqlite3_mprintf() */ + /* Virtual table implementations will typically add additional fields */ +}; + +/* Every module implementation uses a subclass of the following structure +** to describe cursors that point into the virtual table and are used +** to loop through the virtual table. Cursors are created using the +** xOpen method of the module. Each module implementation will define +** the content of a cursor structure to suit its own needs. +** +** This superclass exists in order to define fields of the cursor that +** are common to all implementations. +*/ +struct sqlite3_vtab_cursor { + sqlite3_vtab *pVtab; /* Virtual table of this cursor */ + /* Virtual table implementations will typically add additional fields */ +}; + +/* +** The xCreate and xConnect methods of a module use the following API +** to declare the format (the names and datatypes of the columns) of +** the virtual tables they implement. +*/ +int sqlite3_declare_vtab(sqlite3*, const char *zCreateTable); + +/* +** Virtual tables can provide alternative implementations of functions +** using the xFindFunction method. But global versions of those functions +** must exist in order to be overloaded. +** +** This API makes sure a global version of a function with a particular +** name and number of parameters exists. If no such function exists +** before this API is called, a new function is created. The implementation +** of the new function always causes an exception to be thrown. So +** the new function is not good for anything by itself. Its only +** purpose is to be a place-holder function that can be overloaded +** by virtual tables. +** +** This API should be considered part of the virtual table interface, +** which is experimental and subject to change. +*/ +int sqlite3_overload_function(sqlite3*, const char *zFuncName, int nArg); + +/* +** The interface to the virtual-table mechanism defined above (back up +** to a comment remarkably similar to this one) is currently considered +** to be experimental. The interface might change in incompatible ways. +** If this is a problem for you, do not use the interface at this time. +** +** When the virtual-table mechanism stabilizes, we will declare the +** interface fixed, support it indefinitely, and remove this comment. +** +****** EXPERIMENTAL - subject to change without notice ************** +*/ + +/* +** CAPI3REF: A Handle To An Open BLOB +** +** An instance of the following opaque structure is used to +** represent an blob-handle. A blob-handle is created by +** [sqlite3_blob_open()] and destroyed by [sqlite3_blob_close()]. +** The [sqlite3_blob_read()] and [sqlite3_blob_write()] interfaces +** can be used to read or write small subsections of the blob. +** The [sqlite3_blob_bytes()] interface returns the size of the +** blob in bytes. +*/ +typedef struct sqlite3_blob sqlite3_blob; + +/* +** CAPI3REF: Open A BLOB For Incremental I/O +** +** Open a handle to the blob located in row iRow,, column zColumn, +** table zTable in database zDb. i.e. the same blob that would +** be selected by: +** +** <pre> +** SELECT zColumn FROM zDb.zTable WHERE rowid = iRow; +** </pre> +** +** If the flags parameter is non-zero, the blob is opened for +** read and write access. If it is zero, the blob is opened for read +** access. +** +** On success, [SQLITE_OK] is returned and the new +** [sqlite3_blob | blob handle] is written to *ppBlob. +** Otherwise an error code is returned and +** any value written to *ppBlob should not be used by the caller. +** This function sets the database-handle error code and message +** accessible via [sqlite3_errcode()] and [sqlite3_errmsg()]. +*/ +int sqlite3_blob_open( + sqlite3*, + const char *zDb, + const char *zTable, + const char *zColumn, + sqlite3_int64 iRow, + int flags, + sqlite3_blob **ppBlob +); + +/* +** CAPI3REF: Close A BLOB Handle +** +** Close an open [sqlite3_blob | blob handle]. +*/ +int sqlite3_blob_close(sqlite3_blob *); + +/* +** CAPI3REF: Return The Size Of An Open BLOB +** +** Return the size in bytes of the blob accessible via the open +** [sqlite3_blob | blob-handle] passed as an argument. +*/ +int sqlite3_blob_bytes(sqlite3_blob *); + +/* +** CAPI3REF: Read Data From A BLOB Incrementally +** +** This function is used to read data from an open +** [sqlite3_blob | blob-handle] into a caller supplied buffer. +** n bytes of data are copied into buffer +** z from the open blob, starting at offset iOffset. +** +** On success, SQLITE_OK is returned. Otherwise, an +** [SQLITE_ERROR | SQLite error code] or an +** [SQLITE_IOERR_READ | extended error code] is returned. +*/ +int sqlite3_blob_read(sqlite3_blob *, void *z, int n, int iOffset); + +/* +** CAPI3REF: Write Data Into A BLOB Incrementally +** +** This function is used to write data into an open +** [sqlite3_blob | blob-handle] from a user supplied buffer. +** n bytes of data are copied from the buffer +** pointed to by z into the open blob, starting at offset iOffset. +** +** If the [sqlite3_blob | blob-handle] passed as the first argument +** was not opened for writing (the flags parameter to [sqlite3_blob_open()] +*** was zero), this function returns [SQLITE_READONLY]. +** +** This function may only modify the contents of the blob, it is +** not possible to increase the size of a blob using this API. If +** offset iOffset is less than n bytes from the end of the blob, +** [SQLITE_ERROR] is returned and no data is written. +** +** On success, SQLITE_OK is returned. Otherwise, an +** [SQLITE_ERROR | SQLite error code] or an +** [SQLITE_IOERR_READ | extended error code] is returned. +*/ +int sqlite3_blob_write(sqlite3_blob *, const void *z, int n, int iOffset); + +/* +** CAPI3REF: Virtual File System Objects +** +** A virtual filesystem (VFS) is an [sqlite3_vfs] object +** that SQLite uses to interact +** with the underlying operating system. Most builds come with a +** single default VFS that is appropriate for the host computer. +** New VFSes can be registered and existing VFSes can be unregistered. +** The following interfaces are provided. +** +** The sqlite3_vfs_find() interface returns a pointer to a VFS given its +** name. Names are case sensitive. If there is no match, a NULL +** pointer is returned. If zVfsName is NULL then the default +** VFS is returned. +** +** New VFSes are registered with sqlite3_vfs_register(). Each +** new VFS becomes the default VFS if the makeDflt flag is set. +** The same VFS can be registered multiple times without injury. +** To make an existing VFS into the default VFS, register it again +** with the makeDflt flag set. If two different VFSes with the +** same name are registered, the behavior is undefined. If a +** VFS is registered with a name that is NULL or an empty string, +** then the behavior is undefined. +** +** Unregister a VFS with the sqlite3_vfs_unregister() interface. +** If the default VFS is unregistered, another VFS is chosen as +** the default. The choice for the new VFS is arbitrary. +*/ +sqlite3_vfs *sqlite3_vfs_find(const char *zVfsName); +int sqlite3_vfs_register(sqlite3_vfs*, int makeDflt); +int sqlite3_vfs_unregister(sqlite3_vfs*); + +/* +** CAPI3REF: Mutexes +** +** The SQLite core uses these routines for thread +** synchronization. Though they are intended for internal +** use by SQLite, code that links against SQLite is +** permitted to use any of these routines. +** +** The SQLite source code contains multiple implementations +** of these mutex routines. An appropriate implementation +** is selected automatically at compile-time. The following +** implementations are available in the SQLite core: +** +** <ul> +** <li> SQLITE_MUTEX_OS2 +** <li> SQLITE_MUTEX_PTHREAD +** <li> SQLITE_MUTEX_W32 +** <li> SQLITE_MUTEX_NOOP +** </ul> +** +** The SQLITE_MUTEX_NOOP implementation is a set of routines +** that does no real locking and is appropriate for use in +** a single-threaded application. The SQLITE_MUTEX_OS2, +** SQLITE_MUTEX_PTHREAD, and SQLITE_MUTEX_W32 implementations +** are appropriate for use on os/2, unix, and windows. +** +** If SQLite is compiled with the SQLITE_MUTEX_APPDEF preprocessor +** macro defined (with "-DSQLITE_MUTEX_APPDEF=1"), then no mutex +** implementation is included with the library. The +** mutex interface routines defined here become external +** references in the SQLite library for which implementations +** must be provided by the application. This facility allows an +** application that links against SQLite to provide its own mutex +** implementation without having to modify the SQLite core. +** +** The sqlite3_mutex_alloc() routine allocates a new +** mutex and returns a pointer to it. If it returns NULL +** that means that a mutex could not be allocated. SQLite +** will unwind its stack and return an error. The argument +** to sqlite3_mutex_alloc() is one of these integer constants: +** +** <ul> +** <li> SQLITE_MUTEX_FAST +** <li> SQLITE_MUTEX_RECURSIVE +** <li> SQLITE_MUTEX_STATIC_MASTER +** <li> SQLITE_MUTEX_STATIC_MEM +** <li> SQLITE_MUTEX_STATIC_MEM2 +** <li> SQLITE_MUTEX_STATIC_PRNG +** <li> SQLITE_MUTEX_STATIC_LRU +** </ul> +** +** The first two constants cause sqlite3_mutex_alloc() to create +** a new mutex. The new mutex is recursive when SQLITE_MUTEX_RECURSIVE +** is used but not necessarily so when SQLITE_MUTEX_FAST is used. +** The mutex implementation does not need to make a distinction +** between SQLITE_MUTEX_RECURSIVE and SQLITE_MUTEX_FAST if it does +** not want to. But SQLite will only request a recursive mutex in +** cases where it really needs one. If a faster non-recursive mutex +** implementation is available on the host platform, the mutex subsystem +** might return such a mutex in response to SQLITE_MUTEX_FAST. +** +** The other allowed parameters to sqlite3_mutex_alloc() each return +** a pointer to a static preexisting mutex. Four static mutexes are +** used by the current version of SQLite. Future versions of SQLite +** may add additional static mutexes. Static mutexes are for internal +** use by SQLite only. Applications that use SQLite mutexes should +** use only the dynamic mutexes returned by SQLITE_MUTEX_FAST or +** SQLITE_MUTEX_RECURSIVE. +** +** Note that if one of the dynamic mutex parameters (SQLITE_MUTEX_FAST +** or SQLITE_MUTEX_RECURSIVE) is used then sqlite3_mutex_alloc() +** returns a different mutex on every call. But for the static +** mutex types, the same mutex is returned on every call that has +** the same type number. +** +** The sqlite3_mutex_free() routine deallocates a previously +** allocated dynamic mutex. SQLite is careful to deallocate every +** dynamic mutex that it allocates. The dynamic mutexes must not be in +** use when they are deallocated. Attempting to deallocate a static +** mutex results in undefined behavior. SQLite never deallocates +** a static mutex. +** +** The sqlite3_mutex_enter() and sqlite3_mutex_try() routines attempt +** to enter a mutex. If another thread is already within the mutex, +** sqlite3_mutex_enter() will block and sqlite3_mutex_try() will return +** SQLITE_BUSY. The sqlite3_mutex_try() interface returns SQLITE_OK +** upon successful entry. Mutexes created using SQLITE_MUTEX_RECURSIVE can +** be entered multiple times by the same thread. In such cases the, +** mutex must be exited an equal number of times before another thread +** can enter. If the same thread tries to enter any other kind of mutex +** more than once, the behavior is undefined. SQLite will never exhibit +** such behavior in its own use of mutexes. +** +** Some systems (ex: windows95) do not the operation implemented by +** sqlite3_mutex_try(). On those systems, sqlite3_mutex_try() will +** always return SQLITE_BUSY. The SQLite core only ever uses +** sqlite3_mutex_try() as an optimization so this is acceptable behavior. +** +** The sqlite3_mutex_leave() routine exits a mutex that was +** previously entered by the same thread. The behavior +** is undefined if the mutex is not currently entered by the +** calling thread or is not currently allocated. SQLite will +** never do either. +** +** See also: [sqlite3_mutex_held()] and [sqlite3_mutex_notheld()]. +*/ +sqlite3_mutex *sqlite3_mutex_alloc(int); +void sqlite3_mutex_free(sqlite3_mutex*); +void sqlite3_mutex_enter(sqlite3_mutex*); +int sqlite3_mutex_try(sqlite3_mutex*); +void sqlite3_mutex_leave(sqlite3_mutex*); + +/* +** CAPI3REF: Mutex Verifcation Routines +** +** The sqlite3_mutex_held() and sqlite3_mutex_notheld() routines +** are intended for use inside assert() statements. The SQLite core +** never uses these routines except inside an assert() and applications +** are advised to follow the lead of the core. The core only +** provides implementations for these routines when it is compiled +** with the SQLITE_DEBUG flag. External mutex implementations +** are only required to provide these routines if SQLITE_DEBUG is +** defined and if NDEBUG is not defined. +** +** These routines should return true if the mutex in their argument +** is held or not held, respectively, by the calling thread. +** +** The implementation is not required to provided versions of these +** routines that actually work. +** If the implementation does not provide working +** versions of these routines, it should at least provide stubs +** that always return true so that one does not get spurious +** assertion failures. +** +** If the argument to sqlite3_mutex_held() is a NULL pointer then +** the routine should return 1. This seems counter-intuitive since +** clearly the mutex cannot be held if it does not exist. But the +** the reason the mutex does not exist is because the build is not +** using mutexes. And we do not want the assert() containing the +** call to sqlite3_mutex_held() to fail, so a non-zero return is +** the appropriate thing to do. The sqlite3_mutex_notheld() +** interface should also return 1 when given a NULL pointer. +*/ +int sqlite3_mutex_held(sqlite3_mutex*); +int sqlite3_mutex_notheld(sqlite3_mutex*); + +/* +** CAPI3REF: Mutex Types +** +** The [sqlite3_mutex_alloc()] interface takes a single argument +** which is one of these integer constants. +*/ +#define SQLITE_MUTEX_FAST 0 +#define SQLITE_MUTEX_RECURSIVE 1 +#define SQLITE_MUTEX_STATIC_MASTER 2 +#define SQLITE_MUTEX_STATIC_MEM 3 /* sqlite3_malloc() */ +#define SQLITE_MUTEX_STATIC_MEM2 4 /* sqlite3_release_memory() */ +#define SQLITE_MUTEX_STATIC_PRNG 5 /* sqlite3_random() */ +#define SQLITE_MUTEX_STATIC_LRU 6 /* lru page list */ + +/* +** CAPI3REF: Low-Level Control Of Database Files +** +** The [sqlite3_file_control()] interface makes a direct call to the +** xFileControl method for the [sqlite3_io_methods] object associated +** with a particular database identified by the second argument. The +** name of the database is the name assigned to the database by the +** <a href="lang_attach.html">ATTACH</a> SQL command that opened the +** database. To control the main database file, use the name "main" +** or a NULL pointer. The third and fourth parameters to this routine +** are passed directly through to the second and third parameters of +** the xFileControl method. The return value of the xFileControl +** method becomes the return value of this routine. +** +** If the second parameter (zDbName) does not match the name of any +** open database file, then SQLITE_ERROR is returned. This error +** code is not remembered and will not be recalled by [sqlite3_errcode()] +** or [sqlite3_errmsg()]. The underlying xFileControl method might +** also return SQLITE_ERROR. There is no way to distinguish between +** an incorrect zDbName and an SQLITE_ERROR return from the underlying +** xFileControl method. +** +** See also: [SQLITE_FCNTL_LOCKSTATE] +*/ +int sqlite3_file_control(sqlite3*, const char *zDbName, int op, void*); + +/* +** Undo the hack that converts floating point types to integer for +** builds on processors without floating point support. +*/ +#ifdef SQLITE_OMIT_FLOATING_POINT +# undef double +#endif + +#if 0 +} /* End of the 'extern "C"' block */ +#endif +#endif + +/************** End of sqlite3.h *********************************************/ +/************** Continuing where we left off in fts3_tokenizer.h *************/ + +/* +** Structures used by the tokenizer interface. When a new tokenizer +** implementation is registered, the caller provides a pointer to +** an sqlite3_tokenizer_module containing pointers to the callback +** functions that make up an implementation. +** +** When an fts3 table is created, it passes any arguments passed to +** the tokenizer clause of the CREATE VIRTUAL TABLE statement to the +** sqlite3_tokenizer_module.xCreate() function of the requested tokenizer +** implementation. The xCreate() function in turn returns an +** sqlite3_tokenizer structure representing the specific tokenizer to +** be used for the fts3 table (customized by the tokenizer clause arguments). +** +** To tokenize an input buffer, the sqlite3_tokenizer_module.xOpen() +** method is called. It returns an sqlite3_tokenizer_cursor object +** that may be used to tokenize a specific input buffer based on +** the tokenization rules supplied by a specific sqlite3_tokenizer +** object. +*/ +typedef struct sqlite3_tokenizer_module sqlite3_tokenizer_module; +typedef struct sqlite3_tokenizer sqlite3_tokenizer; +typedef struct sqlite3_tokenizer_cursor sqlite3_tokenizer_cursor; + +struct sqlite3_tokenizer_module { + + /* + ** Structure version. Should always be set to 0. + */ + int iVersion; + + /* + ** Create a new tokenizer. The values in the argv[] array are the + ** arguments passed to the "tokenizer" clause of the CREATE VIRTUAL + ** TABLE statement that created the fts3 table. For example, if + ** the following SQL is executed: + ** + ** CREATE .. USING fts3( ... , tokenizer <tokenizer-name> arg1 arg2) + ** + ** then argc is set to 2, and the argv[] array contains pointers + ** to the strings "arg1" and "arg2". + ** + ** This method should return either SQLITE_OK (0), or an SQLite error + ** code. If SQLITE_OK is returned, then *ppTokenizer should be set + ** to point at the newly created tokenizer structure. The generic + ** sqlite3_tokenizer.pModule variable should not be initialised by + ** this callback. The caller will do so. + */ + int (*xCreate)( + int argc, /* Size of argv array */ + const char *const*argv, /* Tokenizer argument strings */ + sqlite3_tokenizer **ppTokenizer /* OUT: Created tokenizer */ + ); + + /* + ** Destroy an existing tokenizer. The fts3 module calls this method + ** exactly once for each successful call to xCreate(). + */ + int (*xDestroy)(sqlite3_tokenizer *pTokenizer); + + /* + ** Create a tokenizer cursor to tokenize an input buffer. The caller + ** is responsible for ensuring that the input buffer remains valid + ** until the cursor is closed (using the xClose() method). + */ + int (*xOpen)( + sqlite3_tokenizer *pTokenizer, /* Tokenizer object */ + const char *pInput, int nBytes, /* Input buffer */ + sqlite3_tokenizer_cursor **ppCursor /* OUT: Created tokenizer cursor */ + ); + + /* + ** Destroy an existing tokenizer cursor. The fts3 module calls this + ** method exactly once for each successful call to xOpen(). + */ + int (*xClose)(sqlite3_tokenizer_cursor *pCursor); + + /* + ** Retrieve the next token from the tokenizer cursor pCursor. This + ** method should either return SQLITE_OK and set the values of the + ** "OUT" variables identified below, or SQLITE_DONE to indicate that + ** the end of the buffer has been reached, or an SQLite error code. + ** + ** *ppToken should be set to point at a buffer containing the + ** normalized version of the token (i.e. after any case-folding and/or + ** stemming has been performed). *pnBytes should be set to the length + ** of this buffer in bytes. The input text that generated the token is + ** identified by the byte offsets returned in *piStartOffset and + ** *piEndOffset. + ** + ** The buffer *ppToken is set to point at is managed by the tokenizer + ** implementation. It is only required to be valid until the next call + ** to xNext() or xClose(). + */ + /* TODO(shess) current implementation requires pInput to be + ** nul-terminated. This should either be fixed, or pInput/nBytes + ** should be converted to zInput. + */ + int (*xNext)( + sqlite3_tokenizer_cursor *pCursor, /* Tokenizer cursor */ + const char **ppToken, int *pnBytes, /* OUT: Normalized text for token */ + int *piStartOffset, /* OUT: Byte offset of token in input buffer */ + int *piEndOffset, /* OUT: Byte offset of end of token in input buffer */ + int *piPosition /* OUT: Number of tokens returned before this one */ + ); +}; + +struct sqlite3_tokenizer { + const sqlite3_tokenizer_module *pModule; /* The module for this tokenizer */ + /* Tokenizer implementations will typically add additional fields */ +}; + +struct sqlite3_tokenizer_cursor { + sqlite3_tokenizer *pTokenizer; /* Tokenizer for this cursor. */ + /* Tokenizer implementations will typically add additional fields */ +}; + +#endif /* _FTS3_TOKENIZER_H_ */ + +/************** End of fts3_tokenizer.h **************************************/ +/************** Continuing where we left off in fts3_tokenizer1.c ************/ + +typedef struct simple_tokenizer { + sqlite3_tokenizer base; + char delim[128]; /* flag ASCII delimiters */ +} simple_tokenizer; + +typedef struct simple_tokenizer_cursor { + sqlite3_tokenizer_cursor base; + const char *pInput; /* input we are tokenizing */ + int nBytes; /* size of the input */ + int iOffset; /* current position in pInput */ + int iToken; /* index of next token to be returned */ + char *pToken; /* storage for current token */ + int nTokenAllocated; /* space allocated to zToken buffer */ +} simple_tokenizer_cursor; + + +/* Forward declaration */ +static const sqlite3_tokenizer_module simpleTokenizerModule; + +static int simpleDelim(simple_tokenizer *t, unsigned char c){ + return c<0x80 && t->delim[c]; +} + +/* +** Create a new tokenizer instance. +*/ +static int simpleCreate( + int argc, const char * const *argv, + sqlite3_tokenizer **ppTokenizer +){ + simple_tokenizer *t; + + t = (simple_tokenizer *) sqlite3_malloc(sizeof(*t)); + if( t==NULL ) return SQLITE_NOMEM; + memset(t, 0, sizeof(*t)); + + /* TODO(shess) Delimiters need to remain the same from run to run, + ** else we need to reindex. One solution would be a meta-table to + ** track such information in the database, then we'd only want this + ** information on the initial create. + */ + if( argc>1 ){ + int i, n = strlen(argv[1]); + for(i=0; i<n; i++){ + unsigned char ch = argv[1][i]; + /* We explicitly don't support UTF-8 delimiters for now. */ + if( ch>=0x80 ){ + sqlite3_free(t); + return SQLITE_ERROR; + } + t->delim[ch] = 1; + } + } else { + /* Mark non-alphanumeric ASCII characters as delimiters */ + int i; + for(i=1; i<0x80; i++){ + t->delim[i] = !isalnum(i); + } + } + + *ppTokenizer = &t->base; + return SQLITE_OK; +} + +/* +** Destroy a tokenizer +*/ +static int simpleDestroy(sqlite3_tokenizer *pTokenizer){ + sqlite3_free(pTokenizer); + return SQLITE_OK; +} + +/* +** Prepare to begin tokenizing a particular string. The input +** string to be tokenized is pInput[0..nBytes-1]. A cursor +** used to incrementally tokenize this string is returned in +** *ppCursor. +*/ +static int simpleOpen( + sqlite3_tokenizer *pTokenizer, /* The tokenizer */ + const char *pInput, int nBytes, /* String to be tokenized */ + sqlite3_tokenizer_cursor **ppCursor /* OUT: Tokenization cursor */ +){ + simple_tokenizer_cursor *c; + + c = (simple_tokenizer_cursor *) sqlite3_malloc(sizeof(*c)); + if( c==NULL ) return SQLITE_NOMEM; + + c->pInput = pInput; + if( pInput==0 ){ + c->nBytes = 0; + }else if( nBytes<0 ){ + c->nBytes = (int)strlen(pInput); + }else{ + c->nBytes = nBytes; + } + c->iOffset = 0; /* start tokenizing at the beginning */ + c->iToken = 0; + c->pToken = NULL; /* no space allocated, yet. */ + c->nTokenAllocated = 0; + + *ppCursor = &c->base; + return SQLITE_OK; +} + +/* +** Close a tokenization cursor previously opened by a call to +** simpleOpen() above. +*/ +static int simpleClose(sqlite3_tokenizer_cursor *pCursor){ + simple_tokenizer_cursor *c = (simple_tokenizer_cursor *) pCursor; + sqlite3_free(c->pToken); + sqlite3_free(c); + return SQLITE_OK; +} + +/* +** Extract the next token from a tokenization cursor. The cursor must +** have been opened by a prior call to simpleOpen(). +*/ +static int simpleNext( + sqlite3_tokenizer_cursor *pCursor, /* Cursor returned by simpleOpen */ + const char **ppToken, /* OUT: *ppToken is the token text */ + int *pnBytes, /* OUT: Number of bytes in token */ + int *piStartOffset, /* OUT: Starting offset of token */ + int *piEndOffset, /* OUT: Ending offset of token */ + int *piPosition /* OUT: Position integer of token */ +){ + simple_tokenizer_cursor *c = (simple_tokenizer_cursor *) pCursor; + simple_tokenizer *t = (simple_tokenizer *) pCursor->pTokenizer; + unsigned char *p = (unsigned char *)c->pInput; + + while( c->iOffset<c->nBytes ){ + int iStartOffset; + + /* Scan past delimiter characters */ + while( c->iOffset<c->nBytes && simpleDelim(t, p[c->iOffset]) ){ + c->iOffset++; + } + + /* Count non-delimiter characters. */ + iStartOffset = c->iOffset; + while( c->iOffset<c->nBytes && !simpleDelim(t, p[c->iOffset]) ){ + c->iOffset++; + } + + if( c->iOffset>iStartOffset ){ + int i, n = c->iOffset-iStartOffset; + if( n>c->nTokenAllocated ){ + c->nTokenAllocated = n+20; + c->pToken = sqlite3_realloc(c->pToken, c->nTokenAllocated); + if( c->pToken==NULL ) return SQLITE_NOMEM; + } + for(i=0; i<n; i++){ + /* TODO(shess) This needs expansion to handle UTF-8 + ** case-insensitivity. + */ + unsigned char ch = p[iStartOffset+i]; + c->pToken[i] = ch<0x80 ? tolower(ch) : ch; + } + *ppToken = c->pToken; + *pnBytes = n; + *piStartOffset = iStartOffset; + *piEndOffset = c->iOffset; + *piPosition = c->iToken++; + + return SQLITE_OK; + } + } + return SQLITE_DONE; +} + +/* +** The set of routines that implement the simple tokenizer +*/ +static const sqlite3_tokenizer_module simpleTokenizerModule = { + 0, + simpleCreate, + simpleDestroy, + simpleOpen, + simpleClose, + simpleNext, +}; + +/* +** Allocate a new simple tokenizer. Return a pointer to the new +** tokenizer in *ppModule +*/ +void sqlite3Fts3SimpleTokenizerModule( + sqlite3_tokenizer_module const**ppModule +){ + *ppModule = &simpleTokenizerModule; +} + +#endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) */ + +/************** End of fts3_tokenizer1.c *************************************/ +/************** Begin file fts3_icu.c ****************************************/ +/* +** 2007 June 22 +** +** 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 a tokenizer for fts3 based on the ICU library. +** +** $Id: fts3_icu.c,v 1.2 2007/10/24 21:52:37 shess Exp $ +*/ + +#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) +#ifdef SQLITE_ENABLE_ICU + +/************** Include fts3_tokenizer.h in the middle of fts3_icu.c *********/ +/************** Begin file fts3_tokenizer.h **********************************/ +/* +** 2006 July 10 +** +** The author disclaims copyright to this source code. +** +************************************************************************* +** Defines the interface to tokenizers used by fulltext-search. There +** are three basic components: +** +** sqlite3_tokenizer_module is a singleton defining the tokenizer +** interface functions. This is essentially the class structure for +** tokenizers. +** +** sqlite3_tokenizer is used to define a particular tokenizer, perhaps +** including customization information defined at creation time. +** +** sqlite3_tokenizer_cursor is generated by a tokenizer to generate +** tokens from a particular input. +*/ +#ifndef _FTS3_TOKENIZER_H_ +#define _FTS3_TOKENIZER_H_ + +/* TODO(shess) Only used for SQLITE_OK and SQLITE_DONE at this time. +** If tokenizers are to be allowed to call sqlite3_*() functions, then +** we will need a way to register the API consistently. +*/ +/************** Include sqlite3.h in the middle of fts3_tokenizer.h **********/ +/************** Begin file sqlite3.h *****************************************/ +/* +** 2001 September 15 +** +** 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 header file defines the interface that the SQLite library +** presents to client programs. If a C-function, structure, datatype, +** or constant definition does not appear in this file, then it is +** not a published API of SQLite, is subject to change without +** notice, and should not be referenced by programs that use SQLite. +** +** Some of the definitions that are in this file are marked as +** "experimental". Experimental interfaces are normally new +** features recently added to SQLite. We do not anticipate changes +** to experimental interfaces but reserve to make minor changes if +** experience from use "in the wild" suggest such changes are prudent. +** +** The official C-language API documentation for SQLite is derived +** from comments in this file. This file is the authoritative source +** on how SQLite interfaces are suppose to operate. +** +** The name of this file under configuration management is "sqlite.h.in". +** The makefile makes some minor changes to this file (such as inserting +** the version number) and changes its name to "sqlite3.h" as +** part of the build process. +** +** @(#) $Id: sqlite.h.in,v 1.271 2007/11/21 15:24:01 drh Exp $ +*/ +#ifndef _SQLITE3_H_ +#define _SQLITE3_H_ + +/* +** Make sure we can call this stuff from C++. +*/ +#if 0 +extern "C" { +#endif + + +/* +** Add the ability to override 'extern' +*/ +#ifndef SQLITE_EXTERN +# define SQLITE_EXTERN extern +#endif + +/* +** Make sure these symbols where not defined by some previous header +** file. +*/ +#ifdef SQLITE_VERSION +# undef SQLITE_VERSION +#endif +#ifdef SQLITE_VERSION_NUMBER +# undef SQLITE_VERSION_NUMBER +#endif + +/* +** CAPI3REF: Compile-Time Library Version Numbers +** +** The version of the SQLite library is contained in the sqlite3.h +** header file in a #define named SQLITE_VERSION. The SQLITE_VERSION +** macro resolves to a string constant. +** +** The format of the version string is "X.Y.Z", where +** X is the major version number, Y is the minor version number and Z +** is the release number. The X.Y.Z might be followed by "alpha" or "beta". +** For example "3.1.1beta". +** +** The X value is always 3 in SQLite. The X value only changes when +** backwards compatibility is broken and we intend to never break +** backwards compatibility. The Y value only changes when +** there are major feature enhancements that are forwards compatible +** but not backwards compatible. The Z value is incremented with +** each release but resets back to 0 when Y is incremented. +** +** The SQLITE_VERSION_NUMBER is an integer with the value +** (X*1000000 + Y*1000 + Z). For example, for version "3.1.1beta", +** SQLITE_VERSION_NUMBER is set to 3001001. To detect if they are using +** version 3.1.1 or greater at compile time, programs may use the test +** (SQLITE_VERSION_NUMBER>=3001001). +** +** See also: [sqlite3_libversion()] and [sqlite3_libversion_number()]. +*/ +#define SQLITE_VERSION "3.5.2" +#define SQLITE_VERSION_NUMBER 3005002 + +/* +** CAPI3REF: Run-Time Library Version Numbers +** +** These routines return values equivalent to the header constants +** [SQLITE_VERSION] and [SQLITE_VERSION_NUMBER]. The values returned +** by this routines should only be different from the header values +** if you compile your program using an sqlite3.h header from a +** different version of SQLite that the version of the library you +** link against. +** +** The sqlite3_version[] string constant contains the text of the +** [SQLITE_VERSION] string. The sqlite3_libversion() function returns +** a poiner to the sqlite3_version[] string constant. The function +** is provided for DLL users who can only access functions and not +** constants within the DLL. +*/ +SQLITE_EXTERN const char sqlite3_version[]; +const char *sqlite3_libversion(void); +int sqlite3_libversion_number(void); + +/* +** CAPI3REF: Test To See If The Library Is Threadsafe +** +** This routine returns TRUE (nonzero) if SQLite was compiled with +** all of its mutexes enabled and is thus threadsafe. It returns +** zero if the particular build is for single-threaded operation +** only. +** +** Really all this routine does is return true if SQLite was compiled +** with the -DSQLITE_THREADSAFE=1 option and false if +** compiled with -DSQLITE_THREADSAFE=0. If SQLite uses an +** application-defined mutex subsystem, malloc subsystem, collating +** sequence, VFS, SQL function, progress callback, commit hook, +** extension, or other accessories and these add-ons are not +** threadsafe, then clearly the combination will not be threadsafe +** either. Hence, this routine never reports that the library +** is guaranteed to be threadsafe, only when it is guaranteed not +** to be. +** +** This is an experimental API and may go away or change in future +** releases. +*/ +int sqlite3_threadsafe(void); + +/* +** CAPI3REF: Database Connection Handle +** +** Each open SQLite database is represented by pointer to an instance of the +** opaque structure named "sqlite3". It is useful to think of an sqlite3 +** pointer as an object. The [sqlite3_open()], [sqlite3_open16()], and +** [sqlite3_open_v2()] interfaces are its constructors +** and [sqlite3_close()] is its destructor. There are many other interfaces +** (such as [sqlite3_prepare_v2()], [sqlite3_create_function()], and +** [sqlite3_busy_timeout()] to name but three) that are methods on this +** object. +*/ +typedef struct sqlite3 sqlite3; + + +/* +** CAPI3REF: 64-Bit Integer Types +** +** Some compilers do not support the "long long" datatype. So we have +** to do compiler-specific typedefs for 64-bit signed and unsigned integers. +** +** Many SQLite interface functions require a 64-bit integer arguments. +** Those interfaces are declared using this typedef. +*/ +#ifdef SQLITE_INT64_TYPE + typedef SQLITE_INT64_TYPE sqlite_int64; + typedef unsigned SQLITE_INT64_TYPE sqlite_uint64; +#elif defined(_MSC_VER) || defined(__BORLANDC__) + typedef __int64 sqlite_int64; + typedef unsigned __int64 sqlite_uint64; +#else + typedef long long int sqlite_int64; + typedef unsigned long long int sqlite_uint64; +#endif +typedef sqlite_int64 sqlite3_int64; +typedef sqlite_uint64 sqlite3_uint64; + +/* +** If compiling for a processor that lacks floating point support, +** substitute integer for floating-point +*/ +#ifdef SQLITE_OMIT_FLOATING_POINT +# define double sqlite3_int64 +#endif + +/* +** CAPI3REF: Closing A Database Connection +** +** Call this function with a pointer to a structure that was previously +** returned from [sqlite3_open()], [sqlite3_open16()], or +** [sqlite3_open_v2()] and the corresponding database will by +** closed. +** +** All SQL statements prepared using [sqlite3_prepare_v2()] or +** [sqlite3_prepare16_v2()] must be destroyed using [sqlite3_finalize()] +** before this routine is called. Otherwise, SQLITE_BUSY is returned and the +** database connection remains open. +** +** Passing this routine a database connection that has already been +** closed results in undefined behavior. If other interfaces that +** reference the same database connection are pending (either in the +** same thread or in different threads) when this routine is called, +** then the behavior is undefined and is almost certainly undesirable. +*/ +int sqlite3_close(sqlite3 *); + +/* +** The type for a callback function. +** This is legacy and deprecated. It is included for historical +** compatibility and is not documented. +*/ +typedef int (*sqlite3_callback)(void*,int,char**, char**); + +/* +** CAPI3REF: One-Step Query Execution Interface +** +** This interface is used to do a one-time evaluatation of zero +** or more SQL statements. UTF-8 text of the SQL statements to +** be evaluted is passed in as the second parameter. The statements +** are prepared one by one using [sqlite3_prepare()], evaluated +** using [sqlite3_step()], then destroyed using [sqlite3_finalize()]. +** +** If one or more of the SQL statements are queries, then +** the callback function specified by the 3rd parameter is +** invoked once for each row of the query result. This callback +** should normally return 0. If the callback returns a non-zero +** value then the query is aborted, all subsequent SQL statements +** are skipped and the sqlite3_exec() function returns the [SQLITE_ABORT]. +** +** The 4th parameter to this interface is an arbitrary pointer that is +** passed through to the callback function as its first parameter. +** +** The 2nd parameter to the callback function is the number of +** columns in the query result. The 3rd parameter to the callback +** is an array of strings holding the values for each column +** as extracted using [sqlite3_column_text()]. +** The 4th parameter to the callback is an array of strings +** obtained using [sqlite3_column_name()] and holding +** the names of each column. +** +** The callback function may be NULL, even for queries. A NULL +** callback is not an error. It just means that no callback +** will be invoked. +** +** If an error occurs while parsing or evaluating the SQL (but +** not while executing the callback) then an appropriate error +** message is written into memory obtained from [sqlite3_malloc()] and +** *errmsg is made to point to that message. The calling function +** is responsible for freeing the memory using [sqlite3_free()]. +** If errmsg==NULL, then no error message is ever written. +** +** The return value is is SQLITE_OK if there are no errors and +** some other [SQLITE_OK | return code] if there is an error. +** The particular return value depends on the type of error. +** +*/ +int sqlite3_exec( + sqlite3*, /* An open database */ + const char *sql, /* SQL to be evaluted */ + int (*callback)(void*,int,char**,char**), /* Callback function */ + void *, /* 1st argument to callback */ + char **errmsg /* Error msg written here */ +); + +/* +** CAPI3REF: Result Codes +** KEYWORDS: SQLITE_OK +** +** Many SQLite functions return an integer result code from the set shown +** above in order to indicates success or failure. +** +** The result codes above are the only ones returned by SQLite in its +** default configuration. However, the [sqlite3_extended_result_codes()] +** API can be used to set a database connectoin to return more detailed +** result codes. +** +** See also: [SQLITE_IOERR_READ | extended result codes] +** +*/ +#define SQLITE_OK 0 /* Successful result */ +/* beginning-of-error-codes */ +#define SQLITE_ERROR 1 /* SQL error or missing database */ +#define SQLITE_INTERNAL 2 /* NOT USED. Internal logic error in SQLite */ +#define SQLITE_PERM 3 /* Access permission denied */ +#define SQLITE_ABORT 4 /* Callback routine requested an abort */ +#define SQLITE_BUSY 5 /* The database file is locked */ +#define SQLITE_LOCKED 6 /* A table in the database is locked */ +#define SQLITE_NOMEM 7 /* A malloc() failed */ +#define SQLITE_READONLY 8 /* Attempt to write a readonly database */ +#define SQLITE_INTERRUPT 9 /* Operation terminated by sqlite3_interrupt()*/ +#define SQLITE_IOERR 10 /* Some kind of disk I/O error occurred */ +#define SQLITE_CORRUPT 11 /* The database disk image is malformed */ +#define SQLITE_NOTFOUND 12 /* NOT USED. Table or record not found */ +#define SQLITE_FULL 13 /* Insertion failed because database is full */ +#define SQLITE_CANTOPEN 14 /* Unable to open the database file */ +#define SQLITE_PROTOCOL 15 /* NOT USED. Database lock protocol error */ +#define SQLITE_EMPTY 16 /* Database is empty */ +#define SQLITE_SCHEMA 17 /* The database schema changed */ +#define SQLITE_TOOBIG 18 /* String or BLOB exceeds size limit */ +#define SQLITE_CONSTRAINT 19 /* Abort due to constraint violation */ +#define SQLITE_MISMATCH 20 /* Data type mismatch */ +#define SQLITE_MISUSE 21 /* Library used incorrectly */ +#define SQLITE_NOLFS 22 /* Uses OS features not supported on host */ +#define SQLITE_AUTH 23 /* Authorization denied */ +#define SQLITE_FORMAT 24 /* Auxiliary database format error */ +#define SQLITE_RANGE 25 /* 2nd parameter to sqlite3_bind out of range */ +#define SQLITE_NOTADB 26 /* File opened that is not a database file */ +#define SQLITE_ROW 100 /* sqlite3_step() has another row ready */ +#define SQLITE_DONE 101 /* sqlite3_step() has finished executing */ +/* end-of-error-codes */ + +/* +** CAPI3REF: Extended Result Codes +** +** In its default configuration, SQLite API routines return one of 26 integer +** result codes described at result-codes. However, experience has shown that +** many of these result codes are too course-grained. They do not provide as +** much information about problems as users might like. In an effort to +** address this, newer versions of SQLite (version 3.3.8 and later) include +** support for additional result codes that provide more detailed information +** about errors. The extended result codes are enabled (or disabled) for +** each database +** connection using the [sqlite3_extended_result_codes()] API. +** +** Some of the available extended result codes are listed above. +** We expect the number of extended result codes will be expand +** over time. Software that uses extended result codes should expect +** to see new result codes in future releases of SQLite. +** +** The symbolic name for an extended result code always contains a related +** primary result code as a prefix. Primary result codes contain a single +** "_" character. Extended result codes contain two or more "_" characters. +** The numeric value of an extended result code can be converted to its +** corresponding primary result code by masking off the lower 8 bytes. +** +** The SQLITE_OK result code will never be extended. It will always +** be exactly zero. +*/ +#define SQLITE_IOERR_READ (SQLITE_IOERR | (1<<8)) +#define SQLITE_IOERR_SHORT_READ (SQLITE_IOERR | (2<<8)) +#define SQLITE_IOERR_WRITE (SQLITE_IOERR | (3<<8)) +#define SQLITE_IOERR_FSYNC (SQLITE_IOERR | (4<<8)) +#define SQLITE_IOERR_DIR_FSYNC (SQLITE_IOERR | (5<<8)) +#define SQLITE_IOERR_TRUNCATE (SQLITE_IOERR | (6<<8)) +#define SQLITE_IOERR_FSTAT (SQLITE_IOERR | (7<<8)) +#define SQLITE_IOERR_UNLOCK (SQLITE_IOERR | (8<<8)) +#define SQLITE_IOERR_RDLOCK (SQLITE_IOERR | (9<<8)) +#define SQLITE_IOERR_DELETE (SQLITE_IOERR | (10<<8)) +#define SQLITE_IOERR_BLOCKED (SQLITE_IOERR | (11<<8)) +#define SQLITE_IOERR_NOMEM (SQLITE_IOERR | (12<<8)) + +/* +** CAPI3REF: Flags For File Open Operations +** +** Combination of the following bit values are used as the +** third argument to the [sqlite3_open_v2()] interface and +** as fourth argument to the xOpen method of the +** [sqlite3_vfs] object. +** +*/ +#define SQLITE_OPEN_READONLY 0x00000001 +#define SQLITE_OPEN_READWRITE 0x00000002 +#define SQLITE_OPEN_CREATE 0x00000004 +#define SQLITE_OPEN_DELETEONCLOSE 0x00000008 +#define SQLITE_OPEN_EXCLUSIVE 0x00000010 +#define SQLITE_OPEN_MAIN_DB 0x00000100 +#define SQLITE_OPEN_TEMP_DB 0x00000200 +#define SQLITE_OPEN_TRANSIENT_DB 0x00000400 +#define SQLITE_OPEN_MAIN_JOURNAL 0x00000800 +#define SQLITE_OPEN_TEMP_JOURNAL 0x00001000 +#define SQLITE_OPEN_SUBJOURNAL 0x00002000 +#define SQLITE_OPEN_MASTER_JOURNAL 0x00004000 + +/* +** CAPI3REF: Device Characteristics +** +** The xDeviceCapabilities method of the [sqlite3_io_methods] +** object returns an integer which is a vector of the following +** bit values expressing I/O characteristics of the mass storage +** device that holds the file that the [sqlite3_io_methods] +** refers to. +** +** The SQLITE_IOCAP_ATOMIC property means that all writes of +** any size are atomic. The SQLITE_IOCAP_ATOMICnnn values +** mean that writes of blocks that are nnn bytes in size and +** are aligned to an address which is an integer multiple of +** nnn are atomic. The SQLITE_IOCAP_SAFE_APPEND value means +** that when data is appended to a file, the data is appended +** first then the size of the file is extended, never the other +** way around. The SQLITE_IOCAP_SEQUENTIAL property means that +** information is written to disk in the same order as calls +** to xWrite(). +*/ +#define SQLITE_IOCAP_ATOMIC 0x00000001 +#define SQLITE_IOCAP_ATOMIC512 0x00000002 +#define SQLITE_IOCAP_ATOMIC1K 0x00000004 +#define SQLITE_IOCAP_ATOMIC2K 0x00000008 +#define SQLITE_IOCAP_ATOMIC4K 0x00000010 +#define SQLITE_IOCAP_ATOMIC8K 0x00000020 +#define SQLITE_IOCAP_ATOMIC16K 0x00000040 +#define SQLITE_IOCAP_ATOMIC32K 0x00000080 +#define SQLITE_IOCAP_ATOMIC64K 0x00000100 +#define SQLITE_IOCAP_SAFE_APPEND 0x00000200 +#define SQLITE_IOCAP_SEQUENTIAL 0x00000400 + +/* +** CAPI3REF: File Locking Levels +** +** SQLite uses one of the following integer values as the second +** argument to calls it makes to the xLock() and xUnlock() methods +** of an [sqlite3_io_methods] object. +*/ +#define SQLITE_LOCK_NONE 0 +#define SQLITE_LOCK_SHARED 1 +#define SQLITE_LOCK_RESERVED 2 +#define SQLITE_LOCK_PENDING 3 +#define SQLITE_LOCK_EXCLUSIVE 4 + +/* +** CAPI3REF: Synchronization Type Flags +** +** When SQLite invokes the xSync() method of an [sqlite3_io_methods] +** object it uses a combination of the following integer values as +** the second argument. +** +** When the SQLITE_SYNC_DATAONLY flag is used, it means that the +** sync operation only needs to flush data to mass storage. Inode +** information need not be flushed. The SQLITE_SYNC_NORMAL means +** to use normal fsync() semantics. The SQLITE_SYNC_FULL flag means +** to use Mac OS-X style fullsync instead of fsync(). +*/ +#define SQLITE_SYNC_NORMAL 0x00002 +#define SQLITE_SYNC_FULL 0x00003 +#define SQLITE_SYNC_DATAONLY 0x00010 + + +/* +** CAPI3REF: OS Interface Open File Handle +** +** An [sqlite3_file] object represents an open file in the OS +** interface layer. Individual OS interface implementations will +** want to subclass this object by appending additional fields +** for their own use. The pMethods entry is a pointer to an +** [sqlite3_io_methods] object that defines methods for performing +** I/O operations on the open file. +*/ +typedef struct sqlite3_file sqlite3_file; +struct sqlite3_file { + const struct sqlite3_io_methods *pMethods; /* Methods for an open file */ +}; + +/* +** CAPI3REF: OS Interface File Virtual Methods Object +** +** Every file opened by the [sqlite3_vfs] xOpen method contains a pointer to +** an instance of the this object. This object defines the +** methods used to perform various operations against the open file. +** +** The flags argument to xSync may be one of [SQLITE_SYNC_NORMAL] or +** [SQLITE_SYNC_FULL]. The first choice is the normal fsync(). +* The second choice is an +** OS-X style fullsync. The SQLITE_SYNC_DATA flag may be ORed in to +** indicate that only the data of the file and not its inode needs to be +** synced. +** +** The integer values to xLock() and xUnlock() are one of +** <ul> +** <li> [SQLITE_LOCK_NONE], +** <li> [SQLITE_LOCK_SHARED], +** <li> [SQLITE_LOCK_RESERVED], +** <li> [SQLITE_LOCK_PENDING], or +** <li> [SQLITE_LOCK_EXCLUSIVE]. +** </ul> +** xLock() increases the lock. xUnlock() decreases the lock. +** The xCheckReservedLock() method looks +** to see if any database connection, either in this +** process or in some other process, is holding an RESERVED, +** PENDING, or EXCLUSIVE lock on the file. It returns true +** if such a lock exists and false if not. +** +** The xFileControl() method is a generic interface that allows custom +** VFS implementations to directly control an open file using the +** [sqlite3_file_control()] interface. The second "op" argument +** is an integer opcode. The third +** argument is a generic pointer which is intended to be a pointer +** to a structure that may contain arguments or space in which to +** write return values. Potential uses for xFileControl() might be +** functions to enable blocking locks with timeouts, to change the +** locking strategy (for example to use dot-file locks), to inquire +** about the status of a lock, or to break stale locks. The SQLite +** core reserves opcodes less than 100 for its own use. +** A [SQLITE_FCNTL_LOCKSTATE | list of opcodes] less than 100 is available. +** Applications that define a custom xFileControl method should use opcodes +** greater than 100 to avoid conflicts. +** +** The xSectorSize() method returns the sector size of the +** device that underlies the file. The sector size is the +** minimum write that can be performed without disturbing +** other bytes in the file. The xDeviceCharacteristics() +** method returns a bit vector describing behaviors of the +** underlying device: +** +** <ul> +** <li> [SQLITE_IOCAP_ATOMIC] +** <li> [SQLITE_IOCAP_ATOMIC512] +** <li> [SQLITE_IOCAP_ATOMIC1K] +** <li> [SQLITE_IOCAP_ATOMIC2K] +** <li> [SQLITE_IOCAP_ATOMIC4K] +** <li> [SQLITE_IOCAP_ATOMIC8K] +** <li> [SQLITE_IOCAP_ATOMIC16K] +** <li> [SQLITE_IOCAP_ATOMIC32K] +** <li> [SQLITE_IOCAP_ATOMIC64K] +** <li> [SQLITE_IOCAP_SAFE_APPEND] +** <li> [SQLITE_IOCAP_SEQUENTIAL] +** </ul> +** +** The SQLITE_IOCAP_ATOMIC property means that all writes of +** any size are atomic. The SQLITE_IOCAP_ATOMICnnn values +** mean that writes of blocks that are nnn bytes in size and +** are aligned to an address which is an integer multiple of +** nnn are atomic. The SQLITE_IOCAP_SAFE_APPEND value means +** that when data is appended to a file, the data is appended +** first then the size of the file is extended, never the other +** way around. The SQLITE_IOCAP_SEQUENTIAL property means that +** information is written to disk in the same order as calls +** to xWrite(). +*/ +typedef struct sqlite3_io_methods sqlite3_io_methods; +struct sqlite3_io_methods { + int iVersion; + int (*xClose)(sqlite3_file*); + int (*xRead)(sqlite3_file*, void*, int iAmt, sqlite3_int64 iOfst); + int (*xWrite)(sqlite3_file*, const void*, int iAmt, sqlite3_int64 iOfst); + int (*xTruncate)(sqlite3_file*, sqlite3_int64 size); + int (*xSync)(sqlite3_file*, int flags); + int (*xFileSize)(sqlite3_file*, sqlite3_int64 *pSize); + int (*xLock)(sqlite3_file*, int); + int (*xUnlock)(sqlite3_file*, int); + int (*xCheckReservedLock)(sqlite3_file*); + int (*xFileControl)(sqlite3_file*, int op, void *pArg); + int (*xSectorSize)(sqlite3_file*); + int (*xDeviceCharacteristics)(sqlite3_file*); + /* Additional methods may be added in future releases */ +}; + +/* +** CAPI3REF: Standard File Control Opcodes +** +** These integer constants are opcodes for the xFileControl method +** of the [sqlite3_io_methods] object and to the [sqlite3_file_control()] +** interface. +** +** The [SQLITE_FCNTL_LOCKSTATE] opcode is used for debugging. This +** opcode cases the xFileControl method to write the current state of +** the lock (one of [SQLITE_LOCK_NONE], [SQLITE_LOCK_SHARED], +** [SQLITE_LOCK_RESERVED], [SQLITE_LOCK_PENDING], or [SQLITE_LOCK_EXCLUSIVE]) +** into an integer that the pArg argument points to. This capability +** is used during testing and only needs to be supported when SQLITE_TEST +** is defined. +*/ +#define SQLITE_FCNTL_LOCKSTATE 1 + +/* +** CAPI3REF: Mutex Handle +** +** The mutex module within SQLite defines [sqlite3_mutex] to be an +** abstract type for a mutex object. The SQLite core never looks +** at the internal representation of an [sqlite3_mutex]. It only +** deals with pointers to the [sqlite3_mutex] object. +** +** Mutexes are created using [sqlite3_mutex_alloc()]. +*/ +typedef struct sqlite3_mutex sqlite3_mutex; + +/* +** CAPI3REF: OS Interface Object +** +** An instance of this object defines the interface between the +** SQLite core and the underlying operating system. The "vfs" +** in the name of the object stands for "virtual file system". +** +** The iVersion field is initially 1 but may be larger for future +** versions of SQLite. Additional fields may be appended to this +** object when the iVersion value is increased. +** +** The szOsFile field is the size of the subclassed [sqlite3_file] +** structure used by this VFS. mxPathname is the maximum length of +** a pathname in this VFS. +** +** Registered vfs modules are kept on a linked list formed by +** the pNext pointer. The [sqlite3_vfs_register()] +** and [sqlite3_vfs_unregister()] interfaces manage this list +** in a thread-safe way. The [sqlite3_vfs_find()] interface +** searches the list. +** +** The pNext field is the only fields in the sqlite3_vfs +** structure that SQLite will ever modify. SQLite will only access +** or modify this field while holding a particular static mutex. +** The application should never modify anything within the sqlite3_vfs +** object once the object has been registered. +** +** The zName field holds the name of the VFS module. The name must +** be unique across all VFS modules. +** +** SQLite will guarantee that the zFilename string passed to +** xOpen() is a full pathname as generated by xFullPathname() and +** that the string will be valid and unchanged until xClose() is +** called. So the [sqlite3_file] can store a pointer to the +** filename if it needs to remember the filename for some reason. +** +** The flags argument to xOpen() is a copy of the flags argument +** to [sqlite3_open_v2()]. If [sqlite3_open()] or [sqlite3_open16()] +** is used, then flags is [SQLITE_OPEN_READWRITE] | [SQLITE_OPEN_CREATE]. +** If xOpen() opens a file read-only then it sets *pOutFlags to +** include [SQLITE_OPEN_READONLY]. Other bits in *pOutFlags may be +** set. +** +** SQLite will also add one of the following flags to the xOpen() +** call, depending on the object being opened: +** +** <ul> +** <li> [SQLITE_OPEN_MAIN_DB] +** <li> [SQLITE_OPEN_MAIN_JOURNAL] +** <li> [SQLITE_OPEN_TEMP_DB] +** <li> [SQLITE_OPEN_TEMP_JOURNAL] +** <li> [SQLITE_OPEN_TRANSIENT_DB] +** <li> [SQLITE_OPEN_SUBJOURNAL] +** <li> [SQLITE_OPEN_MASTER_JOURNAL] +** </ul> +** +** The file I/O implementation can use the object type flags to +** changes the way it deals with files. For example, an application +** that does not care about crash recovery or rollback, might make +** the open of a journal file a no-op. Writes to this journal are +** also a no-op. Any attempt to read the journal return SQLITE_IOERR. +** Or the implementation might recognize the a database file will +** be doing page-aligned sector reads and writes in a random order +** and set up its I/O subsystem accordingly. +** +** SQLite might also add one of the following flags to the xOpen +** method: +** +** <ul> +** <li> [SQLITE_OPEN_DELETEONCLOSE] +** <li> [SQLITE_OPEN_EXCLUSIVE] +** </ul> +** +** The [SQLITE_OPEN_DELETEONCLOSE] flag means the file should be +** deleted when it is closed. This will always be set for TEMP +** databases and journals and for subjournals. The +** [SQLITE_OPEN_EXCLUSIVE] flag means the file should be opened +** for exclusive access. This flag is set for all files except +** for the main database file. +** +** Space to hold the [sqlite3_file] structure passed as the third +** argument to xOpen is allocated by caller (the SQLite core). +** szOsFile bytes are allocated for this object. The xOpen method +** fills in the allocated space. +** +** The flags argument to xAccess() may be [SQLITE_ACCESS_EXISTS] +** to test for the existance of a file, +** or [SQLITE_ACCESS_READWRITE] to test to see +** if a file is readable and writable, or [SQLITE_ACCESS_READ] +** to test to see if a file is at least readable. The file can be a +** directory. +** +** SQLite will always allocate at least mxPathname+1 byte for +** the output buffers for xGetTempname and xFullPathname. The exact +** size of the output buffer is also passed as a parameter to both +** methods. If the output buffer is not large enough, SQLITE_CANTOPEN +** should be returned. As this is handled as a fatal error by SQLite, +** vfs implementations should endevour to prevent this by setting +** mxPathname to a sufficiently large value. +** +** The xRandomness(), xSleep(), and xCurrentTime() interfaces +** are not strictly a part of the filesystem, but they are +** included in the VFS structure for completeness. +** The xRandomness() function attempts to return nBytes bytes +** of good-quality randomness into zOut. The return value is +** the actual number of bytes of randomness obtained. The +** xSleep() method cause the calling thread to sleep for at +** least the number of microseconds given. The xCurrentTime() +** method returns a Julian Day Number for the current date and +** time. +*/ +typedef struct sqlite3_vfs sqlite3_vfs; +struct sqlite3_vfs { + int iVersion; /* Structure version number */ + int szOsFile; /* Size of subclassed sqlite3_file */ + int mxPathname; /* Maximum file pathname length */ + sqlite3_vfs *pNext; /* Next registered VFS */ + const char *zName; /* Name of this virtual file system */ + void *pAppData; /* Pointer to application-specific data */ + int (*xOpen)(sqlite3_vfs*, const char *zName, sqlite3_file*, + int flags, int *pOutFlags); + int (*xDelete)(sqlite3_vfs*, const char *zName, int syncDir); + int (*xAccess)(sqlite3_vfs*, const char *zName, int flags); + int (*xGetTempname)(sqlite3_vfs*, int nOut, char *zOut); + int (*xFullPathname)(sqlite3_vfs*, const char *zName, int nOut, char *zOut); + void *(*xDlOpen)(sqlite3_vfs*, const char *zFilename); + void (*xDlError)(sqlite3_vfs*, int nByte, char *zErrMsg); + void *(*xDlSym)(sqlite3_vfs*,void*, const char *zSymbol); + void (*xDlClose)(sqlite3_vfs*, void*); + int (*xRandomness)(sqlite3_vfs*, int nByte, char *zOut); + int (*xSleep)(sqlite3_vfs*, int microseconds); + int (*xCurrentTime)(sqlite3_vfs*, double*); + /* New fields may be appended in figure versions. The iVersion + ** value will increment whenever this happens. */ +}; + +/* +** CAPI3REF: Flags for the xAccess VFS method +** +** These integer constants can be used as the third parameter to +** the xAccess method of an [sqlite3_vfs] object. They determine +** the kind of what kind of permissions the xAccess method is +** looking for. With SQLITE_ACCESS_EXISTS, the xAccess method +** simply checks to see if the file exists. With SQLITE_ACCESS_READWRITE, +** the xAccess method checks to see if the file is both readable +** and writable. With SQLITE_ACCESS_READ the xAccess method +** checks to see if the file is readable. +*/ +#define SQLITE_ACCESS_EXISTS 0 +#define SQLITE_ACCESS_READWRITE 1 +#define SQLITE_ACCESS_READ 2 + +/* +** CAPI3REF: Enable Or Disable Extended Result Codes +** +** This routine enables or disables the +** [SQLITE_IOERR_READ | extended result codes] feature. +** By default, SQLite API routines return one of only 26 integer +** [SQLITE_OK | result codes]. When extended result codes +** are enabled by this routine, the repetoire of result codes can be +** much larger and can (hopefully) provide more detailed information +** about the cause of an error. +** +** The second argument is a boolean value that turns extended result +** codes on and off. Extended result codes are off by default for +** backwards compatibility with older versions of SQLite. +*/ +int sqlite3_extended_result_codes(sqlite3*, int onoff); + +/* +** CAPI3REF: Last Insert Rowid +** +** Each entry in an SQLite table has a unique 64-bit signed integer key +** called the "rowid". The rowid is always available as an undeclared +** column named ROWID, OID, or _ROWID_. If the table has a column of +** type INTEGER PRIMARY KEY then that column is another an alias for the +** rowid. +** +** This routine returns the rowid of the most recent successful INSERT into +** the database from the database connection given in the first +** argument. If no successful inserts have ever occurred on this database +** connection, zero is returned. +** +** If an INSERT occurs within a trigger, then the rowid of the +** inserted row is returned by this routine as long as the trigger +** is running. But once the trigger terminates, the value returned +** by this routine reverts to the last value inserted before the +** trigger fired. +** +** An INSERT that fails due to a constraint violation is not a +** successful insert and does not change the value returned by this +** routine. Thus INSERT OR FAIL, INSERT OR IGNORE, INSERT OR ROLLBACK, +** and INSERT OR ABORT make no changes to the return value of this +** routine when their insertion fails. When INSERT OR REPLACE +** encounters a constraint violation, it does not fail. The +** INSERT continues to completion after deleting rows that caused +** the constraint problem so INSERT OR REPLACE will always change +** the return value of this interface. +** +** If another thread does a new insert on the same database connection +** while this routine is running and thus changes the last insert rowid, +** then the return value of this routine is undefined. +*/ +sqlite3_int64 sqlite3_last_insert_rowid(sqlite3*); + +/* +** CAPI3REF: Count The Number Of Rows Modified +** +** This function returns the number of database rows that were changed +** (or inserted or deleted) by the most recent SQL statement. Only +** changes that are directly specified by the INSERT, UPDATE, or +** DELETE statement are counted. Auxiliary changes caused by +** triggers are not counted. Use the [sqlite3_total_changes()] function +** to find the total number of changes including changes caused by triggers. +** +** Within the body of a trigger, the sqlite3_changes() interface can be +** called to find the number of +** changes in the most recently completed INSERT, UPDATE, or DELETE +** statement within the body of the trigger. +** +** All changes are counted, even if they were later undone by a +** ROLLBACK or ABORT. Except, changes associated with creating and +** dropping tables are not counted. +** +** If a callback invokes [sqlite3_exec()] or [sqlite3_step()] recursively, +** then the changes in the inner, recursive call are counted together +** with the changes in the outer call. +** +** SQLite implements the command "DELETE FROM table" without a WHERE clause +** by dropping and recreating the table. (This is much faster than going +** through and deleting individual elements from the table.) Because of +** this optimization, the change count for "DELETE FROM table" will be +** zero regardless of the number of elements that were originally in the +** table. To get an accurate count of the number of rows deleted, use +** "DELETE FROM table WHERE 1" instead. +** +** If another thread makes changes on the same database connection +** while this routine is running then the return value of this routine +** is undefined. +*/ +int sqlite3_changes(sqlite3*); + +/* +** CAPI3REF: Total Number Of Rows Modified +*** +** This function returns the number of database rows that have been +** modified by INSERT, UPDATE or DELETE statements since the database handle +** was opened. This includes UPDATE, INSERT and DELETE statements executed +** as part of trigger programs. All changes are counted as soon as the +** statement that makes them is completed (when the statement handle is +** passed to [sqlite3_reset()] or [sqlite3_finalize()]). +** +** See also the [sqlite3_change()] interface. +** +** SQLite implements the command "DELETE FROM table" without a WHERE clause +** by dropping and recreating the table. (This is much faster than going +** through and deleting individual elements form the table.) Because of +** this optimization, the change count for "DELETE FROM table" will be +** zero regardless of the number of elements that were originally in the +** table. To get an accurate count of the number of rows deleted, use +** "DELETE FROM table WHERE 1" instead. +** +** If another thread makes changes on the same database connection +** while this routine is running then the return value of this routine +** is undefined. +*/ +int sqlite3_total_changes(sqlite3*); + +/* +** CAPI3REF: Interrupt A Long-Running Query +** +** This function causes any pending database operation to abort and +** return at its earliest opportunity. This routine is typically +** called in response to a user action such as pressing "Cancel" +** or Ctrl-C where the user wants a long query operation to halt +** immediately. +** +** It is safe to call this routine from a thread different from the +** thread that is currently running the database operation. But it +** is not safe to call this routine with a database connection that +** is closed or might close before sqlite3_interrupt() returns. +** +** The SQL operation that is interrupted will return [SQLITE_INTERRUPT]. +** If an interrupted operation was an update that is inside an +** explicit transaction, then the entire transaction will be rolled +** back automatically. +*/ +void sqlite3_interrupt(sqlite3*); + +/* +** CAPI3REF: Determine If An SQL Statement Is Complete +** +** These functions return true if the given input string comprises +** one or more complete SQL statements. For the sqlite3_complete() call, +** the parameter must be a nul-terminated UTF-8 string. For +** sqlite3_complete16(), a nul-terminated machine byte order UTF-16 string +** is required. +** +** These routines are useful for command-line input to determine if the +** currently entered text forms one or more complete SQL statements or +** if additional input is needed before sending the statements into +** SQLite for parsing. The algorithm is simple. If the +** last token other than spaces and comments is a semicolon, then return +** true. Actually, the algorithm is a little more complicated than that +** in order to deal with triggers, but the basic idea is the same: the +** statement is not complete unless it ends in a semicolon. +*/ +int sqlite3_complete(const char *sql); +int sqlite3_complete16(const void *sql); + +/* +** CAPI3REF: Register A Callback To Handle SQLITE_BUSY Errors +** +** This routine identifies a callback function that might be invoked +** whenever an attempt is made to open a database table +** that another thread or process has locked. +** If the busy callback is NULL, then [SQLITE_BUSY] +** (or sometimes [SQLITE_IOERR_BLOCKED]) +** is returned immediately upon encountering the lock. +** If the busy callback is not NULL, then the +** callback will be invoked with two arguments. The +** first argument to the handler is a copy of the void* pointer which +** is the third argument to this routine. The second argument to +** the handler is the number of times that the busy handler has +** been invoked for this locking event. If the +** busy callback returns 0, then no additional attempts are made to +** access the database and [SQLITE_BUSY] or [SQLITE_IOERR_BLOCKED] is returned. +** If the callback returns non-zero, then another attempt is made to open the +** database for reading and the cycle repeats. +** +** The presence of a busy handler does not guarantee that +** it will be invoked when there is lock contention. +** If SQLite determines that invoking the busy handler could result in +** a deadlock, it will return [SQLITE_BUSY] instead. +** Consider a scenario where one process is holding a read lock that +** it is trying to promote to a reserved lock and +** a second process is holding a reserved lock that it is trying +** to promote to an exclusive lock. The first process cannot proceed +** because it is blocked by the second and the second process cannot +** proceed because it is blocked by the first. If both processes +** invoke the busy handlers, neither will make any progress. Therefore, +** SQLite returns [SQLITE_BUSY] for the first process, hoping that this +** will induce the first process to release its read lock and allow +** the second process to proceed. +** +** The default busy callback is NULL. +** +** The [SQLITE_BUSY] error is converted to [SQLITE_IOERR_BLOCKED] when +** SQLite is in the middle of a large transaction where all the +** changes will not fit into the in-memory cache. SQLite will +** already hold a RESERVED lock on the database file, but it needs +** to promote this lock to EXCLUSIVE so that it can spill cache +** pages into the database file without harm to concurrent +** readers. If it is unable to promote the lock, then the in-memory +** cache will be left in an inconsistent state and so the error +** code is promoted from the relatively benign [SQLITE_BUSY] to +** the more severe [SQLITE_IOERR_BLOCKED]. This error code promotion +** forces an automatic rollback of the changes. See the +** <a href="http://www.sqlite.org/cvstrac/wiki?p=CorruptionFollowingBusyError"> +** CorruptionFollowingBusyError</a> wiki page for a discussion of why +** this is important. +** +** Sqlite is re-entrant, so the busy handler may start a new query. +** (It is not clear why anyone would every want to do this, but it +** is allowed, in theory.) But the busy handler may not close the +** database. Closing the database from a busy handler will delete +** data structures out from under the executing query and will +** probably result in a segmentation fault or other runtime error. +** +** There can only be a single busy handler defined for each database +** connection. Setting a new busy handler clears any previous one. +** Note that calling [sqlite3_busy_timeout()] will also set or clear +** the busy handler. +** +** When operating in [sqlite3_enable_shared_cache | shared cache mode], +** only a single busy handler can be defined for each database file. +** So if two database connections share a single cache, then changing +** the busy handler on one connection will also change the busy +** handler in the other connection. The busy handler is invoked +** in the thread that was running when the SQLITE_BUSY was hit. +*/ +int sqlite3_busy_handler(sqlite3*, int(*)(void*,int), void*); + +/* +** CAPI3REF: Set A Busy Timeout +** +** This routine sets a busy handler that sleeps for a while when a +** table is locked. The handler will sleep multiple times until +** at least "ms" milliseconds of sleeping have been done. After +** "ms" milliseconds of sleeping, the handler returns 0 which +** causes [sqlite3_step()] to return [SQLITE_BUSY] or [SQLITE_IOERR_BLOCKED]. +** +** Calling this routine with an argument less than or equal to zero +** turns off all busy handlers. +** +** There can only be a single busy handler for a particular database +** connection. If another busy handler was defined +** (using [sqlite3_busy_handler()]) prior to calling +** this routine, that other busy handler is cleared. +*/ +int sqlite3_busy_timeout(sqlite3*, int ms); + +/* +** CAPI3REF: Convenience Routines For Running Queries +** +** This next routine is a convenience wrapper around [sqlite3_exec()]. +** Instead of invoking a user-supplied callback for each row of the +** result, this routine remembers each row of the result in memory +** obtained from [sqlite3_malloc()], then returns all of the result after the +** query has finished. +** +** As an example, suppose the query result where this table: +** +** <blockquote><pre> +** Name | Age +** ----------------------- +** Alice | 43 +** Bob | 28 +** Cindy | 21 +** </pre></blockquote> +** +** If the 3rd argument were &azResult then after the function returns +** azResult will contain the following data: +** +** <blockquote><pre> +** azResult[0] = "Name"; +** azResult[1] = "Age"; +** azResult[2] = "Alice"; +** azResult[3] = "43"; +** azResult[4] = "Bob"; +** azResult[5] = "28"; +** azResult[6] = "Cindy"; +** azResult[7] = "21"; +** </pre></blockquote> +** +** Notice that there is an extra row of data containing the column +** headers. But the *nrow return value is still 3. *ncolumn is +** set to 2. In general, the number of values inserted into azResult +** will be ((*nrow) + 1)*(*ncolumn). +** +** After the calling function has finished using the result, it should +** pass the result data pointer to sqlite3_free_table() in order to +** release the memory that was malloc-ed. Because of the way the +** [sqlite3_malloc()] happens, the calling function must not try to call +** [sqlite3_free()] directly. Only [sqlite3_free_table()] is able to release +** the memory properly and safely. +** +** The return value of this routine is the same as from [sqlite3_exec()]. +*/ +int sqlite3_get_table( + sqlite3*, /* An open database */ + const char *sql, /* SQL to be executed */ + char ***resultp, /* Result written to a char *[] that this points to */ + int *nrow, /* Number of result rows written here */ + int *ncolumn, /* Number of result columns written here */ + char **errmsg /* Error msg written here */ +); +void sqlite3_free_table(char **result); + +/* +** CAPI3REF: Formatted String Printing Functions +** +** These routines are workalikes of the "printf()" family of functions +** from the standard C library. +** +** The sqlite3_mprintf() and sqlite3_vmprintf() routines write their +** results into memory obtained from [sqlite3_malloc()]. +** The strings returned by these two routines should be +** released by [sqlite3_free()]. Both routines return a +** NULL pointer if [sqlite3_malloc()] is unable to allocate enough +** memory to hold the resulting string. +** +** In sqlite3_snprintf() routine is similar to "snprintf()" from +** the standard C library. The result is written into the +** buffer supplied as the second parameter whose size is given by +** the first parameter. Note that the order of the +** first two parameters is reversed from snprintf(). This is an +** historical accident that cannot be fixed without breaking +** backwards compatibility. Note also that sqlite3_snprintf() +** returns a pointer to its buffer instead of the number of +** characters actually written into the buffer. We admit that +** the number of characters written would be a more useful return +** value but we cannot change the implementation of sqlite3_snprintf() +** now without breaking compatibility. +** +** As long as the buffer size is greater than zero, sqlite3_snprintf() +** guarantees that the buffer is always zero-terminated. The first +** parameter "n" is the total size of the buffer, including space for +** the zero terminator. So the longest string that can be completely +** written will be n-1 characters. +** +** These routines all implement some additional formatting +** options that are useful for constructing SQL statements. +** All of the usual printf formatting options apply. In addition, there +** is are "%q", "%Q", and "%z" options. +** +** The %q option works like %s in that it substitutes a null-terminated +** string from the argument list. But %q also doubles every '\'' character. +** %q is designed for use inside a string literal. By doubling each '\'' +** character it escapes that character and allows it to be inserted into +** the string. +** +** For example, so some string variable contains text as follows: +** +** <blockquote><pre> +** char *zText = "It's a happy day!"; +** </pre></blockquote> +** +** One can use this text in an SQL statement as follows: +** +** <blockquote><pre> +** char *zSQL = sqlite3_mprintf("INSERT INTO table VALUES('%q')", zText); +** sqlite3_exec(db, zSQL, 0, 0, 0); +** sqlite3_free(zSQL); +** </pre></blockquote> +** +** Because the %q format string is used, the '\'' character in zText +** is escaped and the SQL generated is as follows: +** +** <blockquote><pre> +** INSERT INTO table1 VALUES('It''s a happy day!') +** </pre></blockquote> +** +** This is correct. Had we used %s instead of %q, the generated SQL +** would have looked like this: +** +** <blockquote><pre> +** INSERT INTO table1 VALUES('It's a happy day!'); +** </pre></blockquote> +** +** This second example is an SQL syntax error. As a general rule you +** should always use %q instead of %s when inserting text into a string +** literal. +** +** The %Q option works like %q except it also adds single quotes around +** the outside of the total string. Or if the parameter in the argument +** list is a NULL pointer, %Q substitutes the text "NULL" (without single +** quotes) in place of the %Q option. So, for example, one could say: +** +** <blockquote><pre> +** char *zSQL = sqlite3_mprintf("INSERT INTO table VALUES(%Q)", zText); +** sqlite3_exec(db, zSQL, 0, 0, 0); +** sqlite3_free(zSQL); +** </pre></blockquote> +** +** The code above will render a correct SQL statement in the zSQL +** variable even if the zText variable is a NULL pointer. +** +** The "%z" formatting option works exactly like "%s" with the +** addition that after the string has been read and copied into +** the result, [sqlite3_free()] is called on the input string. +*/ +char *sqlite3_mprintf(const char*,...); +char *sqlite3_vmprintf(const char*, va_list); +char *sqlite3_snprintf(int,char*,const char*, ...); + +/* +** CAPI3REF: Memory Allocation Subsystem +** +** The SQLite core uses these three routines for all of its own +** internal memory allocation needs. (See the exception below.) +** +** The default implementation +** of the memory allocation subsystem uses the malloc(), realloc() +** and free() provided by the standard C library. However, if +** SQLite is compiled with the following C preprocessor macro +** +** <blockquote> SQLITE_MEMORY_SIZE=<i>NNN</i> </blockquote> +** +** where <i>NNN</i> is an integer, then SQLite create a static +** array of at least <i>NNN</i> bytes in size and use that array +** for all of its dynamic memory allocation needs. +** +** In SQLite version 3.5.0 and 3.5.1, it was possible to define +** the SQLITE_OMIT_MEMORY_ALLOCATION which would cause the built-in +** implementation of these routines to be omitted. That capability +** is no longer provided. Only built-in memory allocators can be +** used. +** +** <b>Exception:</b> The windows OS interface layer calls +** the system malloc() and free() directly when converting +** filenames between the UTF-8 encoding used by SQLite +** and whatever filename encoding is used by the particular windows +** installation. Memory allocation errors are detected, but +** they are reported back as [SQLITE_CANTOPEN] or +** [SQLITE_IOERR] rather than [SQLITE_NOMEM]. +*/ +void *sqlite3_malloc(int); +void *sqlite3_realloc(void*, int); +void sqlite3_free(void*); + +/* +** CAPI3REF: Memory Allocator Statistics +** +** In addition to the basic three allocation routines +** [sqlite3_malloc()], [sqlite3_free()], and [sqlite3_realloc()], +** the memory allocation subsystem included with the SQLite +** sources provides the interfaces shown below. +** +** The first of these two routines returns the amount of memory +** currently outstanding (malloced but not freed). The second +** returns the largest instantaneous amount of outstanding +** memory. The highwater mark is reset if the argument is +** true. +** +** The value returned may or may not include allocation +** overhead, depending on which built-in memory allocator +** implementation is used. +*/ +sqlite3_int64 sqlite3_memory_used(void); +sqlite3_int64 sqlite3_memory_highwater(int resetFlag); + +/* +** CAPI3REF: Compile-Time Authorization Callbacks +*** +** This routine registers a authorizer callback with the SQLite library. +** The authorizer callback is invoked as SQL statements are being compiled +** by [sqlite3_prepare()] or its variants [sqlite3_prepare_v2()], +** [sqlite3_prepare16()] and [sqlite3_prepare16_v2()]. At various +** points during the compilation process, as logic is being created +** to perform various actions, the authorizer callback is invoked to +** see if those actions are allowed. The authorizer callback should +** return SQLITE_OK to allow the action, [SQLITE_IGNORE] to disallow the +** specific action but allow the SQL statement to continue to be +** compiled, or [SQLITE_DENY] to cause the entire SQL statement to be +** rejected with an error. +** +** Depending on the action, the [SQLITE_IGNORE] and [SQLITE_DENY] return +** codes might mean something different or they might mean the same +** thing. If the action is, for example, to perform a delete opertion, +** then [SQLITE_IGNORE] and [SQLITE_DENY] both cause the statement compilation +** to fail with an error. But if the action is to read a specific column +** from a specific table, then [SQLITE_DENY] will cause the entire +** statement to fail but [SQLITE_IGNORE] will cause a NULL value to be +** read instead of the actual column value. +** +** The first parameter to the authorizer callback is a copy of +** the third parameter to the sqlite3_set_authorizer() interface. +** The second parameter to the callback is an integer +** [SQLITE_COPY | action code] that specifies the particular action +** to be authorized. The available action codes are +** [SQLITE_COPY | documented separately]. The third through sixth +** parameters to the callback are strings that contain additional +** details about the action to be authorized. +** +** An authorizer is used when preparing SQL statements from an untrusted +** source, to ensure that the SQL statements do not try to access data +** that they are not allowed to see, or that they do not try to +** execute malicious statements that damage the database. For +** example, an application may allow a user to enter arbitrary +** SQL queries for evaluation by a database. But the application does +** not want the user to be able to make arbitrary changes to the +** database. An authorizer could then be put in place while the +** user-entered SQL is being prepared that disallows everything +** except SELECT statements. +** +** Only a single authorizer can be in place on a database connection +** at a time. Each call to sqlite3_set_authorizer overrides the +** previous call. A NULL authorizer means that no authorization +** callback is invoked. The default authorizer is NULL. +** +** Note that the authorizer callback is invoked only during +** [sqlite3_prepare()] or its variants. Authorization is not +** performed during statement evaluation in [sqlite3_step()]. +*/ +int sqlite3_set_authorizer( + sqlite3*, + int (*xAuth)(void*,int,const char*,const char*,const char*,const char*), + void *pUserData +); + +/* +** CAPI3REF: Authorizer Return Codes +** +** The [sqlite3_set_authorizer | authorizer callback function] must +** return either [SQLITE_OK] or one of these two constants in order +** to signal SQLite whether or not the action is permitted. See the +** [sqlite3_set_authorizer | authorizer documentation] for additional +** information. +*/ +#define SQLITE_DENY 1 /* Abort the SQL statement with an error */ +#define SQLITE_IGNORE 2 /* Don't allow access, but don't generate an error */ + +/* +** CAPI3REF: Authorizer Action Codes +** +** The [sqlite3_set_authorizer()] interface registers a callback function +** that is invoked to authorizer certain SQL statement actions. The +** second parameter to the callback is an integer code that specifies +** what action is being authorized. These are the integer action codes that +** the authorizer callback may be passed. +** +** These action code values signify what kind of operation is to be +** authorized. The 3rd and 4th parameters to the authorization callback +** function will be parameters or NULL depending on which of these +** codes is used as the second parameter. The 5th parameter to the +** authorizer callback is the name of the database ("main", "temp", +** etc.) if applicable. The 6th parameter to the authorizer callback +** is the name of the inner-most trigger or view that is responsible for +** the access attempt or NULL if this access attempt is directly from +** top-level SQL code. +*/ +/******************************************* 3rd ************ 4th ***********/ +#define SQLITE_CREATE_INDEX 1 /* Index Name Table Name */ +#define SQLITE_CREATE_TABLE 2 /* Table Name NULL */ +#define SQLITE_CREATE_TEMP_INDEX 3 /* Index Name Table Name */ +#define SQLITE_CREATE_TEMP_TABLE 4 /* Table Name NULL */ +#define SQLITE_CREATE_TEMP_TRIGGER 5 /* Trigger Name Table Name */ +#define SQLITE_CREATE_TEMP_VIEW 6 /* View Name NULL */ +#define SQLITE_CREATE_TRIGGER 7 /* Trigger Name Table Name */ +#define SQLITE_CREATE_VIEW 8 /* View Name NULL */ +#define SQLITE_DELETE 9 /* Table Name NULL */ +#define SQLITE_DROP_INDEX 10 /* Index Name Table Name */ +#define SQLITE_DROP_TABLE 11 /* Table Name NULL */ +#define SQLITE_DROP_TEMP_INDEX 12 /* Index Name Table Name */ +#define SQLITE_DROP_TEMP_TABLE 13 /* Table Name NULL */ +#define SQLITE_DROP_TEMP_TRIGGER 14 /* Trigger Name Table Name */ +#define SQLITE_DROP_TEMP_VIEW 15 /* View Name NULL */ +#define SQLITE_DROP_TRIGGER 16 /* Trigger Name Table Name */ +#define SQLITE_DROP_VIEW 17 /* View Name NULL */ +#define SQLITE_INSERT 18 /* Table Name NULL */ +#define SQLITE_PRAGMA 19 /* Pragma Name 1st arg or NULL */ +#define SQLITE_READ 20 /* Table Name Column Name */ +#define SQLITE_SELECT 21 /* NULL NULL */ +#define SQLITE_TRANSACTION 22 /* NULL NULL */ +#define SQLITE_UPDATE 23 /* Table Name Column Name */ +#define SQLITE_ATTACH 24 /* Filename NULL */ +#define SQLITE_DETACH 25 /* Database Name NULL */ +#define SQLITE_ALTER_TABLE 26 /* Database Name Table Name */ +#define SQLITE_REINDEX 27 /* Index Name NULL */ +#define SQLITE_ANALYZE 28 /* Table Name NULL */ +#define SQLITE_CREATE_VTABLE 29 /* Table Name Module Name */ +#define SQLITE_DROP_VTABLE 30 /* Table Name Module Name */ +#define SQLITE_FUNCTION 31 /* Function Name NULL */ +#define SQLITE_COPY 0 /* No longer used */ + +/* +** CAPI3REF: Tracing And Profiling Functions +** +** These routines register callback functions that can be used for +** tracing and profiling the execution of SQL statements. +** The callback function registered by sqlite3_trace() is invoked +** at the first [sqlite3_step()] for the evaluation of an SQL statement. +** The callback function registered by sqlite3_profile() is invoked +** as each SQL statement finishes and includes +** information on how long that statement ran. +** +** The sqlite3_profile() API is currently considered experimental and +** is subject to change. +*/ +void *sqlite3_trace(sqlite3*, void(*xTrace)(void*,const char*), void*); +void *sqlite3_profile(sqlite3*, + void(*xProfile)(void*,const char*,sqlite3_uint64), void*); + +/* +** CAPI3REF: Query Progress Callbacks +** +** This routine configures a callback function - the progress callback - that +** is invoked periodically during long running calls to [sqlite3_exec()], +** [sqlite3_step()] and [sqlite3_get_table()]. An example use for this +** interface is to keep a GUI updated during a large query. +** +** The progress callback is invoked once for every N virtual machine opcodes, +** where N is the second argument to this function. The progress callback +** itself is identified by the third argument to this function. The fourth +** argument to this function is a void pointer passed to the progress callback +** function each time it is invoked. +** +** If a call to [sqlite3_exec()], [sqlite3_step()], or [sqlite3_get_table()] +** results in fewer than N opcodes being executed, then the progress +** callback is never invoked. +** +** Only a single progress callback function may be registered for each +** open database connection. Every call to sqlite3_progress_handler() +** overwrites the results of the previous call. +** To remove the progress callback altogether, pass NULL as the third +** argument to this function. +** +** If the progress callback returns a result other than 0, then the current +** query is immediately terminated and any database changes rolled back. +** The containing [sqlite3_exec()], [sqlite3_step()], or +** [sqlite3_get_table()] call returns SQLITE_INTERRUPT. This feature +** can be used, for example, to implement the "Cancel" button on a +** progress dialog box in a GUI. +*/ +void sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*); + +/* +** CAPI3REF: Opening A New Database Connection +** +** Open the sqlite database file "filename". The "filename" is UTF-8 +** encoded for [sqlite3_open()] and [sqlite3_open_v2()] and UTF-16 encoded +** in the native byte order for [sqlite3_open16()]. +** An [sqlite3*] handle is returned in *ppDb, even +** if an error occurs. If the database is opened (or created) successfully, +** then [SQLITE_OK] is returned. Otherwise an error code is returned. The +** [sqlite3_errmsg()] or [sqlite3_errmsg16()] routines can be used to obtain +** an English language description of the error. +** +** The default encoding for the database will be UTF-8 if +** [sqlite3_open()] or [sqlite3_open_v2()] is called and +** UTF-16 if [sqlite3_open16()] is used. +** +** Whether or not an error occurs when it is opened, resources associated +** with the [sqlite3*] handle should be released by passing it to +** [sqlite3_close()] when it is no longer required. +** +** The [sqlite3_open_v2()] interface works like [sqlite3_open()] except that +** provides two additional parameters for additional control over the +** new database connection. The flags parameter can be one of: +** +** <ol> +** <li> [SQLITE_OPEN_READONLY] +** <li> [SQLITE_OPEN_READWRITE] +** <li> [SQLITE_OPEN_READWRITE] | [SQLITE_OPEN_CREATE] +** </ol> +** +** The first value opens the database read-only. If the database does +** not previously exist, an error is returned. The second option opens +** the database for reading and writing if possible, or reading only if +** if the file is write protected. In either case the database must already +** exist or an error is returned. The third option opens the database +** for reading and writing and creates it if it does not already exist. +** The third options is behavior that is always used for [sqlite3_open()] +** and [sqlite3_open16()]. +** +** If the filename is ":memory:", then an private +** in-memory database is created for the connection. This in-memory +** database will vanish when the database connection is closed. Future +** version of SQLite might make use of additional special filenames +** that begin with the ":" character. It is recommended that +** when a database filename really does begin with +** ":" that you prefix the filename with a pathname like "./" to +** avoid ambiguity. +** +** If the filename is an empty string, then a private temporary +** on-disk database will be created. This private database will be +** automatically deleted as soon as the database connection is closed. +** +** The fourth parameter to sqlite3_open_v2() is the name of the +** [sqlite3_vfs] object that defines the operating system +** interface that the new database connection should use. If the +** fourth parameter is a NULL pointer then the default [sqlite3_vfs] +** object is used. +** +** <b>Note to windows users:</b> The encoding used for the filename argument +** of [sqlite3_open()] and [sqlite3_open_v2()] must be UTF-8, not whatever +** codepage is currently defined. Filenames containing international +** characters must be converted to UTF-8 prior to passing them into +** [sqlite3_open()] or [sqlite3_open_v2()]. +*/ +int sqlite3_open( + const char *filename, /* Database filename (UTF-8) */ + sqlite3 **ppDb /* OUT: SQLite db handle */ +); +int sqlite3_open16( + const void *filename, /* Database filename (UTF-16) */ + sqlite3 **ppDb /* OUT: SQLite db handle */ +); +int sqlite3_open_v2( + const char *filename, /* Database filename (UTF-8) */ + sqlite3 **ppDb, /* OUT: SQLite db handle */ + int flags, /* Flags */ + const char *zVfs /* Name of VFS module to use */ +); + +/* +** CAPI3REF: Error Codes And Messages +** +** The sqlite3_errcode() interface returns the numeric +** [SQLITE_OK | result code] or [SQLITE_IOERR_READ | extended result code] +** for the most recent failed sqlite3_* API call associated +** with [sqlite3] handle 'db'. If a prior API call failed but the +** most recent API call succeeded, the return value from sqlite3_errcode() +** is undefined. +** +** The sqlite3_errmsg() and sqlite3_errmsg16() return English-language +** text that describes the error, as either UTF8 or UTF16 respectively. +** Memory to hold the error message string is managed internally. The +** string may be overwritten or deallocated by subsequent calls to SQLite +** interface functions. +** +** Calls to many sqlite3_* functions set the error code and string returned +** by [sqlite3_errcode()], [sqlite3_errmsg()], and [sqlite3_errmsg16()] +** (overwriting the previous values). Note that calls to [sqlite3_errcode()], +** [sqlite3_errmsg()], and [sqlite3_errmsg16()] themselves do not affect the +** results of future invocations. Calls to API routines that do not return +** an error code (example: [sqlite3_data_count()]) do not +** change the error code returned by this routine. Interfaces that are +** not associated with a specific database connection (examples: +** [sqlite3_mprintf()] or [sqlite3_enable_shared_cache()] do not change +** the return code. +** +** Assuming no other intervening sqlite3_* API calls are made, the error +** code returned by this function is associated with the same error as +** the strings returned by [sqlite3_errmsg()] and [sqlite3_errmsg16()]. +*/ +int sqlite3_errcode(sqlite3 *db); +const char *sqlite3_errmsg(sqlite3*); +const void *sqlite3_errmsg16(sqlite3*); + +/* +** CAPI3REF: SQL Statement Object +** +** Instance of this object represent single SQL statements. This +** is variously known as a "prepared statement" or a +** "compiled SQL statement" or simply as a "statement". +** +** The life of a statement object goes something like this: +** +** <ol> +** <li> Create the object using [sqlite3_prepare_v2()] or a related +** function. +** <li> Bind values to host parameters using +** [sqlite3_bind_blob | sqlite3_bind_* interfaces]. +** <li> Run the SQL by calling [sqlite3_step()] one or more times. +** <li> Reset the statement using [sqlite3_reset()] then go back +** to step 2. Do this zero or more times. +** <li> Destroy the object using [sqlite3_finalize()]. +** </ol> +** +** Refer to documentation on individual methods above for additional +** information. +*/ +typedef struct sqlite3_stmt sqlite3_stmt; + +/* +** CAPI3REF: Compiling An SQL Statement +** +** To execute an SQL query, it must first be compiled into a byte-code +** program using one of these routines. +** +** The first argument "db" is an [sqlite3 | SQLite database handle] +** obtained from a prior call to [sqlite3_open()], [sqlite3_open_v2()] +** or [sqlite3_open16()]. +** The second argument "zSql" is the statement to be compiled, encoded +** as either UTF-8 or UTF-16. The sqlite3_prepare() and sqlite3_prepare_v2() +** interfaces uses UTF-8 and sqlite3_prepare16() and sqlite3_prepare16_v2() +** use UTF-16. +** +** If the nByte argument is less +** than zero, then zSql is read up to the first zero terminator. If +** nByte is non-negative, then it is the maximum number of +** bytes read from zSql. When nByte is non-negative, the +** zSql string ends at either the first '\000' character or +** until the nByte-th byte, whichever comes first. +** +** *pzTail is made to point to the first byte past the end of the first +** SQL statement in zSql. This routine only compiles the first statement +** in zSql, so *pzTail is left pointing to what remains uncompiled. +** +** *ppStmt is left pointing to a compiled +** [sqlite3_stmt | SQL statement structure] that can be +** executed using [sqlite3_step()]. Or if there is an error, *ppStmt may be +** set to NULL. If the input text contained no SQL (if the input is and +** empty string or a comment) then *ppStmt is set to NULL. The calling +** procedure is responsible for deleting the compiled SQL statement +** using [sqlite3_finalize()] after it has finished with it. +** +** On success, [SQLITE_OK] is returned. Otherwise an +** [SQLITE_ERROR | error code] is returned. +** +** The sqlite3_prepare_v2() and sqlite3_prepare16_v2() interfaces are +** recommended for all new programs. The two older interfaces are retained +** for backwards compatibility, but their use is discouraged. +** In the "v2" interfaces, the prepared statement +** that is returned (the [sqlite3_stmt] object) contains a copy of the +** original SQL text. This causes the [sqlite3_step()] interface to +** behave a differently in two ways: +** +** <ol> +** <li> +** If the database schema changes, instead of returning [SQLITE_SCHEMA] as it +** always used to do, [sqlite3_step()] will automatically recompile the SQL +** statement and try to run it again. If the schema has changed in a way +** that makes the statement no longer valid, [sqlite3_step()] will still +** return [SQLITE_SCHEMA]. But unlike the legacy behavior, [SQLITE_SCHEMA] is +** now a fatal error. Calling [sqlite3_prepare_v2()] again will not make the +** error go away. Note: use [sqlite3_errmsg()] to find the text of the parsing +** error that results in an [SQLITE_SCHEMA] return. +** </li> +** +** <li> +** When an error occurs, +** [sqlite3_step()] will return one of the detailed +** [SQLITE_ERROR | result codes] or +** [SQLITE_IOERR_READ | extended result codes] such as directly. +** The legacy behavior was that [sqlite3_step()] would only return a generic +** [SQLITE_ERROR] result code and you would have to make a second call to +** [sqlite3_reset()] in order to find the underlying cause of the problem. +** With the "v2" prepare interfaces, the underlying reason for the error is +** returned immediately. +** </li> +** </ol> +*/ +int sqlite3_prepare( + sqlite3 *db, /* Database handle */ + const char *zSql, /* SQL statement, UTF-8 encoded */ + int nByte, /* Maximum length of zSql in bytes. */ + sqlite3_stmt **ppStmt, /* OUT: Statement handle */ + const char **pzTail /* OUT: Pointer to unused portion of zSql */ +); +int sqlite3_prepare_v2( + sqlite3 *db, /* Database handle */ + const char *zSql, /* SQL statement, UTF-8 encoded */ + int nByte, /* Maximum length of zSql in bytes. */ + sqlite3_stmt **ppStmt, /* OUT: Statement handle */ + const char **pzTail /* OUT: Pointer to unused portion of zSql */ +); +int sqlite3_prepare16( + sqlite3 *db, /* Database handle */ + const void *zSql, /* SQL statement, UTF-16 encoded */ + int nByte, /* Maximum length of zSql in bytes. */ + sqlite3_stmt **ppStmt, /* OUT: Statement handle */ + const void **pzTail /* OUT: Pointer to unused portion of zSql */ +); +int sqlite3_prepare16_v2( + sqlite3 *db, /* Database handle */ + const void *zSql, /* SQL statement, UTF-16 encoded */ + int nByte, /* Maximum length of zSql in bytes. */ + sqlite3_stmt **ppStmt, /* OUT: Statement handle */ + const void **pzTail /* OUT: Pointer to unused portion of zSql */ +); + +/* +** Retrieve the original SQL statement associated with a compiled statement +** in UTF-8 encoding. +** +** If the compiled SQL statement passed as an argument was compiled using +** either sqlite3_prepare_v2 or sqlite3_prepare16_v2, then this function +** returns a pointer to a nul-terminated string containing a copy of +** the original SQL statement. The pointer is valid until the statement +** is deleted using sqlite3_finalize(). +** +** If the statement was compiled using either of the legacy interfaces +** sqlite3_prepare() or sqlite3_prepare16(), this function returns NULL. +** +****** EXPERIMENTAL - subject to change without notice ************** +*/ +const char *sqlite3_sql(sqlite3_stmt *pStmt); + +/* +** CAPI3REF: Dynamically Typed Value Object +** +** SQLite uses dynamic typing for the values it stores. Values can +** be integers, floating point values, strings, BLOBs, or NULL. When +** passing around values internally, each value is represented as +** an instance of the sqlite3_value object. +*/ +typedef struct Mem sqlite3_value; + +/* +** CAPI3REF: SQL Function Context Object +** +** The context in which an SQL function executes is stored in an +** sqlite3_context object. A pointer to such an object is the +** first parameter to user-defined SQL functions. +*/ +typedef struct sqlite3_context sqlite3_context; + +/* +** CAPI3REF: Binding Values To Prepared Statements +** +** In the SQL strings input to [sqlite3_prepare_v2()] and its variants, +** one or more literals can be replace by a parameter in one of these +** forms: +** +** <ul> +** <li> ? +** <li> ?NNN +** <li> :AAA +** <li> @AAA +** <li> $VVV +** </ul> +** +** In the parameter forms shown above NNN is an integer literal, +** AAA is an alphanumeric identifier and VVV is a variable name according +** to the syntax rules of the TCL programming language. +** The values of these parameters (also called "host parameter names") +** can be set using the sqlite3_bind_*() routines defined here. +** +** The first argument to the sqlite3_bind_*() routines always is a pointer +** to the [sqlite3_stmt] object returned from [sqlite3_prepare_v2()] or +** its variants. The second +** argument is the index of the parameter to be set. The first parameter has +** an index of 1. When the same named parameter is used more than once, second +** and subsequent +** occurrences have the same index as the first occurrence. The index for +** named parameters can be looked up using the +** [sqlite3_bind_parameter_name()] API if desired. The index for "?NNN" +** parametes is the value of NNN. +** The NNN value must be between 1 and the compile-time +** parameter SQLITE_MAX_VARIABLE_NUMBER (default value: 999). +** See <a href="limits.html">limits.html</a> for additional information. +** +** The third argument is the value to bind to the parameter. +** +** In those +** routines that have a fourth argument, its value is the number of bytes +** in the parameter. To be clear: the value is the number of bytes in the +** string, not the number of characters. The number +** of bytes does not include the zero-terminator at the end of strings. +** If the fourth parameter is negative, the length of the string is +** number of bytes up to the first zero terminator. +** +** The fifth argument to sqlite3_bind_blob(), sqlite3_bind_text(), and +** sqlite3_bind_text16() is a destructor used to dispose of the BLOB or +** text after SQLite has finished with it. If the fifth argument is the +** special value [SQLITE_STATIC], then the library assumes that the information +** is in static, unmanaged space and does not need to be freed. If the +** fifth argument has the value [SQLITE_TRANSIENT], then SQLite makes its +** own private copy of the data immediately, before the sqlite3_bind_*() +** routine returns. +** +** The sqlite3_bind_zeroblob() routine binds a BLOB of length n that +** is filled with zeros. A zeroblob uses a fixed amount of memory +** (just an integer to hold it size) while it is being processed. +** Zeroblobs are intended to serve as place-holders for BLOBs whose +** content is later written using +** [sqlite3_blob_open | increment BLOB I/O] routines. A negative +** value for the zeroblob results in a zero-length BLOB. +** +** The sqlite3_bind_*() routines must be called after +** [sqlite3_prepare_v2()] (and its variants) or [sqlite3_reset()] and +** before [sqlite3_step()]. +** Bindings are not cleared by the [sqlite3_reset()] routine. +** Unbound parameters are interpreted as NULL. +** +** These routines return [SQLITE_OK] on success or an error code if +** anything goes wrong. [SQLITE_RANGE] is returned if the parameter +** index is out of range. [SQLITE_NOMEM] is returned if malloc fails. +** [SQLITE_MISUSE] is returned if these routines are called on a virtual +** machine that is the wrong state or which has already been finalized. +*/ +int sqlite3_bind_blob(sqlite3_stmt*, int, const void*, int n, void(*)(void*)); +int sqlite3_bind_double(sqlite3_stmt*, int, double); +int sqlite3_bind_int(sqlite3_stmt*, int, int); +int sqlite3_bind_int64(sqlite3_stmt*, int, sqlite3_int64); +int sqlite3_bind_null(sqlite3_stmt*, int); +int sqlite3_bind_text(sqlite3_stmt*, int, const char*, int n, void(*)(void*)); +int sqlite3_bind_text16(sqlite3_stmt*, int, const void*, int, void(*)(void*)); +int sqlite3_bind_value(sqlite3_stmt*, int, const sqlite3_value*); +int sqlite3_bind_zeroblob(sqlite3_stmt*, int, int n); + +/* +** CAPI3REF: Number Of Host Parameters +** +** Return the largest host parameter index in the precompiled statement given +** as the argument. When the host parameters are of the forms like ":AAA" +** or "?", then they are assigned sequential increasing numbers beginning +** with one, so the value returned is the number of parameters. However +** if the same host parameter name is used multiple times, each occurrance +** is given the same number, so the value returned in that case is the number +** of unique host parameter names. If host parameters of the form "?NNN" +** are used (where NNN is an integer) then there might be gaps in the +** numbering and the value returned by this interface is the index of the +** host parameter with the largest index value. +** +** The prepared statement must not be [sqlite3_finalize | finalized] +** prior to this routine returnning. Otherwise the results are undefined +** and probably undesirable. +*/ +int sqlite3_bind_parameter_count(sqlite3_stmt*); + +/* +** CAPI3REF: Name Of A Host Parameter +** +** This routine returns a pointer to the name of the n-th parameter in a +** [sqlite3_stmt | prepared statement]. +** Host parameters of the form ":AAA" or "@AAA" or "$VVV" have a name +** which is the string ":AAA" or "@AAA" or "$VVV". +** In other words, the initial ":" or "$" or "@" +** is included as part of the name. +** Parameters of the form "?" or "?NNN" have no name. +** +** The first bound parameter has an index of 1, not 0. +** +** If the value n is out of range or if the n-th parameter is nameless, +** then NULL is returned. The returned string is always in the +** UTF-8 encoding even if the named parameter was originally specified +** as UTF-16 in [sqlite3_prepare16()] or [sqlite3_prepare16_v2()]. +*/ +const char *sqlite3_bind_parameter_name(sqlite3_stmt*, int); + +/* +** CAPI3REF: Index Of A Parameter With A Given Name +** +** This routine returns the index of a host parameter with the given name. +** The name must match exactly. If no parameter with the given name is +** found, return 0. Parameter names must be UTF8. +*/ +int sqlite3_bind_parameter_index(sqlite3_stmt*, const char *zName); + +/* +** CAPI3REF: Reset All Bindings On A Prepared Statement +** +** Contrary to the intuition of many, [sqlite3_reset()] does not +** reset the [sqlite3_bind_blob | bindings] on a +** [sqlite3_stmt | prepared statement]. Use this routine to +** reset all host parameters to NULL. +*/ +int sqlite3_clear_bindings(sqlite3_stmt*); + +/* +** CAPI3REF: Number Of Columns In A Result Set +** +** Return the number of columns in the result set returned by the +** [sqlite3_stmt | compiled SQL statement]. This routine returns 0 +** if pStmt is an SQL statement that does not return data (for +** example an UPDATE). +*/ +int sqlite3_column_count(sqlite3_stmt *pStmt); + +/* +** CAPI3REF: Column Names In A Result Set +** +** These routines return the name assigned to a particular column +** in the result set of a SELECT statement. The sqlite3_column_name() +** interface returns a pointer to a UTF8 string and sqlite3_column_name16() +** returns a pointer to a UTF16 string. The first parameter is the +** [sqlite3_stmt | prepared statement] that implements the SELECT statement. +** The second parameter is the column number. The left-most column is +** number 0. +** +** The returned string pointer is valid until either the +** [sqlite3_stmt | prepared statement] is destroyed by [sqlite3_finalize()] +** or until the next call sqlite3_column_name() or sqlite3_column_name16() +** on the same column. +** +** If sqlite3_malloc() fails during the processing of either routine +** (for example during a conversion from UTF-8 to UTF-16) then a +** NULL pointer is returned. +*/ +const char *sqlite3_column_name(sqlite3_stmt*, int N); +const void *sqlite3_column_name16(sqlite3_stmt*, int N); + +/* +** CAPI3REF: Source Of Data In A Query Result +** +** These routines provide a means to determine what column of what +** table in which database a result of a SELECT statement comes from. +** The name of the database or table or column can be returned as +** either a UTF8 or UTF16 string. The _database_ routines return +** the database name, the _table_ routines return the table name, and +** the origin_ routines return the column name. +** The returned string is valid until +** the [sqlite3_stmt | prepared statement] is destroyed using +** [sqlite3_finalize()] or until the same information is requested +** again in a different encoding. +** +** The names returned are the original un-aliased names of the +** database, table, and column. +** +** The first argument to the following calls is a +** [sqlite3_stmt | compiled SQL statement]. +** These functions return information about the Nth column returned by +** the statement, where N is the second function argument. +** +** If the Nth column returned by the statement is an expression +** or subquery and is not a column value, then all of these functions +** return NULL. Otherwise, they return the +** name of the attached database, table and column that query result +** column was extracted from. +** +** As with all other SQLite APIs, those postfixed with "16" return UTF-16 +** encoded strings, the other functions return UTF-8. +** +** These APIs are only available if the library was compiled with the +** SQLITE_ENABLE_COLUMN_METADATA preprocessor symbol defined. +** +** If two or more threads call one or more of these routines against the same +** prepared statement and column at the same time then the results are +** undefined. +*/ +const char *sqlite3_column_database_name(sqlite3_stmt*,int); +const void *sqlite3_column_database_name16(sqlite3_stmt*,int); +const char *sqlite3_column_table_name(sqlite3_stmt*,int); +const void *sqlite3_column_table_name16(sqlite3_stmt*,int); +const char *sqlite3_column_origin_name(sqlite3_stmt*,int); +const void *sqlite3_column_origin_name16(sqlite3_stmt*,int); + +/* +** CAPI3REF: Declared Datatype Of A Query Result +** +** The first parameter is a [sqlite3_stmt | compiled SQL statement]. +** If this statement is a SELECT statement and the Nth column of the +** returned result set of that SELECT is a table column (not an +** expression or subquery) then the declared type of the table +** column is returned. If the Nth column of the result set is an +** expression or subquery, then a NULL pointer is returned. +** The returned string is always UTF-8 encoded. For example, in +** the database schema: +** +** CREATE TABLE t1(c1 VARIANT); +** +** And the following statement compiled: +** +** SELECT c1 + 1, c1 FROM t1; +** +** Then this routine would return the string "VARIANT" for the second +** result column (i==1), and a NULL pointer for the first result column +** (i==0). +** +** SQLite uses dynamic run-time typing. So just because a column +** is declared to contain a particular type does not mean that the +** data stored in that column is of the declared type. SQLite is +** strongly typed, but the typing is dynamic not static. Type +** is associated with individual values, not with the containers +** used to hold those values. +*/ +const char *sqlite3_column_decltype(sqlite3_stmt *, int i); +const void *sqlite3_column_decltype16(sqlite3_stmt*,int); + +/* +** CAPI3REF: Evaluate An SQL Statement +** +** After an [sqlite3_stmt | SQL statement] has been prepared with a call +** to either [sqlite3_prepare_v2()] or [sqlite3_prepare16_v2()] or to one of +** the legacy interfaces [sqlite3_prepare()] or [sqlite3_prepare16()], +** then this function must be called one or more times to evaluate the +** statement. +** +** The details of the behavior of this sqlite3_step() interface depend +** on whether the statement was prepared using the newer "v2" interface +** [sqlite3_prepare_v2()] and [sqlite3_prepare16_v2()] or the older legacy +** interface [sqlite3_prepare()] and [sqlite3_prepare16()]. The use of the +** new "v2" interface is recommended for new applications but the legacy +** interface will continue to be supported. +** +** In the lagacy interface, the return value will be either [SQLITE_BUSY], +** [SQLITE_DONE], [SQLITE_ROW], [SQLITE_ERROR], or [SQLITE_MISUSE]. +** With the "v2" interface, any of the other [SQLITE_OK | result code] +** or [SQLITE_IOERR_READ | extended result code] might be returned as +** well. +** +** [SQLITE_BUSY] means that the database engine was unable to acquire the +** database locks it needs to do its job. If the statement is a COMMIT +** or occurs outside of an explicit transaction, then you can retry the +** statement. If the statement is not a COMMIT and occurs within a +** explicit transaction then you should rollback the transaction before +** continuing. +** +** [SQLITE_DONE] means that the statement has finished executing +** successfully. sqlite3_step() should not be called again on this virtual +** machine without first calling [sqlite3_reset()] to reset the virtual +** machine back to its initial state. +** +** If the SQL statement being executed returns any data, then +** [SQLITE_ROW] is returned each time a new row of data is ready +** for processing by the caller. The values may be accessed using +** the [sqlite3_column_int | column access functions]. +** sqlite3_step() is called again to retrieve the next row of data. +** +** [SQLITE_ERROR] means that a run-time error (such as a constraint +** violation) has occurred. sqlite3_step() should not be called again on +** the VM. More information may be found by calling [sqlite3_errmsg()]. +** With the legacy interface, a more specific error code (example: +** [SQLITE_INTERRUPT], [SQLITE_SCHEMA], [SQLITE_CORRUPT], and so forth) +** can be obtained by calling [sqlite3_reset()] on the +** [sqlite3_stmt | prepared statement]. In the "v2" interface, +** the more specific error code is returned directly by sqlite3_step(). +** +** [SQLITE_MISUSE] means that the this routine was called inappropriately. +** Perhaps it was called on a [sqlite3_stmt | prepared statement] that has +** already been [sqlite3_finalize | finalized] or on one that had +** previously returned [SQLITE_ERROR] or [SQLITE_DONE]. Or it could +** be the case that the same database connection is being used by two or +** more threads at the same moment in time. +** +** <b>Goofy Interface Alert:</b> +** In the legacy interface, +** the sqlite3_step() API always returns a generic error code, +** [SQLITE_ERROR], following any error other than [SQLITE_BUSY] +** and [SQLITE_MISUSE]. You must call [sqlite3_reset()] or +** [sqlite3_finalize()] in order to find one of the specific +** [SQLITE_ERROR | result codes] that better describes the error. +** We admit that this is a goofy design. The problem has been fixed +** with the "v2" interface. If you prepare all of your SQL statements +** using either [sqlite3_prepare_v2()] or [sqlite3_prepare16_v2()] instead +** of the legacy [sqlite3_prepare()] and [sqlite3_prepare16()], then the +** more specific [SQLITE_ERROR | result codes] are returned directly +** by sqlite3_step(). The use of the "v2" interface is recommended. +*/ +int sqlite3_step(sqlite3_stmt*); + +/* +** CAPI3REF: +** +** Return the number of values in the current row of the result set. +** +** After a call to [sqlite3_step()] that returns [SQLITE_ROW], this routine +** will return the same value as the [sqlite3_column_count()] function. +** After [sqlite3_step()] has returned an [SQLITE_DONE], [SQLITE_BUSY], or +** a [SQLITE_ERROR | error code], or before [sqlite3_step()] has been +** called on the [sqlite3_stmt | prepared statement] for the first time, +** this routine returns zero. +*/ +int sqlite3_data_count(sqlite3_stmt *pStmt); + +/* +** CAPI3REF: Fundamental Datatypes +** +** Every value in SQLite has one of five fundamental datatypes: +** +** <ul> +** <li> 64-bit signed integer +** <li> 64-bit IEEE floating point number +** <li> string +** <li> BLOB +** <li> NULL +** </ul> +** +** These constants are codes for each of those types. +** +** Note that the SQLITE_TEXT constant was also used in SQLite version 2 +** for a completely different meaning. Software that links against both +** SQLite version 2 and SQLite version 3 should use SQLITE3_TEXT not +** SQLITE_TEXT. +*/ +#define SQLITE_INTEGER 1 +#define SQLITE_FLOAT 2 +#define SQLITE_BLOB 4 +#define SQLITE_NULL 5 +#ifdef SQLITE_TEXT +# undef SQLITE_TEXT +#else +# define SQLITE_TEXT 3 +#endif +#define SQLITE3_TEXT 3 + +/* +** CAPI3REF: Results Values From A Query +** +** These routines return information about +** a single column of the current result row of a query. In every +** case the first argument is a pointer to the +** [sqlite3_stmt | SQL statement] that is being +** evaluated (the [sqlite3_stmt*] that was returned from +** [sqlite3_prepare_v2()] or one of its variants) and +** the second argument is the index of the column for which information +** should be returned. The left-most column of the result set +** has an index of 0. +** +** If the SQL statement is not currently point to a valid row, or if the +** the column index is out of range, the result is undefined. +** These routines may only be called when the most recent call to +** [sqlite3_step()] has returned [SQLITE_ROW] and neither +** [sqlite3_reset()] nor [sqlite3_finalize()] has been call subsequently. +** If any of these routines are called after [sqlite3_reset()] or +** [sqlite3_finalize()] or after [sqlite3_step()] has returned +** something other than [SQLITE_ROW], the results are undefined. +** If [sqlite3_step()] or [sqlite3_reset()] or [sqlite3_finalize()] +** are called from a different thread while any of these routines +** are pending, then the results are undefined. +** +** The sqlite3_column_type() routine returns +** [SQLITE_INTEGER | datatype code] for the initial data type +** of the result column. The returned value is one of [SQLITE_INTEGER], +** [SQLITE_FLOAT], [SQLITE_TEXT], [SQLITE_BLOB], or [SQLITE_NULL]. The value +** returned by sqlite3_column_type() is only meaningful if no type +** conversions have occurred as described below. After a type conversion, +** the value returned by sqlite3_column_type() is undefined. Future +** versions of SQLite may change the behavior of sqlite3_column_type() +** following a type conversion. +** +** If the result is a BLOB or UTF-8 string then the sqlite3_column_bytes() +** routine returns the number of bytes in that BLOB or string. +** If the result is a UTF-16 string, then sqlite3_column_bytes() converts +** the string to UTF-8 and then returns the number of bytes. +** If the result is a numeric value then sqlite3_column_bytes() uses +** [sqlite3_snprintf()] to convert that value to a UTF-8 string and returns +** the number of bytes in that string. +** The value returned does not include the zero terminator at the end +** of the string. For clarity: the value returned is the number of +** bytes in the string, not the number of characters. +** +** Strings returned by sqlite3_column_text() and sqlite3_column_text16(), +** even zero-length strings, are always zero terminated. The return +** value from sqlite3_column_blob() for a zero-length blob is an arbitrary +** pointer, possibly even a NULL pointer. +** +** The sqlite3_column_bytes16() routine is similar to sqlite3_column_bytes() +** but leaves the result in UTF-16 instead of UTF-8. +** The zero terminator is not included in this count. +** +** These routines attempt to convert the value where appropriate. For +** example, if the internal representation is FLOAT and a text result +** is requested, [sqlite3_snprintf()] is used internally to do the conversion +** automatically. The following table details the conversions that +** are applied: +** +** <blockquote> +** <table border="1"> +** <tr><th> Internal<br>Type <th> Requested<br>Type <th> Conversion +** +** <tr><td> NULL <td> INTEGER <td> Result is 0 +** <tr><td> NULL <td> FLOAT <td> Result is 0.0 +** <tr><td> NULL <td> TEXT <td> Result is NULL pointer +** <tr><td> NULL <td> BLOB <td> Result is NULL pointer +** <tr><td> INTEGER <td> FLOAT <td> Convert from integer to float +** <tr><td> INTEGER <td> TEXT <td> ASCII rendering of the integer +** <tr><td> INTEGER <td> BLOB <td> Same as for INTEGER->TEXT +** <tr><td> FLOAT <td> INTEGER <td> Convert from float to integer +** <tr><td> FLOAT <td> TEXT <td> ASCII rendering of the float +** <tr><td> FLOAT <td> BLOB <td> Same as FLOAT->TEXT +** <tr><td> TEXT <td> INTEGER <td> Use atoi() +** <tr><td> TEXT <td> FLOAT <td> Use atof() +** <tr><td> TEXT <td> BLOB <td> No change +** <tr><td> BLOB <td> INTEGER <td> Convert to TEXT then use atoi() +** <tr><td> BLOB <td> FLOAT <td> Convert to TEXT then use atof() +** <tr><td> BLOB <td> TEXT <td> Add a zero terminator if needed +** </table> +** </blockquote> +** +** The table above makes reference to standard C library functions atoi() +** and atof(). SQLite does not really use these functions. It has its +** on equavalent internal routines. The atoi() and atof() names are +** used in the table for brevity and because they are familiar to most +** C programmers. +** +** Note that when type conversions occur, pointers returned by prior +** calls to sqlite3_column_blob(), sqlite3_column_text(), and/or +** sqlite3_column_text16() may be invalidated. +** Type conversions and pointer invalidations might occur +** in the following cases: +** +** <ul> +** <li><p> The initial content is a BLOB and sqlite3_column_text() +** or sqlite3_column_text16() is called. A zero-terminator might +** need to be added to the string.</p></li> +** +** <li><p> The initial content is UTF-8 text and sqlite3_column_bytes16() or +** sqlite3_column_text16() is called. The content must be converted +** to UTF-16.</p></li> +** +** <li><p> The initial content is UTF-16 text and sqlite3_column_bytes() or +** sqlite3_column_text() is called. The content must be converted +** to UTF-8.</p></li> +** </ul> +** +** Conversions between UTF-16be and UTF-16le are always done in place and do +** not invalidate a prior pointer, though of course the content of the buffer +** that the prior pointer points to will have been modified. Other kinds +** of conversion are done in place when it is possible, but sometime it is +** not possible and in those cases prior pointers are invalidated. +** +** The safest and easiest to remember policy is to invoke these routines +** in one of the following ways: +** +** <ul> +** <li>sqlite3_column_text() followed by sqlite3_column_bytes()</li> +** <li>sqlite3_column_blob() followed by sqlite3_column_bytes()</li> +** <li>sqlite3_column_text16() followed by sqlite3_column_bytes16()</li> +** </ul> +** +** In other words, you should call sqlite3_column_text(), sqlite3_column_blob(), +** or sqlite3_column_text16() first to force the result into the desired +** format, then invoke sqlite3_column_bytes() or sqlite3_column_bytes16() to +** find the size of the result. Do not mix call to sqlite3_column_text() or +** sqlite3_column_blob() with calls to sqlite3_column_bytes16(). And do not +** mix calls to sqlite3_column_text16() with calls to sqlite3_column_bytes(). +** +** The pointers returned are valid until a type conversion occurs as +** described above, or until [sqlite3_step()] or [sqlite3_reset()] or +** [sqlite3_finalize()] is called. The memory space used to hold strings +** and blobs is freed automatically. Do <b>not</b> pass the pointers returned +** [sqlite3_column_blob()], [sqlite3_column_text()], etc. into +** [sqlite3_free()]. +** +** If a memory allocation error occurs during the evaluation of any +** of these routines, a default value is returned. The default value +** is either the integer 0, the floating point number 0.0, or a NULL +** pointer. Subsequent calls to [sqlite3_errcode()] will return +** [SQLITE_NOMEM]. +*/ +const void *sqlite3_column_blob(sqlite3_stmt*, int iCol); +int sqlite3_column_bytes(sqlite3_stmt*, int iCol); +int sqlite3_column_bytes16(sqlite3_stmt*, int iCol); +double sqlite3_column_double(sqlite3_stmt*, int iCol); +int sqlite3_column_int(sqlite3_stmt*, int iCol); +sqlite3_int64 sqlite3_column_int64(sqlite3_stmt*, int iCol); +const unsigned char *sqlite3_column_text(sqlite3_stmt*, int iCol); +const void *sqlite3_column_text16(sqlite3_stmt*, int iCol); +int sqlite3_column_type(sqlite3_stmt*, int iCol); +sqlite3_value *sqlite3_column_value(sqlite3_stmt*, int iCol); + +/* +** CAPI3REF: Destroy A Prepared Statement Object +** +** The sqlite3_finalize() function is called to delete a +** [sqlite3_stmt | compiled SQL statement]. If the statement was +** executed successfully, or not executed at all, then SQLITE_OK is returned. +** If execution of the statement failed then an +** [SQLITE_ERROR | error code] or [SQLITE_IOERR_READ | extended error code] +** is returned. +** +** This routine can be called at any point during the execution of the +** [sqlite3_stmt | virtual machine]. If the virtual machine has not +** completed execution when this routine is called, that is like +** encountering an error or an interrupt. (See [sqlite3_interrupt()].) +** Incomplete updates may be rolled back and transactions cancelled, +** depending on the circumstances, and the +** [SQLITE_ERROR | result code] returned will be [SQLITE_ABORT]. +*/ +int sqlite3_finalize(sqlite3_stmt *pStmt); + +/* +** CAPI3REF: Reset A Prepared Statement Object +** +** The sqlite3_reset() function is called to reset a +** [sqlite3_stmt | compiled SQL statement] object. +** back to it's initial state, ready to be re-executed. +** Any SQL statement variables that had values bound to them using +** the [sqlite3_bind_blob | sqlite3_bind_*() API] retain their values. +** Use [sqlite3_clear_bindings()] to reset the bindings. +*/ +int sqlite3_reset(sqlite3_stmt *pStmt); + +/* +** CAPI3REF: Create Or Redefine SQL Functions +** +** The following two functions are used to add SQL functions or aggregates +** or to redefine the behavior of existing SQL functions or aggregates. The +** difference only between the two is that the second parameter, the +** name of the (scalar) function or aggregate, is encoded in UTF-8 for +** sqlite3_create_function() and UTF-16 for sqlite3_create_function16(). +** +** The first argument is the [sqlite3 | database handle] that holds the +** SQL function or aggregate is to be added or redefined. If a single +** program uses more than one database handle internally, then SQL +** functions or aggregates must be added individually to each database +** handle with which they will be used. +** +** The second parameter is the name of the SQL function to be created +** or redefined. +** The length of the name is limited to 255 bytes, exclusive of the +** zero-terminator. Note that the name length limit is in bytes, not +** characters. Any attempt to create a function with a longer name +** will result in an SQLITE_ERROR error. +** +** The third parameter is the number of arguments that the SQL function or +** aggregate takes. If this parameter is negative, then the SQL function or +** aggregate may take any number of arguments. +** +** The fourth parameter, eTextRep, specifies what +** [SQLITE_UTF8 | text encoding] this SQL function prefers for +** its parameters. Any SQL function implementation should be able to work +** work with UTF-8, UTF-16le, or UTF-16be. But some implementations may be +** more efficient with one encoding than another. It is allowed to +** invoke sqlite3_create_function() or sqlite3_create_function16() multiple +** times with the same function but with different values of eTextRep. +** When multiple implementations of the same function are available, SQLite +** will pick the one that involves the least amount of data conversion. +** If there is only a single implementation which does not care what +** text encoding is used, then the fourth argument should be +** [SQLITE_ANY]. +** +** The fifth parameter is an arbitrary pointer. The implementation +** of the function can gain access to this pointer using +** [sqlite3_user_data()]. +** +** The seventh, eighth and ninth parameters, xFunc, xStep and xFinal, are +** pointers to C-language functions that implement the SQL +** function or aggregate. A scalar SQL function requires an implementation of +** the xFunc callback only, NULL pointers should be passed as the xStep +** and xFinal parameters. An aggregate SQL function requires an implementation +** of xStep and xFinal and NULL should be passed for xFunc. To delete an +** existing SQL function or aggregate, pass NULL for all three function +** callback. +** +** It is permitted to register multiple implementations of the same +** functions with the same name but with either differing numbers of +** arguments or differing perferred text encodings. SQLite will use +** the implementation most closely matches the way in which the +** SQL function is used. +*/ +int sqlite3_create_function( + sqlite3 *, + const char *zFunctionName, + int nArg, + int eTextRep, + void*, + void (*xFunc)(sqlite3_context*,int,sqlite3_value**), + void (*xStep)(sqlite3_context*,int,sqlite3_value**), + void (*xFinal)(sqlite3_context*) +); +int sqlite3_create_function16( + sqlite3*, + const void *zFunctionName, + int nArg, + int eTextRep, + void*, + void (*xFunc)(sqlite3_context*,int,sqlite3_value**), + void (*xStep)(sqlite3_context*,int,sqlite3_value**), + void (*xFinal)(sqlite3_context*) +); + +/* +** CAPI3REF: Text Encodings +** +** These constant define integer codes that represent the various +** text encodings supported by SQLite. +*/ +#define SQLITE_UTF8 1 +#define SQLITE_UTF16LE 2 +#define SQLITE_UTF16BE 3 +#define SQLITE_UTF16 4 /* Use native byte order */ +#define SQLITE_ANY 5 /* sqlite3_create_function only */ +#define SQLITE_UTF16_ALIGNED 8 /* sqlite3_create_collation only */ + +/* +** CAPI3REF: Obsolete Functions +** +** These functions are all now obsolete. In order to maintain +** backwards compatibility with older code, we continue to support +** these functions. However, new development projects should avoid +** the use of these functions. To help encourage people to avoid +** using these functions, we are not going to tell you want they do. +*/ +int sqlite3_aggregate_count(sqlite3_context*); +int sqlite3_expired(sqlite3_stmt*); +int sqlite3_transfer_bindings(sqlite3_stmt*, sqlite3_stmt*); +int sqlite3_global_recover(void); +void sqlite3_thread_cleanup(void); +int sqlite3_memory_alarm(void(*)(void*,sqlite3_int64,int),void*,sqlite3_int64); + +/* +** CAPI3REF: Obtaining SQL Function Parameter Values +** +** The C-language implementation of SQL functions and aggregates uses +** this set of interface routines to access the parameter values on +** the function or aggregate. +** +** The xFunc (for scalar functions) or xStep (for aggregates) parameters +** to [sqlite3_create_function()] and [sqlite3_create_function16()] +** define callbacks that implement the SQL functions and aggregates. +** The 4th parameter to these callbacks is an array of pointers to +** [sqlite3_value] objects. There is one [sqlite3_value] object for +** each parameter to the SQL function. These routines are used to +** extract values from the [sqlite3_value] objects. +** +** These routines work just like the corresponding +** [sqlite3_column_blob | sqlite3_column_* routines] except that +** these routines take a single [sqlite3_value*] pointer instead +** of an [sqlite3_stmt*] pointer and an integer column number. +** +** The sqlite3_value_text16() interface extracts a UTF16 string +** in the native byte-order of the host machine. The +** sqlite3_value_text16be() and sqlite3_value_text16le() interfaces +** extract UTF16 strings as big-endian and little-endian respectively. +** +** The sqlite3_value_numeric_type() interface attempts to apply +** numeric affinity to the value. This means that an attempt is +** made to convert the value to an integer or floating point. If +** such a conversion is possible without loss of information (in order +** words if the value is original a string that looks like a number) +** then it is done. Otherwise no conversion occurs. The +** [SQLITE_INTEGER | datatype] after conversion is returned. +** +** Please pay particular attention to the fact that the pointer that +** is returned from [sqlite3_value_blob()], [sqlite3_value_text()], or +** [sqlite3_value_text16()] can be invalidated by a subsequent call to +** [sqlite3_value_bytes()], [sqlite3_value_bytes16()], [sqlite3_value_text()], +** or [sqlite3_value_text16()]. +** +** These routines must be called from the same thread as +** the SQL function that supplied the sqlite3_value* parameters. +** Or, if the sqlite3_value* argument comes from the [sqlite3_column_value()] +** interface, then these routines should be called from the same thread +** that ran [sqlite3_column_value()]. +*/ +const void *sqlite3_value_blob(sqlite3_value*); +int sqlite3_value_bytes(sqlite3_value*); +int sqlite3_value_bytes16(sqlite3_value*); +double sqlite3_value_double(sqlite3_value*); +int sqlite3_value_int(sqlite3_value*); +sqlite3_int64 sqlite3_value_int64(sqlite3_value*); +const unsigned char *sqlite3_value_text(sqlite3_value*); +const void *sqlite3_value_text16(sqlite3_value*); +const void *sqlite3_value_text16le(sqlite3_value*); +const void *sqlite3_value_text16be(sqlite3_value*); +int sqlite3_value_type(sqlite3_value*); +int sqlite3_value_numeric_type(sqlite3_value*); + +/* +** CAPI3REF: Obtain Aggregate Function Context +** +** The implementation of aggregate SQL functions use this routine to allocate +** a structure for storing their state. The first time this routine +** is called for a particular aggregate, a new structure of size nBytes +** is allocated, zeroed, and returned. On subsequent calls (for the +** same aggregate instance) the same buffer is returned. The implementation +** of the aggregate can use the returned buffer to accumulate data. +** +** The buffer allocated is freed automatically by SQLite whan the aggregate +** query concludes. +** +** The first parameter should be a copy of the +** [sqlite3_context | SQL function context] that is the first +** parameter to the callback routine that implements the aggregate +** function. +** +** This routine must be called from the same thread in which +** the aggregate SQL function is running. +*/ +void *sqlite3_aggregate_context(sqlite3_context*, int nBytes); + +/* +** CAPI3REF: User Data For Functions +** +** The pUserData parameter to the [sqlite3_create_function()] +** and [sqlite3_create_function16()] routines +** used to register user functions is available to +** the implementation of the function using this call. +** +** This routine must be called from the same thread in which +** the SQL function is running. +*/ +void *sqlite3_user_data(sqlite3_context*); + +/* +** CAPI3REF: Function Auxiliary Data +** +** The following two functions may be used by scalar SQL functions to +** associate meta-data with argument values. If the same value is passed to +** multiple invocations of the same SQL function during query execution, under +** some circumstances the associated meta-data may be preserved. This may +** be used, for example, to add a regular-expression matching scalar +** function. The compiled version of the regular expression is stored as +** meta-data associated with the SQL value passed as the regular expression +** pattern. The compiled regular expression can be reused on multiple +** invocations of the same function so that the original pattern string +** does not need to be recompiled on each invocation. +** +** The sqlite3_get_auxdata() interface returns a pointer to the meta-data +** associated with the Nth argument value to the current SQL function +** call, where N is the second parameter. If no meta-data has been set for +** that value, then a NULL pointer is returned. +** +** The sqlite3_set_auxdata() is used to associate meta-data with an SQL +** function argument. The third parameter is a pointer to the meta-data +** to be associated with the Nth user function argument value. The fourth +** parameter specifies a destructor that will be called on the meta- +** data pointer to release it when it is no longer required. If the +** destructor is NULL, it is not invoked. +** +** In practice, meta-data is preserved between function calls for +** expressions that are constant at compile time. This includes literal +** values and SQL variables. +** +** These routines must be called from the same thread in which +** the SQL function is running. +*/ +void *sqlite3_get_auxdata(sqlite3_context*, int); +void sqlite3_set_auxdata(sqlite3_context*, int, void*, void (*)(void*)); + + +/* +** CAPI3REF: Constants Defining Special Destructor Behavior +** +** These are special value for the destructor that is passed in as the +** final argument to routines like [sqlite3_result_blob()]. If the destructor +** argument is SQLITE_STATIC, it means that the content pointer is constant +** and will never change. It does not need to be destroyed. The +** SQLITE_TRANSIENT value means that the content will likely change in +** the near future and that SQLite should make its own private copy of +** the content before returning. +** +** The typedef is necessary to work around problems in certain +** C++ compilers. See ticket #2191. +*/ +typedef void (*sqlite3_destructor_type)(void*); +#define SQLITE_STATIC ((sqlite3_destructor_type)0) +#define SQLITE_TRANSIENT ((sqlite3_destructor_type)-1) + +/* +** CAPI3REF: Setting The Result Of An SQL Function +** +** These routines are used by the xFunc or xFinal callbacks that +** implement SQL functions and aggregates. See +** [sqlite3_create_function()] and [sqlite3_create_function16()] +** for additional information. +** +** These functions work very much like the +** [sqlite3_bind_blob | sqlite3_bind_*] family of functions used +** to bind values to host parameters in prepared statements. +** Refer to the +** [sqlite3_bind_blob | sqlite3_bind_* documentation] for +** additional information. +** +** The sqlite3_result_error() and sqlite3_result_error16() functions +** cause the implemented SQL function to throw an exception. The +** parameter to sqlite3_result_error() or sqlite3_result_error16() +** is the text of an error message. +** +** The sqlite3_result_toobig() cause the function implementation +** to throw and error indicating that a string or BLOB is to long +** to represent. +** +** These routines must be called from within the same thread as +** the SQL function associated with the [sqlite3_context] pointer. +*/ +void sqlite3_result_blob(sqlite3_context*, const void*, int, void(*)(void*)); +void sqlite3_result_double(sqlite3_context*, double); +void sqlite3_result_error(sqlite3_context*, const char*, int); +void sqlite3_result_error16(sqlite3_context*, const void*, int); +void sqlite3_result_error_toobig(sqlite3_context*); +void sqlite3_result_error_nomem(sqlite3_context*); +void sqlite3_result_int(sqlite3_context*, int); +void sqlite3_result_int64(sqlite3_context*, sqlite3_int64); +void sqlite3_result_null(sqlite3_context*); +void sqlite3_result_text(sqlite3_context*, const char*, int, void(*)(void*)); +void sqlite3_result_text16(sqlite3_context*, const void*, int, void(*)(void*)); +void sqlite3_result_text16le(sqlite3_context*, const void*, int,void(*)(void*)); +void sqlite3_result_text16be(sqlite3_context*, const void*, int,void(*)(void*)); +void sqlite3_result_value(sqlite3_context*, sqlite3_value*); +void sqlite3_result_zeroblob(sqlite3_context*, int n); + +/* +** CAPI3REF: Define New Collating Sequences +** +** These functions are used to add new collation sequences to the +** [sqlite3*] handle specified as the first argument. +** +** The name of the new collation sequence is specified as a UTF-8 string +** for sqlite3_create_collation() and sqlite3_create_collation_v2() +** and a UTF-16 string for sqlite3_create_collation16(). In all cases +** the name is passed as the second function argument. +** +** The third argument may be one of the constants [SQLITE_UTF8], +** [SQLITE_UTF16LE] or [SQLITE_UTF16BE], indicating that the user-supplied +** routine expects to be passed pointers to strings encoded using UTF-8, +** UTF-16 little-endian or UTF-16 big-endian respectively. The +** third argument might also be [SQLITE_UTF16_ALIGNED] to indicate that +** the routine expects pointers to 16-bit word aligned strings +** of UTF16 in the native byte order of the host computer. +** +** A pointer to the user supplied routine must be passed as the fifth +** argument. If it is NULL, this is the same as deleting the collation +** sequence (so that SQLite cannot call it anymore). Each time the user +** supplied function is invoked, it is passed a copy of the void* passed as +** the fourth argument to sqlite3_create_collation() or +** sqlite3_create_collation16() as its first parameter. +** +** The remaining arguments to the user-supplied routine are two strings, +** each represented by a [length, data] pair and encoded in the encoding +** that was passed as the third argument when the collation sequence was +** registered. The user routine should return negative, zero or positive if +** the first string is less than, equal to, or greater than the second +** string. i.e. (STRING1 - STRING2). +** +** The sqlite3_create_collation_v2() works like sqlite3_create_collation() +** excapt that it takes an extra argument which is a destructor for +** the collation. The destructor is called when the collation is +** destroyed and is passed a copy of the fourth parameter void* pointer +** of the sqlite3_create_collation_v2(). Collations are destroyed when +** they are overridden by later calls to the collation creation functions +** or when the [sqlite3*] database handle is closed using [sqlite3_close()]. +** +** The sqlite3_create_collation_v2() interface is experimental and +** subject to change in future releases. The other collation creation +** functions are stable. +*/ +int sqlite3_create_collation( + sqlite3*, + const char *zName, + int eTextRep, + void*, + int(*xCompare)(void*,int,const void*,int,const void*) +); +int sqlite3_create_collation_v2( + sqlite3*, + const char *zName, + int eTextRep, + void*, + int(*xCompare)(void*,int,const void*,int,const void*), + void(*xDestroy)(void*) +); +int sqlite3_create_collation16( + sqlite3*, + const char *zName, + int eTextRep, + void*, + int(*xCompare)(void*,int,const void*,int,const void*) +); + +/* +** CAPI3REF: 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 handle to be called whenever an undefined collation sequence is +** required. +** +** If the function is registered using the sqlite3_collation_needed() API, +** then it is passed the names of undefined collation sequences as strings +** encoded in UTF-8. If sqlite3_collation_needed16() is used, the names +** are passed as UTF-16 in machine native byte order. A call to either +** function replaces any existing callback. +** +** When the callback is invoked, the first argument passed is a copy +** of the second argument to sqlite3_collation_needed() or +** sqlite3_collation_needed16(). The second argument is the database +** handle. The third argument is one of [SQLITE_UTF8], [SQLITE_UTF16BE], or +** [SQLITE_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 +** [sqlite3_create_collation()], [sqlite3_create_collation16()], or +** [sqlite3_create_collation_v2()]. +*/ +int sqlite3_collation_needed( + sqlite3*, + void*, + void(*)(void*,sqlite3*,int eTextRep,const char*) +); +int sqlite3_collation_needed16( + sqlite3*, + void*, + void(*)(void*,sqlite3*,int eTextRep,const void*) +); + +/* +** Specify the key for an encrypted database. This routine should be +** called right after sqlite3_open(). +** +** The code to implement this API is not available in the public release +** of SQLite. +*/ +int sqlite3_key( + sqlite3 *db, /* Database to be rekeyed */ + const void *pKey, int nKey /* The key */ +); + +/* +** Change the key on an open database. If the current database is not +** encrypted, this routine will encrypt it. If pNew==0 or nNew==0, the +** database is decrypted. +** +** The code to implement this API is not available in the public release +** of SQLite. +*/ +int sqlite3_rekey( + sqlite3 *db, /* Database to be rekeyed */ + const void *pKey, int nKey /* The new key */ +); + +/* +** CAPI3REF: Suspend Execution For A Short Time +** +** This function causes the current thread to suspend execution +** a number of milliseconds specified in its parameter. +** +** If the operating system does not support sleep requests with +** millisecond time resolution, then the time will be rounded up to +** the nearest second. The number of milliseconds of sleep actually +** requested from the operating system is returned. +** +** SQLite implements this interface by calling the xSleep() +** method of the default [sqlite3_vfs] object. +*/ +int sqlite3_sleep(int); + +/* +** CAPI3REF: Name Of The Folder Holding Temporary Files +** +** If this global variable is made to point to a string which is +** the name of a folder (a.ka. directory), then all temporary files +** created by SQLite will be placed in that directory. If this variable +** is NULL pointer, then SQLite does a search for an appropriate temporary +** file directory. +** +** It is not safe to modify this variable once a database connection +** has been opened. It is intended that this variable be set once +** as part of process initialization and before any SQLite interface +** routines have been call and remain unchanged thereafter. +*/ +SQLITE_EXTERN char *sqlite3_temp_directory; + +/* +** CAPI3REF: Test To See If The Database Is In Auto-Commit Mode +** +** Test to see whether or not the database connection is in autocommit +** mode. Return TRUE if it is and FALSE if not. Autocommit mode is on +** by default. Autocommit is disabled by a BEGIN statement and reenabled +** by the next COMMIT or ROLLBACK. +** +** If certain kinds of errors occur on a statement within a multi-statement +** transactions (errors including [SQLITE_FULL], [SQLITE_IOERR], +** [SQLITE_NOMEM], [SQLITE_BUSY], and [SQLITE_INTERRUPT]) then the +** transaction might be rolled back automatically. The only way to +** find out if SQLite automatically rolled back the transaction after +** an error is to use this function. +** +** If another thread changes the autocommit status of the database +** connection while this routine is running, then the return value +** is undefined. +*/ +int sqlite3_get_autocommit(sqlite3*); + +/* +** CAPI3REF: Find The Database Handle Associated With A Prepared Statement +** +** Return the [sqlite3*] database handle to which a +** [sqlite3_stmt | prepared statement] belongs. +** This is the same database handle that was +** the first argument to the [sqlite3_prepare_v2()] or its variants +** that was used to create the statement in the first place. +*/ +sqlite3 *sqlite3_db_handle(sqlite3_stmt*); + + +/* +** CAPI3REF: Commit And Rollback Notification Callbacks +** +** These routines +** register callback functions to be invoked whenever a transaction +** is committed or rolled back. The pArg argument is passed through +** to the callback. If the callback on a commit hook function +** returns non-zero, then the commit is converted into a rollback. +** +** If another function was previously registered, its pArg value is returned. +** Otherwise NULL is returned. +** +** Registering a NULL function disables the callback. +** +** For the purposes of this API, a transaction is said to have been +** rolled back if an explicit "ROLLBACK" statement is executed, or +** an error or constraint causes an implicit rollback to occur. The +** callback is not invoked if a transaction is automatically rolled +** back because the database connection is closed. +** +** These are experimental interfaces and are subject to change. +*/ +void *sqlite3_commit_hook(sqlite3*, int(*)(void*), void*); +void *sqlite3_rollback_hook(sqlite3*, void(*)(void *), void*); + +/* +** CAPI3REF: Data Change Notification Callbacks +** +** Register a callback function with the database connection identified by the +** first argument to be invoked whenever a row is updated, inserted or deleted. +** Any callback set by a previous call to this function for the same +** database connection is overridden. +** +** The second argument is a pointer to the function to invoke when a +** row is updated, inserted or deleted. The first argument to the callback is +** a copy of the third argument to sqlite3_update_hook(). The second callback +** argument is one of SQLITE_INSERT, SQLITE_DELETE or SQLITE_UPDATE, depending +** on the operation that caused the callback to be invoked. The third and +** fourth arguments to the callback contain pointers to the database and +** table name containing the affected row. The final callback parameter is +** the rowid of the row. In the case of an update, this is the rowid after +** the update takes place. +** +** The update hook is not invoked when internal system tables are +** modified (i.e. sqlite_master and sqlite_sequence). +** +** If another function was previously registered, its pArg value is returned. +** Otherwise NULL is returned. +*/ +void *sqlite3_update_hook( + sqlite3*, + void(*)(void *,int ,char const *,char const *,sqlite3_int64), + void* +); + +/* +** CAPI3REF: Enable Or Disable Shared Pager Cache +** +** This routine enables or disables the sharing of the database cache +** and schema data structures between connections to the same database. +** Sharing is enabled if the argument is true and disabled if the argument +** is false. +** +** Beginning in SQLite version 3.5.0, cache sharing is enabled and disabled +** for an entire process. In prior versions of SQLite, sharing was +** enabled or disabled for each thread separately. +** +** The cache sharing mode set by this interface effects all subsequent +** calls to [sqlite3_open()], [sqlite3_open_v2()], and [sqlite3_open16()]. +** Existing database connections continue use the sharing mode that was +** in effect at the time they were opened. +** +** Virtual tables cannot be used with a shared cache. When shared +** cache is enabled, the [sqlite3_create_module()] API used to register +** virtual tables will always return an error. +** +** This routine returns [SQLITE_OK] if shared cache was +** enabled or disabled successfully. An [SQLITE_ERROR | error code] +** is returned otherwise. +** +** Shared cache is disabled by default. But this might change in +** future releases of SQLite. Applications that care about shared +** cache setting should set it explicitly. +*/ +int sqlite3_enable_shared_cache(int); + +/* +** CAPI3REF: Attempt To Free Heap Memory +** +** Attempt to free N bytes of heap memory by deallocating non-essential +** memory allocations held by the database library (example: memory +** used to cache database pages to improve performance). +*/ +int sqlite3_release_memory(int); + +/* +** CAPI3REF: Impose A Limit On Heap Size +** +** Place a "soft" limit on the amount of heap memory that may be allocated +** by SQLite. If an internal allocation is requested +** that would exceed the specified limit, [sqlite3_release_memory()] is +** invoked one or more times to free up some space before the allocation +** is made. +** +** The limit is called "soft", because if [sqlite3_release_memory()] cannot +** free sufficient memory to prevent the limit from being exceeded, +** the memory is allocated anyway and the current operation proceeds. +** +** A negative or zero value for N means that there is no soft heap limit and +** [sqlite3_release_memory()] will only be called when memory is exhausted. +** The default value for the soft heap limit is zero. +** +** SQLite makes a best effort to honor the soft heap limit. But if it +** is unable to reduce memory usage below the soft limit, execution will +** continue without error or notification. This is why the limit is +** called a "soft" limit. It is advisory only. +** +** Prior to SQLite version 3.5.0, this routine only constrained the memory +** allocated by a single thread - the same thread in which this routine +** runs. Beginning with SQLite version 3.5.0, the soft heap limit is +** applied to all threads. The value specified for the soft heap limit +** is an upper bound on the total memory allocation for all threads. In +** version 3.5.0 there is no mechanism for limiting the heap usage for +** individual threads. +*/ +void sqlite3_soft_heap_limit(int); + +/* +** CAPI3REF: Extract Metadata About A Column Of A Table +** +** This routine +** returns meta-data about a specific column of a specific database +** table accessible using the connection handle passed as the first function +** argument. +** +** The column is identified by the second, third and fourth parameters to +** this function. The second parameter is either the name of the database +** (i.e. "main", "temp" or an attached database) containing the specified +** table or NULL. If it is NULL, then all attached databases are searched +** for the table using the same algorithm as the database engine uses to +** resolve unqualified table references. +** +** The third and fourth parameters to this function are the table and column +** name of the desired column, respectively. Neither of these parameters +** may be NULL. +** +** Meta information is returned by writing to the memory locations passed as +** the 5th and subsequent parameters to this function. Any of these +** arguments may be NULL, in which case the corresponding element of meta +** information is ommitted. +** +** <pre> +** Parameter Output Type Description +** ----------------------------------- +** +** 5th const char* Data type +** 6th const char* Name of the default collation sequence +** 7th int True if the column has a NOT NULL constraint +** 8th int True if the column is part of the PRIMARY KEY +** 9th int True if the column is AUTOINCREMENT +** </pre> +** +** +** The memory pointed to by the character pointers returned for the +** declaration type and collation sequence is valid only until the next +** call to any sqlite API function. +** +** If the specified table is actually a view, then an error is returned. +** +** If the specified column is "rowid", "oid" or "_rowid_" and an +** INTEGER PRIMARY KEY column has been explicitly declared, then the output +** parameters are set for the explicitly declared column. If there is no +** explicitly declared IPK column, then the output parameters are set as +** follows: +** +** <pre> +** data type: "INTEGER" +** collation sequence: "BINARY" +** not null: 0 +** primary key: 1 +** auto increment: 0 +** </pre> +** +** This function may load one or more schemas from database files. If an +** error occurs during this process, or if the requested table or column +** cannot be found, an SQLITE error code is returned and an error message +** left in the database handle (to be retrieved using sqlite3_errmsg()). +** +** This API is only available if the library was compiled with the +** SQLITE_ENABLE_COLUMN_METADATA preprocessor symbol defined. +*/ +int sqlite3_table_column_metadata( + sqlite3 *db, /* Connection handle */ + const char *zDbName, /* Database name or NULL */ + const char *zTableName, /* Table name */ + const char *zColumnName, /* Column name */ + char const **pzDataType, /* OUTPUT: Declared data type */ + char const **pzCollSeq, /* OUTPUT: Collation sequence name */ + int *pNotNull, /* OUTPUT: True if NOT NULL constraint exists */ + int *pPrimaryKey, /* OUTPUT: True if column part of PK */ + int *pAutoinc /* OUTPUT: True if column is auto-increment */ +); + +/* +** CAPI3REF: Load An Extension +** +** Attempt to load an SQLite extension library contained in the file +** zFile. The entry point is zProc. zProc may be 0 in which case the +** name of the entry point defaults to "sqlite3_extension_init". +** +** Return [SQLITE_OK] on success and [SQLITE_ERROR] if something goes wrong. +** +** If an error occurs and pzErrMsg is not 0, then fill *pzErrMsg with +** error message text. The calling function should free this memory +** by calling [sqlite3_free()]. +** +** Extension loading must be enabled using [sqlite3_enable_load_extension()] +** prior to calling this API or an error will be returned. +*/ +int sqlite3_load_extension( + sqlite3 *db, /* Load the extension into this database connection */ + const char *zFile, /* Name of the shared library containing extension */ + const char *zProc, /* Entry point. Derived from zFile if 0 */ + char **pzErrMsg /* Put error message here if not 0 */ +); + +/* +** CAPI3REF: Enable Or Disable Extension Loading +** +** So as not to open security holes in older applications that are +** unprepared to deal with extension loading, and as a means of disabling +** extension loading while evaluating user-entered SQL, the following +** API is provided to turn the [sqlite3_load_extension()] mechanism on and +** off. It is off by default. See ticket #1863. +** +** Call this routine with onoff==1 to turn extension loading on +** and call it with onoff==0 to turn it back off again. +*/ +int sqlite3_enable_load_extension(sqlite3 *db, int onoff); + +/* +** CAPI3REF: Make Arrangements To Automatically Load An Extension +** +** Register an extension entry point that is automatically invoked +** whenever a new database connection is opened using +** [sqlite3_open()], [sqlite3_open16()], or [sqlite3_open_v2()]. +** +** This API can be invoked at program startup in order to register +** one or more statically linked extensions that will be available +** to all new database connections. +** +** Duplicate extensions are detected so calling this routine multiple +** times with the same extension is harmless. +** +** This routine stores a pointer to the extension in an array +** that is obtained from malloc(). If you run a memory leak +** checker on your program and it reports a leak because of this +** array, then invoke [sqlite3_reset_auto_extension()] prior +** to shutdown to free the memory. +** +** Automatic extensions apply across all threads. +** +** This interface is experimental and is subject to change or +** removal in future releases of SQLite. +*/ +int sqlite3_auto_extension(void *xEntryPoint); + + +/* +** CAPI3REF: Reset Automatic Extension Loading +** +** Disable all previously registered automatic extensions. This +** routine undoes the effect of all prior [sqlite3_automatic_extension()] +** calls. +** +** This call disabled automatic extensions in all threads. +** +** This interface is experimental and is subject to change or +** removal in future releases of SQLite. +*/ +void sqlite3_reset_auto_extension(void); + + +/* +****** EXPERIMENTAL - subject to change without notice ************** +** +** The interface to the virtual-table mechanism is currently considered +** to be experimental. The interface might change in incompatible ways. +** If this is a problem for you, do not use the interface at this time. +** +** When the virtual-table mechanism stablizes, we will declare the +** interface fixed, support it indefinitely, and remove this comment. +*/ + +/* +** Structures used by the virtual table interface +*/ +typedef struct sqlite3_vtab sqlite3_vtab; +typedef struct sqlite3_index_info sqlite3_index_info; +typedef struct sqlite3_vtab_cursor sqlite3_vtab_cursor; +typedef struct sqlite3_module sqlite3_module; + +/* +** A module is a class of virtual tables. Each module is defined +** by an instance of the following structure. This structure consists +** mostly of methods for the module. +*/ +struct sqlite3_module { + int iVersion; + int (*xCreate)(sqlite3*, void *pAux, + int argc, const char *const*argv, + sqlite3_vtab **ppVTab, char**); + int (*xConnect)(sqlite3*, void *pAux, + int argc, const char *const*argv, + sqlite3_vtab **ppVTab, char**); + int (*xBestIndex)(sqlite3_vtab *pVTab, sqlite3_index_info*); + int (*xDisconnect)(sqlite3_vtab *pVTab); + int (*xDestroy)(sqlite3_vtab *pVTab); + int (*xOpen)(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor); + int (*xClose)(sqlite3_vtab_cursor*); + int (*xFilter)(sqlite3_vtab_cursor*, int idxNum, const char *idxStr, + int argc, sqlite3_value **argv); + int (*xNext)(sqlite3_vtab_cursor*); + int (*xEof)(sqlite3_vtab_cursor*); + int (*xColumn)(sqlite3_vtab_cursor*, sqlite3_context*, int); + int (*xRowid)(sqlite3_vtab_cursor*, sqlite3_int64 *pRowid); + int (*xUpdate)(sqlite3_vtab *, int, sqlite3_value **, sqlite3_int64 *); + int (*xBegin)(sqlite3_vtab *pVTab); + int (*xSync)(sqlite3_vtab *pVTab); + int (*xCommit)(sqlite3_vtab *pVTab); + int (*xRollback)(sqlite3_vtab *pVTab); + int (*xFindFunction)(sqlite3_vtab *pVtab, int nArg, const char *zName, + void (**pxFunc)(sqlite3_context*,int,sqlite3_value**), + void **ppArg); + + int (*xRename)(sqlite3_vtab *pVtab, const char *zNew); +}; + +/* +** The sqlite3_index_info structure and its substructures is used to +** pass information into and receive the reply from the xBestIndex +** method of an sqlite3_module. The fields under **Inputs** are the +** inputs to xBestIndex and are read-only. xBestIndex inserts its +** results into the **Outputs** fields. +** +** The aConstraint[] array records WHERE clause constraints of the +** form: +** +** column OP expr +** +** Where OP is =, <, <=, >, or >=. The particular operator is stored +** in aConstraint[].op. The index of the column is stored in +** aConstraint[].iColumn. aConstraint[].usable is TRUE if the +** expr on the right-hand side can be evaluated (and thus the constraint +** is usable) and false if it cannot. +** +** The optimizer automatically inverts terms of the form "expr OP column" +** and makes other simplifications to the WHERE clause in an attempt to +** get as many WHERE clause terms into the form shown above as possible. +** The aConstraint[] array only reports WHERE clause terms in the correct +** form that refer to the particular virtual table being queried. +** +** Information about the ORDER BY clause is stored in aOrderBy[]. +** Each term of aOrderBy records a column of the ORDER BY clause. +** +** The xBestIndex method must fill aConstraintUsage[] with information +** about what parameters to pass to xFilter. If argvIndex>0 then +** the right-hand side of the corresponding aConstraint[] is evaluated +** and becomes the argvIndex-th entry in argv. If aConstraintUsage[].omit +** is true, then the constraint is assumed to be fully handled by the +** virtual table and is not checked again by SQLite. +** +** The idxNum and idxPtr values are recorded and passed into xFilter. +** sqlite3_free() is used to free idxPtr if needToFreeIdxPtr is true. +** +** The orderByConsumed means that output from xFilter will occur in +** the correct order to satisfy the ORDER BY clause so that no separate +** sorting step is required. +** +** The estimatedCost value is an estimate of the cost of doing the +** particular lookup. A full scan of a table with N entries should have +** a cost of N. A binary search of a table of N entries should have a +** cost of approximately log(N). +*/ +struct sqlite3_index_info { + /* Inputs */ + int nConstraint; /* Number of entries in aConstraint */ + struct sqlite3_index_constraint { + int iColumn; /* Column on left-hand side of constraint */ + unsigned char op; /* Constraint operator */ + unsigned char usable; /* True if this constraint is usable */ + int iTermOffset; /* Used internally - xBestIndex should ignore */ + } *aConstraint; /* Table of WHERE clause constraints */ + int nOrderBy; /* Number of terms in the ORDER BY clause */ + struct sqlite3_index_orderby { + int iColumn; /* Column number */ + unsigned char desc; /* True for DESC. False for ASC. */ + } *aOrderBy; /* The ORDER BY clause */ + + /* Outputs */ + struct sqlite3_index_constraint_usage { + int argvIndex; /* if >0, constraint is part of argv to xFilter */ + unsigned char omit; /* Do not code a test for this constraint */ + } *aConstraintUsage; + int idxNum; /* Number used to identify the index */ + char *idxStr; /* String, possibly obtained from sqlite3_malloc */ + int needToFreeIdxStr; /* Free idxStr using sqlite3_free() if true */ + int orderByConsumed; /* True if output is already ordered */ + double estimatedCost; /* Estimated cost of using this index */ +}; +#define SQLITE_INDEX_CONSTRAINT_EQ 2 +#define SQLITE_INDEX_CONSTRAINT_GT 4 +#define SQLITE_INDEX_CONSTRAINT_LE 8 +#define SQLITE_INDEX_CONSTRAINT_LT 16 +#define SQLITE_INDEX_CONSTRAINT_GE 32 +#define SQLITE_INDEX_CONSTRAINT_MATCH 64 + +/* +** This routine is used to register a new module name with an SQLite +** connection. Module names must be registered before creating new +** virtual tables on the module, or before using preexisting virtual +** tables of the module. +*/ +int sqlite3_create_module( + sqlite3 *db, /* SQLite connection to register module with */ + const char *zName, /* Name of the module */ + const sqlite3_module *, /* Methods for the module */ + void * /* Client data for xCreate/xConnect */ +); + +/* +** This routine is identical to the sqlite3_create_module() method above, +** except that it allows a destructor function to be specified. It is +** even more experimental than the rest of the virtual tables API. +*/ +int sqlite3_create_module_v2( + sqlite3 *db, /* SQLite connection to register module with */ + const char *zName, /* Name of the module */ + const sqlite3_module *, /* Methods for the module */ + void *, /* Client data for xCreate/xConnect */ + void(*xDestroy)(void*) /* Module destructor function */ +); + +/* +** Every module implementation uses a subclass of the following structure +** to describe a particular instance of the module. Each subclass will +** be tailored to the specific needs of the module implementation. The +** purpose of this superclass is to define certain fields that are common +** to all module implementations. +** +** Virtual tables methods can set an error message by assigning a +** string obtained from sqlite3_mprintf() to zErrMsg. The method should +** take care that any prior string is freed by a call to sqlite3_free() +** prior to assigning a new string to zErrMsg. After the error message +** is delivered up to the client application, the string will be automatically +** freed by sqlite3_free() and the zErrMsg field will be zeroed. Note +** that sqlite3_mprintf() and sqlite3_free() are used on the zErrMsg field +** since virtual tables are commonly implemented in loadable extensions which +** do not have access to sqlite3MPrintf() or sqlite3Free(). +*/ +struct sqlite3_vtab { + const sqlite3_module *pModule; /* The module for this virtual table */ + int nRef; /* Used internally */ + char *zErrMsg; /* Error message from sqlite3_mprintf() */ + /* Virtual table implementations will typically add additional fields */ +}; + +/* Every module implementation uses a subclass of the following structure +** to describe cursors that point into the virtual table and are used +** to loop through the virtual table. Cursors are created using the +** xOpen method of the module. Each module implementation will define +** the content of a cursor structure to suit its own needs. +** +** This superclass exists in order to define fields of the cursor that +** are common to all implementations. +*/ +struct sqlite3_vtab_cursor { + sqlite3_vtab *pVtab; /* Virtual table of this cursor */ + /* Virtual table implementations will typically add additional fields */ +}; + +/* +** The xCreate and xConnect methods of a module use the following API +** to declare the format (the names and datatypes of the columns) of +** the virtual tables they implement. +*/ +int sqlite3_declare_vtab(sqlite3*, const char *zCreateTable); + +/* +** Virtual tables can provide alternative implementations of functions +** using the xFindFunction method. But global versions of those functions +** must exist in order to be overloaded. +** +** This API makes sure a global version of a function with a particular +** name and number of parameters exists. If no such function exists +** before this API is called, a new function is created. The implementation +** of the new function always causes an exception to be thrown. So +** the new function is not good for anything by itself. Its only +** purpose is to be a place-holder function that can be overloaded +** by virtual tables. +** +** This API should be considered part of the virtual table interface, +** which is experimental and subject to change. +*/ +int sqlite3_overload_function(sqlite3*, const char *zFuncName, int nArg); + +/* +** The interface to the virtual-table mechanism defined above (back up +** to a comment remarkably similar to this one) is currently considered +** to be experimental. The interface might change in incompatible ways. +** If this is a problem for you, do not use the interface at this time. +** +** When the virtual-table mechanism stabilizes, we will declare the +** interface fixed, support it indefinitely, and remove this comment. +** +****** EXPERIMENTAL - subject to change without notice ************** +*/ + +/* +** CAPI3REF: A Handle To An Open BLOB +** +** An instance of the following opaque structure is used to +** represent an blob-handle. A blob-handle is created by +** [sqlite3_blob_open()] and destroyed by [sqlite3_blob_close()]. +** The [sqlite3_blob_read()] and [sqlite3_blob_write()] interfaces +** can be used to read or write small subsections of the blob. +** The [sqlite3_blob_bytes()] interface returns the size of the +** blob in bytes. +*/ +typedef struct sqlite3_blob sqlite3_blob; + +/* +** CAPI3REF: Open A BLOB For Incremental I/O +** +** Open a handle to the blob located in row iRow,, column zColumn, +** table zTable in database zDb. i.e. the same blob that would +** be selected by: +** +** <pre> +** SELECT zColumn FROM zDb.zTable WHERE rowid = iRow; +** </pre> +** +** If the flags parameter is non-zero, the blob is opened for +** read and write access. If it is zero, the blob is opened for read +** access. +** +** On success, [SQLITE_OK] is returned and the new +** [sqlite3_blob | blob handle] is written to *ppBlob. +** Otherwise an error code is returned and +** any value written to *ppBlob should not be used by the caller. +** This function sets the database-handle error code and message +** accessible via [sqlite3_errcode()] and [sqlite3_errmsg()]. +*/ +int sqlite3_blob_open( + sqlite3*, + const char *zDb, + const char *zTable, + const char *zColumn, + sqlite3_int64 iRow, + int flags, + sqlite3_blob **ppBlob +); + +/* +** CAPI3REF: Close A BLOB Handle +** +** Close an open [sqlite3_blob | blob handle]. +*/ +int sqlite3_blob_close(sqlite3_blob *); + +/* +** CAPI3REF: Return The Size Of An Open BLOB +** +** Return the size in bytes of the blob accessible via the open +** [sqlite3_blob | blob-handle] passed as an argument. +*/ +int sqlite3_blob_bytes(sqlite3_blob *); + +/* +** CAPI3REF: Read Data From A BLOB Incrementally +** +** This function is used to read data from an open +** [sqlite3_blob | blob-handle] into a caller supplied buffer. +** n bytes of data are copied into buffer +** z from the open blob, starting at offset iOffset. +** +** On success, SQLITE_OK is returned. Otherwise, an +** [SQLITE_ERROR | SQLite error code] or an +** [SQLITE_IOERR_READ | extended error code] is returned. +*/ +int sqlite3_blob_read(sqlite3_blob *, void *z, int n, int iOffset); + +/* +** CAPI3REF: Write Data Into A BLOB Incrementally +** +** This function is used to write data into an open +** [sqlite3_blob | blob-handle] from a user supplied buffer. +** n bytes of data are copied from the buffer +** pointed to by z into the open blob, starting at offset iOffset. +** +** If the [sqlite3_blob | blob-handle] passed as the first argument +** was not opened for writing (the flags parameter to [sqlite3_blob_open()] +*** was zero), this function returns [SQLITE_READONLY]. +** +** This function may only modify the contents of the blob, it is +** not possible to increase the size of a blob using this API. If +** offset iOffset is less than n bytes from the end of the blob, +** [SQLITE_ERROR] is returned and no data is written. +** +** On success, SQLITE_OK is returned. Otherwise, an +** [SQLITE_ERROR | SQLite error code] or an +** [SQLITE_IOERR_READ | extended error code] is returned. +*/ +int sqlite3_blob_write(sqlite3_blob *, const void *z, int n, int iOffset); + +/* +** CAPI3REF: Virtual File System Objects +** +** A virtual filesystem (VFS) is an [sqlite3_vfs] object +** that SQLite uses to interact +** with the underlying operating system. Most builds come with a +** single default VFS that is appropriate for the host computer. +** New VFSes can be registered and existing VFSes can be unregistered. +** The following interfaces are provided. +** +** The sqlite3_vfs_find() interface returns a pointer to a VFS given its +** name. Names are case sensitive. If there is no match, a NULL +** pointer is returned. If zVfsName is NULL then the default +** VFS is returned. +** +** New VFSes are registered with sqlite3_vfs_register(). Each +** new VFS becomes the default VFS if the makeDflt flag is set. +** The same VFS can be registered multiple times without injury. +** To make an existing VFS into the default VFS, register it again +** with the makeDflt flag set. If two different VFSes with the +** same name are registered, the behavior is undefined. If a +** VFS is registered with a name that is NULL or an empty string, +** then the behavior is undefined. +** +** Unregister a VFS with the sqlite3_vfs_unregister() interface. +** If the default VFS is unregistered, another VFS is chosen as +** the default. The choice for the new VFS is arbitrary. +*/ +sqlite3_vfs *sqlite3_vfs_find(const char *zVfsName); +int sqlite3_vfs_register(sqlite3_vfs*, int makeDflt); +int sqlite3_vfs_unregister(sqlite3_vfs*); + +/* +** CAPI3REF: Mutexes +** +** The SQLite core uses these routines for thread +** synchronization. Though they are intended for internal +** use by SQLite, code that links against SQLite is +** permitted to use any of these routines. +** +** The SQLite source code contains multiple implementations +** of these mutex routines. An appropriate implementation +** is selected automatically at compile-time. The following +** implementations are available in the SQLite core: +** +** <ul> +** <li> SQLITE_MUTEX_OS2 +** <li> SQLITE_MUTEX_PTHREAD +** <li> SQLITE_MUTEX_W32 +** <li> SQLITE_MUTEX_NOOP +** </ul> +** +** The SQLITE_MUTEX_NOOP implementation is a set of routines +** that does no real locking and is appropriate for use in +** a single-threaded application. The SQLITE_MUTEX_OS2, +** SQLITE_MUTEX_PTHREAD, and SQLITE_MUTEX_W32 implementations +** are appropriate for use on os/2, unix, and windows. +** +** If SQLite is compiled with the SQLITE_MUTEX_APPDEF preprocessor +** macro defined (with "-DSQLITE_MUTEX_APPDEF=1"), then no mutex +** implementation is included with the library. The +** mutex interface routines defined here become external +** references in the SQLite library for which implementations +** must be provided by the application. This facility allows an +** application that links against SQLite to provide its own mutex +** implementation without having to modify the SQLite core. +** +** The sqlite3_mutex_alloc() routine allocates a new +** mutex and returns a pointer to it. If it returns NULL +** that means that a mutex could not be allocated. SQLite +** will unwind its stack and return an error. The argument +** to sqlite3_mutex_alloc() is one of these integer constants: +** +** <ul> +** <li> SQLITE_MUTEX_FAST +** <li> SQLITE_MUTEX_RECURSIVE +** <li> SQLITE_MUTEX_STATIC_MASTER +** <li> SQLITE_MUTEX_STATIC_MEM +** <li> SQLITE_MUTEX_STATIC_MEM2 +** <li> SQLITE_MUTEX_STATIC_PRNG +** <li> SQLITE_MUTEX_STATIC_LRU +** </ul> +** +** The first two constants cause sqlite3_mutex_alloc() to create +** a new mutex. The new mutex is recursive when SQLITE_MUTEX_RECURSIVE +** is used but not necessarily so when SQLITE_MUTEX_FAST is used. +** The mutex implementation does not need to make a distinction +** between SQLITE_MUTEX_RECURSIVE and SQLITE_MUTEX_FAST if it does +** not want to. But SQLite will only request a recursive mutex in +** cases where it really needs one. If a faster non-recursive mutex +** implementation is available on the host platform, the mutex subsystem +** might return such a mutex in response to SQLITE_MUTEX_FAST. +** +** The other allowed parameters to sqlite3_mutex_alloc() each return +** a pointer to a static preexisting mutex. Four static mutexes are +** used by the current version of SQLite. Future versions of SQLite +** may add additional static mutexes. Static mutexes are for internal +** use by SQLite only. Applications that use SQLite mutexes should +** use only the dynamic mutexes returned by SQLITE_MUTEX_FAST or +** SQLITE_MUTEX_RECURSIVE. +** +** Note that if one of the dynamic mutex parameters (SQLITE_MUTEX_FAST +** or SQLITE_MUTEX_RECURSIVE) is used then sqlite3_mutex_alloc() +** returns a different mutex on every call. But for the static +** mutex types, the same mutex is returned on every call that has +** the same type number. +** +** The sqlite3_mutex_free() routine deallocates a previously +** allocated dynamic mutex. SQLite is careful to deallocate every +** dynamic mutex that it allocates. The dynamic mutexes must not be in +** use when they are deallocated. Attempting to deallocate a static +** mutex results in undefined behavior. SQLite never deallocates +** a static mutex. +** +** The sqlite3_mutex_enter() and sqlite3_mutex_try() routines attempt +** to enter a mutex. If another thread is already within the mutex, +** sqlite3_mutex_enter() will block and sqlite3_mutex_try() will return +** SQLITE_BUSY. The sqlite3_mutex_try() interface returns SQLITE_OK +** upon successful entry. Mutexes created using SQLITE_MUTEX_RECURSIVE can +** be entered multiple times by the same thread. In such cases the, +** mutex must be exited an equal number of times before another thread +** can enter. If the same thread tries to enter any other kind of mutex +** more than once, the behavior is undefined. SQLite will never exhibit +** such behavior in its own use of mutexes. +** +** Some systems (ex: windows95) do not the operation implemented by +** sqlite3_mutex_try(). On those systems, sqlite3_mutex_try() will +** always return SQLITE_BUSY. The SQLite core only ever uses +** sqlite3_mutex_try() as an optimization so this is acceptable behavior. +** +** The sqlite3_mutex_leave() routine exits a mutex that was +** previously entered by the same thread. The behavior +** is undefined if the mutex is not currently entered by the +** calling thread or is not currently allocated. SQLite will +** never do either. +** +** See also: [sqlite3_mutex_held()] and [sqlite3_mutex_notheld()]. +*/ +sqlite3_mutex *sqlite3_mutex_alloc(int); +void sqlite3_mutex_free(sqlite3_mutex*); +void sqlite3_mutex_enter(sqlite3_mutex*); +int sqlite3_mutex_try(sqlite3_mutex*); +void sqlite3_mutex_leave(sqlite3_mutex*); + +/* +** CAPI3REF: Mutex Verifcation Routines +** +** The sqlite3_mutex_held() and sqlite3_mutex_notheld() routines +** are intended for use inside assert() statements. The SQLite core +** never uses these routines except inside an assert() and applications +** are advised to follow the lead of the core. The core only +** provides implementations for these routines when it is compiled +** with the SQLITE_DEBUG flag. External mutex implementations +** are only required to provide these routines if SQLITE_DEBUG is +** defined and if NDEBUG is not defined. +** +** These routines should return true if the mutex in their argument +** is held or not held, respectively, by the calling thread. +** +** The implementation is not required to provided versions of these +** routines that actually work. +** If the implementation does not provide working +** versions of these routines, it should at least provide stubs +** that always return true so that one does not get spurious +** assertion failures. +** +** If the argument to sqlite3_mutex_held() is a NULL pointer then +** the routine should return 1. This seems counter-intuitive since +** clearly the mutex cannot be held if it does not exist. But the +** the reason the mutex does not exist is because the build is not +** using mutexes. And we do not want the assert() containing the +** call to sqlite3_mutex_held() to fail, so a non-zero return is +** the appropriate thing to do. The sqlite3_mutex_notheld() +** interface should also return 1 when given a NULL pointer. +*/ +int sqlite3_mutex_held(sqlite3_mutex*); +int sqlite3_mutex_notheld(sqlite3_mutex*); + +/* +** CAPI3REF: Mutex Types +** +** The [sqlite3_mutex_alloc()] interface takes a single argument +** which is one of these integer constants. +*/ +#define SQLITE_MUTEX_FAST 0 +#define SQLITE_MUTEX_RECURSIVE 1 +#define SQLITE_MUTEX_STATIC_MASTER 2 +#define SQLITE_MUTEX_STATIC_MEM 3 /* sqlite3_malloc() */ +#define SQLITE_MUTEX_STATIC_MEM2 4 /* sqlite3_release_memory() */ +#define SQLITE_MUTEX_STATIC_PRNG 5 /* sqlite3_random() */ +#define SQLITE_MUTEX_STATIC_LRU 6 /* lru page list */ + +/* +** CAPI3REF: Low-Level Control Of Database Files +** +** The [sqlite3_file_control()] interface makes a direct call to the +** xFileControl method for the [sqlite3_io_methods] object associated +** with a particular database identified by the second argument. The +** name of the database is the name assigned to the database by the +** <a href="lang_attach.html">ATTACH</a> SQL command that opened the +** database. To control the main database file, use the name "main" +** or a NULL pointer. The third and fourth parameters to this routine +** are passed directly through to the second and third parameters of +** the xFileControl method. The return value of the xFileControl +** method becomes the return value of this routine. +** +** If the second parameter (zDbName) does not match the name of any +** open database file, then SQLITE_ERROR is returned. This error +** code is not remembered and will not be recalled by [sqlite3_errcode()] +** or [sqlite3_errmsg()]. The underlying xFileControl method might +** also return SQLITE_ERROR. There is no way to distinguish between +** an incorrect zDbName and an SQLITE_ERROR return from the underlying +** xFileControl method. +** +** See also: [SQLITE_FCNTL_LOCKSTATE] +*/ +int sqlite3_file_control(sqlite3*, const char *zDbName, int op, void*); + +/* +** Undo the hack that converts floating point types to integer for +** builds on processors without floating point support. +*/ +#ifdef SQLITE_OMIT_FLOATING_POINT +# undef double +#endif + +#if 0 +} /* End of the 'extern "C"' block */ +#endif +#endif + +/************** End of sqlite3.h *********************************************/ +/************** Continuing where we left off in fts3_tokenizer.h *************/ + +/* +** Structures used by the tokenizer interface. When a new tokenizer +** implementation is registered, the caller provides a pointer to +** an sqlite3_tokenizer_module containing pointers to the callback +** functions that make up an implementation. +** +** When an fts3 table is created, it passes any arguments passed to +** the tokenizer clause of the CREATE VIRTUAL TABLE statement to the +** sqlite3_tokenizer_module.xCreate() function of the requested tokenizer +** implementation. The xCreate() function in turn returns an +** sqlite3_tokenizer structure representing the specific tokenizer to +** be used for the fts3 table (customized by the tokenizer clause arguments). +** +** To tokenize an input buffer, the sqlite3_tokenizer_module.xOpen() +** method is called. It returns an sqlite3_tokenizer_cursor object +** that may be used to tokenize a specific input buffer based on +** the tokenization rules supplied by a specific sqlite3_tokenizer +** object. +*/ +typedef struct sqlite3_tokenizer_module sqlite3_tokenizer_module; +typedef struct sqlite3_tokenizer sqlite3_tokenizer; +typedef struct sqlite3_tokenizer_cursor sqlite3_tokenizer_cursor; + +struct sqlite3_tokenizer_module { + + /* + ** Structure version. Should always be set to 0. + */ + int iVersion; + + /* + ** Create a new tokenizer. The values in the argv[] array are the + ** arguments passed to the "tokenizer" clause of the CREATE VIRTUAL + ** TABLE statement that created the fts3 table. For example, if + ** the following SQL is executed: + ** + ** CREATE .. USING fts3( ... , tokenizer <tokenizer-name> arg1 arg2) + ** + ** then argc is set to 2, and the argv[] array contains pointers + ** to the strings "arg1" and "arg2". + ** + ** This method should return either SQLITE_OK (0), or an SQLite error + ** code. If SQLITE_OK is returned, then *ppTokenizer should be set + ** to point at the newly created tokenizer structure. The generic + ** sqlite3_tokenizer.pModule variable should not be initialised by + ** this callback. The caller will do so. + */ + int (*xCreate)( + int argc, /* Size of argv array */ + const char *const*argv, /* Tokenizer argument strings */ + sqlite3_tokenizer **ppTokenizer /* OUT: Created tokenizer */ + ); + + /* + ** Destroy an existing tokenizer. The fts3 module calls this method + ** exactly once for each successful call to xCreate(). + */ + int (*xDestroy)(sqlite3_tokenizer *pTokenizer); + + /* + ** Create a tokenizer cursor to tokenize an input buffer. The caller + ** is responsible for ensuring that the input buffer remains valid + ** until the cursor is closed (using the xClose() method). + */ + int (*xOpen)( + sqlite3_tokenizer *pTokenizer, /* Tokenizer object */ + const char *pInput, int nBytes, /* Input buffer */ + sqlite3_tokenizer_cursor **ppCursor /* OUT: Created tokenizer cursor */ + ); + + /* + ** Destroy an existing tokenizer cursor. The fts3 module calls this + ** method exactly once for each successful call to xOpen(). + */ + int (*xClose)(sqlite3_tokenizer_cursor *pCursor); + + /* + ** Retrieve the next token from the tokenizer cursor pCursor. This + ** method should either return SQLITE_OK and set the values of the + ** "OUT" variables identified below, or SQLITE_DONE to indicate that + ** the end of the buffer has been reached, or an SQLite error code. + ** + ** *ppToken should be set to point at a buffer containing the + ** normalized version of the token (i.e. after any case-folding and/or + ** stemming has been performed). *pnBytes should be set to the length + ** of this buffer in bytes. The input text that generated the token is + ** identified by the byte offsets returned in *piStartOffset and + ** *piEndOffset. + ** + ** The buffer *ppToken is set to point at is managed by the tokenizer + ** implementation. It is only required to be valid until the next call + ** to xNext() or xClose(). + */ + /* TODO(shess) current implementation requires pInput to be + ** nul-terminated. This should either be fixed, or pInput/nBytes + ** should be converted to zInput. + */ + int (*xNext)( + sqlite3_tokenizer_cursor *pCursor, /* Tokenizer cursor */ + const char **ppToken, int *pnBytes, /* OUT: Normalized text for token */ + int *piStartOffset, /* OUT: Byte offset of token in input buffer */ + int *piEndOffset, /* OUT: Byte offset of end of token in input buffer */ + int *piPosition /* OUT: Number of tokens returned before this one */ + ); +}; + +struct sqlite3_tokenizer { + const sqlite3_tokenizer_module *pModule; /* The module for this tokenizer */ + /* Tokenizer implementations will typically add additional fields */ +}; + +struct sqlite3_tokenizer_cursor { + sqlite3_tokenizer *pTokenizer; /* Tokenizer for this cursor. */ + /* Tokenizer implementations will typically add additional fields */ +}; + +#endif /* _FTS3_TOKENIZER_H_ */ + +/************** End of fts3_tokenizer.h **************************************/ +/************** Continuing where we left off in fts3_icu.c *******************/ + +#include <unicode/ubrk.h> +#include <unicode/ucol.h> +#include <unicode/ustring.h> +#include <unicode/utf16.h> + +typedef struct IcuTokenizer IcuTokenizer; +typedef struct IcuCursor IcuCursor; + +struct IcuTokenizer { + sqlite3_tokenizer base; + char *zLocale; +}; + +struct IcuCursor { + sqlite3_tokenizer_cursor base; + + UBreakIterator *pIter; /* ICU break-iterator object */ + int nChar; /* Number of UChar elements in pInput */ + UChar *aChar; /* Copy of input using utf-16 encoding */ + int *aOffset; /* Offsets of each character in utf-8 input */ + + int nBuffer; + char *zBuffer; + + int iToken; +}; + +/* +** Create a new tokenizer instance. +*/ +static int icuCreate( + int argc, /* Number of entries in argv[] */ + const char * const *argv, /* Tokenizer creation arguments */ + sqlite3_tokenizer **ppTokenizer /* OUT: Created tokenizer */ +){ + IcuTokenizer *p; + int n = 0; + + if( argc>0 ){ + n = strlen(argv[0])+1; + } + p = (IcuTokenizer *)sqlite3_malloc(sizeof(IcuTokenizer)+n); + if( !p ){ + return SQLITE_NOMEM; + } + memset(p, 0, sizeof(IcuTokenizer)); + + if( n ){ + p->zLocale = (char *)&p[1]; + memcpy(p->zLocale, argv[0], n); + } + + *ppTokenizer = (sqlite3_tokenizer *)p; + + return SQLITE_OK; +} + +/* +** Destroy a tokenizer +*/ +static int icuDestroy(sqlite3_tokenizer *pTokenizer){ + IcuTokenizer *p = (IcuTokenizer *)pTokenizer; + sqlite3_free(p); + return SQLITE_OK; +} + +/* +** Prepare to begin tokenizing a particular string. The input +** string to be tokenized is pInput[0..nBytes-1]. A cursor +** used to incrementally tokenize this string is returned in +** *ppCursor. +*/ +static int icuOpen( + sqlite3_tokenizer *pTokenizer, /* The tokenizer */ + const char *zInput, /* Input string */ + int nInput, /* Length of zInput in bytes */ + sqlite3_tokenizer_cursor **ppCursor /* OUT: Tokenization cursor */ +){ + IcuTokenizer *p = (IcuTokenizer *)pTokenizer; + IcuCursor *pCsr; + + const int32_t opt = U_FOLD_CASE_DEFAULT; + UErrorCode status = U_ZERO_ERROR; + int nChar; + + UChar32 c; + int iInput = 0; + int iOut = 0; + + *ppCursor = 0; + + if( -1 == nInput ) nInput = strlen(nInput); + nChar = nInput+1; + pCsr = (IcuCursor *)sqlite3_malloc( + sizeof(IcuCursor) + /* IcuCursor */ + nChar * sizeof(UChar) + /* IcuCursor.aChar[] */ + (nChar+1) * sizeof(int) /* IcuCursor.aOffset[] */ + ); + if( !pCsr ){ + return SQLITE_NOMEM; + } + memset(pCsr, 0, sizeof(IcuCursor)); + pCsr->aChar = (UChar *)&pCsr[1]; + pCsr->aOffset = (int *)&pCsr->aChar[nChar]; + + pCsr->aOffset[iOut] = iInput; + U8_NEXT(zInput, iInput, nInput, c); + while( c>0 ){ + int isError = 0; + c = u_foldCase(c, opt); + U16_APPEND(pCsr->aChar, iOut, nChar, c, isError); + if( isError ){ + sqlite3_free(pCsr); + return SQLITE_ERROR; + } + pCsr->aOffset[iOut] = iInput; + + if( iInput<nInput ){ + U8_NEXT(zInput, iInput, nInput, c); + }else{ + c = 0; + } + } + + pCsr->pIter = ubrk_open(UBRK_WORD, p->zLocale, pCsr->aChar, iOut, &status); + if( !U_SUCCESS(status) ){ + sqlite3_free(pCsr); + return SQLITE_ERROR; + } + pCsr->nChar = iOut; + + ubrk_first(pCsr->pIter); + *ppCursor = (sqlite3_tokenizer_cursor *)pCsr; + return SQLITE_OK; +} + +/* +** Close a tokenization cursor previously opened by a call to icuOpen(). +*/ +static int icuClose(sqlite3_tokenizer_cursor *pCursor){ + IcuCursor *pCsr = (IcuCursor *)pCursor; + ubrk_close(pCsr->pIter); + sqlite3_free(pCsr->zBuffer); + sqlite3_free(pCsr); + return SQLITE_OK; +} + +/* +** Extract the next token from a tokenization cursor. +*/ +static int icuNext( + sqlite3_tokenizer_cursor *pCursor, /* Cursor returned by simpleOpen */ + const char **ppToken, /* OUT: *ppToken is the token text */ + int *pnBytes, /* OUT: Number of bytes in token */ + int *piStartOffset, /* OUT: Starting offset of token */ + int *piEndOffset, /* OUT: Ending offset of token */ + int *piPosition /* OUT: Position integer of token */ +){ + IcuCursor *pCsr = (IcuCursor *)pCursor; + + int iStart = 0; + int iEnd = 0; + int nByte = 0; + + while( iStart==iEnd ){ + UChar32 c; + + iStart = ubrk_current(pCsr->pIter); + iEnd = ubrk_next(pCsr->pIter); + if( iEnd==UBRK_DONE ){ + return SQLITE_DONE; + } + + while( iStart<iEnd ){ + int iWhite = iStart; + U8_NEXT(pCsr->aChar, iWhite, pCsr->nChar, c); + if( u_isspace(c) ){ + iStart = iWhite; + }else{ + break; + } + } + assert(iStart<=iEnd); + } + + do { + UErrorCode status = U_ZERO_ERROR; + if( nByte ){ + char *zNew = sqlite3_realloc(pCsr->zBuffer, nByte); + if( !zNew ){ + return SQLITE_NOMEM; + } + pCsr->zBuffer = zNew; + pCsr->nBuffer = nByte; + } + + u_strToUTF8( + pCsr->zBuffer, pCsr->nBuffer, &nByte, /* Output vars */ + &pCsr->aChar[iStart], iEnd-iStart, /* Input vars */ + &status /* Output success/failure */ + ); + } while( nByte>pCsr->nBuffer ); + + *ppToken = pCsr->zBuffer; + *pnBytes = nByte; + *piStartOffset = pCsr->aOffset[iStart]; + *piEndOffset = pCsr->aOffset[iEnd]; + *piPosition = pCsr->iToken++; + + return SQLITE_OK; +} + +/* +** The set of routines that implement the simple tokenizer +*/ +static const sqlite3_tokenizer_module icuTokenizerModule = { + 0, /* iVersion */ + icuCreate, /* xCreate */ + icuDestroy, /* xCreate */ + icuOpen, /* xOpen */ + icuClose, /* xClose */ + icuNext, /* xNext */ +}; + +/* +** Set *ppModule to point at the implementation of the ICU tokenizer. +*/ +void sqlite3Fts3IcuTokenizerModule( + sqlite3_tokenizer_module const**ppModule +){ + *ppModule = &icuTokenizerModule; +} + +#endif /* defined(SQLITE_ENABLE_ICU) */ +#endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) */ + +/************** End of fts3_icu.c ********************************************/
Modified src/style.c from [4e8cafc457] to [773050316b].
@@ -1,7 +1,7 @@ /* -** Copyright (c) 2006 D. Richard Hipp +** Copyright (c) 2006,2007 D. Richard Hipp ** ** This program is free software; you can redistribute it and/or ** modify it under the terms of the GNU General Public ** License version 2 as published by the Free Software Foundation. ** @@ -46,112 +46,293 @@ ** Add a new element to the submenu */ void style_submenu_element( const char *zLabel, const char *zTitle, - const char *zLink + const char *zLink, + ... ){ + va_list ap; assert( nSubmenu < sizeof(aSubmenu)/sizeof(aSubmenu[0]) ); aSubmenu[nSubmenu].zLabel = zLabel; aSubmenu[nSubmenu].zTitle = zTitle; - aSubmenu[nSubmenu].zLink = zLink; + va_start(ap, zLink); + aSubmenu[nSubmenu].zLink = vmprintf(zLink, ap); + va_end(ap); nSubmenu++; } /* ** Compare two submenu items for sorting purposes */ static int submenuCompare(const void *a, const void *b){ const struct Submenu *A = (const struct Submenu*)a; - const struct Submenu *B = (const struct Submenu*)B; + const struct Submenu *B = (const struct Submenu*)b; return strcmp(A->zLabel, B->zLabel); } + +/* +** The Subscript interpreter used to render header and footer. +*/ +static struct Subscript *pInterp; /* ** Draw the header. */ void style_header(const char *zTitle){ - const char *zLogInOut = "Logout"; + const char *zLogInOut = "Login"; + const char *zHeader = db_get("header", (char*)zDefaultHeader); login_check_credentials(); - @ <html> - @ <body bgcolor="white"> - @ <hr size="1"> - @ <table border="0" cellpadding="0" cellspacing="0" width="100%%"> - @ <tr><td valign="top" align="left"> - @ <big><big><b>%s(zTitle)</b></big></big><br> - if( g.zLogin==0 ){ - @ <small>not logged in</small> - zLogInOut = "Login"; - }else{ - @ <small>logged in as %h(g.zLogin)</small> + + if( pInterp ) return; + + /* Generate the header up through the main menu */ + pInterp = SbS_Create(); + SbS_Store(pInterp, "project_name", + db_get("project-name","Unnamed Fossil Project"), 0); + SbS_Store(pInterp, "title", zTitle, 0); + SbS_Store(pInterp, "baseurl", g.zBaseURL, 0); + SbS_Store(pInterp, "manifest_version", MANIFEST_VERSION, 0); + SbS_Store(pInterp, "manifest_date", MANIFEST_DATE, 0); + if( g.zLogin ){ + SbS_Store(pInterp, "login", g.zLogin, 0); + zLogInOut = "Logout"; } - @ </td><td valign="top" align="right"> - @ <a href="%s(g.zBaseURL)/index">Home</a> + SbS_Render(pInterp, zHeader); + + /* Generate the main menu and the submenu (if any) */ + @ <div class="mainmenu"> + @ <a href="%s(g.zBaseURL)/home">Home</a> if( g.okRead ){ - @ | <a href="%s(g.zBaseURL)/leaves">Leaves</a> - @ | <a href="%s(g.zBaseURL)/timeline">Timeline</a> + @ <a href="%s(g.zBaseURL)/leaves">Leaves</a> + @ <a href="%s(g.zBaseURL)/timeline">Timeline</a> } if( g.okRdWiki ){ - @ | <a href="%s(g.zBaseURL)/wiki">Wiki</a> + @ <a href="%s(g.zBaseURL)/wiki">Wiki</a> } #if 0 - @ | <font color="#888888">Search</font> - @ | <font color="#888888">Ticket</font> - @ | <font color="#888888">Reports</font> + @ <font color="#888888">Search</font> + @ <font color="#888888">Ticket</font> + @ <font color="#888888">Reports</font> #endif if( g.okSetup ){ - @ | <a href="%s(g.zBaseURL)/setup">Setup</a> + @ <a href="%s(g.zBaseURL)/setup">Setup</a> } if( !g.noPswd ){ - @ | <a href="%s(g.zBaseURL)/login">%s(zLogInOut)</a> + @ <a href="%s(g.zBaseURL)/login">%s(zLogInOut)</a> } + @ </div> if( nSubmenu>0 ){ int i; - @ <br> + @ <div class="submenu"> qsort(aSubmenu, nSubmenu, sizeof(aSubmenu[0]), submenuCompare); for(i=0; i<nSubmenu; i++){ struct Submenu *p = &aSubmenu[i]; - char *zTail = i<nSubmenu-1 ? " | " : ""; if( p->zLink==0 ){ - @ <font color="#888888">%h(p->zLabel)</font> %s(zTail) + @ <span class="label">%h(p->zLabel)</span> }else{ - @ <a href="%T(p->zLink)">%h(p->zLabel)</a> %s(zTail) + @ <a class="label" href="%s(p->zLink)">%h(p->zLabel)</a> } } + @ </div> } - @ </td></tr></table> - @ <hr size="1"> + @ <div class="content"> g.cgiPanic = 1; } /* ** Draw the footer at the bottom of the page. */ void style_footer(void){ + const char *zFooter; + + if( pInterp==0 ) return; + zFooter = db_get("footer", (char*)zDefaultFooter); + @ </div> + SbS_Render(pInterp, zFooter); + SbS_Destroy(pInterp); + pInterp = 0; } +/* @-comment: // */ +/* +** The default page header. +*/ +const char zDefaultHeader[] = +@ <html> +@ <head> +@ <title>[project_name html]: [title html]</title> +@ <link rel="alternate" type="application/rss+xml" title="RSS Feed" +@ href="[baseurl puts]/timeline.rss"> +@ <link rel="stylesheet" href="[baseurl puts]/style.css" type="text/css" +@ media="screen"> +@ </head> +@ <body> +@ <div class="header"> +@ <div class="logo"> +@ <!-- <img src="logo.gif" alt="logo"><br></br> --> +@ <nobr>[project_name html]</nobr> +@ </div> +@ <div class="title">[title html]</div> +@ <div class="status"><nobr> +@ [/login exists enable_output] Logged in as [0 /login get html] +@ [/login exists not enable_output] Not logged in +@ [1 enable_output] +@ </nobr></div> +@ </div> +; + +/* +** The default page footer +*/ +const char zDefaultFooter[] = +@ <div class="footer"> +@ Fossil version [manifest_version puts] [manifest_date puts] +@ </div> +@ </body></html> +; + +/* +** The default Cascading Style Sheet. +*/ +const char zDefaultCSS[] = +@ /* General settings for the entire page */ +@ body { +@ margin: 0ex 1ex; +@ padding: 0px; +@ background-color: white; +@ font-family: "sans serif"; +@ } +@ +@ /* The project logo in the upper left-hand corner of each page */ +@ div.logo { +@ display: table-cell; +@ text-align: center; +@ vertical-align: bottom; +@ font-weight: bold; +@ color: #558195; +@ } +@ +@ /* The page title centered at the top of each page */ +@ div.title { +@ display: table-cell; +@ font-size: 2em; +@ font-weight: bold; +@ text-align: center; +@ color: #558195; +@ vertical-align: bottom; +@ width: 100%; +@ } +@ +@ /* The login status message in the top right-hand corner */ +@ div.status { +@ display: table-cell; +@ text-align: right; +@ vertical-align: bottom; +@ color: #558195; +@ font-size: 0.8em; +@ font-weight: bold; +@ } +@ +@ /* The header across the top of the page */ +@ div.header { +@ display: table; +@ width: 100%; +@ } +@ +@ /* The main menu bar that appears at the top of the page beneath +@ ** the header */ +@ div.mainmenu { +@ padding: 5px 10px 5px 10px; +@ font-size: 0.9em; +@ font-weight: bold; +@ text-align: center; +@ letter-spacing: 1px; +@ background-color: #558195; +@ color: white; +@ } +@ +@ /* The submenu bar that *sometimes* appears below the main menu */ +@ div.submenu { +@ padding: 3px 10px 3px 0px; +@ font-size: 0.9em; +@ text-align: center; +@ background-color: #456878; +@ color: white; +@ } +@ div.mainmenu a, div.mainmenu a:visited, div.submenu a, div.submenu a:visited { +@ padding: 3px 10px 3px 10px; +@ color: white; +@ text-decoration: none; +@ } +@ div.mainmenu a:hover, div.submenu a:hover { +@ color: #558195; +@ background-color: white; +@ } +@ +@ /* All page content from the bottom of the menu or submenu down to +@ ** the footer */ +@ div.content { +@ padding: 0ex 1ex 0ex 2ex; +@ } +@ +@ /* Some pages have section dividers */ +@ div.section { +@ margin-bottom: 0px; +@ margin-top: 1em; +@ padding: 1px 1px 1px 1px; +@ font-size: 1.2em; +@ font-weight: bold; +@ background-color: #558195; +@ color: white; +@ } +@ +@ /* The "Date" that occurs on the left hand side of timelines */ +@ div.divider { +@ background: #a1c4d4; +@ border: 2px #558195 solid; +@ font-size: 1em; font-weight: normal; +@ padding: .25em; +@ margin: .2em 0 .2em 0; +@ float: left; +@ clear: left; +@ } +@ +@ /* The footer at the very bottom of the page */ +@ div.footer { +@ font-size: 0.8em; +@ margin-top: 12px; +@ padding: 5px 10px 5px 10px; +@ text-align: right; +@ background-color: #558195; +@ color: white; +@ } +@ +@ /* The label/value pairs on (for example) the vinfo page */ +@ table.label-value th { +@ vertical-align: top; +@ text-align: right; +@ padding: 0.2ex 2ex; +@ } +; + /* -** WEBPAGE: index -** WEBPAGE: home -** WEBPAGE: not_found +** WEBPAGE: style.css */ -void page_index(void){ - char *zHome = db_get("homepage", 0); - if( zHome ){ - g.zExtra = zHome; - g.okRdWiki = 1; - wiki_page(); - }else{ - style_header("Main Title Page"); - @ No homepage configured for this server - style_footer(); - } +void page_style_css(void){ + char *zCSS = 0; + + cgi_set_content_type("text/css"); + zCSS = db_get("css",(char*)zDefaultCSS); + cgi_append_content(zCSS, -1); } /* ** WEBPAGE: test_env */ void page_test_env(void){ style_header("Environment Test"); + @ g.zBaseURL = %h(g.zBaseURL)<br> + @ g.zTop = %h(g.zTop)<br> cgi_print_all(); style_footer(); }
Added src/subscript.c version [b76caa035f]
@@ -1,1 +1,1165 @@ +/* +** Copyright (c) 2007 D. Richard Hipp +** +** This program is free software; you can redistribute it and/or +** modify it under the terms of the GNU General Public +** License version 2 as published by the Free Software Foundation. +** +** This program is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +** General Public License for more details. +** +** You should have received a copy of the GNU General Public +** License along with this library; if not, write to the +** Free Software Foundation, Inc., 59 Temple Place - Suite 330, +** Boston, MA 02111-1307, USA. +** +** Author contact information: +** drh@hwaci.com +** http://www.hwaci.com/drh/ +** +******************************************************************************* +** +** This file contains an implementation of the "subscript" interpreter. +** +** Subscript attempts to be an extremely light-weight scripting +** language. It contains the barest of bare essentials. It is +** stack-based and forth-like. Everything is in a single global +** namespace. There is only a single datatype of zero-terminated +** string. The stack is of fixed, limited depth. The symbal table +** is of a limited and fixed size. +** +** TOKENS: +** +** * All tokens are separated from each other by whitespace. +** * Leading and trailing whitespace is ignored. +** * Text within nested {...} is a single string token. The outermost +** curly braces are not part of the token. +** * An identifier with a leading "/" is a string token. +** * A token that looks like a number is a string token. +** * An identifier token is called a "verb". +** +** PROCESSING: +** +** * The input is divided into tokens. Whitespace is discarded. +** String and verb tokens are passed into the engine. +** * String tokens are pushed onto the stack. +** * If a verb token corresponds to a procedure, that procedure is +** run. The procedure might use, pop, or pull elements from +** the stack. +** * If a verb token corresponds to a variable, the value of that +** variable is pushed onto the stack. +** +** This module attempts to be completely self-contained so that it can +** be portable to other projects. +*/ +#include "config.h" +#include "subscript.h" +#include <assert.h> + +#if INTERFACE +typedef struct Subscript Subscript; +#define SBS_OK 0 +#define SBS_ERROR 1 +#define SBS_RETURN 2 +#define SBS_BREAK 3 +#endif + +/* +** Configuration constants +*/ +#define SBSCONFIG_NHASH 41 /* Size of the hash table */ +#define SBSCONFIG_NSTACK 20 /* Maximum stack depth */ +#define SBSCONFIG_ERRSIZE 100 /* Maximum size of an error message */ + +/* +** Available token types: +*/ +#define SBSTT_WHITESPACE 1 /* ex: \040 */ +#define SBSTT_NAME 2 /* ex: /abcde */ +#define SBSTT_VERB 3 /* ex: abcde */ +#define SBSTT_STRING 4 /* ex: {...} */ +#define SBSTT_QUOTED 5 /* ex: "...\n..." */ +#define SBSTT_INTEGER 6 /* Integer including option sign */ +#define SBSTT_INCOMPLETE 7 /* Unterminated string token */ +#define SBSTT_UNKNOWN 8 /* Unknown token */ +#define SBSTT_EOF 9 /* End of input */ + +/* +** Values are stored in the hash table as instances of the following +** structure. +*/ +typedef struct SbSValue SbSValue; +struct SbSValue { + int flags; /* Bitmask of SBSVAL_* values */ + union { + struct { + int size; /* Number of bytes in string, not counting final zero */ + char *z; /* Pointer to string content */ + } str; /* Value if SBSVAL_STR */ + struct { + int (*xVerb)(Subscript*, void*); /* Function to do the work */ + void *pArg; /* 2nd parameter to xVerb */ + } verb; /* Value if SBSVAL_VERB */ + } u; +}; +#define SBSVAL_VERB 0x0001 /* Value stored in u.verb */ +#define SBSVAL_STR 0x0002 /* Value stored in u.str */ +#define SBSVAL_DYN 0x0004 /* u.str.z is dynamically allocated */ +#define SBSVAL_EXEC 0x0008 /* u.str.z is a script */ + +/* +** An entry in the hash table is an instance of this structure. +*/ +typedef struct SbsHashEntry SbsHashEntry; +struct SbsHashEntry { + SbsHashEntry *pNext; /* Next entry with the same hash on zKey */ + SbSValue val; /* The payload */ + int nKey; /* Length of the key */ + char zKey[1]; /* The key */ +}; + +/* +** A hash table is an instance of the following structure. +*/ +typedef struct SbsHashTab SbsHashTab; +struct SbsHashTab { + SbsHashEntry *aHash[SBSCONFIG_NHASH]; /* The hash table */ +}; + +/* +** An instance of the Subscript interpreter +*/ +struct Subscript { + int nStack; /* Number of entries on stack */ + SbsHashTab symTab; /* The symbol table */ + char zErrMsg[SBSCONFIG_ERRSIZE]; /* Space to write an error message */ + SbSValue aStack[SBSCONFIG_NSTACK]; /* The stack */ +}; + + +/* +** Given an input string z of length n, identify the token that +** starts at z[0]. Write the token type into *pTokenType and +** return the length of the token. +*/ +static int sbs_next_token(const char *z, int n, int *pTokenType){ + int c; + if( n<=0 || z[0]==0 ){ + *pTokenType = SBSTT_EOF; + return 0; + } + c = z[0]; + if( isspace(c) ){ + int i; + *pTokenType = SBSTT_WHITESPACE; + for(i=1; i<n && isspace(z[i]); i++){} + return i; + } + if( c=='#' ){ + int i; + for(i=1; i<n && z[i] && z[i-1]!='\n'; i++){} + *pTokenType = SBSTT_WHITESPACE; + return i; + } + if( c=='"' ){ + int i; + for(i=1; i<n && z[i] && z[i]!='"'; i++){ + if( z[i]=='\\' && i<n-1 ){ i++; } + } + if( z[i]=='"' ){ + *pTokenType = SBSTT_QUOTED; + return i+1; + }else{ + *pTokenType = SBSTT_INCOMPLETE; + return i; + } + } + if( c=='{' ){ + int depth = 1; + int i; + for(i=1; i<n && z[i]; i++){ + if( z[i]=='{' ){ + depth++; + }else if( z[i]=='}' ){ + depth--; + if( depth==0 ){ + i++; + break; + } + } + } + if( depth ){ + *pTokenType = SBSTT_INCOMPLETE; + }else{ + *pTokenType = SBSTT_STRING; + } + return i; + } + if( c=='/' && n>=2 && isalpha(z[1]) ){ + int i; + for(i=2; i<n && (isalnum(z[i]) || z[i]=='_'); i++){} + *pTokenType = SBSTT_NAME; + return i; + } + if( isalpha(c) ){ + int i; + for(i=1; i<n && (isalnum(z[i]) || z[i]=='_'); i++){} + *pTokenType = SBSTT_VERB; + return i; + } + if( isdigit(c) || ((c=='-' || c=='+') && n>=2 && isdigit(z[1])) ){ + int i; + for(i=1; i<n && isdigit(z[i]); i++){} + *pTokenType = SBSTT_INTEGER; + return i; + } + *pTokenType = SBSTT_UNKNOWN; + return 1; +} + + +/* +** Release any memory allocated by a value. +*/ +static void sbs_value_reset(SbSValue *p){ + if( p->flags & SBSVAL_DYN ){ + free(p->u.str.z); + p->flags = SBSVAL_STR; + p->u.str.z = ""; + p->u.str.size = 0; + } +} + +/* +** Compute a hash on a string. +*/ +static int sbs_hash(const char *z, int n){ + int h = 0; + int i; + for(i=0; i<n; i++){ + h ^= (h<<1) | z[i]; + } + h &= 0x7ffffff; + return h % SBSCONFIG_NHASH; +} + +/* +** Look up a value in the hash table. Return a pointer to the value. +** Return NULL if not found. +*/ +static const SbSValue *sbs_fetch( + SbsHashTab *pHash, + const char *zKey, + int nKey +){ + int h; + SbsHashEntry *p; + + if( nKey<0 ) nKey = strlen(zKey); + h = sbs_hash(zKey, nKey); + for(p = pHash->aHash[h]; p; p=p->pNext){ + if( p->nKey==nKey && memcmp(p->zKey,zKey,nKey)==0 ){ + return &p->val; + } + } + return 0; +} + +/* +** Store a value in the hash table. Overwrite any prior value stored +** under the same name. +** +** If the value in the 4th argument needs to be reset or freed, +** the hash table will take over responsibiliity for doing so. +*/ +static int sbs_store( + SbsHashTab *pHash, /* Insert into this hash table */ + const char *zKey, /* The key */ + int nKey, /* Size of the key */ + const SbSValue *pValue /* The value to be stored */ +){ + int h; + SbsHashEntry *p, *pNew; + + if( nKey<0 ) nKey = strlen(zKey); + h = sbs_hash(zKey, nKey); + for(p = pHash->aHash[h]; p; p=p->pNext){ + if( p->nKey==nKey && memcmp(p->zKey,zKey,nKey)==0 ){ + sbs_value_reset(&p->val); + memcpy(&p->val, pValue, sizeof(p->val)); + return SBS_OK; + } + } + pNew = malloc( sizeof(*pNew) + nKey ); + if( pNew ){ + pNew->nKey = nKey; + memcpy(pNew->zKey, zKey, nKey+1); + memcpy(&pNew->val, pValue, sizeof(pNew->val)); + pNew->pNext = pHash->aHash[h]; + pHash->aHash[h] = pNew; + return SBS_OK; + } + return SBS_ERROR; +} + +/* +** Reset a hash table. +*/ +static void sbs_hash_reset(SbsHashTab *pHash){ + int i; + SbsHashEntry *p, *pNext; + for(i=0; i<SBSCONFIG_NHASH; i++){ + for(p=pHash->aHash[i]; p; p=pNext){ + pNext = p->pNext; + sbs_value_reset(&p->val); + free(p); + } + } + memset(pHash, 0, sizeof(*pHash)); +} + +/* +** Push a value onto the stack of an interpreter +*/ +static int sbs_push(Subscript *p, SbSValue *pVal){ + if( p->nStack>=SBSCONFIG_NSTACK ){ + sqlite3_snprintf(SBSCONFIG_ERRSIZE, p->zErrMsg, "stack overflow"); + return SBS_ERROR; + } + p->aStack[p->nStack++] = *pVal; + return SBS_OK; +} + +/* +** Create a new subscript interpreter. Return a pointer to the +** new interpreter, or return NULL if malloc fails. +*/ +struct Subscript *SbS_Create(void){ + Subscript *p; + p = malloc( sizeof(*p) ); + if( p ){ + memset(p, 0, sizeof(*p)); + } + return p; +} + +/* +** Destroy an subscript interpreter +*/ +void SbS_Destroy(struct Subscript *p){ + int i; + sbs_hash_reset(&p->symTab); + for(i=0; i<p->nStack; i++){ + sbs_value_reset(&p->aStack[i]); + } + free(p); +} + +/* +** Set the error message for an interpreter. Verb implementations +** use this routine when they encounter an error. +*/ +void SbS_SetErrorMessage(struct Subscript *p, const char *zErr, ...){ + int nErr; + char *zMsg; + va_list ap; + + va_start(ap, zErr); + zMsg = vmprintf(zErr, ap); + va_end(ap); + nErr = strlen(zMsg); + if( nErr>sizeof(p->zErrMsg)-1 ){ + nErr = sizeof(p->zErrMsg)-1; + } + memcpy(p->zErrMsg, zMsg, nErr); + p->zErrMsg[nErr] = 0; + free(zMsg); +} + +/* +** Return a pointer to the current error message for the +** interpreter. +*/ +const char *SbS_GetErrorMessage(struct Subscript *p){ + return p->zErrMsg; +} + +/* +** Add a new verb the given interpreter +*/ +int SbS_AddVerb( + struct Subscript *p, + const char *zVerb, + int (*xVerb)(struct Subscript*,void*), + void *pArg +){ + SbSValue v; + v.flags = SBSVAL_VERB; + v.u.verb.xVerb = xVerb; + v.u.verb.pArg = pArg; + return sbs_store(&p->symTab, zVerb, -1, &v); +} + +/* +** Store a value in an interpreter variable. +*/ +int SbS_Store( + struct Subscript *p, /* Store into this interpreter */ + const char *zName, /* Name of the variable */ + const char *zValue, /* Value of the variable */ + int persistence /* 0: static. 1: ephemeral. 2: dynamic */ +){ + SbSValue v; + v.flags = SBSVAL_STR; + v.u.str.size = strlen(zValue); + if( persistence==1 ){ + v.u.str.z = mprintf("%s", zValue); + }else{ + v.u.str.z = (char*)zValue; + } + if( persistence>0 ){ + v.flags |= SBSVAL_DYN; + } + return sbs_store(&p->symTab, zName, -1, &v); +} + +/* +** Push a string value onto the stack. +** +** If the 4th parameter is 0, then the string is static. +** If the 4th parameter is non-zero then the string was obtained +** from malloc and Subscript will take responsibility for freeing +** it. +** +** Return 0 on success and non-zero if there is an error. +*/ +int SbS_Push( + struct Subscript *p, /* Push onto this interpreter */ + char *z, /* String value to push */ + int n, /* Length of the string, or -1 */ + int dyn /* If true, z was obtained from malloc */ +){ + SbSValue v; + v.flags = SBSVAL_STR; + if( dyn ){ + v.flags |= SBSVAL_DYN; + } + if( n<0 ) n = strlen(z); + v.u.str.size = n; + v.u.str.z = z; + return sbs_push(p, &v); +} + +/* +** Push an integer value onto the stack. +** +** This routine really just converts the integer into a string +** then calls SbS_Push. +*/ +int SbS_PushInt(struct Subscript *p, int iVal){ + if( iVal==0 ){ + return SbS_Push(p, "0", 1, 0); + }else if( iVal==1 ){ + return SbS_Push(p, "1", 1, 0); + }else{ + char *z; + int n; + char zVal[50]; + sprintf(zVal, "%d", iVal); + n = strlen(zVal); + z = malloc( n+1 ); + if( z ){ + strcpy(z, zVal); + return SbS_Push(p, z, n, 1); + }else{ + return SBS_ERROR; + } + } +} + +/* +** Pop and destroy zero or more values from the stack. +** Return the number of values remaining on the stack after +** the pops occur. +*/ +int SbS_Pop(struct Subscript *p, int N){ + while( N>0 && p->nStack>0 ){ + p->nStack--; + sbs_value_reset(&p->aStack[p->nStack]); + N--; + } + return p->nStack; +} + +/* +** Return the N-th element of the stack. 0 is the top of the stack. +** 1 is the first element down. 2 is the second element. And so forth. +** Return NULL if there is no N-th element. +** +** The pointer returned is only valid until the value is popped +** from the stack. +*/ +const char *SbS_StackValue(struct Subscript *p, int N, int *pSize){ + SbSValue *pVal; + if( N<0 || N>=p->nStack ){ + return 0; + } + pVal = &p->aStack[p->nStack-N-1]; + if( (pVal->flags & SBSVAL_STR)==0 ){ + return 0; + } + *pSize = pVal->u.str.size; + return pVal->u.str.z; +} + +/* +** A convenience routine for extracting an integer value from the +** stack. +*/ +int SbS_StackValueInt(struct Subscript *p, int N){ + int n, v; + int isNeg = 0; + const char *z = SbS_StackValue(p, N, &n); + v = 0; + if( n==0 ) return 0; + if( z[0]=='-' ){ + isNeg = 1; + z++; + n--; + }else if( z[0]=='+' ){ + z++; + n--; + } + while( n>0 && isdigit(z[0]) ){ + v = v*10 + z[0] - '0'; + z++; + n--; + } + if( isNeg ){ + v = -v; + } + return v; +} + +/* +** Retrieve the value of a variable from the interpreter. Return +** NULL if no such variable is defined. +** +** The returned string is not necessarily (probably not) zero-terminated. +** The string may be deallocated the next time anything is done to +** the interpreter. Make a copy if you need it to persist. +*/ +const char *SbS_Fetch( + struct Subscript *p, /* The interpreter we are interrogating */ + const char *zKey, /* Name of the variable. Case sensitive */ + int nKey, /* Length of the key */ + int *pLength /* Write the length here */ +){ + const SbSValue *pVal; + + pVal = sbs_fetch(&p->symTab, zKey, nKey); + if( pVal==0 || (pVal->flags & SBSVAL_STR)==0 ){ + *pLength = 0; + return 0; + }else{ + *pLength = pVal->u.str.size; + return pVal->u.str.z; + } +} + +/* +** Generate an error and return non-zero if the stack has +** fewer than N elements. This is utility routine used in +** the implementation of verbs. +*/ +int SbS_RequireStack(struct Subscript *p, int N, const char *zCmd){ + if( p->nStack>=N ) return 0; + sqlite3_snprintf(sizeof(p->zErrMsg), p->zErrMsg, + "\"%s\" requires at least %d stack elements - only found %d", + zCmd, N, p->nStack); + return 1; +} + +/* +** Subscript command: STRING NAME set +** +** Write the value of STRING into variable called NAME. +*/ +static int setCmd(Subscript *p, void *pNotUsed){ + SbSValue *pTos; + SbSValue *pNos; + if( SbS_RequireStack(p, 2, "set") ) return SBS_ERROR; + pTos = &p->aStack[--p->nStack]; + pNos = &p->aStack[--p->nStack]; + sbs_store(&p->symTab, pTos->u.str.z, pTos->u.str.size, pNos); + sbs_value_reset(pTos); + return 0; +} + +/* +** Subscript command: INTEGER not INTEGER +*/ +static int notCmd(struct Subscript *p, void *pNotUsed){ + int n; + if( SbS_RequireStack(p, 1, "not") ) return 1; + n = SbS_StackValueInt(p, 0); + SbS_Pop(p, 1); + SbS_PushInt(p, !n); + return 0; +} + +#define SBSOP_ADD 1 +#define SBSOP_SUB 2 +#define SBSOP_MUL 3 +#define SBSOP_DIV 4 +#define SBSOP_AND 5 +#define SBSOP_OR 6 +#define SBSOP_MIN 7 +#define SBSOP_MAX 8 +#define SBSOP_EQ 9 +#define SBSOP_NE 10 +#define SBSOP_LT 11 +#define SBSOP_GT 12 +#define SBSOP_LE 13 +#define SBSOP_GE 14 + +/* +** Subscript command: INTEGER INTEGER <binary-op> INTEGER +*/ +static int bopCmd(struct Subscript *p, void *pOp){ + int a, b, c; + if( SbS_RequireStack(p, 2, "BINARY-OP") ) return 1; + a = SbS_StackValueInt(p, 1); + b = SbS_StackValueInt(p, 0); + switch( (int)pOp ){ + case SBSOP_EQ: c = a==b; break; + case SBSOP_NE: c = a!=b; break; + case SBSOP_LT: c = a<b; break; + case SBSOP_LE: c = a<=b; break; + case SBSOP_GT: c = a>b; break; + case SBSOP_GE: c = a>=b; break; + case SBSOP_ADD: c = a+b; break; + case SBSOP_SUB: c = a-b; break; + case SBSOP_MUL: c = a*b; break; + case SBSOP_DIV: c = b!=0 ? a/b : 0; break; + case SBSOP_AND: c = a && b; break; + case SBSOP_OR: c = a || b; break; + case SBSOP_MIN: c = a<b ? a : b; break; + case SBSOP_MAX: c = a<b ? b : a; break; + } + SbS_Pop(p, 2); + SbS_PushInt(p, c); + return 0; +} + +/* +** Subscript command: STRING STRING streq INTEGER +*/ +static int streqCmd(struct Subscript *p, void *pOp){ + int c, nA, nB; + const char *A, *B; + + if( SbS_RequireStack(p, 2, "BINARY-OP") ) return 1; + A = SbS_StackValue(p, 1, &nA); + B = SbS_StackValue(p, 0, &nB); + c = nA==nB && memcmp(A,B,nA)==0; + SbS_Pop(p, 2); + SbS_PushInt(p, c); + return 0; +} + +/* +** Subscript command: STRING hascap INTEGER +** +** Return true if the user has all of the capabilities listed. +*/ +static int hascapCmd(struct Subscript *p, void *pNotUsed){ + const char *z; + int n, a; + if( SbS_RequireStack(p, 1, "hascap") ) return 1; + z = SbS_StackValue(p, 0, &n); + a = login_has_capability(z, n); + SbS_Pop(p, 1); + SbS_PushInt(p, a); + return 0; +} + +/* +** Subscript command: STRING linecount INTEGER +** +** Return one more than the number of \n characters in STRING. +*/ +static int linecntCmd(struct Subscript *p, void *pNotUsed){ + const char *z; + int size, n, i; + if( SbS_RequireStack(p, 1, "linecount") ) return 1; + z = SbS_StackValue(p, 0, &size); + for(n=1, i=0; i<size; i++){ + if( z[i]=='\n' ) n++; + } + SbS_Pop(p, 1); + SbS_PushInt(p, n); + return 0; +} + +/* +** Subscript command: STRING length INTEGER +** +** Return one more than the number characters in STRING. +*/ +static int lengthCmd(struct Subscript *p, void *pNotUsed){ + int size; + if( SbS_RequireStack(p, 1, "length") ) return 1; + SbS_StackValue(p, 0, &size); + SbS_Pop(p, 1); + SbS_PushInt(p, size); + return 0; +} + +/* +** Subscript command: NAME exists INTEGER +** +** Return TRUE if the variable NAME exists. +*/ +static int existsCmd(struct Subscript *p, void *pNotUsed){ + const char *z; + int size, x; + if( SbS_RequireStack(p, 1, "exists") ) return 1; + z = SbS_StackValue(p, 0, &size); + x = sbs_fetch(&p->symTab, (char*)z, size)!=0; + SbS_Pop(p, 1); + SbS_PushInt(p, x); + return 0; +} + +/* +** Subscript command: VALUE NAME get VALUE +** +** Push the value of varible NAME onto the stack if it exists. +** If NAME does not exist, puts VALUE onto the stack instead. +*/ +static int getCmd(Subscript *p, void *pNotUsed){ + const char *zName; + int nName; + const SbSValue *pVal; + int rc = 0; + + if( SbS_RequireStack(p, 2, "get") ) return SBS_ERROR; + zName = SbS_StackValue(p, 0, &nName); + pVal = sbs_fetch(&p->symTab, (char*)zName, nName); + if( pVal!=0 && (pVal->flags & SBSVAL_STR)!=0 ){ + SbS_Pop(p, 2); + rc = SbS_Push(p, pVal->u.str.z, pVal->u.str.size, 0); + }else{ + SbS_Pop(p, 1); + } + return rc; +} + + + +/* +** True if output is enabled. False if disabled. +*/ +static int enableOutput = 1; + +/* +** Subscript command: BOOLEAN enable_output +** +** Enable or disable the puts and hputs commands. +*/ +static int enableOutputCmd(struct Subscript *p, void *pNotUsed){ + if( SbS_RequireStack(p, 1, "enable_output") ) return 1; + enableOutput = SbS_StackValueInt(p, 0)!=0; + SbS_Pop(p, 1); + return 0; +} + +/* +** Send text to the appropriate output: Either to the console +** or to the CGI reply buffer. +*/ +static void sendText(const char *z, int n){ + if( enableOutput && n ){ + if( n<0 ) n = strlen(z); + if( g.cgiPanic ){ + cgi_append_content(z, n); + }else{ + fwrite(z, 1, n, stdout); + } + } +} + +/* +** Subscript command: STRING puts +** Subscript command: STRING html +** +** Output STRING as HTML (html) or unchanged (puts). +** Pop it from the stack. +*/ +static int putsCmd(struct Subscript *p, void *pConvert){ + int size; + const char *z; + char *zOut; + if( SbS_RequireStack(p, 1, "puts") ) return 1; + if( enableOutput ){ + z = SbS_StackValue(p, 0, &size); + if( pConvert ){ + zOut = htmlize(z, size); + size = strlen(zOut); + }else{ + zOut = (char*)z; + } + sendText(zOut, size); + if( pConvert ){ + free(zOut); + } + } + SbS_Pop(p, 1); + return 0; +} + +/* +** Subscript command: STRING wiki +** +** Render the input string as wiki. +*/ +static int wikiCmd(struct Subscript *p, void *pConvert){ + int size; + const char *z; + if( SbS_RequireStack(p, 1, "wiki") ) return 1; + if( enableOutput ){ + Blob src; + z = SbS_StackValue(p, 0, &size); + blob_init(&src, z, size); + wiki_convert(&src, 0, WIKI_INLINE); + blob_reset(&src); + } + SbS_Pop(p, 1); + return 0; +} + +/* +** Subscript command: NAME TEXT-LIST NUMLINES combobox +** +** Generate an HTML combobox. NAME is both the name of the +** CGI parameter and the name of a variable that contains the +** currently selected value. TEXT-LIST is a list of possible +** values for the combobox. NUMLINES is 1 for a true combobox. +** If NUMLINES is greater than one then the display is a listbox +** with the number of lines given. +*/ +static int comboboxCmd(struct Subscript *p, void *NotUsed){ + if( SbS_RequireStack(p, 3, "combobox") ) return 1; + if( enableOutput ){ + int height; + Blob list, elem; + char *zName, *zList; + int nName, nList, nValue; + const char *zValue; + char *z, *zH; + + height = SbS_StackValueInt(p, 0); + zList = (char*)SbS_StackValue(p, 1, &nList); + blob_init(&list, zList, nList); + zName = (char*)SbS_StackValue(p, 2, &nName); + zValue = SbS_Fetch(p, zName, nName, &nValue); + z = mprintf("<select name=\"%z\" size=\"%d\">", + htmlize(zName, nName), height); + sendText(z, -1); + free(z); + while( blob_token(&list, &elem) ){ + zH = htmlize(blob_buffer(&elem), blob_size(&elem)); + if( zValue && blob_size(&elem)==nValue + && memcmp(zValue, blob_buffer(&elem), nValue)==0 ){ + z = mprintf("<option value=\"%s\" selected>%s</option>", zH, zH); + }else{ + z = mprintf("<option value=\"%s\">%s</option>", zH, zH); + } + free(zH); + sendText(z, -1); + free(z); + } + sendText("</select>", -1); + blob_reset(&list); + } + SbS_Pop(p, 3); + return 0; +} + +/* +** Subscript command: STRING BOOLEAN if +** +** Evaluate STRING as a script if BOOLEAN is true. +*/ +static int ifCmd(struct Subscript *p, void *pNotUsed){ + int cond; + int rc = SBS_OK; + + if( SbS_RequireStack(p, 2, "if") ) return 1; + cond = SbS_StackValueInt(p, 0); + if( cond ){ + SbSValue script = p->aStack[p->nStack-2]; + p->aStack[p->nStack-2].flags = 0; + SbS_Pop(p, 2); + rc = SbS_Eval(p, script.u.str.z, script.u.str.size); + sbs_value_reset(&script); + }else{ + SbS_Pop(p, 2); + } + return rc; +} + +/* +** Subscript command: ... STRING COUNT concat STRING +** +** Concatenate COUNT strings into a single string and leave +** the concatenation on the stack. +*/ +static int concatCmd(struct Subscript *p, void *pNotUsed){ + int count; + int nByte; + char *z; + int i, j; + + if( SbS_RequireStack(p, 1, "concat") ) return SBS_ERROR; + count = SbS_StackValueInt(p, 0); + if( SbS_RequireStack(p, count+1, "concat") ) return SBS_ERROR; + SbS_Pop(p, 1); + nByte = 1; + for(i=p->nStack-count; i<p->nStack; i++){ + nByte += p->aStack[i].u.str.size; + } + z = malloc(nByte); + if( z==0 ){ fossil_panic("out of memory"); } + for(j=0, i=p->nStack-count; i<p->nStack; i++){ + nByte = p->aStack[i].u.str.size; + memcpy(&z[j], p->aStack[i].u.str.z, nByte); + j += nByte; + } + z[j] = 0; + SbS_Pop(p, count); + SbS_Push(p, z, j, 1); + return SBS_OK; +} + + +/* +** A table of built-in commands +*/ +static const struct { + const char *zCmd; + int (*xCmd)(Subscript*,void*); + void *pArg; +} aBuiltin[] = { + { "add", bopCmd, (void*)SBSOP_AND }, + { "and", bopCmd, (void*)SBSOP_AND }, + { "combobox", comboboxCmd, 0, }, + { "concat", concatCmd, 0, }, + { "div", bopCmd, (void*)SBSOP_DIV }, + { "enable_output", enableOutputCmd, 0 }, + { "eq", bopCmd, (void*)SBSOP_EQ }, + { "exists", existsCmd, 0, }, + { "get", getCmd, 0, }, + { "hascap", hascapCmd, 0 }, + { "html", putsCmd, (void*)1 }, + { "if", ifCmd, 0, }, + { "le", bopCmd, (void*)SBSOP_LE }, + { "length", lengthCmd, 0 }, + { "linecount", linecntCmd, 0 }, + { "lt", bopCmd, (void*)SBSOP_LT }, + { "max", bopCmd, (void*)SBSOP_MAX }, + { "min", bopCmd, (void*)SBSOP_MIN }, + { "mul", bopCmd, (void*)SBSOP_MUL }, + { "not", notCmd, 0 }, + { "or", bopCmd, (void*)SBSOP_OR }, + { "puts", putsCmd, 0 }, + { "set", setCmd, 0 }, + { "streq", streqCmd, 0 }, + { "sub", bopCmd, (void*)SBSOP_SUB }, + { "wiki", wikiCmd, 0, }, +}; + + +/* +** Compare a zero-terminated string zPattern against +** an unterminated string zStr of length nStr. +** +** Return less than, equal to, or greater than zero if +** zPattern is less than, equal to, or greater than zStr. +*/ +static int compare_cmd(const char *zPattern, const char *zStr, int nStr){ + int c = strncmp(zPattern, zStr, nStr); + if( c==0 && zPattern[nStr]!=0 ){ + c = 1; + } + return c; +} + +/* +** Evaluate the script given by the first nScript bytes of zScript[]. +** Return 0 on success and non-zero for an error. +*/ +int SbS_Eval(struct Subscript *p, const char *zScript, int nScript){ + int rc = SBS_OK; + if( nScript<0 ) nScript = strlen(zScript); + while( nScript>0 && rc==SBS_OK ){ + int n; + int ttype; + n = sbs_next_token(zScript, nScript, &ttype); + +#if 0 + { + int i, nElem; + const char *zElem; + if( p->nStack>0 ){ + printf("STACK:"); + for(i=0; i<p->nStack; i++){ + zElem = SbS_StackValue(p, i, &nElem); + printf(" [%.*s]", nElem, zElem); + } + printf("\n"); + } + printf("TOKEN(%d): [%.*s]\n", ttype, n, zScript); + } +#endif + + switch( ttype ){ + case SBSTT_WHITESPACE: { + break; + } + case SBSTT_EOF: { + nScript = 0; + break; + } + case SBSTT_INCOMPLETE: + case SBSTT_UNKNOWN: { + rc = SBS_ERROR; + nScript = n; + break; + } + case SBSTT_INTEGER: { + rc = SbS_Push(p, (char*)zScript, n, 0); + break; + } + case SBSTT_NAME: { + rc = SbS_Push(p, (char*)&zScript[1], n-1, 0); + break; + } + case SBSTT_STRING: { + rc = SbS_Push(p, (char*)&zScript[1], n-2, 0); + break; + } + case SBSTT_QUOTED: { + char *z = mprintf("%.*s", n-2, &zScript[1]); + int i, j; + for(i=j=0; z[i]; i++, j++){ + int c = z[i]; + if( c=='\\' && z[i+1] ){ + c = z[++i]; + if( c=='n' ){ + c = '\n'; + }else if( c>='0' && c<='7' ){ + int k; + c -= '0'; + for(k=1; k<3 && z[i+k]>='0' && z[i+k]<='7'; k++){ + c = c*8 + z[i+k] - '0'; + } + i += k-1; + } + } + z[j] = c; + } + z[j] = 0; + rc = SbS_Push(p, z, j, 1); + break; + } + case SBSTT_VERB: { + /* First look up the verb in the hash table */ + const SbSValue *pVal = sbs_fetch(&p->symTab, (char*)zScript, n); + if( pVal==0 ){ + /* If the verb is not in the hash table, look for a + ** built-in command */ + int upr = sizeof(aBuiltin)/sizeof(aBuiltin[0]) - 1; + int lwr = 0; + rc = SBS_ERROR; + while( upr>=lwr ){ + int i = (upr+lwr)/2; + int c = compare_cmd(aBuiltin[i].zCmd, zScript, n); + if( c==0 ){ + rc = aBuiltin[i].xCmd(p, aBuiltin[i].pArg); + break; + }else if( c>0 ){ + upr = i-1; + }else{ + lwr = i+1; + } + } + if( upr<lwr ){ + SbS_SetErrorMessage(p, "unknown verb: %.*s", n, zScript); + } + }else if( pVal->flags & SBSVAL_VERB ){ + rc = pVal->u.verb.xVerb(p, pVal->u.verb.pArg); + }else if( pVal->flags & SBSVAL_EXEC ){ + rc = SbS_Eval(p, pVal->u.str.z, pVal->u.str.size); + }else{ + rc = SbS_Push(p, pVal->u.str.z, pVal->u.str.size, 0); + } + break; + } + } + zScript += n; + nScript -= n; + } + return rc; +} + +/* +** The z[] input contains text mixed with subscript scripts. +** The subscript scripts are contained within [...]. This routine +** processes the template and writes the results on either +** stdout or into CGI. +*/ +int SbS_Render(struct Subscript *p, const char *z){ + int i = 0; + int rc = SBS_OK; + while( z[i] ){ + if( z[i]=='[' ){ + sendText(z, i); + z += i+1; + for(i=0; z[i] && z[i]!=']'; i++){} + rc = SbS_Eval(p, z, i); + if( rc!=SBS_OK ) break; + if( z[i] ) i++; + z += i; + i = 0; + }else{ + i++; + } + } + if( rc==SBS_ERROR ){ + sendText("<hr><p><font color=\"red\"><b>ERROR: ", -1); + sendText(SbS_GetErrorMessage(p), -1); + sendText("</b></font></p>", -1); + }else{ + sendText(z, i); + } + return rc; +} +/* +** COMMAND: test-subscript +*/ +void test_subscript(void){ + Subscript *p; + Blob in; + if( g.argc<3 ){ + usage("FILE"); + } + blob_zero(&in); + blob_read_from_file(&in, g.argv[2]); + p = SbS_Create(); + SbS_Render(p, blob_str(&in)); +}
Modified src/sync.c from [fc0e1584ee] to [39558ac818].
@@ -26,10 +26,38 @@ #include "config.h" #include "sync.h" #include <assert.h> /* +** If the respository is configured for autosyncing, then do an +** autosync. This will be a pull if the argument is true or a push +** if the argument is false. Return true if the autosync is done +** and false if autosync is not requested for the current repository. +*/ +int autosync(int pullFlag){ + const char *zUrl; + if( db_get_boolean("autosync", 0)==0 ){ + return 0; + } + zUrl = db_get("last-sync-url", 0); + if( zUrl==0 ){ + return 0; /* No default server */ + } + url_parse(zUrl); + if( g.urlIsFile ){ + return 0; /* Network sync only */ + } + if( g.urlPort!=80 ){ + printf("Autosync: http://%s:%d%s\n", g.urlName, g.urlPort, g.urlPath); + }else{ + printf("Autosync: http://%s%s\n", g.urlName, g.urlPath); + } + client_sync(!pullFlag, pullFlag, 0); + return 1; +} + +/* ** This routine processes the command-line argument for push, pull, ** and sync. If a command-line argument is given, that is the URL ** of a server to sync against. If no argument is given, use the ** most recently synced URL. Remember the current URL for next time. */ @@ -46,11 +74,11 @@ } url_parse(zUrl); if( g.urlIsFile ){ fossil_fatal("network sync only"); } - db_set("last-sync-url", zUrl); + db_set("last-sync-url", zUrl, 0); user_select(); if( g.argc==2 ){ if( g.urlPort!=80 ){ printf("Server: http://%s:%d%s\n", g.urlName, g.urlPort, g.urlPath); }else{
Added src/tag.c version [d36aa255e1]
@@ -1,1 +1,427 @@ +/* +** Copyright (c) 2007 D. Richard Hipp +** +** This program is free software; you can redistribute it and/or +** modify it under the terms of the GNU General Public +** License version 2 as published by the Free Software Foundation. +** +** This program is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +** General Public License for more details. +** +** You should have received a copy of the GNU General Public +** License along with this library; if not, write to the +** Free Software Foundation, Inc., 59 Temple Place - Suite 330, +** Boston, MA 02111-1307, USA. +** +** Author contact information: +** drh@hwaci.com +** http://www.hwaci.com/drh/ +** +******************************************************************************* +** +** This file contains code used to manage tags +*/ +#include "config.h" +#include "tag.h" +#include <assert.h> + +/* +** Propagate the tag given by tagid to the children of pid. +** +** This routine assumes that tagid is a tag that should be +** propagated and that the tag is already present in pid. +** +** If tagtype is 2 then the tag is being propagated from an +** ancestor node. If tagtype is 0 it means a branch tag is +** being cancelled. +*/ +void tag_propagate( + int pid, /* Propagate the tag to children of this node */ + int tagid, /* Tag to propagate */ + int tagType, /* 2 for a propagating tag. 0 for an antitag */ + const char *zValue, /* Value of the tag. Might be NULL */ + double mtime /* Timestamp on the tag */ +){ + PQueue queue; + Stmt s, ins, eventupdate; + + assert( tagType==0 || tagType==2 ); + pqueue_init(&queue); + pqueue_insert(&queue, pid, 0.0); + db_prepare(&s, + "SELECT cid, plink.mtime," + " coalesce(srcid=0 AND tagxref.mtime<:mtime, %d) AS doit" + " FROM plink LEFT JOIN tagxref ON cid=rid AND tagid=%d" + " WHERE pid=:pid AND isprim", + tagType!=0, tagid + ); + db_bind_double(&s, ":mtime", mtime); + if( tagType==2 ){ + db_prepare(&ins, + "REPLACE INTO tagxref(tagid, tagtype, srcid, value, mtime, rid)" + "VALUES(%d,2,0,%Q,:mtime,:rid)", + tagid, zValue + ); + db_bind_double(&ins, ":mtime", mtime); + }else{ + zValue = 0; + db_prepare(&ins, + "DELETE FROM tagxref WHERE tagid=%d AND rid=:rid", tagid + ); + } + if( tagid==TAG_BGCOLOR ){ + db_prepare(&eventupdate, + "UPDATE event SET brbgcolor=%Q WHERE objid=:rid", zValue + ); + } + while( (pid = pqueue_extract(&queue))!=0 ){ + db_bind_int(&s, ":pid", pid); + while( db_step(&s)==SQLITE_ROW ){ + int doit = db_column_int(&s, 2); + if( doit ){ + int cid = db_column_int(&s, 0); + double mtime = db_column_double(&s, 1); + pqueue_insert(&queue, cid, mtime); + db_bind_int(&ins, ":rid", cid); + db_step(&ins); + db_reset(&ins); + if( tagid==TAG_BGCOLOR ){ + db_bind_int(&eventupdate, ":rid", cid); + db_step(&eventupdate); + db_reset(&eventupdate); + } + } + } + db_reset(&s); + } + pqueue_clear(&queue); + db_finalize(&ins); + db_finalize(&s); + if( tagid==TAG_BGCOLOR ){ + db_finalize(&eventupdate); + } +} + +/* +** Propagate all propagatable tags in pid to its children. +*/ +void tag_propagate_all(int pid){ + Stmt q; + db_prepare(&q, + "SELECT tagid, tagtype, mtime, value FROM tagxref" + " WHERE rid=%d" + " AND (tagtype=0 OR tagtype=2)", + pid + ); + while( db_step(&q)==SQLITE_ROW ){ + int tagid = db_column_int(&q, 0); + int tagtype = db_column_int(&q, 1); + double mtime = db_column_double(&q, 2); + const char *zValue = db_column_text(&q, 3); + tag_propagate(pid, tagid, tagtype, zValue, mtime); + } + db_finalize(&q); +} + +/* +** Get a tagid for the given TAG. Create a new tag if necessary +** if createFlag is 1. +*/ +int tag_findid(const char *zTag, int createFlag){ + int id; + id = db_int(0, "SELECT tagid FROM tag WHERE tagname=%Q", zTag); + if( id==0 && createFlag ){ + db_multi_exec("INSERT INTO tag(tagname) VALUES(%Q)", zTag); + id = db_last_insert_rowid(); + } + return id; +} + +/* +** Insert a tag into the database. +*/ +void tag_insert( + const char *zTag, /* Name of the tag (w/o the "+" or "-" prefix */ + int tagtype, /* 0:cancel 1:singleton 2:propagated */ + const char *zValue, /* Value if the tag is really a property */ + int srcId, /* Artifact that contains this tag */ + double mtime, /* Timestamp. Use default if <=0.0 */ + int rid /* Artifact to which the tag is to attached */ +){ + Stmt s; + const char *zCol; + int tagid = tag_findid(zTag, 1); + int rc; + + if( mtime<=0.0 ){ + mtime = db_double(0.0, "SELECT julianday('now')"); + } + db_prepare(&s, + "SELECT 1 FROM tagxref" + " WHERE tagid=%d" + " AND rid=%d" + " AND mtime>=:mtime", + tagid, rid + ); + db_bind_double(&s, ":mtime", mtime); + rc = db_step(&s); + db_finalize(&s); + if( rc==SQLITE_ROW ){ + /* Another entry this is more recent already exists. Do nothing */ + return; + } + db_prepare(&s, + "REPLACE INTO tagxref(tagid,tagtype,srcId,value,mtime,rid)" + " VALUES(%d,%d,%d,%Q,:mtime,%d)", + tagid, tagtype, srcId, zValue, rid + ); + db_bind_double(&s, ":mtime", mtime); + db_step(&s); + db_finalize(&s); + if( tagtype==0 ){ + zValue = 0; + } + zCol = 0; + switch( tagid ){ + case TAG_BGCOLOR: { + if( tagtype==1 ){ + zCol = "bgcolor"; + }else{ + zCol = "brbgcolor"; + } + break; + } + case TAG_COMMENT: { + zCol = "ecomment"; + break; + } + case TAG_USER: { + zCol = "euser"; + break; + } + } + if( zCol ){ + db_multi_exec("UPDATE event SET %s=%Q WHERE objid=%d", zCol, zValue, rid); + } + if( tagtype==0 || tagtype==2 ){ + tag_propagate(rid, tagid, tagtype, zValue, mtime); + } +} + + +/* +** COMMAND: test-tag +** %fossil test-tag (+|*|-)TAGNAME UUID ?VALUE? +** +** Add a tag or anti-tag to the rebuildable tables of the local repository. +** No tag artifact is created so the new tag is erased the next +** time the repository is rebuilt. This routine is for testing +** use only. +*/ +void testtag_cmd(void){ + const char *zTag; + const char *zValue; + int rid; + int tagtype; + db_must_be_within_tree(); + if( g.argc!=4 && g.argc!=5 ){ + usage("TAGNAME UUID ?VALUE?"); + } + zTag = g.argv[2]; + switch( zTag[0] ){ + case '+': tagtype = 1; break; + case '*': tagtype = 2; break; + case '-': tagtype = 0; break; + default: + fossil_fatal("tag should begin with '+', '*', or '-'"); + return; + } + rid = name_to_rid(g.argv[3]); + if( rid==0 ){ + fossil_fatal("no such object: %s", g.argv[3]); + } + zValue = g.argc==5 ? g.argv[4] : 0; + db_begin_transaction(); + tag_insert(zTag, tagtype, zValue, -1, 0.0, rid); + db_end_transaction(0); +} + +/* +** Add a control record to the repository that either creates +** or cancels a tag. +*/ +static void tag_add_artifact( + const char *zTagname, /* The tag to add or cancel */ + const char *zObjName, /* Name of object attached to */ + const char *zValue, /* Value for the tag. Might be NULL */ + int tagtype /* 0:cancel 1:singleton 2:propagated */ +){ + int rid; + int nrid; + char *zDate; + Blob uuid; + Blob ctrl; + Blob cksum; + static const char zTagtype[] = { '-', '+', '*' }; + + assert( tagtype>=0 && tagtype<=2 ); + user_select(); + rid = name_to_rid(zObjName); + blob_zero(&uuid); + db_blob(&uuid, "SELECT uuid FROM blob WHERE rid=%d", rid); + blob_zero(&ctrl); + + if( validate16(zTagname, strlen(zTagname)) ){ + fossil_fatal("invalid tag name \"%s\" - might be confused with a UUID", + zTagname); + } + zDate = db_text(0, "SELECT datetime('now')"); + zDate[10] = 'T'; + blob_appendf(&ctrl, "D %s\n", zDate); + blob_appendf(&ctrl, "T %c%F %b", zTagtype[tagtype], zTagname, &uuid); + if( tagtype && zValue && zValue[0] ){ + blob_appendf(&ctrl, " %F\n", zValue); + }else{ + blob_appendf(&ctrl, "\n"); + } + blob_appendf(&ctrl, "U %F\n", g.zLogin); + md5sum_blob(&ctrl, &cksum); + blob_appendf(&ctrl, "Z %b\n", &cksum); + db_begin_transaction(); + nrid = content_put(&ctrl, 0, 0); + manifest_crosslink(nrid, &ctrl); + db_end_transaction(0); + + /* Do an autosync push if requested */ + autosync(0); +} + +/* +** COMMAND: tag +** Usage: %fossil tag SUBCOMMAND ... +** +** Run various subcommands to control tags and properties +** +** %fossil tag add TAGNAME UUID ?VALUE? +** +** Add a new tag or property to UUID. +** +** %fossil tag branch TAGNAME UUID ?VALUE? +** +** Add a new tag or property to UUID and make that +** tag propagate to all direct children. +** +** %fossil tag delete TAGNAME UUID +** +** Delete the tag TAGNAME from UUID +** +** %fossil tag find TAGNAME +** +** List all baselines that use TAGNAME +** +** %fossil tag list ?UUID? +** +** List all tags, or if UUID is supplied, list +** all tags and their values for UUID. +*/ +void tag_cmd(void){ + int n; + db_find_and_open_repository(); + if( g.argc<3 ){ + goto tag_cmd_usage; + } + n = strlen(g.argv[2]); + if( n==0 ){ + goto tag_cmd_usage; + } + + if( strncmp(g.argv[2],"add",n)==0 ){ + char *zValue; + if( g.argc!=5 && g.argc!=6 ){ + usage("add TAGNAME UUID ?VALUE?"); + } + zValue = g.argc==6 ? g.argv[5] : 0; + tag_add_artifact(g.argv[3], g.argv[4], zValue, 1); + }else + + if( strncmp(g.argv[2],"branch",n)==0 ){ + char *zValue; + if( g.argc!=5 && g.argc!=6 ){ + usage("branch TAGNAME UUID ?VALUE?"); + } + zValue = g.argc==6 ? g.argv[5] : 0; + tag_add_artifact(g.argv[3], g.argv[4], zValue, 2); + }else + + if( strncmp(g.argv[2],"delete",n)==0 ){ + if( g.argc!=5 ){ + usage("delete TAGNAME UUID"); + } + tag_add_artifact(g.argv[3], g.argv[4], 0, 0); + }else + + if( strncmp(g.argv[2],"find",n)==0 ){ + Stmt q; + if( g.argc!=4 ){ + usage("find TAGNAME"); + } + db_prepare(&q, + "SELECT blob.uuid FROM tagxref, blob" + " WHERE tagid=(SELECT tagid FROM tag WHERE tagname=%Q)" + " AND blob.rid=tagxref.rid", g.argv[3] + ); + while( db_step(&q)==SQLITE_ROW ){ + printf("%s\n", db_column_text(&q, 0)); + } + db_finalize(&q); + }else + + if( strncmp(g.argv[2],"list",n)==0 ){ + Stmt q; + if( g.argc==3 ){ + db_prepare(&q, + "SELECT tagname" + " FROM tag" + " WHERE EXISTS(SELECT 1 FROM tagxref" + " WHERE tagid=tag.tagid" + " AND tagtype>0)" + " ORDER BY tagname" + ); + while( db_step(&q)==SQLITE_ROW ){ + printf("%s\n", db_column_text(&q, 0)); + } + db_finalize(&q); + }else if( g.argc==4 ){ + int rid = name_to_rid(g.argv[3]); + db_prepare(&q, + "SELECT tagname, value" + " FROM tagxref, tag" + " WHERE tagxref.rid=%d AND tagxref.tagid=tag.tagid" + " AND tagtype>0" + " ORDER BY tagname", + rid + ); + while( db_step(&q)==SQLITE_ROW ){ + const char *zName = db_column_text(&q, 0); + const char *zValue = db_column_text(&q, 1); + if( zValue ){ + printf("%s=%s\n", zName, zValue); + }else{ + printf("%s\n", zName); + } + } + db_finalize(&q); + }else{ + usage("tag list ?UUID?"); + } + }else + { + goto tag_cmd_usage; + } + return; +tag_cmd_usage: + usage("add|branch|delete|find|list ..."); +}
Modified src/timeline.c from [44b7795660] to [6f6c62303a].
@@ -33,11 +33,11 @@ */ void hyperlink_to_uuid(const char *zUuid){ char zShortUuid[UUID_SIZE+1]; sprintf(zShortUuid, "%.10s", zUuid); if( g.okHistory ){ - @ <a href="%s(g.zBaseURL)/vinfo/%s(zUuid)">[%s(zShortUuid)]</a> + @ <a href="%s(g.zBaseURL)/info/%s(zUuid)">[%s(zShortUuid)]</a> }else{ @ <b>[%s(zShortUuid)]</b> } } @@ -75,46 +75,64 @@ } } /* ** Output a timeline in the web format given a query. The query -** should return 4 columns: +** should return these columns: ** ** 0. rid ** 1. UUID ** 2. Date/Time ** 3. Comment string ** 4. User ** 5. Number of non-merge children ** 6. Number of parents ** 7. True if is a leaf +** 8. background color +** 9. type ("ci", "w") */ void www_print_timeline( Stmt *pQuery, int *pFirstEvent, int *pLastEvent, int (*xCallback)(int, Blob*), Blob *pArg ){ - char zPrevDate[20]; int cnt = 0; + int wikiFlags; + int mxWikiLen; + Blob comment; + char zPrevDate[20]; zPrevDate[0] = 0; + + mxWikiLen = db_get_int("timeline-max-comment", 0); + if( db_get_boolean("timeline-block-markup", 0) ){ + wikiFlags = WIKI_INLINE; + }else{ + wikiFlags = WIKI_INLINE | WIKI_NOBLOCK; + } + db_multi_exec( "CREATE TEMP TABLE IF NOT EXISTS seen(rid INTEGER PRIMARY KEY);" "DELETE FROM seen;" ); @ <table cellspacing=0 border=0 cellpadding=0> + blob_zero(&comment); while( db_step(pQuery)==SQLITE_ROW ){ int rid = db_column_int(pQuery, 0); const char *zUuid = db_column_text(pQuery, 1); int nPChild = db_column_int(pQuery, 5); int nParent = db_column_int(pQuery, 6); int isLeaf = db_column_int(pQuery, 7); + const char *zBgClr = db_column_text(pQuery, 8); const char *zDate = db_column_text(pQuery, 2); + const char *zType = db_column_text(pQuery, 9); + const char *zUser = db_column_text(pQuery, 4); if( cnt==0 && pFirstEvent ){ *pFirstEvent = rid; } + cnt++; if( pLastEvent ){ *pLastEvent = rid; } db_multi_exec("INSERT OR IGNORE INTO seen VALUES(%d)", rid); if( xCallback ){ @@ -121,35 +139,49 @@ xCallback(rid, pArg); } if( memcmp(zDate, zPrevDate, 10) ){ sprintf(zPrevDate, "%.10s", zDate); @ <tr><td colspan=3> - @ <table cellpadding=2 border=0> - @ <tr><td bgcolor="#a0b5f4" class="border1"> - @ <table cellpadding=2 cellspacing=0 border=0><tr> - @ <td bgcolor="#d0d9f4" class="bkgnd1">%s(zPrevDate)</td> - @ </tr></table> - @ </td></tr></table> + @ <div class="divider">%s(zPrevDate)</div> @ </td></tr> } @ <tr> @ <td valign="top">%s(&zDate[11])</td> @ <td width="20" align="center" valign="top"> @ <font id="m%d(rid)" size="+1" color="white">*</font></td> - @ <td valign="top" align="left"> - hyperlink_to_uuid_with_mouseover(zUuid, "xin", "xout", rid); - if( nParent>1 ){ - @ <b>Merge</b> - } - if( nPChild>1 ){ - @ <b>Fork</b> - } - if( isLeaf ){ - @ <b>Leaf</b> - } - @ %h(db_column_text(pQuery,3)) - @ (by %h(db_column_text(pQuery,4)))</td></tr> + if( zBgClr && zBgClr[0] ){ + @ <td valign="top" align="left" bgcolor="%h(zBgClr)"> + }else{ + @ <td valign="top" align="left"> + } + if( zType[0]=='c' ){ + hyperlink_to_uuid_with_mouseover(zUuid, "xin", "xout", rid); + if( nParent>1 ){ + @ <b>Merge</b> + } + if( nPChild>1 ){ + @ <b>Fork</b> + } + if( isLeaf ){ + @ <b>Leaf</b> + } + }else{ + hyperlink_to_uuid(zUuid); + } + db_column_blob(pQuery, 3, &comment); + if( mxWikiLen>0 && blob_size(&comment)>mxWikiLen ){ + Blob truncated; + blob_zero(&truncated); + blob_append(&truncated, blob_buffer(&comment), mxWikiLen); + blob_append(&truncated, "...", 3); + wiki_convert(&truncated, 0, wikiFlags); + blob_reset(&truncated); + }else{ + wiki_convert(&comment, 0, wikiFlags); + } + blob_reset(&comment); + @ (by %h(zUser))</td></tr> } @ </table> } /* @@ -182,10 +214,33 @@ blob_appendf(pOut, "];\n"); return 0; } /* +** Return a pointer to a constant string that forms the basis +** for a timeline query for the WWW interface. +*/ +const char *timeline_query_for_www(void){ + static const char zBaseSql[] = + @ SELECT + @ blob.rid, + @ uuid, + @ datetime(event.mtime,'localtime') AS timestamp, + @ coalesce(ecomment, comment), + @ coalesce(euser, user), + @ (SELECT count(*) FROM plink WHERE pid=blob.rid AND isprim=1), + @ (SELECT count(*) FROM plink WHERE cid=blob.rid), + @ NOT EXISTS (SELECT 1 FROM plink WHERE pid=blob.rid), + @ coalesce(bgcolor, brbgcolor), + @ event.type + @ FROM event JOIN blob + @ WHERE blob.rid=event.objid + ; + return zBaseSql; +} + +/* ** WEBPAGE: timeline ** ** Query parameters: ** ** d=STARTDATE date in iso8601 notation. dflt: newest event @@ -192,22 +247,26 @@ ** n=INTEGER number of events to show. dflt: 25 ** e=INTEGER starting event id. dflt: nil ** u=NAME show only events from user. dflt: nil ** a show events after and including. dflt: false ** r show only related events. dflt: false +** y=TYPE show only TYPE ('ci' or 'w') dflt: nil +** s show the SQL dflt: nil */ void page_timeline(void){ Stmt q; + Blob sql; char *zSQL; Blob scriptInit; char zDate[100]; const char *zStart = P("d"); int nEntry = atoi(PD("n","20")); const char *zUser = P("u"); int objid = atoi(PD("e","0")); int relatedEvents = P("r")!=0; int afterFlag = P("a")!=0; + const char *zType = P("y"); int firstEvent; int lastEvent; /* To view the timeline, must have permission to read project data. */ @@ -218,35 +277,33 @@ if( !g.okHistory && db_exists("SELECT 1 FROM user" " WHERE login='anonymous'" " AND cap LIKE '%%h%%'") ){ @ <p><b>Note:</b> You will be able to access <u>much</u> more - @ historical information if <a href="%s(g.zBaseURL)/login">login</a>.</p> - } - zSQL = mprintf( - "SELECT blob.rid, uuid, datetime(event.mtime,'localtime'), comment, user," - " (SELECT count(*) FROM plink WHERE pid=blob.rid AND isprim=1)," - " (SELECT count(*) FROM plink WHERE cid=blob.rid)," - " NOT EXISTS (SELECT 1 FROM plink WHERE pid=blob.rid)" - " FROM event, blob" - " WHERE event.type='ci' AND blob.rid=event.objid" - ); + @ historical information if <a href="%s(g.zTop)/login">login</a>.</p> + } + blob_zero(&sql); + blob_append(&sql, timeline_query_for_www(), -1); + if( zType ){ + blob_appendf(&sql, " AND event.type=%Q", zType); + } if( zUser ){ - zSQL = mprintf("%z AND event.user=%Q", zSQL, zUser); + blob_appendf(&sql, " AND event.user=%Q", zUser); } if( objid ){ - char *z = db_text(0, "SELECT datetime(event.mtime) FROM event" + char *z = db_text(0, "SELECT datetime(event.mtime, 'localtime') FROM event" " WHERE objid=%d", objid); if( z ){ zStart = z; } } if( zStart ){ while( isspace(zStart[0]) ){ zStart++; } if( zStart[0] ){ - zSQL = mprintf("%z AND event.mtime %s julianday(%Q, 'localtime')", - zSQL, afterFlag ? ">=" : "<=", zStart); + blob_appendf(&sql, + " AND event.mtime %s (SELECT julianday(%Q, 'utc'))", + afterFlag ? ">=" : "<=", zStart); } } if( relatedEvents && objid ){ db_multi_exec( "CREATE TEMP TABLE IF NOT EXISTS ok(rid INTEGER PRIMARY KEY)" @@ -254,21 +311,38 @@ if( afterFlag ){ compute_descendents(objid, nEntry); }else{ compute_ancestors(objid, nEntry); } - zSQL = mprintf("%z AND event.objid IN ok", zSQL); + blob_append(&sql, " AND event.objid IN ok", -1); + } + if( afterFlag ){ + blob_appendf(&sql, " ORDER BY event.mtime ASC LIMIT %d", + nEntry); + }else{ + blob_appendf(&sql, " ORDER BY event.mtime DESC LIMIT %d", + nEntry); } - zSQL = mprintf("%z ORDER BY event.mtime DESC LIMIT %d", zSQL, nEntry); + zSQL = blob_str(&sql); + if( afterFlag ){ + zSQL = mprintf("SELECT * FROM (%s) ORDER BY timestamp DESC", zSQL); + } db_prepare(&q, zSQL); - free(zSQL); + if( P("s")!=0 ){ + @ <hr><p>%h(zSQL)</p><hr> + } + blob_zero(&sql); + if( afterFlag ){ + free(zSQL); + } zDate[0] = 0; blob_zero(&scriptInit); zDate[0] = 0; www_print_timeline(&q, &firstEvent, &lastEvent, save_parentage_javascript, &scriptInit); db_finalize(&q); + @ <p>firstEvent=%d(firstEvent) lastEvent=%d(lastEvent)</p> if( zStart==0 ){ zStart = zDate; } @ <script> @ var parentof = new Object(); @@ -341,36 +415,65 @@ @ <input type="text" size="30" value="%h(zStart)" name="d"> @ Number Of Entries: @ <input type="text" size="4" value="%d(nEntry)" name="n"> @ <br><input type="submit" value="Submit"> @ </form> + @ <table><tr><td> @ <form method="GET" action="%s(g.zBaseURL)/timeline"> - @ <input type="hidden" value="%h(zDate)" name="d"> + @ <input type="hidden" value="%d(lastEvent)" name="e"> @ <input type="hidden" value="%d(nEntry)" name="n"> @ <input type="submit" value="Next %d(nEntry) Rows"> - @ </form> + @ </form></td><td> + @ <form method="GET" action="%s(g.zBaseURL)/timeline"> + @ <input type="hidden" value="%d(firstEvent)" name="e"> + @ <input type="hidden" value="%d(nEntry)" name="n"> + @ <input type="hidden" value="1" name="a"> + @ <input type="submit" value="Previous %d(nEntry) Rows"> + @ </form></td></tr></table> style_footer(); } /* ** The input query q selects various records. Print a human-readable ** summary of those records. ** ** Limit the number of entries printed to nLine. +** +** The query should return these columns: +** +** 0. rid +** 1. uuid +** 2. Date/Time +** 3. Comment string and user +** 4. Number of non-merge children +** 5. Number of parents */ void print_timeline(Stmt *q, int mxLine){ int nLine = 0; char zPrevDate[20]; + const char *zCurrentUuid=0; + Stmt currentQ; + int rid = db_lget_int("checkout", 0); zPrevDate[0] = 0; + + db_prepare(¤tQ, + "SELECT uuid" + " FROM blob WHERE rid=%d", rid + ); + if( db_step(¤tQ)==SQLITE_ROW ){ + zCurrentUuid = db_column_text(¤tQ, 0); + } while( db_step(q)==SQLITE_ROW && nLine<=mxLine ){ const char *zId = db_column_text(q, 1); const char *zDate = db_column_text(q, 2); const char *zCom = db_column_text(q, 3); int nChild = db_column_int(q, 4); int nParent = db_column_int(q, 5); char *zFree = 0; + int n = 0; + char zPrefix[80]; char zUuid[UUID_SIZE+1]; sprintf(zUuid, "%.10s", zId); if( memcmp(zDate, zPrevDate, 10) ){ printf("=== %.10s ===\n", zDate); @@ -377,30 +480,48 @@ memcpy(zPrevDate, zDate, 10); nLine++; } if( zCom==0 ) zCom = ""; printf("%.8s ", &zDate[11]); - if( nChild>1 || nParent>1 ){ - int n = 0; - char zPrefix[50]; - if( nParent>1 ){ - sqlite3_snprintf(sizeof(zPrefix), zPrefix, "*MERGE* "); - n = strlen(zPrefix); - } - if( nChild>1 ){ - sqlite3_snprintf(sizeof(zPrefix)-n, &zPrefix[n], "*FORK* "); - n = strlen(zPrefix); - } - zFree = sqlite3_mprintf("[%.10s] %s%s", zUuid, zPrefix, zCom); - }else{ - zFree = sqlite3_mprintf("[%.10s] %s", zUuid, zCom); + zPrefix[0] = 0; + if( nParent>1 ){ + sqlite3_snprintf(sizeof(zPrefix), zPrefix, "*MERGE* "); + n = strlen(zPrefix); + } + if( nChild>1 ){ + sqlite3_snprintf(sizeof(zPrefix)-n, &zPrefix[n], "*FORK* "); + n = strlen(zPrefix); + } + if( strcmp(zCurrentUuid,zId)==0 ){ + sqlite3_snprintf(sizeof(zPrefix)-n, &zPrefix[n], "*CURRENT* "); + n += strlen(zPrefix); } + zFree = sqlite3_mprintf("[%.10s] %s%s", zUuid, zPrefix, zCom); nLine += comment_print(zFree, 9, 79); sqlite3_free(zFree); } + db_finalize(¤tQ); } +/* +** Return a pointer to a static string that forms the basis for +** a timeline query for display on a TTY. +*/ +const char *timeline_query_for_tty(void){ + static const char zBaseSql[] = + @ SELECT + @ blob.rid, + @ uuid, + @ datetime(event.mtime,'localtime'), + @ coalesce(ecomment,comment) || ' (by ' || coalesce(euser,user,'?') ||')', + @ (SELECT count(*) FROM plink WHERE pid=blob.rid AND isprim), + @ (SELECT count(*) FROM plink WHERE cid=blob.rid) + @ FROM event, blob + @ WHERE blob.rid=event.objid + ; + return zBaseSql; +} /* ** COMMAND: timeline ** ** Usage: %fossil timeline ?WHEN? ?UUID|DATETIME? ?-n|--count N? @@ -466,11 +587,11 @@ blob_append(&uuid, zOrigin, -1); if( strcmp(zOrigin, "now")==0 ){ if( mode==3 || mode==4 ){ fossil_fatal("cannot compute descendents or ancestors of a date"); } - zDate = mprintf("(SELECT julianday('now','utc'))"); + zDate = mprintf("(SELECT datetime('now'))"); }else if( strncmp(zOrigin, "current", k)==0 ){ objid = db_lget_int("checkout",0); zDate = mprintf("(SELECT mtime FROM plink WHERE cid=%d)", objid); }else if( name_to_uuid(&uuid, 0)==0 ){ objid = db_int(0, "SELECT rid FROM blob WHERE uuid=%B", &uuid); @@ -479,19 +600,14 @@ if( mode==3 || mode==4 ){ fossil_fatal("cannot compute descendents or ancestors of a date"); } zDate = mprintf("(SELECT julianday(%Q, 'utc'))", zOrigin); } - zSQL = mprintf( - "SELECT blob.rid, uuid, datetime(event.mtime,'localtime')," - " comment || ' (by ' || user || ')'," - " (SELECT count(*) FROM plink WHERE pid=blob.rid AND isprim)," - " (SELECT count(*) FROM plink WHERE cid=blob.rid)" - " FROM event, blob" - " WHERE event.type='ci' AND blob.rid=event.objid" - " AND event.mtime %s %s", - (mode==1 || mode==4) ? "<=" : ">=", zDate + zSQL = mprintf("%s AND event.mtime %s %s", + timeline_query_for_tty(), + (mode==1 || mode==4) ? "<=" : ">=", + zDate ); if( mode==3 || mode==4 ){ db_multi_exec("CREATE TEMP TABLE ok(rid INTEGER PRIMARY KEY)"); if( mode==3 ){ compute_descendents(objid, n);
Added src/tkt.c version [1c6be6341e]
@@ -1,1 +1,581 @@ +/* +** Copyright (c) 2007 D. Richard Hipp +** +** This program is free software; you can redistribute it and/or +** modify it under the terms of the GNU General Public +** License version 2 as published by the Free Software Foundation. +** +** This program is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +** General Public License for more details. +** +** You should have received a copy of the GNU General Public +** License along with this library; if not, write to the +** Free Software Foundation, Inc., 59 Temple Place - Suite 330, +** Boston, MA 02111-1307, USA. +** +** Author contact information: +** drh@hwaci.com +** http://www.hwaci.com/drh/ +** +******************************************************************************* +** +** This file contains code used render and control ticket entry +** and display pages. +*/ +#include "config.h" +#include "tkt.h" +#include <assert.h> + +/* +** The list of database user-defined fields in the TICKET table. +** The real table also contains some addition fields for internal +** used. The internal-use fields begin with "tkt_". +*/ +static int nField = 0; +static char **azField = 0; /* Names of database fields */ +static char **azValue = 0; /* Original values */ +static char **azAppend = 0; /* Value to be appended */ + +/* +** A subscript interpreter used for processing Tickets. +*/ +static struct Subscript *pInterp = 0; + +/* +** Compare two entries in azField for sorting purposes +*/ +static int nameCmpr(const void *a, const void *b){ + return strcmp(*(char**)a, *(char**)b); +} + +/* +** Obtain a list of all fields of the TICKET table. Put them +** in sorted order in azField[]. +** +** Also allocate space for azValue[] and azAppend[] and initialize +** all the values there to zero. +*/ +static void getAllTicketFields(void){ + Stmt q; + int i; + if( nField>0 ) return; + db_prepare(&q, "PRAGMA table_info(ticket)"); + while( db_step(&q)==SQLITE_ROW ){ + const char *zField = db_column_text(&q, 1); + if( strncmp(zField,"tkt_",4)==0 ) continue; + if( nField%10==0 ){ + azField = realloc(azField, sizeof(azField)*3*(nField+10) ); + if( azField==0 ){ + fossil_fatal("out of memory"); + } + } + azField[nField] = mprintf("%s", zField); + nField++; + } + db_finalize(&q); + qsort(azField, nField, sizeof(azField[0]), nameCmpr); + azAppend = &azField[nField]; + memset(azAppend, 0, sizeof(azAppend[0])*nField); + azValue = &azAppend[nField]; + for(i=0; i<nField; i++){ + azValue[i] = ""; + } +} + +/* +** Return the index into azField[] of the given field name. +** Return -1 if zField is not in azField[]. +*/ +static int fieldId(const char *zField){ + int i; + for(i=0; i<nField; i++){ + if( strcmp(azField[i], zField)==0 ) return i; + } + return -1; +} + +/* +** Query the database for all TICKET fields for the specific +** ticket whose name is given by the "name" CGI parameter. +** Load the values for all fields into the interpreter. +** +** Only load those fields which do not already exist as +** variables. +*/ +static void initializeVariablesFromDb(void){ + const char *zName; + Stmt q; + int i, n, size, j; + + zName = PD("name",""); + db_prepare(&q, "SELECT * FROM ticket WHERE tkt_uuid GLOB '%q*'", zName); + if( db_step(&q)==SQLITE_ROW ){ + n = db_column_count(&q); + for(i=0; i<n; i++){ + const char *zVal = db_column_text(&q, i); + const char *zName = db_column_name(&q, i); + if( zVal==0 ) zVal = ""; + for(j=0; j<nField; j++){ + if( strcmp(azField[j],zName)==0 ){ + azValue[j] = mprintf("%s", zVal); + break; + } + } + if( SbS_Fetch(pInterp, zName, -1, &size)==0 ){ + SbS_Store(pInterp, db_column_name(&q,i), zVal, 1); + } + } + }else{ + db_finalize(&q); + db_prepare(&q, "PRAGMA table_info(ticket)"); + while( db_step(&q)==SQLITE_ROW ){ + const char *zField = db_column_text(&q, 1); + if( SbS_Fetch(pInterp, zField, -1, &size)==0 ){ + SbS_Store(pInterp, zField, "", 0); + } + } + } + db_finalize(&q); +} + +/* +** Transfer all CGI parameters to variables in the interpreter. +*/ +static void initializeVariablesFromCGI(void){ + int i; + const char *z; + + for(i=0; (z = cgi_parameter_name(i))!=0; i++){ + SbS_Store(pInterp, z, P(z), 0); + } +} + +/* +** Rebuild all tickets named in the _pending_ticket table. +** +** This routine is called just prior to commit after new +** out-of-sequence ticket changes have been added. +*/ +static int ticket_rebuild_at_commit(void){ + Stmt q; + db_multi_exec( + "DELETE FROM ticket WHERE tkt_uuid IN _pending_ticket" + ); + db_prepare(&q, "SELECT uuid FROM _pending_ticket"); + while( db_step(&q)==SQLITE_ROW ){ + const char *zUuid = db_column_text(&q, 0); + ticket_rebuild_entry(zUuid); + } + db_multi_exec( + "DELETE FROM _pending_ticket" + ); + return 0; +} + +/* +** Update an entry of the TICKET table according to the information +** in the control file given in p. Attempt to create the appropriate +** TICKET table entry if createFlag is true. If createFlag is false, +** that means we already know the entry exists and so we can save the +** work of trying to create it. +*/ +void ticket_insert(Manifest *p, int createFlag, int checkTime){ + Blob sql; + Stmt q; + int i; + const char *zSep; + + getAllTicketFields(); + if( createFlag ){ + db_multi_exec("INSERT OR IGNORE INTO ticket(tkt_uuid, tkt_mtime) " + "VALUES(%Q, 0)", p->zTicketUuid); + } + blob_zero(&sql); + blob_appendf(&sql, "UPDATE ticket SET tkt_mtime=:mtime"); + zSep = "SET"; + for(i=0; i<p->nField; i++){ + const char *zName = p->aField[i].zName; + if( zName[0]=='+' ){ + zName++; + if( fieldId(zName)<0 ) continue; + blob_appendf(&sql,", %s=%s || %Q", zName, zName, p->aField[i].zValue); + }else{ + if( fieldId(zName)<0 ) continue; + blob_appendf(&sql,", %s=%Q", zName, p->aField[i].zValue); + } + } + blob_appendf(&sql, " WHERE tkt_uuid='%s' AND tkt_mtime<:mtime", + p->zTicketUuid); + db_prepare(&q, "%s", blob_str(&sql)); + db_bind_double(&q, ":mtime", p->rDate); + db_step(&q); + db_finalize(&q); + if( checkTime && db_changes()==0 ){ + static int isInit = 0; + if( !isInit ){ + db_multi_exec("CREATE TEMP TABLE _pending_ticket(uuid TEXT UNIQUE)"); + db_commit_hook(ticket_rebuild_at_commit, 1); + isInit = 1; + } + db_multi_exec("INSERT OR IGNORE INTO _pending_ticket " + "VALUES(%Q)", p->zTicketUuid); + } + blob_reset(&sql); +} + +/* +** Rebuild an entire entry in the TICKET table +*/ +void ticket_rebuild_entry(const char *zTktUuid){ + char *zTag = mprintf("tkt-%s", zTktUuid); + int tagid = tag_findid(zTag, 1); + Stmt q; + Manifest manifest; + Blob content; + int createFlag = 1; + + db_multi_exec( + "DELETE FROM ticket WHERE tkt_uuid=%Q", zTktUuid + ); + db_prepare(&q, "SELECT rid FROM tagxref WHERE tagid=%d ORDER BY mtime",tagid); + while( db_step(&q)==SQLITE_ROW ){ + int rid = db_column_int(&q, 0); + content_get(rid, &content); + manifest_parse(&manifest, &content); + ticket_insert(&manifest, createFlag, 0); + manifest_clear(&manifest); + createFlag = 0; + } + db_finalize(&q); +} + +/* +** Create the subscript interpreter and load the ticket configuration. +*/ +void ticket_init(void){ + char *zConfig; + if( pInterp ) return; + pInterp = SbS_Create(); + zConfig = db_text((char*)zDefaultTicketConfig, + "SELECT value FROM config WHERE name='ticket-configuration'"); + SbS_Eval(pInterp, zConfig, -1); +} + +/* +** Recreate the ticket table. +*/ +void ticket_create_table(int separateConnection){ + char *zSql; + int nSql; + + db_multi_exec("DROP TABLE IF EXISTS ticket;"); + ticket_init(); + zSql = (char*)SbS_Fetch(pInterp, "ticket_sql", -1, &nSql); + if( zSql==0 ){ + fossil_panic("no ticket_sql defined by ticket configuration"); + } + if( separateConnection ){ + zSql = mprintf("%.*s", nSql, zSql); + db_init_database(g.zRepositoryName, zSql, 0); + free(zSql); + }else{ + db_multi_exec("%.*s", nSql, zSql); + } +} + +/* +** Repopulate the ticket table +*/ +void ticket_rebuild(void){ + Stmt q; + db_begin_transaction(); + db_prepare(&q,"SELECT tagname FROM tag WHERE tagname GLOB 'tkt-*'"); + while( db_step(&q)==SQLITE_ROW ){ + const char *zName = db_column_text(&q, 0); + int len; + zName += 4; + len = strlen(zName); + if( len<20 || !validate16(zName, len) ) continue; + ticket_rebuild_entry(zName); + } + db_finalize(&q); + db_end_transaction(0); +} + +/* +** WEBPAGE: tktview +** +** View a ticket. +*/ +void tktview_page(void){ + char *zScript; + int nScript; + login_check_credentials(); + if( !g.okRdTkt ){ login_needed(); return; } + if( g.okWrTkt ){ + style_submenu_element("Edit", "Edit The Ticket", "%s/tktedit?name=%T", + g.zTop, PD("name","")); + } + style_header("View Ticket"); + ticket_init(); + initializeVariablesFromDb(); + zScript = (char*)SbS_Fetch(pInterp, "tktview_template", -1, &nScript); + zScript = mprintf("%.*s", nScript, zScript); + SbS_Render(pInterp, zScript); + style_footer(); +} + + + +/* +** Subscript command: STRING FIELD append_field +** +** FIELD is the name of a database column to which we might want +** to append text. STRING is the text to be appended to that +** column. The append does not actually occur until the +** submit_ticket_change verb is run. +*/ +static int appendRemarkCmd(struct Subscript *p, void *notUsed){ + int idx; + const char *zField, *zValue; + int nField, nValue; + + if( SbS_RequireStack(p, 2, "append_field") ) return 1; + zField = SbS_StackValue(p, 0, &nField); + for(idx=0; idx<nField; idx++){ + if( strncmp(azField[idx], zField, nField)==0 && azField[idx][nField]==0 ){ + break; + } + } + if( idx>=nField ){ + SbS_SetErrorMessage(p, "no such TICKET column: %.*s", nField, zField); + return SBS_ERROR; + } + zValue = SbS_StackValue(p, 1, &nValue); + azAppend[idx] = mprintf("%.*s", nValue, zValue); + SbS_Pop(p, 2); + return SBS_OK; +} + +/* +** Subscript command: submit_ticket +** +** Construct and submit a new ticket artifact. +*/ +static int submitTicketCmd(struct Subscript *p, void *pUuid){ + char *zDate; + const char *zUuid; + int i; + int rid; + Blob tktchng, cksum; + + zUuid = (const char *)pUuid; + blob_zero(&tktchng); + zDate = db_text(0, "SELECT datetime('now')"); + zDate[10] = 'T'; + blob_appendf(&tktchng, "D %s\n", zDate); + free(zDate); + for(i=0; i<nField; i++){ + const char *zValue; + int nValue; + if( azAppend[i] ){ + blob_appendf(&tktchng, "J +%s %z\n", azField[i], + fossilize(azAppend[i], -1)); + }else{ + zValue = SbS_Fetch(p, azField[i], -1, &nValue); + if( zValue ){ + while( nValue>0 && isspace(zValue[nValue-1]) ){ nValue--; } + if( strncmp(zValue, azValue[i], nValue) + || strlen(azValue[i])!=nValue ){ + blob_appendf(&tktchng, "J %s %z\n", + azField[i], fossilize(zValue,nValue)); + } + } + } + } + if( *(char**)pUuid ){ + zUuid = db_text(0, + "SELECT tkt_uuid FROM ticket WHERE tkt_uuid GLOB '%s*'", P("name") + ); + }else{ + zUuid = db_text(0, "SELECT lower(hex(randomblob(20)))"); + } + *(const char**)pUuid = zUuid; + blob_appendf(&tktchng, "K %s\n", zUuid); + blob_appendf(&tktchng, "U %F\n", g.zLogin ? g.zLogin : ""); + md5sum_blob(&tktchng, &cksum); + blob_appendf(&tktchng, "Z %b\n", &cksum); + + if( strncmp(g.zPath,"debug_",6)==0 ){ + @ <hr><pre> + @ %h(blob_str(&tktchng)) + @ </pre><hr> + blob_zero(&tktchng); + SbS_Pop(p, 1); + return SBS_OK; + } + + rid = content_put(&tktchng, 0, 0); + if( rid==0 ){ + fossil_panic("trouble committing ticket: %s", g.zErrMsg); + } + manifest_crosslink(rid, &tktchng); + return SBS_RETURN; +} + + +/* +** WEBPAGE: tktnew +** WEBPAGE: debug_tktnew +** +** Enter a new ticket. the tktnew_template script in the ticket +** configuration is used. The /tktnew page is the official ticket +** entry page. The /debug_tktnew page is used for debugging the +** tktnew_template in the ticket configuration. /debug_tktnew works +** just like /tktnew except that it does not really save the new ticket +** when you press submit - it just prints the ticket artifact at the +** top of the screen. +*/ +void tktnew_page(void){ + char *zScript; + int nScript; + char *zNewUuid = 0; + + login_check_credentials(); + if( !g.okNewTkt ){ login_needed(); return; } + style_header("New Ticket"); + ticket_init(); + getAllTicketFields(); + initializeVariablesFromCGI(); + @ <form method="POST" action="%s(g.zBaseURL)/%s(g.zPath)"> + zScript = (char*)SbS_Fetch(pInterp, "tktnew_template", -1, &nScript); + zScript = mprintf("%.*s", nScript, zScript); + SbS_Store(pInterp, "login", g.zLogin, 0); + SbS_Store(pInterp, "date", db_text(0, "SELECT datetime('now')"), 2); + SbS_AddVerb(pInterp, "submit_ticket", submitTicketCmd, (void*)&zNewUuid); + if( SbS_Render(pInterp, zScript)==SBS_RETURN && zNewUuid ){ + cgi_redirect(mprintf("%s/tktview/%s", g.zBaseURL, zNewUuid)); + return; + } + @ </form> + style_footer(); +} + +/* +** WEBPAGE: tktedit +** WEBPAGE: debug_tktedit +** +** Edit a ticket. The ticket is identified by the name CGI parameter. +** /tktedit is the official page. The /debug_tktedit page does the same +** thing except that it does not save the ticket change record when you +** press submit - it instead prints the ticket change record at the top +** of the page. The /debug_tktedit page is intended to be used when +** debugging ticket configurations. +*/ +void tktedit_page(void){ + char *zScript; + int nScript; + int nName; + const char *zName; + int nRec; + + login_check_credentials(); + if( !g.okApndTkt && !g.okWrTkt ){ login_needed(); return; } + style_header("Edit Ticket"); + zName = P("name"); + if( zName==0 || (nName = strlen(zName))<4 || nName>UUID_SIZE + || !validate16(zName,nName) ){ + @ <font color="red"><b>Not a valid ticket id: \"%h(zName)\"</b></font> + style_footer(); + return; + } + nRec = db_int(0, "SELECT count(*) FROM ticket WHERE tkt_uuid GLOB '%q*'", + zName); + if( nRec==0 ){ + @ <font color="red"><b>No such ticket: \"%h(zName)\"</b></font> + style_footer(); + return; + } + if( nRec>1 ){ + @ <font color="red"><b>%d(nRec) tickets begin with: \"%h(zName)\"</b></font> + style_footer(); + return; + } + ticket_init(); + getAllTicketFields(); + initializeVariablesFromCGI(); + initializeVariablesFromDb(); + @ <form method="POST" action="%s(g.zBaseURL)/%s(g.zPath)"> + @ <input type="hidden" name="name" value="%s(zName)"> + zScript = (char*)SbS_Fetch(pInterp, "tktedit_template", -1, &nScript); + zScript = mprintf("%.*s", nScript, zScript); + SbS_Store(pInterp, "login", g.zLogin, 0); + SbS_Store(pInterp, "date", db_text(0, "SELECT datetime('now')"), 2); + SbS_AddVerb(pInterp, "append_field", appendRemarkCmd, 0); + SbS_AddVerb(pInterp, "submit_ticket", submitTicketCmd, (void*)&zName); + if( SbS_Render(pInterp, zScript)==SBS_RETURN && zName ){ + cgi_redirect(mprintf("%s/tktview/%s", g.zBaseURL, zName)); + return; + } + @ </form> + style_footer(); +} + +/* +** Check the ticket configuration in zConfig to see if it appears to +** be well-formed. If everything is OK, return NULL. If something is +** amiss, then return a pointer to a string (obtained from malloc) that +** describes the problem. +*/ +char *ticket_config_check(const char *zConfig){ + struct Subscript *p; + char *zErr = 0; + const char *z; + int n; + int i; + int rc; + sqlite3 *db; + static const char *azRequired[] = { + "tktnew_template", + "tktview_template", + "tktedit_template", + }; + p = SbS_Create(); + rc = SbS_Eval(p, zConfig, strlen(zConfig)); + if( rc!=SBS_OK ){ + zErr = mprintf("%s", SbS_GetErrorMessage(p)); + SbS_Destroy(p); + return zErr; + } + for(i=0; i<sizeof(azRequired)/sizeof(azRequired[0]); i++){ + z = SbS_Fetch(p, azRequired[i], -1, &n); + if( z==0 ){ + zErr = mprintf("missing definition: %s", azRequired[i]); + SbS_Destroy(p); + return zErr; + } + } + z = SbS_Fetch(p, "ticket_sql", -1, &n); + if( z==0 ){ + zErr = mprintf("missing definition: ticket_sql"); + SbS_Destroy(p); + return zErr; + } + rc = sqlite3_open(":memory:", &db); + if( rc==SQLITE_OK ){ + char *zSql = mprintf("%.*s", n, z); + rc = sqlite3_exec(db, zSql, 0, 0, &zErr); + if( rc!=SQLITE_OK ){ + sqlite3_close(db); + SbS_Destroy(p); + return zErr; + } + /* TODO: verify that the TICKET table exists and has required fields */ + sqlite3_close(db); + } + SbS_Destroy(p); + return 0; +}
Added src/tktconfig.c version [c567cf64e8]
@@ -1,1 +1,369 @@ +/* +** Copyright (c) 2007 D. Richard Hipp +** +** This program is free software; you can redistribute it and/or +** modify it under the terms of the GNU General Public +** License version 2 as published by the Free Software Foundation. +** +** This program is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +** General Public License for more details. +** +** You should have received a copy of the GNU General Public +** License along with this library; if not, write to the +** Free Software Foundation, Inc., 59 Temple Place - Suite 330, +** Boston, MA 02111-1307, USA. +** +** Author contact information: +** drh@hwaci.com +** http://www.hwaci.com/drh/ +** +******************************************************************************* +** +** This file contains a string constant that is the default ticket +** configuration. +*/ +#include "config.h" +#include "tktconfig.h" + +/* +** This is a sample "ticket configuration" file for fossil. +** +** There is considerable flexibility in how tickets are defined +** in fossil. Each repository can define its own ticket setup +** differently. Each repository has an instance of a file, like +** this one that defines how that repository deals with tickets. +** +** This file is in the form of a script in an exceedingly +** minimalist scripting language called "subscript". Here are +** the rules: +** +** SYNTAX +** +** * The script consists of a sequence of whitespace +** separated tokens. Whitespace is ignored, except +** as its role as a token separator. +** +** * Lines that begin with '#' are considered to be whitespace. +** +** * Text within matching {...} is consider to be a single "string" +** token, even if the text spans multiple lines and includes +** embedded whitespace. The outermost {...} are not part of +** the text of the token. +** +** * A token that begins with "/" is a string token. +** +** * A token that looks like a number is a string token. +** +** * Tokens that do not fall under the previous three rules +** are "verb" tokens. +** +** PROCESSING: +** +** * When a script is processed, the engine reads tokens +** one by one. +** +** * String tokens are pushed onto the stack. +** +** * Verb tokens which correspond to the names of variables +** cause the corresponding variable to be pushed onto the +** stack. +** +** * Verb tokens which correspond to procedures cause the +** procedures to run. The procedures might push or pull +** values from the stack. +** +** There are just a handful of verbs. For the purposes of this +** configuration script, there is only a single verb: "set". The +** "set" verb pops two arguments from the stack. The topmost is +** the name of a variable. The second element is the value. The +** "set" verb sets the value of the named variable. +** +** VALUE NAME set +** +** This configuration file just sets the values of various variables. +** Some of the variables have special meanings. The content of some +** of the variables are additional subscript scripts. +*/ +/* @-comment: ** */ +const char zDefaultTicketConfig[] = +@ ############################################################################ +@ # Every ticket configuration *must* define an SQL statement that creates +@ # the TICKET table. This table must have three columns named +@ # tkt_id, tkt_uuid, and tkt_mtime. tkt_id must be the integer primary +@ # key and tkt_uuid and tkt_mtime must be unique. A configuration should +@ # define addition columns as necessary. All columns should be in all +@ # lower-case letters and should not begin with "tkt". +@ # +@ { +@ CREATE TABLE ticket( +@ -- Do not change any column that begins with tkt_ +@ tkt_id INTEGER PRIMARY KEY, +@ tkt_uuid TEXT, +@ tkt_mtime DATE, +@ -- Add as many field as required below this line +@ type TEXT, +@ status TEXT, +@ subsystem TEXT, +@ priority TEXT, +@ severity TEXT, +@ foundin TEXT, +@ contact TEXT, +@ title TEXT, +@ comment TEXT, +@ -- Do not alter this UNIQUE clause: +@ UNIQUE(tkt_uuid, tkt_mtime) +@ ); +@ -- Add indices as desired +@ } /ticket_sql set +@ +@ ############################################################################ +@ # You can define additional variables here. These variables will be +@ # accessible to the page templates when they run. +@ # +@ { +@ Code_Defect +@ Build_Problem +@ Documentation +@ Feature_Request +@ Incident +@ } /type_choices set +@ {Immediate High Medium Low Zero} /priority_choices set +@ {Critical Severe Important Minor Cosmetic} /severity_choices set +@ { +@ Open +@ Fixed +@ Rejected +@ Unable_To_Reproduce +@ Works_As_Designed +@ External_Bug +@ Not_A_Bug +@ Duplicate +@ Overcome_By_Events +@ Drive_By_Patch +@ } /resolution_choices set +@ { +@ Open +@ Verified +@ In_Process +@ Deferred +@ Fixed +@ Tested +@ Closed +@ } /status_choices set +@ {one two three} /subsystem_choices set +@ +@ ########################################################################## +@ # The "tktnew_template" variable is set to text which is a template for +@ # the HTML of the "New Ticket" page. Within this template, text contained +@ # within [...] is subscript. That subscript runs when the page is +@ # rendered. +@ # +@ { +@ <!-- load database field names not found in CGI with an empty string --> +@ <!-- start a form --> +@ [{ +@ {Open} /status set +@ submit_ticket +@ } /submit exists if] +@ <table cellpadding="5"> +@ <tr> +@ <td colspan="2"> +@ Enter a one-line summary of the problem:<br> +@ <input type="text" name="title" size="60" value="[{} /title get html]"> +@ </td> +@ </tr> +@ +@ <tr> +@ <td align="right">Type: +@ [/type type_choices 1 combobox] +@ </td> +@ <td>What type of ticket is this?</td> +@ </tr> +@ +@ <tr> +@ <td align="right">Version: +@ <input type="text" name="foundin" size="20" value="[{} /foundin get html]"> +@ </td> +@ <td>In what version or build number do you observer the problem?</td> +@ </tr> +@ +@ <tr> +@ <td align="right">Severity: +@ [/severity severity_choices 1 combobox] +@ </td> +@ <td>How debilitating is the problem? How badly does the problem +@ effect the operation of the product?</td> +@ </tr> +@ +@ <tr> +@ <td align="right">EMail: +@ <input type="text" name="contact" value="[{} /contact get html]" size="30"> +@ </td> +@ <td>Not publically visible. Used by developers to contact you with +@ questions.</td> +@ </tr> +@ +@ <tr> +@ <td colspan="2"> +@ Enter a detailed description of the problem. +@ For code defects, be sure to provide details on exactly how +@ the problem can be reproduced. Provide as much detail as +@ possible. +@ <br> +@ <textarea name="comment" cols="80" +@ rows="[{} /comment get linecount 50 max 10 min html]" +@ wrap="virtual" class="wikiedit">[{} /comment get html]</textarea><br> +@ <input type="submit" name="preview" value="Preview"> +@ </tr> +@ +@ [/preview exists enable_output] +@ <tr><td colspan="2"> +@ Description Preview:<br><hr> +@ [{} /comment get wiki] +@ <hr> +@ </td></tr> +@ [1 enable_output] +@ +@ <tr> +@ <td align="right"> +@ <input type="submit" name="submit" value="Submit"> +@ </td> +@ <td>After filling in the information above, press this button to create +@ the new ticket</td> +@ </tr> +@ </table> +@ <!-- end of form --> +@ } /tktnew_template set +@ +@ ########################################################################## +@ # The template for the "edit ticket" page +@ # +@ # Then generated text is inserted inside a form which feeds back to itself. +@ # All CGI parameters are loaded into variables. All database files are +@ # loaded into variables if they have not previously been loaded by +@ # CGI parameters. +@ { +@ [ +@ login /username get /username set +@ { +@ { +@ username login eq /samename set +@ { +@ "\n\n<hr><i>" login " added on " date ":</i><br>\n" +@ cmappnd 6 concat /comment append_field +@ } samename if +@ { +@ "\n\n<hr><i>" login " claiming to be " username " added on " date +@ "</i><br>\n" cmappnd 8 concat /comment append_field +@ } samename not if +@ } 0 {} /cmappnd get length lt if +@ submit_ticket +@ } /submit exists if +@ ] +@ <table cellpadding="5"> +@ <tr><td align="right">Title:</td><td> +@ <input type="text" name="title" value="[title html]" size="60"> +@ </td></tr> +@ <tr><td align="right">Status:</td><td> +@ [/status status_choices 1 combobox] +@ </td></tr> +@ <tr><td align="right">Type:</td><td> +@ [/type type_choices 1 combobox] +@ </td></tr> +@ <tr><td align="right">Severity:</td><td> +@ [/severity severity_choices 1 combobox] +@ </td></tr> +@ <tr><td align="right">Priority:</td><td> +@ [/priority priority_choices 1 combobox] +@ </td></tr> +@ <tr><td align="right">Resolution:</td><td> +@ [/resolution resolution_choices 1 combobox] +@ </td></tr> +@ <tr><td align="right">Subsystem:</td><td> +@ [/subsystem subsystem_choices 1 combobox] +@ </td></tr> +@ [/e hascap enable_output] +@ <tr><td align="right">Contact:</td><td> +@ <input type="text" name="contact" size="40" value="[contact html]"> +@ </td></tr> +@ [1 enable_output] +@ <tr><td align="right">Version Found In:</td><td> +@ <input type="text" name="foundin" size="50" value="[foundin html]"> +@ </td></tr> +@ <tr><td colspan="2"> +@ +@ [ +@ 0 /eall get /eall set # eall means "edit all". default==no +@ /aonlybtn exists not /eall set # Edit all if no aonlybtn CGI param +@ /eallbtn exists /eall set # Edit all if eallbtn CGI param +@ /w hascap eall and /eall set # WrTkt permission needed to edit all +@ ] +@ +@ [eall enable_output] +@ Description And Comments:<br> +@ <textarea name="comment" cols="80" +@ rows="[{} /comment get linecount 15 max 10 min html]" +@ wrap="virtual" class="wikiedit">[comment html]</textarea><br> +@ <input type="hidden" name="eall" value="1"> +@ <input type="submit" name="aonlybtn" value="Append Remark"> +@ +@ [eall not enable_output] +@ Append Remark from +@ <input type="text" name="username" value="[username html]" size="30">:<br> +@ <textarea name="cmappnd" cols="80" rows="15" +@ wrap="virtual" class="wikiedit">[{} /cmappnd get html]</textarea><br> +@ [/w hascap eall not and enable_output] +@ <input type="submit" name="eallbtn" value="Edit All"> +@ +@ [1 enable_output] +@ </td></tr> +@ <tr><td align="right"></td><td> +@ <input type="submit" name="submit" value="Submit Changes"> +@ </td></tr> +@ </table> +@ } /tktedit_template set +@ +@ ########################################################################## +@ # The template for the "view ticket" page +@ { +@ <!-- load database fields automatically loaded into variables --> +@ <table cellpadding="5"> +@ <tr><td align="right">Title:</td><td> +@ [title html] +@ </td></tr> +@ <tr><td align="right">Status:</td><td> +@ [status html] +@ </td></tr> +@ <tr><td align="right">Type:</td><td> +@ [type html] +@ </td></tr> +@ <tr><td align="right">Severity:</td><td> +@ [severity html] +@ </td></tr> +@ <tr><td align="right">Priority:</td><td> +@ [priority html] +@ </td></tr> +@ <tr><td align="right">Resolution:</td><td> +@ [priority html] +@ </td></tr> +@ <tr><td align="right">Subsystem:</td><td> +@ [subsystem html] +@ </td></tr> +@ [{e} hascap enable_output] +@ <tr><td align="right">Contact:</td><td> +@ [contact html] +@ </td></tr> +@ [1 enable_output] +@ <tr><td align="right">Version Found In:</td><td> +@ [foundin html] +@ </td></tr> +@ <tr><td colspan="2"> +@ Description And Comments:<br> +@ [comment wiki] +@ </td></tr> +@ </table> +@ } /tktview_template set +;
Added src/tktsetup.c version [eeccd454b7]
@@ -1,1 +1,44 @@ +/* +** Copyright (c) 2007 D. Richard Hipp +** +** This program is free software; you can redistribute it and/or +** modify it under the terms of the GNU General Public +** License version 2 as published by the Free Software Foundation. +** +** This program is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +** General Public License for more details. +** +** You should have received a copy of the GNU General Public +** License along with this library; if not, write to the +** Free Software Foundation, Inc., 59 Temple Place - Suite 330, +** Boston, MA 02111-1307, USA. +** +** Author contact information: +** drh@hwaci.com +** http://www.hwaci.com/drh/ +** +******************************************************************************* +** +** This file contains code to implement the ticket configuration +** setup screens. +*/ +#include "config.h" +#include "tktsetup.h" +#include <assert.h> + +/* +** Main sub-menu for configuring the ticketing system. +** WEBPAGE: /tktsetup +*/ +void tktsetup_page(void){ + login_check_credentials(); + if( !g.okSetup ){ + login_needed(); + } + style_header("Ticket Setup"); + @ <i>TBD...</i> + style_footer(); +}
Modified src/translate.c from [40ee3ab100] to [f57afdee03].
@@ -75,35 +75,45 @@ /* ** Translate the input stream into the output stream */ static void trans(FILE *in, FILE *out){ int i, j, k; /* Loop counters */ + char c1, c2; /* Characters used to start a comment */ int lastWasEq = 0; /* True if last non-whitespace character was "=" */ char zLine[2000]; /* A single line of input */ char zOut[4000]; /* The input line translated into appropriate output */ + c1 = c2 = '-'; while( fgets(zLine, sizeof(zLine), in) ){ for(i=0; zLine[i] && isspace(zLine[i]); i++){} if( zLine[i]!='@' ){ if( inPrint || inStr ) end_block(out); fprintf(out,"%s",zLine); + /* 0123456789 12345 */ + if( strncmp(zLine, "/* @-comment: ", 14)==0 ){ + c1 = zLine[14]; + c2 = zLine[15]; + } i += strlen(&zLine[i]); while( i>0 && isspace(zLine[i-1]) ){ i--; } lastWasEq = i>0 && zLine[i-1]=='='; }else if( lastWasEq ){ /* If the last non-whitespace character before the first @ was - ** an "=" then generate a string literal. But skip SQL comments - ** consisting of all text between "--" and end of line. + ** an "=" then generate a string literal. But skip comments + ** consisting of all text between c1 and c2 (default "--") + ** and end of line. */ int indent, omitline; i++; if( isspace(zLine[i]) ){ i++; } indent = i - 2; if( indent<0 ) indent = 0; omitline = 0; for(j=0; zLine[i] && zLine[i]!='\r' && zLine[i]!='\n'; i++){ - if( zLine[i]=='-' && zLine[i+1]=='-' ){ omitline = 1; break; } + if( zLine[i]==c1 && (c2==' ' || zLine[i+1]==c2) ){ + omitline = 1; break; + } if( zLine[i]=='"' || zLine[i]=='\\' ){ zOut[j++] = '\\'; } zOut[j++] = zLine[i]; } while( j>0 && isspace(zOut[j-1]) ){ j--; } zOut[j] = 0;
Modified src/update.c from [6cc6e53fd7] to [676d19419e].
@@ -27,63 +27,94 @@ #include "config.h" #include "update.h" #include <assert.h> /* +** Return true if artifact rid is a version +*/ +int is_a_version(int rid){ + return db_exists("SELECT 1 FROM plink WHERE cid=%d", rid); +} + +/* ** COMMAND: update ** -** Usage: %fossil update ?VERSION? +** Usage: %fossil update ?VERSION? ?--force? ?--latest? ** ** The optional argument is a version that should become the current ** version. If the argument is omitted, then use the leaf of the ** tree that begins with the current version, if there is only a -** single leaf. +** single leaf. If there are a multiple leaves, the latest is used +** if the --latest flag is present. ** ** This command is different from the "checkout" in that edits are ** not overwritten. Edits are merged into the new version. ** +** If there are uncommitted edits and the safemerge option is +** enabled then no update will occur unless you provide the +** --force flag. */ void update_cmd(void){ int vid; /* Current version */ - int tid; /* Target version - version we are changing to */ + int tid=0; /* Target version - version we are changing to */ Stmt q; - + int latestFlag; /* Pick the latest version if true */ + int forceFlag; /* True force the update */ + + latestFlag = find_option("latest",0, 0)!=0; + forceFlag = find_option("force","f",0)!=0; if( g.argc!=3 && g.argc!=2 ){ usage("?VERSION?"); } db_must_be_within_tree(); vid = db_lget_int("checkout", 0); if( vid==0 ){ - vid = 1; + fossil_fatal("cannot find current version"); } if( db_exists("SELECT 1 FROM vmerge") ){ fossil_fatal("cannot update an uncommitted merge"); } + if( !forceFlag && db_get_int("safemerge", 0) && unsaved_changes() ){ + fossil_fatal("there are uncommitted changes and safemerge is enabled"); + } + if( g.argc==3 ){ tid = name_to_rid(g.argv[2]); if( tid==0 ){ fossil_fatal("not a version: %s", g.argv[2]); } - if( !db_exists("SELECT 1 FROM mlink WHERE mid=%d", tid) ){ + if( !is_a_version(tid) ){ fossil_fatal("not a version: %s", g.argv[2]); } - }else{ + } + + if( tid==0 ){ + /* + ** Do an autosync pull prior to the update, if autosync is on and they + ** did not want a specific version (i.e. another branch, a past revision). + ** By not giving a specific version, they are asking for the latest, thus + ** pull to get the latest, then update. + */ + autosync(1); + } + + if( tid==0 ){ compute_leaves(vid); - if( db_int(0, "SELECT count(*) FROM leaves")>1 ){ + if( !latestFlag && db_int(0, "SELECT count(*) FROM leaves")>1 ){ db_prepare(&q, - "SELECT blob.rid, uuid, datetime(event.mtime,'localtime')," - " comment || ' (by ' || user || ')', 1, 1" - " FROM event, blob" - " WHERE event.type='ci' AND blob.rid=event.objid" + "%s " " AND event.objid IN leaves" - " ORDER BY event.mtime DESC" + " ORDER BY event.mtime DESC", + timeline_query_for_tty() ); print_timeline(&q, 100); db_finalize(&q); fossil_fatal("Multiple descendents"); } - tid = db_int(0, "SELECT rid FROM leaves"); + tid = db_int(0, "SELECT rid FROM leaves, event" + " WHERE event.objid=leaves.rid" + " ORDER BY event.mtime DESC"); } db_begin_transaction(); vfile_check_signature(vid); undo_begin(); @@ -175,25 +206,34 @@ free(zFullPath); } }else if( idt>0 && idv>0 && ridt!=ridv && chnged ){ /* Merge the changes in the current tree into the target version */ Blob e, r, t, v; + int rc; char *zFullPath; printf("MERGE %s\n", zName); undo_save(zName); zFullPath = mprintf("%s/%s", g.zLocalRoot, zName); content_get(ridt, &t); content_get(ridv, &v); blob_zero(&e); blob_read_from_file(&e, zFullPath); - blob_merge(&v, &e, &t, &r); - blob_write_to_file(&r, zFullPath); + rc = blob_merge(&v, &e, &t, &r); + if( rc>=0 ){ + blob_write_to_file(&r, zFullPath); + if( rc>0 ){ + printf("***** %d merge conflicts in %s\n", rc, zName); + } + }else{ + printf("***** Cannot merge binary file %s\n", zName); + } free(zFullPath); blob_reset(&v); blob_reset(&e); blob_reset(&t); blob_reset(&r); + } } db_finalize(&q); /* @@ -201,6 +241,102 @@ */ db_multi_exec("DELETE FROM vfile WHERE vid!=%d", tid); manifest_to_disk(tid); db_lset_int("checkout", tid); db_end_transaction(0); +} + + +/* +** Get the contents of a file within a given revision. +*/ +int historical_version_of_file( + const char *revision, /* The baseline name containing the file */ + const char *file, /* Full treename of the file */ + Blob *content /* Put the content here */ +){ + Blob mfile; + Manifest m; + int i, rid=0; + + rid = name_to_rid(revision); + content_get(rid, &mfile); + + if( manifest_parse(&m, &mfile) ){ + for(i=0; i<m.nFile; i++){ + if( strcmp(m.aFile[i].zName, file)==0 ){ + rid = uuid_to_rid(m.aFile[i].zUuid, 0); + return content_get(rid, content); + } + } + fossil_fatal("file %s does not exist in baseline: %s", file, revision); + }else{ + fossil_panic("could not parse manifest for baseline: %s", revision); + } + return 0; +} + + +/* +** COMMAND: revert +** +** Usage: %fossil revert ?--yes? ?-r REVISION? FILE +** +** Revert to the current repository version of FILE, or to +** the version associated with baseline REVISION if the -r flag +** appears. This command will confirm your operation unless the +** file is missing or the --yes option is used. +**/ +void revert_cmd(void){ + const char *zFile; + const char *zRevision; + Blob fname; + Blob record; + Blob ans; + int rid = 0, yesRevert; + + yesRevert = find_option("yes", "y", 0)!=0; + zRevision = find_option("revision", "r", 1); + verify_all_options(); + + if( g.argc<3 ){ + usage("?OPTIONS FILE"); + } + db_must_be_within_tree(); + + zFile = mprintf("%/", g.argv[g.argc-1]); + + if( !file_tree_name(zFile, &fname) ){ + fossil_panic("unknown file: %s", zFile); + } + + if( access(zFile, 0) ) yesRevert = 1; + if( yesRevert==0 ){ + char *prompt = mprintf("revert file %B? this will" + " destroy local changes [y/N]? ", + &fname); + blob_zero(&ans); + prompt_user(prompt, &ans); + if( blob_str(&ans)[0]=='y' ){ + yesRevert = 1; + } + } + + if( yesRevert==1 && zRevision!=0 ){ + historical_version_of_file(zRevision, zFile, &record); + }else if( yesRevert==1 ){ + rid = db_int(0, "SELECT rid FROM vfile WHERE pathname=%B", &fname); + if( rid==0 ){ + fossil_panic("no history for file: %b", &fname); + } + content_get(rid, &record); + } + + if( yesRevert==1 ){ + blob_write_to_file(&record, zFile); + printf("%s reverted\n", zFile); + blob_reset(&record); + blob_reset(&fname); + }else{ + printf("revert canceled\n"); + } }
Modified src/user.c from [7f6b214713] to [dde3c3d16a].
@@ -45,10 +45,50 @@ if( z[i]<' ' ) z[i] = ' '; } blob_append(pBlob, z, -1); } +#ifdef __MINGW32__ +/* +** getpass for Windows +*/ +static char *getpass(const char *prompt){ + static char pwd[64]; + size_t i; + + fputs(prompt,stderr); + fflush(stderr); + for(i=0; i<sizeof(pwd)-1; ++i){ + pwd[i] = _getch(); + if(pwd[i]=='\r' || pwd[i]=='\n'){ + break; + } + /* BS or DEL */ + else if(i>0 && (pwd[i]==8 || pwd[i]==127)){ + i -= 2; + continue; + } + /* CTRL-C */ + else if(pwd[i]==3) { + i=0; + break; + } + /* ESC */ + else if(pwd[i]==27){ + i=0; + break; + } + else{ + fputc('*',stderr); + } + } + pwd[i]='\0'; + fputs("\n", stderr); + return pwd; +} +#endif + /* ** Do a single prompt for a passphrase. Store the results in the blob. */ static void prompt_for_passphrase(const char *zPrompt, Blob *pPassphrase){ char *z = getpass(zPrompt); @@ -125,11 +165,11 @@ ** ** %fossil user list ** ** List all users known to the repository ** -** %fossil user new +** %fossil user new ?USERNAME? ** ** Create a new user in the repository. Users can never be ** deleted. They can be denied all access but they must continue ** to exist in the database. ** @@ -145,11 +185,19 @@ } n = strlen(g.argv[2]); if( n>=2 && strncmp(g.argv[2],"new",n)==0 ){ Blob passwd, login, contact; - prompt_user("login: ", &login); + if( g.argc>=4 ){ + blob_zero(&login); + blob_append(&login, g.argv[3], -1); + }else{ + prompt_user("login: ", &login); + } + if( db_exists("SELECT 1 FROM user WHERE login=%B", &login) ){ + fossil_fatal("user %b already exists", &login); + } prompt_user("contact-info: ", &contact); prompt_for_password("password: ", &passwd, 1); db_multi_exec( "INSERT INTO user(login,pw,cap,info)" "VALUES(%B,%B,'jnor',%B)", @@ -160,11 +208,11 @@ if( g.argc==3 ){ printf("%s\n", g.zLogin); }else if( g.localOpen ){ db_lset("default-user", g.zLogin); }else{ - db_set("default-user", g.zLogin); + db_set("default-user", g.zLogin, 0); } }else if( n>=2 && strncmp(g.argv[2],"list",n)==0 ){ Stmt q; db_prepare(&q, "SELECT login, info FROM user ORDER BY login"); while( db_step(&q)==SQLITE_ROW ){ @@ -173,11 +221,11 @@ db_finalize(&q); }else if( n>=2 && strncmp(g.argv[2],"password",2)==0 ){ char *zPrompt; int uid; Blob pw; - if( g.argc!=4 ) usage("user password USERNAME"); + if( g.argc!=4 ) usage("password USERNAME"); uid = db_int(0, "SELECT uid FROM user WHERE login=%Q", g.argv[3]); if( uid==0 ){ fossil_fatal("no such user: %s", g.argv[3]); } zPrompt = mprintf("new passwd for %s: ", g.argv[3]); @@ -252,11 +300,12 @@ if( attempt_user(db_get("default-user", 0)) ) return; if( attempt_user(getenv("USER")) ) return; - db_prepare(&s, "SELECT uid, login FROM user WHERE login<>'anonymous'"); + db_prepare(&s, "SELECT uid, login FROM user" + " WHERE login NOT IN ('anonymous','nobody')"); if( db_step(&s)==SQLITE_ROW ){ g.userUid = db_column_int(&s, 0); g.zLogin = mprintf("%s", db_column_text(&s, 1)); } db_finalize(&s); @@ -271,11 +320,11 @@ } if( g.userUid==0 ){ db_multi_exec( "INSERT INTO user(login, pw, cap, info)" - "VALUES('anonymous', '', '', '')" + "VALUES('anonymous', '', 'cfghjkmnoqw', '')" ); g.userUid = db_last_insert_rowid(); g.zLogin = "anonymous"; } }
Modified src/verify.c from [a3038ce20f] to [8d633e10bb].
@@ -20,11 +20,17 @@ ** http://www.hwaci.com/drh/ ** ******************************************************************************* ** ** This file contains code used to help verify the integrity of the -** the repository +** the repository. +** +** This file primarily implements the verify_before_commit() interface. +** Any function can call verify_before_commit() with a record id (RID) +** as an argument. Then before the next change to the database commits, +** this routine will reach in and check that the record can be extracted +** correctly from the BLOB table. */ #include "config.h" #include "verify.h" #include <assert.h> @@ -56,21 +62,29 @@ } blob_reset(&uuid); } /* -** +** The following bag holds the rid for every record that needs +** to be verified. +*/ +static Bag toVerify; +static int inFinalVerify = 0; + +/* +** This routine is called just prior to each commit operation. */ -static int verify_at_commit(void *notUsed){ - Stmt q; - db_prepare(&q, "SELECT rid FROM toverify"); - while( db_step(&q)==SQLITE_ROW ){ - int rid = db_column_int(&q, 0); +static int verify_at_commit(void){ + int rid; + inFinalVerify = 1; + rid = bag_first(&toVerify); + while( rid>0 ){ verify_rid(rid); + rid = bag_next(&toVerify, rid); } - db_finalize(&q); - db_multi_exec("DELETE FROM toverify"); + bag_clear(&toVerify); + inFinalVerify = 0; return 0; } /* ** Arrange to verify a particular record prior to committing. @@ -80,20 +94,16 @@ ** verification. */ void verify_before_commit(int rid){ static int isInit = 0; if( !isInit ){ - db_multi_exec( - "CREATE TEMP TABLE toverify(rid INTEGER PRIMARY KEY);" - ); - sqlite3_commit_hook(g.db, verify_at_commit, 0); + db_commit_hook(verify_at_commit, 1000); isInit = 1; } + assert( !inFinalVerify ); if( rid>0 ){ - db_multi_exec( - "INSERT OR IGNORE INTO toverify VALUES(%d)", rid - ); + bag_insert(&toVerify, rid); } } /* ** COMMAND: test-verify-all @@ -100,13 +110,18 @@ ** ** Verify all records in the repository. */ void verify_all_cmd(void){ Stmt q; + int cnt = 0; db_must_be_within_tree(); db_prepare(&q, "SELECT rid FROM blob"); while( db_step(&q)==SQLITE_ROW ){ int rid = db_column_int(&q, 0); - verify_rid(rid); + verify_before_commit(rid); + cnt++; + assert( bag_count(&toVerify)==cnt ); } db_finalize(&q); + verify_at_commit(); + assert( bag_count(&toVerify)==0 ); }
Modified src/vfile.c from [5ad913c384] to [429ccc29e5].
@@ -98,11 +98,11 @@ db_bind_int(&ins, ":vid", vid); while( blob_line(p, &line) ){ char *z = blob_buffer(&line); if( z[0]=='-' ){ if( seenHeader ) break; - while( blob_line(p, &line)>1 ){} + while( blob_line(p, &line)>2 ){} if( blob_line(p, &line)==0 ) break; } seenHeader = 1; if( z[0]!='F' || z[1]!=' ' ) continue; blob_token(&line, &token); /* Skip the "F" token */
Modified src/wiki.c from [804763a66e] to [9e63012182].
@@ -25,183 +25,577 @@ */ #include <assert.h> #include "config.h" #include "wiki.h" +/* +** Return true if the input string is a well-formed wiki page name. +** +** Well-formed wiki page names do not begin or end with whitespace, +** and do not contain tabs or other control characters and do not +** contain more than a single space character in a row. Well-formed +** names must be between 3 and 100 chracters in length, inclusive. +*/ +int wiki_name_is_wellformed(const char *z){ + int i; + if( z[0]<=0x20 ){ + return 0; + } + for(i=1; z[i]; i++){ + if( z[i]<0x20 ) return 0; + if( z[i]==0x20 && z[i-1]==0x20 ) return 0; + } + if( z[i-1]==' ' ) return 0; + if( i<3 || i>100 ) return 0; + return 1; +} + +/* +** Check a wiki name. If it is not well-formed, then issue an error +** and return true. If it is well-formed, return false. +*/ +static int check_name(const char *z){ + if( !wiki_name_is_wellformed(z) ){ + style_header("Wiki Page Name Error"); + @ The wiki name "<b>%h(z)</b>" is not well-formed. Rules for + @ wiki page names: + @ <ul> + @ <li> Must not begin or end with a space. + @ <li> Must not contain any control characters, including tab or + @ newline. + @ <li> Must not have two or more spaces in a row internally. + @ <li> Must be between 3 and 100 characters in length. + @ </ul> + style_footer(); + return 1; + } + return 0; +} /* -** Create a fake replicate of the "vfile" table as a TEMP table -** using the manifest identified by manid. +** WEBPAGE: home +** WEBPAGE: index +** WEBPAGE: not_found */ -static void create_fake_vfile(int manid){ - static const char zVfileDef[] = - @ CREATE TEMP TABLE vfile( - @ id INTEGER PRIMARY KEY, -- ID of the checked out file - @ vid INTEGER REFERENCES blob, -- The version this file is part of. - @ chnged INT DEFAULT 0, -- 0:unchnged 1:edited 2:m-chng 3:m-add - @ deleted BOOLEAN DEFAULT 0, -- True if deleted - @ rid INTEGER, -- Originally from this repository record - @ mrid INTEGER, -- Based on this record due to a merge - @ pathname TEXT, -- Full pathname - @ UNIQUE(pathname,vid) - @ ); - ; - db_multi_exec(zVfileDef); - load_vfile_from_rid(manid); +void home_page(void){ + char *zPageName = db_get("project-name",0); + if( zPageName ){ + login_check_credentials(); + g.zExtra = zPageName; + cgi_set_parameter_nocopy("name", g.zExtra); + g.okRdWiki = 1; + g.okApndWiki = 0; + g.okWrWiki = 0; + g.okHistory = 0; + wiki_page(); + return; + } + style_header("Home"); + @ <p>This is a stub home-page for the project. + @ To fill in this page, first go to + @ <a href="%s(g.zBaseURL)/setup_config">setup/config</a> + @ and establish a "Project Name". Then create a + @ wiki page with that name. The content of that wiki page + @ will be displayed in place of this message. + style_footer(); } /* -** Locate the wiki page with the name zPageName and render it. +** Return true if the given pagename is the name of the sandbox */ -static void locate_and_render_wikipage(const char *zPageName){ - Stmt q; - int id = 0; - int rid = 0; - int chnged = 0; - char *zPathname = 0; - db_prepare(&q, - "SELECT id, rid, chnged, pathname FROM vfile" - " WHERE (pathname='%q.wiki' OR pathname LIKE '%%/%q.wiki')" - " AND NOT deleted", zPageName, zPageName - ); - if( db_step(&q)==SQLITE_ROW ){ - id = db_column_int(&q, 0); - rid = db_column_int(&q, 1); - chnged = db_column_int(&q, 2); - if( chnged || rid==0 ){ - zPathname = db_column_malloc(&q, 3); - } - } - db_finalize(&q); - if( id ){ - Blob page, src; - char *zTitle = "wiki"; - char *z; - blob_zero(&src); - if( zPathname ){ - zPathname = mprintf("%s/%z", g.zLocalRoot, zPathname); - blob_read_from_file(&src, zPathname); - free(zPathname); - }else{ - content_get(rid, &src); - } - - /* The wiki page content is now in src. Check to see if - ** there is a <readonly/> or <appendonly/> element at the - ** beginning of the content. - */ - z = blob_str(&src); - while( isspace(*z) ) z++; - if( strncmp(z, "<readonly/>", 11)==0 ){ - z += 11; - }else if( strncmp(z, "<appendonly/>", 13)==0 ){ - z += 13; - } - - /* Check for <title>...</title> markup and remove it if present. */ - while( isspace(*z) ) z++; - if( strncmp(z, "<title>", 7)==0 ){ - int i; - for(i=7; z[i] && z[i]!='<'; i++){} - if( z[i]=='<' && strncmp(&z[i], "</title>", 8)==0 ){ - zTitle = htmlize(&z[7], i-7); - z = &z[i+8]; - } - } - - /* Render the page */ - style_header(zTitle); - blob_init(&page, z, -1); - wiki_convert(&page, cgi_output_blob(), WIKI_HTML); - blob_reset(&src); - }else{ - style_header("Unknown Wiki Page"); - @ The wiki page "%h(zPageName)" does not exist. - } - style_footer(); +static int is_sandbox(const char *zPagename){ + return strcasecmp(zPagename,"sandbox")==0 || + strcasecmp(zPagename,"sand box")==0; } /* ** WEBPAGE: wiki -** URL: /wiki/PAGENAME -** -** If the local database is available (which only happens if run -** as "server" instead of "cgi" or "http") then the file is taken -** from the local checkout. If there is no local checkout, then -** the content is taken from the "head" baseline. +** URL: /wiki?name=PAGENAME */ void wiki_page(void){ + char *zTag; + int rid; + int isSandbox; + Blob wiki; + Manifest m; + const char *zPageName; + char *zHtmlPageName; + char *zBody = mprintf("%s","<i>Empty Page</i>"); + login_check_credentials(); if( !g.okRdWiki ){ login_needed(); return; } - if( !g.localOpen ){ - int headid = db_int(0, - "SELECT cid FROM plink ORDER BY mtime DESC LIMIT 1" + zPageName = P("name"); + if( zPageName==0 ){ + style_header("Wiki"); + @ <ul> + @ <li> <a href="%s(g.zBaseURL)/timeline?y=w">Recent changes</a> to wiki + @ pages. </li> + @ <li> <a href="%s(g.zBaseURL)/wiki_rules">Formatting rules</a> for + @ wiki.</li> + @ <li> Use the <a href="%s(g.zBaseURL)/wiki?name=Sandbox">Sandbox</a> + @ to experiment.</li> + @ <li> <a href="%s(g.zBaseURL)/wcontent">List of All Wiki Pages</a> + @ available on this server.</li> + @ </ul> + style_footer(); + return; + } + if( check_name(zPageName) ) return; + isSandbox = is_sandbox(zPageName); + if( isSandbox ){ + zBody = db_get("sandbox",zBody); + }else{ + zTag = mprintf("wiki-%s", zPageName); + rid = db_int(0, + "SELECT rid FROM tagxref" + " WHERE tagid=(SELECT tagid FROM tag WHERE tagname=%Q)" + " ORDER BY mtime DESC", zTag + ); + free(zTag); + memset(&m, 0, sizeof(m)); + blob_zero(&m.content); + if( rid ){ + Blob content; + content_get(rid, &content); + manifest_parse(&m, &content); + if( m.type==CFTYPE_WIKI ){ + zBody = m.zWiki; + } + } + } + if( isSandbox || (rid && g.okWrWiki) || (!rid && g.okNewWiki) ){ + style_submenu_element("Edit", "Edit Wiki Page", "%s/wikiedit?name=%T", + g.zTop, zPageName); + } + if( isSandbox || (rid && g.okApndWiki) ){ + style_submenu_element("Append", "Add A Comment", "%s/wikiappend?name=%T", + g.zTop, zPageName); + } + if( !isSandbox && g.okHistory ){ + style_submenu_element("History", "History", "%s/whistory?name=%T", + g.zTop, zPageName); + } + zHtmlPageName = mprintf("%h", zPageName); + style_header(zHtmlPageName); + blob_init(&wiki, zBody, -1); + wiki_convert(&wiki, 0, 0); + blob_reset(&wiki); + if( !isSandbox ){ + manifest_clear(&m); + } + style_footer(); +} + +/* +** WEBPAGE: wikiedit +** URL: /wikiedit?name=PAGENAME +*/ +void wikiedit_page(void){ + char *zTag; + int rid; + int isSandbox; + Blob wiki; + Manifest m; + const char *zPageName; + char *zHtmlPageName; + int n; + const char *z; + char *zBody = (char*)P("w"); + + if( zBody ){ + zBody = mprintf("%s", zBody); + } + login_check_credentials(); + zPageName = PD("name",""); + if( check_name(zPageName) ) return; + isSandbox = is_sandbox(zPageName); + if( isSandbox ){ + if( zBody==0 ){ + zBody = db_get("sandbox",""); + } + }else{ + zTag = mprintf("wiki-%s", zPageName); + rid = db_int(0, + "SELECT rid FROM tagxref" + " WHERE tagid=(SELECT tagid FROM tag WHERE tagname=%Q)" + " ORDER BY mtime DESC", zTag + ); + free(zTag); + if( (rid && !g.okWrWiki) || (!rid && !g.okNewWiki) ){ + login_needed(); + return; + } + memset(&m, 0, sizeof(m)); + blob_zero(&m.content); + if( rid && zBody==0 ){ + Blob content; + content_get(rid, &content); + manifest_parse(&m, &content); + if( m.type==CFTYPE_WIKI ){ + zBody = m.zWiki; + } + } + } + if( P("submit")!=0 && zBody!=0 ){ + char *zDate; + Blob cksum; + int nrid; + blob_zero(&wiki); + db_begin_transaction(); + if( isSandbox ){ + db_set("sandbox",zBody,0); + }else{ + zDate = db_text(0, "SELECT datetime('now')"); + zDate[10] = 'T'; + blob_appendf(&wiki, "D %s\n", zDate); + free(zDate); + blob_appendf(&wiki, "L %F\n", zPageName); + if( rid ){ + char *zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", rid); + blob_appendf(&wiki, "P %s\n", zUuid); + free(zUuid); + } + if( g.zLogin ){ + blob_appendf(&wiki, "U %F\n", g.zLogin); + } + blob_appendf(&wiki, "W %d\n%s\n", strlen(zBody), zBody); + md5sum_blob(&wiki, &cksum); + blob_appendf(&wiki, "Z %b\n", &cksum); + blob_reset(&cksum); + nrid = content_put(&wiki, 0, 0); + db_multi_exec("INSERT OR IGNORE INTO unsent VALUES(%d)", nrid); + manifest_crosslink(nrid, &wiki); + blob_reset(&wiki); + content_deltify(rid, nrid, 0); + } + db_end_transaction(0); + cgi_redirectf("wiki?name=%T", zPageName); + } + if( P("cancel")!=0 ){ + cgi_redirectf("wiki?name=%T", zPageName); + return; + } + if( zBody==0 ){ + zBody = mprintf("<i>Empty Page</i>"); + } + zHtmlPageName = mprintf("Edit: %h", zPageName); + style_header(zHtmlPageName); + if( P("preview")!=0 ){ + blob_zero(&wiki); + blob_append(&wiki, zBody, -1); + @ Preview:<hr> + wiki_convert(&wiki, 0, 0); + @ <hr> + blob_reset(&wiki); + } + for(n=2, z=zBody; z[0]; z++){ + if( z[0]=='\n' ) n++; + } + if( n<20 ) n = 20; + if( n>200 ) n = 200; + @ <form method="POST" action="%s(g.zBaseURL)/wikiedit"> + @ <input type="hidden" name="name" value="%h(zPageName)"> + @ <textarea name="w" class="wikiedit" cols="80" + @ rows="%d(n)" wrap="virtual">%h(zBody)</textarea> + @ <br> + @ <input type="submit" name="preview" value="Preview Your Changes"> + @ <input type="submit" name="submit" value="Apply These Changes"> + @ <input type="submit" name="cancel" value="Cancel"> + @ </form> + if( !isSandbox ){ + manifest_clear(&m); + } + style_footer(); +} + +/* +** Append the wiki text for an remark to the end of the given BLOB. +*/ +static void appendRemark(Blob *p){ + char *zDate; + const char *zUser; + const char *zRemark; + + zDate = db_text(0, "SELECT datetime('now')"); + blob_appendf(p, "\n\n<hr><i>On %s UTC %h", zDate, g.zLogin); + free(zDate); + zUser = PD("u",g.zLogin); + if( zUser[0] && strcmp(zUser,g.zLogin) ){ + blob_appendf(p, " (claiming to be %h)", zUser); + } + zRemark = PD("r",""); + blob_appendf(p, " added:</i><br />\n%s", zRemark); +} + +/* +** WEBPAGE: wikiappend +** URL: /wikiappend?name=PAGENAME +*/ +void wikiappend_page(void){ + char *zTag; + int rid; + int isSandbox; + const char *zPageName; + char *zHtmlPageName; + const char *zUser; + + login_check_credentials(); + zPageName = PD("name",""); + if( check_name(zPageName) ) return; + isSandbox = is_sandbox(zPageName); + if( !isSandbox ){ + zTag = mprintf("wiki-%s", zPageName); + rid = db_int(0, + "SELECT rid FROM tagxref" + " WHERE tagid=(SELECT tagid FROM tag WHERE tagname=%Q)" + " ORDER BY mtime DESC", zTag ); - create_fake_vfile(headid); + free(zTag); + if( !rid ){ + cgi_redirect("index"); + return; + } + } + if( !g.okApndWiki ){ + login_needed(); + return; } - locate_and_render_wikipage(g.zExtra); -} - -/* -** The g.zExtra value is of the form UUID/otherstuff. -** Extract the UUID and convert it to a record id. Leave -** g.zExtra holding just otherstuff. If UUID does not exist -** or is malformed, return 0 and leave g.zExtra unchanged. -*/ -int extract_uuid_from_url(void){ - int i, rid; - Blob uuid; - for(i=0; g.zExtra[i] && g.zExtra[i]!='/'; i++){} - blob_zero(&uuid); - blob_append(&uuid, g.zExtra, i); - rid = name_to_uuid(&uuid, 0); - blob_reset(&uuid); - if( rid ){ - while( g.zExtra[i]=='/' ){ i++; } - g.zExtra = &g.zExtra[i]; - } - return rid; -} + if( P("submit")!=0 && P("r")!=0 && P("u")!=0 ){ + char *zDate; + Blob cksum; + int nrid; + Blob body; + Blob content; + Blob wiki; + Manifest m; -/* -** WEBPAGE: bwiki -** URL: /bwiki/UUID/PAGENAME -** -** UUID specifies a baseline. Render the wiki page PAGENAME as -** it appears in that baseline. -*/ -void bwiki_page(void){ - int headid; - login_check_credentials(); - if( !g.okRdWiki || !g.okHistory ){ login_needed(); return; } - headid = extract_uuid_from_url(); - if( headid ){ - create_fake_vfile(headid); + blob_zero(&body); + if( isSandbox ){ + blob_appendf(&body, db_get("sandbox","")); + appendRemark(&body); + db_set("sandbox", blob_str(&body), 0); + }else{ + content_get(rid, &content); + manifest_parse(&m, &content); + if( m.type==CFTYPE_WIKI ){ + blob_appendf(&body, m.zWiki, -1); + } + manifest_clear(&m); + blob_zero(&wiki); + db_begin_transaction(); + zDate = db_text(0, "SELECT datetime('now')"); + zDate[10] = 'T'; + blob_appendf(&wiki, "D %s\n", zDate); + blob_appendf(&wiki, "L %F\n", zPageName); + if( rid ){ + char *zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", rid); + blob_appendf(&wiki, "P %s\n", zUuid); + free(zUuid); + } + if( g.zLogin ){ + blob_appendf(&wiki, "U %F\n", g.zLogin); + } + blob_appendf(&body, "\n<hr>\n"); + appendRemark(&body); + blob_appendf(&wiki, "W %d\n%s\n", blob_size(&body), blob_str(&body)); + md5sum_blob(&wiki, &cksum); + blob_appendf(&wiki, "Z %b\n", &cksum); + blob_reset(&cksum); + nrid = content_put(&wiki, 0, 0); + db_multi_exec("INSERT OR IGNORE INTO unsent VALUES(%d)", nrid); + manifest_crosslink(nrid, &wiki); + blob_reset(&wiki); + content_deltify(rid, nrid, 0); + db_end_transaction(0); + } + cgi_redirectf("wiki?name=%T", zPageName); + } + if( P("cancel")!=0 ){ + cgi_redirectf("wiki?name=%T", zPageName); + return; + } + zHtmlPageName = mprintf("Append Comment To: %h", zPageName); + style_header(zHtmlPageName); + if( P("preview")!=0 ){ + Blob preview; + blob_zero(&preview); + appendRemark(&preview); + @ Preview:<hr> + wiki_convert(&preview, 0, 0); + @ <hr> + blob_reset(&preview); } - locate_and_render_wikipage(g.zExtra); + zUser = PD("u", g.zLogin); + @ <form method="POST" action="%s(g.zBaseURL)/wikiappend"> + @ <input type="hidden" name="name" value="%h(zPageName)"> + @ Your Name: + @ <input type="text" name="u" size="20" value="%h(zUser)"><br> + @ Comment to append:<br> + @ <textarea name="r" class="wikiedit" cols="80" + @ rows="10" wrap="virtual">%h(PD("r",""))</textarea> + @ <br> + @ <input type="submit" name="preview" value="Preview Your Comment"> + @ <input type="submit" name="submit" value="Append Your Changes"> + @ <input type="submit" name="cancel" value="Cancel"> + @ </form> + style_footer(); +} + +/* +** WEBPAGE: whistory +** URL: /whistory?name=PAGENAME +** +** Show the complete change history for a single wiki page. +*/ +void whistory_page(void){ + Stmt q; + char *zTitle; + char *zSQL; + const char *zPageName; + login_check_credentials(); + if( !g.okHistory ){ login_needed(); return; } + zPageName = PD("name",""); + zTitle = mprintf("History Of %h", zPageName); + style_header(zTitle); + free(zTitle); + + zSQL = mprintf("%s AND event.objid IN " + " (SELECT rid FROM tagxref WHERE tagid=" + "(SELECT tagid FROM tag WHERE tagname='wiki-%q'))" + "ORDER BY mtime DESC", + timeline_query_for_www(), zPageName); + db_prepare(&q, zSQL); + free(zSQL); + www_print_timeline(&q, 0, 0, 0, 0); + db_finalize(&q); + style_footer(); } /* -** WEBPAGE: ambiguous +** WEBPAGE: wcontent ** -** This is the destination for UUID hyperlinks that are ambiguous. -** Show all possible choices for the destination with links to each. -** -** The ambiguous UUID prefix is in g.zExtra +** List all available wiki pages with date created and last modified. */ -void ambiguous_page(void){ +void wcontent_page(void){ Stmt q; - style_header("Ambiguous UUID"); - @ <p>The link <a href="%s(g.zBaseURL)/ambiguous/%T(g.zExtra)"> - @ [%h(g.zExtra)]</a> is ambiguous. It might mean any of the following:</p> + login_check_credentials(); + if( !g.okRdWiki ){ login_needed(); return; } + style_header("Available Wiki Pages"); @ <ul> - db_prepare(&q, "SELECT uuid, rid FROM blob WHERE uuid>=%Q AND uuid<'%qz'" - " ORDER BY uuid", g.zExtra, g.zExtra); + db_prepare(&q, + "SELECT substr(tagname, 6, 1000) FROM tag WHERE tagname GLOB 'wiki-*'" + " ORDER BY lower(tagname)" + ); while( db_step(&q)==SQLITE_ROW ){ - const char *zUuid = db_column_text(&q, 0); - int rid = db_column_int(&q, 1); - @ <li> %s(zUuid) - %d(rid) + const char *zName = db_column_text(&q, 0); + @ <li><a href="%s(g.zBaseURL)/wiki?name=%T(zName)">%h(zName)</a></li> } db_finalize(&q); @ </ul> style_footer(); } + +/* +** WEBPAGE: wiki_rules +*/ +void wikirules_page(void){ + style_header("Wiki Formatting Rules"); + @ <h2>Formatting Rule Summary</h2> + @ <ol> + @ <li> Blank lines are paragraph breaks + @ <li> Bullet list items are a "*" at the beginning of the line. + @ <li> Enumeration list items are a number at the beginning of a line. + @ <li> Indented pargraphs begin with a tab or two spaces. + @ <li> Hyperlinks are contained with square brackets: "[target]" + @ <li> Most ordinary HTML works. + @ <li> <verbatim> and <nowiki>. + @ </ol> + @ <p>We call the first five rules above "wiki" formatting rules. The + @ last two rules are the HTML formatting rule.</p> + @ <h2>Formatting Rule Details</h2> + @ <ol> + @ <li> <p><b>Paragraphs</b>. Any sequence of one or more blank lines forms + @ a paragraph break. Centered or right-justified paragraphs are not + @ supported by wiki markup, but you can do these things if you need them + @ using HTML.</p> + @ <li> <p><b>Bullet Lists</b>. + @ A bullet list item begins with a single "*" character surrounded on + @ both sides by two or more spaces or by a tab. Only a single level + @ of bullet list is supported by wiki. For tested lists, use HTML.</p> + @ <li> <p><b>Enumeration Lists</b>. + @ An enumeration list item begins with one or more digits optionally + @ followed by a "." surrounded on both sides by two or more spaces or + @ by a tab. The number is significant and becomes the number shown + @ in the rendered enumeration item. Only a single level of enumeration + @ list is supported by wiki. For nested enumerations or for + @ enumerations that count using letters or roman numerials, use HTML.</p> + @ <li> <p><b>Indented Paragraphs</b>. + @ Any paragraph that begins with two or more spaces or a tab and + @ which is not a bullet or enumeration list item is rendered + @ indented. Only a single level of indentation is supported by</p> + @ <li> <p><b>Hyperlinks</b>. + @ Text within square brackets ("[...]") becomes a hyperlink. The + @ target can be a wiki page name, the UUID of a check-in or ticket, + @ the name of an image, or a URL. By default, the target is displayed + @ as the text of the hyperlink. But you can specify alternative text + @ after the target name separated by a "|" character.</p> + @ <li> <p><b>HTML</b>. + @ The following standard HTML elements may be used: + @ <a> + @ <address> + @ <b> + @ <big> + @ <blockquote> + @ <br> + @ <center> + @ <cite> + @ <code> + @ <dd> + @ <dfn> + @ <dl> + @ <dt> + @ <em> + @ <font> + @ <h1> + @ <h2> + @ <h3> + @ <h4> + @ <h5> + @ <h6> + @ <hr> + @ <img> + @ <i> + @ <kbd> + @ <li> + @ <nobr> + @ <ol> + @ <p> + @ <pre> + @ <s> + @ <samp> + @ <small> + @ <strike> + @ <strong> + @ <sub> + @ <sup> + @ <table> + @ <td> + @ <th> + @ <tr> + @ <tt> + @ <u> + @ <ul> + @ <var>. + @ In addition, there are two non-standard elements available: + @ <verbatim> and <nowiki>. + @ No other elements are allowed. All attributes are checked and + @ only a few benign attributes are allowed on each element. + @ In particular, any attributes that specify javascript or CSS + @ are elided.</p> + @ <p>The <verbatim> tag disables all wiki and HTML markup + @ up through the next </verbatim>. The <nowiki> tag + @ disables all wiki formatting rules through the matching + @ </nowiki> element. + @ </ol> + style_footer(); +} +
Modified src/wikiformat.c from [a4e0918f23] to [8bd2fe1f58].
@@ -31,45 +31,49 @@ /* ** Allowed wiki transformation operations */ #define WIKI_NOFOLLOW 0x001 #define WIKI_HTML 0x002 +#define WIKI_INLINE 0x004 /* Do not surround with <p>..</p> */ +#define WIKI_NOBLOCK 0x008 /* No block markup of any kind */ #endif /* ** These are the only markup attributes allowed. */ -#define ATTR_ALIGN 0x000001 -#define ATTR_ALT 0x000002 -#define ATTR_BGCOLOR 0x000004 -#define ATTR_BORDER 0x000008 -#define ATTR_CELLPADDING 0x000010 -#define ATTR_CELLSPACING 0x000020 -#define ATTR_CLEAR 0x000040 -#define ATTR_COLOR 0x000080 -#define ATTR_COLSPAN 0x000100 -#define ATTR_COMPACT 0x000200 -#define ATTR_FACE 0x000400 -#define ATTR_HEIGHT 0x000800 -#define ATTR_HREF 0x001000 -#define ATTR_HSPACE 0x002000 -#define ATTR_ID 0x004000 -#define ATTR_ROWSPAN 0x008000 -#define ATTR_SIZE 0x010000 -#define ATTR_SRC 0x020000 -#define ATTR_START 0x040000 -#define ATTR_TYPE 0x080000 -#define ATTR_VALIGN 0x100000 -#define ATTR_VALUE 0x200000 -#define ATTR_VSPACE 0x400000 -#define ATTR_WIDTH 0x800000 +#define ATTR_ALIGN 0x0000001 +#define ATTR_ALT 0x0000002 +#define ATTR_BGCOLOR 0x0000004 +#define ATTR_BORDER 0x0000008 +#define ATTR_CELLPADDING 0x0000010 +#define ATTR_CELLSPACING 0x0000020 +#define ATTR_CLEAR 0x0000040 +#define ATTR_COLOR 0x0000080 +#define ATTR_COLSPAN 0x0000100 +#define ATTR_COMPACT 0x0000200 +#define ATTR_FACE 0x0000400 +#define ATTR_HEIGHT 0x0000800 +#define ATTR_HREF 0x0001000 +#define ATTR_HSPACE 0x0002000 +#define ATTR_ID 0x0004000 +#define ATTR_NAME 0x0008000 +#define ATTR_ROWSPAN 0x0010000 +#define ATTR_SIZE 0x0020000 +#define ATTR_SRC 0x0040000 +#define ATTR_START 0x0080000 +#define ATTR_TYPE 0x0100000 +#define ATTR_VALIGN 0x0200000 +#define ATTR_VALUE 0x0400000 +#define ATTR_VSPACE 0x0800000 +#define ATTR_WIDTH 0x1000000 static const struct AllowedAttribute { const char *zName; unsigned int iMask; } aAttribute[] = { + { 0, 0 }, { "align", ATTR_ALIGN, }, { "alt", ATTR_ALT, }, { "bgcolor", ATTR_BGCOLOR, }, { "border", ATTR_BORDER, }, { "cellpadding", ATTR_CELLPADDING, }, @@ -81,10 +85,11 @@ { "face", ATTR_FACE, }, { "height", ATTR_HEIGHT, }, { "href", ATTR_HREF, }, { "hspace", ATTR_HSPACE, }, { "id", ATTR_ID, }, + { "name", ATTR_NAME, }, { "rowspan", ATTR_ROWSPAN, }, { "size", ATTR_SIZE, }, { "src", ATTR_SRC, }, { "start", ATTR_START, }, { "type", ATTR_TYPE, }, @@ -97,17 +102,17 @@ /* ** Use binary search to locate a tag in the aAttribute[] table. */ static int findAttr(const char *z){ int i, c, first, last; - first = 0; + first = 1; last = sizeof(aAttribute)/sizeof(aAttribute[0]) - 1; while( first<=last ){ i = (first+last)/2; c = strcmp(aAttribute[i].zName, z); if( c==0 ){ - return aAttribute[i].iMask; + return i; }else if( c<0 ){ first = i+1; }else{ last = i-1; } @@ -123,87 +128,96 @@ ** Except for MARKUP_INVALID, this must all be in alphabetical order ** and in numerical sequence. The first markup type must be zero. ** The value for MARKUP_XYZ must correspond to the <xyz> entry ** in aAllowedMarkup[]. */ -#define MARKUP_INVALID 255 -#define MARKUP_A 0 -#define MARKUP_ADDRESS 1 -#define MARKUP_BIG 2 -#define MARKUP_BLOCKQUOTE 3 -#define MARKUP_B 4 -#define MARKUP_BR 5 -#define MARKUP_CENTER 6 -#define MARKUP_CITE 7 -#define MARKUP_CODE 8 -#define MARKUP_DD 9 -#define MARKUP_DFN 10 -#define MARKUP_DL 11 -#define MARKUP_DT 12 -#define MARKUP_EM 13 -#define MARKUP_FONT 14 -#define MARKUP_H1 15 -#define MARKUP_H2 16 -#define MARKUP_H3 17 -#define MARKUP_H4 18 -#define MARKUP_H5 19 -#define MARKUP_H6 20 -#define MARKUP_HR 21 -#define MARKUP_IMG 22 -#define MARKUP_I 23 -#define MARKUP_KBD 24 -#define MARKUP_LI 25 -#define MARKUP_NOBR 26 -#define MARKUP_NOWIKI 27 -#define MARKUP_OL 28 -#define MARKUP_P 29 -#define MARKUP_PRE 30 -#define MARKUP_SAMP 31 -#define MARKUP_SMALL 32 -#define MARKUP_S 33 -#define MARKUP_STRIKE 34 -#define MARKUP_STRONG 35 -#define MARKUP_SUB 36 -#define MARKUP_SUP 37 -#define MARKUP_TABLE 38 -#define MARKUP_TD 39 -#define MARKUP_TH 40 -#define MARKUP_TR 41 -#define MARKUP_TT 42 -#define MARKUP_UL 43 +#define MARKUP_INVALID 0 +#define MARKUP_A 1 +#define MARKUP_ADDRESS 2 +#define MARKUP_B 3 +#define MARKUP_BIG 4 +#define MARKUP_BLOCKQUOTE 5 +#define MARKUP_BR 6 +#define MARKUP_CENTER 7 +#define MARKUP_CITE 8 +#define MARKUP_CODE 9 +#define MARKUP_DD 10 +#define MARKUP_DFN 11 +#define MARKUP_DL 12 +#define MARKUP_DT 13 +#define MARKUP_EM 14 +#define MARKUP_FONT 15 +#define MARKUP_H1 16 +#define MARKUP_H2 17 +#define MARKUP_H3 18 +#define MARKUP_H4 19 +#define MARKUP_H5 20 +#define MARKUP_H6 21 +#define MARKUP_HR 22 +#define MARKUP_IMG 23 +#define MARKUP_I 24 +#define MARKUP_KBD 25 +#define MARKUP_LI 26 +#define MARKUP_NOBR 27 +#define MARKUP_NOWIKI 28 +#define MARKUP_OL 29 +#define MARKUP_P 30 +#define MARKUP_PRE 31 +#define MARKUP_S 32 +#define MARKUP_SAMP 33 +#define MARKUP_SMALL 34 +#define MARKUP_STRIKE 35 +#define MARKUP_STRONG 36 +#define MARKUP_SUB 37 +#define MARKUP_SUP 38 +#define MARKUP_TABLE 39 +#define MARKUP_TD 40 +#define MARKUP_TH 41 +#define MARKUP_TR 42 +#define MARKUP_TT 43 #define MARKUP_U 44 -#define MARKUP_VAR 45 -#define MARKUP_VERBATIM 46 +#define MARKUP_UL 45 +#define MARKUP_VAR 46 +#define MARKUP_VERBATIM 47 /* ** The various markup is divided into the following types: */ #define MUTYPE_SINGLE 0x0001 /* <img>, <br>, or <hr> */ #define MUTYPE_BLOCK 0x0002 /* Forms a new paragraph. ex: <p>, <h2> */ #define MUTYPE_FONT 0x0004 /* Font changes. ex: <b>, <font>, <sub> */ -#define MUTYPE_LINK 0x0008 /* Hyperlink: <a> */ #define MUTYPE_LIST 0x0010 /* Lists. <ol>, <ul>, or <dl> */ #define MUTYPE_LI 0x0020 /* List items. <li>, <dd>, <dt> */ #define MUTYPE_TABLE 0x0040 /* <table> */ #define MUTYPE_TR 0x0080 /* <tr> */ #define MUTYPE_TD 0x0100 /* <td> or <th> */ #define MUTYPE_SPECIAL 0x0200 /* <nowiki> or <verbatim> */ #define MUTYPE_HYPERLINK 0x0400 /* <a> */ +/* +** These markup types must have an end tag. +*/ #define MUTYPE_STACK (MUTYPE_BLOCK | MUTYPE_FONT | MUTYPE_LIST | MUTYPE_TABLE) + +/* +** This markup types are allowed for "inline" text. +*/ +#define MUTYPE_INLINE (MUTYPE_FONT | MUTYPE_HYPERLINK) static const struct AllowedMarkup { const char *zName; /* Name of the markup */ char iCode; /* The MARKUP_* code */ short int iType; /* The MUTYPE_* code */ int allowedAttr; /* Allowed attributes on this markup */ } aMarkup[] = { - { "a", MARKUP_A, MUTYPE_HYPERLINK, ATTR_HREF }, + { 0, MARKUP_INVALID, 0, 0 }, + { "a", MARKUP_A, MUTYPE_HYPERLINK, + ATTR_HREF|ATTR_NAME }, { "address", MARKUP_ADDRESS, MUTYPE_BLOCK, 0 }, + { "b", MARKUP_B, MUTYPE_FONT, 0 }, { "big", MARKUP_BIG, MUTYPE_FONT, 0 }, { "blockquote", MARKUP_BLOCKQUOTE, MUTYPE_BLOCK, 0 }, - { "b", MARKUP_B, MUTYPE_FONT, 0 }, { "br", MARKUP_BR, MUTYPE_SINGLE, ATTR_CLEAR }, { "center", MARKUP_CENTER, MUTYPE_BLOCK, 0 }, { "cite", MARKUP_CITE, MUTYPE_FONT, 0 }, { "code", MARKUP_CODE, MUTYPE_FONT, 0 }, { "dd", MARKUP_DD, MUTYPE_LI, 0 }, @@ -232,13 +246,13 @@ { "nowiki", MARKUP_NOWIKI, MUTYPE_SPECIAL, 0 }, { "ol", MARKUP_OL, MUTYPE_LIST, ATTR_START|ATTR_TYPE|ATTR_COMPACT }, { "p", MARKUP_P, MUTYPE_BLOCK, ATTR_ALIGN }, { "pre", MARKUP_PRE, MUTYPE_BLOCK, 0 }, + { "s", MARKUP_S, MUTYPE_FONT, 0 }, { "samp", MARKUP_SAMP, MUTYPE_FONT, 0 }, { "small", MARKUP_SMALL, MUTYPE_FONT, 0 }, - { "s", MARKUP_S, MUTYPE_FONT, 0 }, { "strike", MARKUP_STRIKE, MUTYPE_FONT, 0 }, { "strong", MARKUP_STRONG, MUTYPE_FONT, 0 }, { "sub", MARKUP_SUB, MUTYPE_FONT, 0 }, { "sup", MARKUP_SUP, MUTYPE_FONT, 0 }, { "table", MARKUP_TABLE, MUTYPE_TABLE, @@ -251,23 +265,23 @@ ATTR_ALIGN|ATTR_BGCOLOR|ATTR_COLSPAN| ATTR_ROWSPAN|ATTR_VALIGN }, { "tr", MARKUP_TR, MUTYPE_TR, ATTR_ALIGN|ATTR_BGCOLOR||ATTR_VALIGN }, { "tt", MARKUP_TT, MUTYPE_FONT, 0 }, + { "u", MARKUP_U, MUTYPE_FONT, 0 }, { "ul", MARKUP_UL, MUTYPE_LIST, ATTR_TYPE|ATTR_COMPACT }, - { "u", MARKUP_U, MUTYPE_FONT, 0 }, { "var", MARKUP_VAR, MUTYPE_FONT, 0 }, { "verbatim", MARKUP_VERBATIM, MUTYPE_SPECIAL, ATTR_ID }, }; /* ** Use binary search to locate a tag in the aMarkup[] table. */ static int findTag(const char *z){ int i, c, first, last; - first = 0; + first = 1; last = sizeof(aMarkup)/sizeof(aMarkup[0]) - 1; while( first<=last ){ i = (first+last)/2; c = strcmp(aMarkup[i].zName, z); if( c==0 ){ @@ -296,15 +310,35 @@ #define TOKEN_TEXT 9 /* None of the above */ /* ** State flags */ -#define AT_NEWLINE 0x001 /* At start of a line */ -#define AT_PARAGRAPH 0x002 /* At start of a paragraph */ -#define ALLOW_WIKI 0x004 /* Allow wiki markup */ -#define FONT_MARKUP_ONLY 0x008 /* Only allow MUTYPE_FONT markup */ -#define IN_LIST 0x010 /* Within <ul> */ +#define AT_NEWLINE 0x001 /* At start of a line */ +#define AT_PARAGRAPH 0x002 /* At start of a paragraph */ +#define ALLOW_WIKI 0x004 /* Allow wiki markup */ +#define FONT_MARKUP_ONLY 0x008 /* Only allow MUTYPE_FONT markup */ +#define INLINE_MARKUP_ONLY 0x010 /* Allow only "inline" markup */ +#define IN_LIST 0x020 /* Within wiki <ul> or <ol> */ + +/* +** Current state of the rendering engine +*/ +typedef struct Renderer Renderer; +struct Renderer { + Blob *pOut; /* Output appended to this blob */ + int state; /* Flag that govern rendering */ + int wikiList; /* Current wiki list type */ + int inVerbatim; /* True in <verbatim> mode */ + int preVerbState; /* Value of state prior to verbatim */ + int wantAutoParagraph; /* True if a <p> is desired */ + int inAutoParagraph; /* True if within an automatic paragraph */ + const char *zVerbatimId; /* The id= attribute of <verbatim> */ + int nStack; /* Number of elements on the stack */ + int nAlloc; /* Space allocated for aStack */ + unsigned char *aStack; /* Open markup stack */ +}; + /* ** z points to a "<" character. Check to see if this is the start of ** a valid markup. If it is, return the total number of characters in ** the markup including the initial "<" and the terminating ">". If @@ -313,11 +347,11 @@ static int markupLength(const char *z){ int n = 1; int inparen = 0; if( z[n]=='/' ){ n++; } if( !isalpha(z[n]) ) return 0; - while( isalpha(z[n]) ){ n++; } + while( isalnum(z[n]) ){ n++; } if( z[n]!='>' && !isspace(z[n]) ) return 0; while( z[n] && (z[n]!='>' || inparen) ){ if( z[n]=='"' ){ inparen = !inparen; } @@ -412,10 +446,46 @@ if( i<2 || isspace(z[n]) ) return 0; return n; } /* +** Check to see if the z[] string is the beginning of a enumeration value. +** If it is, return the length of the bullet text. Otherwise return 0. +** +** Syntax: +** * a tab or two or more spaces +** * one or more digits +** * optional "." +** * another tab or two ore more spaces. +** +*/ +static int enumLength(const char *z){ + int i, n; + n = 0; + i = 0; + while( z[n]==' ' || z[n]=='\t' ){ + if( z[n]=='\t' ) i++; + i++; + n++; + } + if( i<2 ) return 0; + for(i=0; isdigit(z[n]); i++, n++){} + if( i==0 ) return 0; + if( z[n]=='.' ){ + n++; + } + i = 0; + while( z[n]==' ' || z[n]=='\t' ){ + if( z[n]=='\t' ) i++; + i++; + n++; + } + if( i<2 || isspace(z[n]) ) return 0; + return n; +} + +/* ** Check to see if the z[] string is the beginning of an indented ** paragraph. If it is, return the length of the indent. Otherwise ** return 0. */ static int indentLength(const char *z){ @@ -449,11 +519,11 @@ /* ** z points to the start of a token. Return the number of ** characters in that token. Write the token type into *pTokenType. */ -static int nextToken(const char *z, int state, int *pTokenType){ +static int nextToken(const char *z, Renderer *p, int *pTokenType){ int n; if( z[0]=='<' ){ n = markupLength(z); if( n>0 ){ *pTokenType = TOKEN_MARKUP; @@ -461,15 +531,15 @@ }else{ *pTokenType = TOKEN_CHARACTER; return 1; } } - if( z[0]=='&' && !isElement(z) ){ + if( z[0]=='&' && (p->inVerbatim || !isElement(z)) ){ *pTokenType = TOKEN_CHARACTER; return 1; } - if( (state & ALLOW_WIKI)!=0 ){ + if( (p->state & ALLOW_WIKI)!=0 ){ if( z[0]=='\n' ){ n = paragraphBreakLength(z); if( n>0 ){ *pTokenType = TOKEN_PARAGRAPH; return n; @@ -476,26 +546,23 @@ }else if( isspace(z[1]) ){ *pTokenType = TOKEN_NEWLINE; return 1; } } - if( (state & AT_NEWLINE)!=0 /* && (state & (AT_PARAGRAPH|IN_LIST))!=0 */ - && isspace(z[0]) ){ + if( (p->state & AT_NEWLINE)!=0 && isspace(z[0]) ){ n = bulletLength(z); if( n>0 ){ *pTokenType = TOKEN_BULLET; return n; } -#if 0 n = enumLength(z); if( n>0 ){ *pTokenType = TOKEN_ENUM; return n; } -#endif } - if( (state & AT_PARAGRAPH)!=0 && isspace(z[0]) ){ + if( (p->state & AT_PARAGRAPH)!=0 && isspace(z[0]) ){ n = indentLength(z); if( n>0 ){ *pTokenType = TOKEN_INDENT; return n; } @@ -504,11 +571,11 @@ *pTokenType = TOKEN_LINK; return n; } } *pTokenType = TOKEN_TEXT; - return 1 + textLength(z+1, state & ALLOW_WIKI); + return 1 + textLength(z+1, p->state & ALLOW_WIKI); } /* ** A single markup is parsed into an instance of the following ** structure. @@ -604,11 +671,11 @@ if( p->endTag ){ blob_appendf(pOut, "</%s>", aMarkup[p->iCode].zName); }else{ blob_appendf(pOut, "<%s", aMarkup[p->iCode].zName); for(i=0; i<p->nAttr; i++){ - blob_appendf(pOut, " %s", aAttribute[p->aAttr[i].iCode]); + blob_appendf(pOut, " %s", aAttribute[p->aAttr[i].iCode].zName); if( p->aAttr[i].zValue ){ blob_appendf(pOut, "=\"%s\"", p->aAttr[i].zValue); } } blob_append(pOut, ">", 1); @@ -627,25 +694,10 @@ if( z==0 ) continue; n = strlen(z); z[n] = p->aAttr[i].cTerm; } } - -/* -** Current state of the rendering engine -*/ -typedef struct Renderer Renderer; -struct Renderer { - Blob *pOut; /* Output appended to this blob */ - int state; /* Flag that govern rendering */ - int inVerbatim; /* True in <verbatim> mode */ - int preVerbState; /* Value of state prior to verbatim */ - const char *zVerbatimId; /* The id= attribute of <verbatim> */ - int nStack; /* Number of elements on the stack */ - int nAlloc; /* Space allocated for aStack */ - unsigned char *aStack; /* Open markup stack */ -}; /* ** Pop a single element off of the stack. As the element is popped, ** output its end tag. */ @@ -686,41 +738,78 @@ } /* ** Pop the stack until the top-most element of the stack ** is an element that matches the type in iMask. Return -** true on success. If the stack does not have an element +** code of the markup element that is on left on top of the stack. +** If the stack does not have an element ** that matches iMask, then leave the stack unchanged and -** return false. +** return false (MARKUP_INVALID). */ static int backupToType(Renderer *p, int iMask){ int i; for(i=p->nStack-1; i>=0 && (aMarkup[p->aStack[i]].iType&iMask)==0; i--){} if( i<0 ) return 0; i++; while( p->nStack>i ){ popStack(p); } - return 1; + return p->aStack[i-1]; +} + +/* +** Begin a new paragraph if that something that is needed. +*/ +static void startAutoParagraph(Renderer *p){ + if( p->wantAutoParagraph==0 ) return; + blob_appendf(p->pOut, "<p>", -1); + pushStack(p, MARKUP_P); + p->wantAutoParagraph = 0; + p->inAutoParagraph = 1; +} + +/* +** End a paragraph if we are in one. +*/ +static void endAutoParagraph(Renderer *p){ + if( p->inAutoParagraph ){ + popStackToTag(p, MARKUP_P); + p->inAutoParagraph = 0; + } } /* -** Add missing markup in preparation for writing text. -** -** "Missing" markup are things like start tags for table rows -** or table columns or paragraphs that are omitted from input. +** If the input string corresponds to an existing baseline, +** return true. */ -static void addMissingMarkup(Renderer *p){ - /* TBD */ +static int is_valid_uuid(const char *z){ + int n = strlen(z); + if( n<4 || n>UUID_SIZE ) return 0; + if( !validate16(z, n) ) return 0; + return 1; } /* ** Resolve a hyperlink. The argument is the content of the [...] ** in the wiki. Append the URL to the output of the Renderer. */ static void resolveHyperlink(const char *zTarget, Renderer *p){ - blob_appendf(p->pOut, "http://www.fossil-scm.org/test-%T", zTarget); + if( strncmp(zTarget, "http:", 5)==0 + || strncmp(zTarget, "https:", 6)==0 + || strncmp(zTarget, "ftp:", 4)==0 + || strncmp(zTarget, "mailto:", 7)==0 + ){ + blob_appendf(p->pOut, zTarget); + }else if( zTarget[0]=='/' ){ + blob_appendf(p->pOut, "%s%h", g.zBaseURL, zTarget); + }else if( is_valid_uuid(zTarget) ){ + blob_appendf(p->pOut, "%s/info/%s", g.zBaseURL, zTarget); + }else if( wiki_name_is_wellformed(zTarget) ){ + blob_appendf(p->pOut, "%s/wiki?name=%T", g.zBaseURL, zTarget); + }else{ + blob_appendf(p->pOut, "error"); + } } /* ** Check to see if the given parsed markup is the correct ** </verbatim> tag. @@ -752,36 +841,87 @@ */ static void wiki_render(Renderer *p, char *z){ int tokenType; ParsedMarkup markup; int n; + int inlineOnly = (p->state & INLINE_MARKUP_ONLY)!=0; while( z[0] ){ - n = nextToken(z, p->state, &tokenType); + n = nextToken(z, p, &tokenType); p->state &= ~(AT_NEWLINE|AT_PARAGRAPH); switch( tokenType ){ case TOKEN_PARAGRAPH: { - blob_append(p->pOut, "\n\n<p>", -1); - p->state |= AT_PARAGRAPH|AT_NEWLINE; - popStackToTag(p, MARKUP_P); + if( inlineOnly ){ + /* blob_append(p->pOut, " ¶ ", -1); */ + blob_append(p->pOut, " ", -1); + }else{ + if( p->wikiList ){ + popStackToTag(p, p->wikiList); + p->wikiList = 0; + } + endAutoParagraph(p); + blob_appendf(p->pOut, "\n\n", 1); + p->wantAutoParagraph = 1; + } + p->state |= AT_PARAGRAPH|AT_NEWLINE; break; } case TOKEN_NEWLINE: { blob_append(p->pOut, "\n", 1); p->state |= AT_NEWLINE; break; } case TOKEN_BULLET: { - if( backupToType(p, MUTYPE_LIST)==0 ){ - pushStack(p, MARKUP_UL); - blob_append(p->pOut, "<ul>", 4); + if( inlineOnly ){ + blob_append(p->pOut, " • ", -1); + }else{ + if( p->wikiList!=MARKUP_UL ){ + if( p->wikiList ){ + popStackToTag(p, p->wikiList); + } + pushStack(p, MARKUP_UL); + blob_append(p->pOut, "<ul>", 4); + p->wikiList = MARKUP_UL; + } + popStackToTag(p, MARKUP_LI); + startAutoParagraph(p); + pushStack(p, MARKUP_LI); + blob_append(p->pOut, "<li>", 4); + } + break; + } + case TOKEN_ENUM: { + if( inlineOnly ){ + blob_appendf(p->pOut, " (%d) ", atoi(z)); + }else{ + if( p->wikiList!=MARKUP_OL ){ + if( p->wikiList ){ + popStackToTag(p, p->wikiList); + } + pushStack(p, MARKUP_OL); + blob_append(p->pOut, "<ol>", 4); + p->wikiList = MARKUP_OL; + } + popStackToTag(p, MARKUP_LI); + startAutoParagraph(p); + pushStack(p, MARKUP_LI); + blob_appendf(p->pOut, "<li value=\"%d\">", atoi(z)); } - pushStack(p, MARKUP_LI); - blob_append(p->pOut, "<li>", 4); + break; + } + case TOKEN_INDENT: { + if( inlineOnly ){ + assert( p->wikiList==0 ); + pushStack(p, MARKUP_BLOCKQUOTE); + blob_append(p->pOut, "<blockquote>", -1); + p->wantAutoParagraph = 0; + p->wikiList = MARKUP_BLOCKQUOTE; + } break; } case TOKEN_CHARACTER: { + startAutoParagraph(p); if( z[0]=='<' ){ blob_append(p->pOut, "<", 4); }else if( z[0]=='&' ){ blob_append(p->pOut, "&", 5); } @@ -788,18 +928,19 @@ break; } case TOKEN_LINK: { char *zTarget; char *zDisplay = 0; - int i; + int i, j; int savedState; - addMissingMarkup(p); + startAutoParagraph(p); zTarget = &z[1]; for(i=1; z[i] && z[i]!=']'; i++){ if( z[i]=='|' && zDisplay==0 ){ zDisplay = &z[i+1]; z[i] = 0; + for(j=i-1; j>0 && isspace(z[j]); j--){ z[j] = 0; } } } z[i] = 0; if( zDisplay==0 ){ zDisplay = zTarget; @@ -816,11 +957,11 @@ p->state = savedState; blob_append(p->pOut, "</a>", 4); break; } case TOKEN_TEXT: { - addMissingMarkup(p); + startAutoParagraph(p); blob_append(p->pOut, z, n); break; } case TOKEN_MARKUP: { parseMarkup(&markup, z); @@ -833,20 +974,24 @@ unparseMarkup(&markup); blob_append(p->pOut, "<", 4); n = 1; } }else if( markup.iCode==MARKUP_INVALID ){ + unparseMarkup(&markup); + startAutoParagraph(p); blob_append(p->pOut, "<", 4); n = 1; }else if( (markup.iType&MUTYPE_FONT)==0 && (p->state & FONT_MARKUP_ONLY)!=0 ){ /* Do nothing */ + }else if( inlineOnly && (markup.iType&MUTYPE_INLINE)==0 ){ + /* Do nothing */ }else if( markup.iCode==MARKUP_NOWIKI ){ if( markup.endTag ){ p->state |= ALLOW_WIKI; }else{ - p->state &= ALLOW_WIKI; + p->state &= ~ALLOW_WIKI; } }else if( markup.endTag ){ popStackToTag(p, markup.iCode); }else if( markup.iCode==MARKUP_VERBATIM ){ if( markup.nAttr==1 ){ @@ -856,10 +1001,11 @@ } p->inVerbatim = 1; p->preVerbState = p->state; p->state &= ~ALLOW_WIKI; blob_append(p->pOut, "<pre>", 5); + p->wantAutoParagraph = 0; }else if( markup.iType==MUTYPE_LI ){ if( backupToType(p, MUTYPE_LIST)==0 ){ pushStack(p, MARKUP_UL); blob_append(p->pOut, "<ul>", 4); } @@ -877,11 +1023,21 @@ blob_append(p->pOut, "<tr>", 4); } pushStack(p, markup.iCode); renderMarkup(p->pOut, &markup); } + }else if( markup.iType==MUTYPE_HYPERLINK ){ + popStackToTag(p, markup.iCode); + startAutoParagraph(p); + renderMarkup(p->pOut, &markup); + pushStack(p, markup.iCode); }else{ + if( markup.iType==MUTYPE_FONT ){ + startAutoParagraph(p); + }else if( markup.iType==MUTYPE_BLOCK ){ + p->wantAutoParagraph = 0; + } if( (markup.iType & MUTYPE_STACK )!=0 ){ pushStack(p, markup.iCode); } renderMarkup(p->pOut, &markup); } @@ -895,50 +1051,49 @@ /* ** Transform the text in the pIn blob. Write the results ** into the pOut blob. The pOut blob should already be ** initialized. The output is merely appended to pOut. -** -** The transformations carried out depend on the ops flag: -** -** WIKI_NOFOLLOW -** -** * Add the nofollow attribute to external links -** -** WIKI_HTML -** -** * Convert wiki into HTML -** * Remove <nowiki> and <verbatium> -** * Convert & into & -** * Unrecognized markup and markup within <verbatim> -** is converted into <...> -** * Unauthorized attributes on markup are removed +** If pOut is NULL, then the output is appended to the CGI +** reply. */ -void wiki_convert(Blob *pIn, Blob *pOut, int ops){ +void wiki_convert(Blob *pIn, Blob *pOut, int flags){ char *z; Renderer renderer; memset(&renderer, 0, sizeof(renderer)); renderer.state = ALLOW_WIKI|AT_NEWLINE|AT_PARAGRAPH; - renderer.pOut = pOut; + if( flags & WIKI_NOBLOCK ){ + renderer.state |= INLINE_MARKUP_ONLY; + } + if( flags & WIKI_INLINE ){ + renderer.wantAutoParagraph = 0; + }else{ + renderer.wantAutoParagraph = 1; + } + if( pOut ){ + renderer.pOut = pOut; + }else{ + renderer.pOut = cgi_output_blob(); + } z = blob_str(pIn); wiki_render(&renderer, z); + endAutoParagraph(&renderer); while( renderer.nStack ){ popStack(&renderer); } - blob_append(pOut, "\n", 1); + blob_append(renderer.pOut, "\n", 1); free(renderer.aStack); } - /* ** COMMAND: test-wiki-render */ void test_wiki_render(void){ Blob in, out; if( g.argc!=3 ) usage("FILE"); blob_zero(&out); blob_read_from_file(&in, g.argv[2]); - wiki_convert(&in, &out, WIKI_HTML); + wiki_convert(&in, &out, 0); blob_write_to_file(&out, "-"); }
Modified src/xfer.c from [1a89a70762] to [fe8089aded].
@@ -91,10 +91,11 @@ ** be initialized to an empty string. */ static void xfer_accept_file(Xfer *pXfer){ int n; int rid; + int srcid = 0; Blob content, hash; if( pXfer->nToken<3 || pXfer->nToken>4 || !blob_is_uuid(&pXfer->aToken[1]) @@ -106,13 +107,17 @@ return; } blob_zero(&content); blob_zero(&hash); blob_extract(pXfer->pIn, n, &content); + if( db_exists("SELECT 1 FROM shun WHERE uuid=%B", &pXfer->aToken[1]) ){ + /* Ignore files that have been shunned */ + return; + } if( pXfer->nToken==4 ){ Blob src; - int srcid = rid_from_uuid(&pXfer->aToken[2], 1); + srcid = rid_from_uuid(&pXfer->aToken[2], 1); if( content_get(srcid, &src)==0 ){ content_put(&content, blob_str(&pXfer->aToken[1]), srcid); blob_appendf(pXfer->pOut, "gimme %b\n", &pXfer->aToken[2]); pXfer->nGimmeSent++; pXfer->nDanglingFile++; @@ -137,35 +142,38 @@ } remote_has(rid); } /* -** Try to send a file as a delta. If successful, return the number -** of bytes in the delta. If not, return zero. -** -** If srcId is specified, use it. If not, try to figure out a -** reasonable srcId. -*/ -static int send_as_delta( +** Try to send a file as a delta against its parent. +** If successful, return the number of bytes in the delta. +** If we cannot generate an appropriate delta, then send +** nothing and return zero. +*/ +static int send_delta_parent( Xfer *pXfer, /* The transfer context */ int rid, /* record id of the file to send */ Blob *pContent, /* The content of the file to send */ - Blob *pUuid, /* The UUID of the file to send */ - int srcId /* Send as a delta against this record */ + Blob *pUuid /* The UUID of the file to send */ ){ static const char *azQuery[] = { - "SELECT pid FROM plink" + "SELECT pid FROM plink x" " WHERE cid=%d" - " AND NOT EXISTS(SELECT 1 FROM phantom WHERE rid=pid)", - - "SELECT pid FROM mlink" + " AND NOT EXISTS(SELECT 1 FROM phantom WHERE rid=pid)" + " AND NOT EXISTS(SELECT 1 FROM plink y" + " WHERE y.pid=x.cid AND y.cid=x.pid)", + + "SELECT pid FROM mlink x" " WHERE fid=%d" - " AND NOT EXISTS(SELECT 1 FROM phantom WHERE rid=pid)", + " AND NOT EXISTS(SELECT 1 FROM phantom WHERE rid=pid)" + " AND NOT EXISTS(SELECT 1 FROM mlink y" + " WHERE y.pid=x.fid AND y.fid=x.pid)" }; int i; Blob src, delta; int size = 0; + int srcId = 0; for(i=0; srcId==0 && i<count(azQuery); i++){ srcId = db_int(0, azQuery[i], rid); } if( srcId>0 && content_get(srcId, &src) ){ @@ -185,21 +193,53 @@ } return size; } /* +** Try to send a file as a native delta. +** If successful, return the number of bytes in the delta. +** If we cannot generate an appropriate delta, then send +** nothing and return zero. +*/ +static int send_delta_native( + Xfer *pXfer, /* The transfer context */ + int rid, /* record id of the file to send */ + Blob *pUuid /* The UUID of the file to send */ +){ + Blob src, delta; + int size = 0; + int srcId; + + srcId = db_int(0, "SELECT srcid FROM delta WHERE rid=%d", rid); + if( srcId>0 ){ + blob_zero(&delta); + db_blob(&delta, "SELECT content FROM blob WHERE rid=%d", rid); + blob_uncompress(&delta, &delta); + blob_zero(&src); + db_blob(&src, "SELECT uuid FROM blob WHERE rid=%d", srcId); + blob_appendf(pXfer->pOut, "file %b %b %d\n", + pUuid, &src, blob_size(&delta)); + blob_append(pXfer->pOut, blob_buffer(&delta), blob_size(&delta)); + size = blob_size(&delta); + blob_reset(&delta); + blob_reset(&src); + }else{ + size = 0; + } + return size; +} + +/* ** Send the file identified by rid. ** ** The pUuid can be NULL in which case the correct UUID is computed ** from the rid. ** -** If srcId is positive, then a delta is sent against that srcId. -** If srcId is zero, then an attempt is made to find an appropriate -** file to delta against. If srcId is negative, the file is sent -** without deltaing. +** Try to send the file as a native delta if nativeDelta is true, or +** as a parent delta if nativeDelta is false. */ -static void send_file(Xfer *pXfer, int rid, Blob *pUuid, int srcId){ +static void send_file(Xfer *pXfer, int rid, Blob *pUuid, int nativeDelta){ Blob content, uuid; int size = 0; if( db_exists("SELECT 1 FROM onremote WHERE rid=%d", rid) ){ return; @@ -216,22 +256,30 @@ blob_appendf(pXfer->pOut, "igot %b\n", pUuid); pXfer->nIGotSent++; blob_reset(&uuid); return; } - content_get(rid, &content); - - if( blob_size(&content)>100 ){ - size = send_as_delta(pXfer, rid, &content, pUuid, srcId); + if( nativeDelta ){ + size = send_delta_native(pXfer, rid, pUuid); + if( size ){ + pXfer->nDeltaSent++; + } } if( size==0 ){ - int size = blob_size(&content); - blob_appendf(pXfer->pOut, "file %b %d\n", pUuid, size); - blob_append(pXfer->pOut, blob_buffer(&content), size); - pXfer->nFileSent++; - }else{ - pXfer->nDeltaSent++; + content_get(rid, &content); + + if( !nativeDelta && blob_size(&content)>100 ){ + size = send_delta_parent(pXfer, rid, &content, pUuid); + } + if( size==0 ){ + int size = blob_size(&content); + blob_appendf(pXfer->pOut, "file %b %d\n", pUuid, size); + blob_append(pXfer->pOut, blob_buffer(&content), size); + pXfer->nFileSent++; + }else{ + pXfer->nDeltaSent++; + } } remote_has(rid); blob_reset(&uuid); } @@ -238,11 +286,14 @@ /* ** Send a gimme message for every phantom. */ static void request_phantoms(Xfer *pXfer){ Stmt q; - db_prepare(&q, "SELECT uuid FROM phantom JOIN blob USING(rid)"); + db_prepare(&q, + "SELECT uuid FROM phantom JOIN blob USING(rid)" + " WHERE NOT EXISTS(SELECT 1 FROM shun WHERE uuid=blob.uuid)" + ); while( db_step(&q)==SQLITE_ROW ){ const char *zUuid = db_column_text(&q, 0); blob_appendf(pXfer->pOut, "gimme %s\n", zUuid); pXfer->nGimmeSent++; } @@ -375,11 +426,14 @@ ** Return the number of messages sent. */ static int send_unclustered(Xfer *pXfer){ Stmt q; int cnt = 0; - db_prepare(&q, "SELECT uuid FROM unclustered JOIN blob USING(rid)"); + db_prepare(&q, + "SELECT uuid FROM unclustered JOIN blob USING(rid)" + " WHERE NOT EXISTS(SELECT 1 FROM shun WHERE uuid=blob.uuid)" + ); while( db_step(&q)==SQLITE_ROW ){ blob_appendf(pXfer->pOut, "igot %s\n", db_column_text(&q, 0)); cnt++; } db_finalize(&q); @@ -402,10 +456,11 @@ void page_xfer(void){ int isPull = 0; int isPush = 0; int nErr = 0; Xfer xfer; + int deltaFlag = 0; memset(&xfer, 0, sizeof(xfer)); blobarray_zero(xfer.aToken, count(xfer.aToken)); cgi_set_content_type(g.zContentType); blob_zero(&xfer.err); @@ -450,11 +505,11 @@ && blob_is_uuid(&xfer.aToken[1]) ){ if( isPull ){ int rid = rid_from_uuid(&xfer.aToken[1], 0); if( rid ){ - send_file(&xfer, rid, &xfer.aToken[1], 0); + send_file(&xfer, rid, &xfer.aToken[1], deltaFlag); } } }else /* igot UUID @@ -515,16 +570,20 @@ break; } isPull = 1; }else{ if( !g.okWrite ){ - cgi_reset_content(); - @ error not\sauthorized\sto\swrite - nErr++; - break; - } - isPush = 1; + if( !isPull ){ + cgi_reset_content(); + @ error not\sauthorized\sto\swrite + nErr++; + }else{ + @ message pull\sonly\s-\snot\sauthorized\sto\spush + } + }else{ + isPush = 1; + } } }else /* clone ** @@ -537,10 +596,11 @@ @ error not\sauthorized\sto\sclone nErr++; break; } isPull = 1; + deltaFlag = 1; @ push %s(db_get("server-code", "x")) %s(db_get("project-code", "x")) }else /* login USER NONCE SIGNATURE ** @@ -698,11 +758,11 @@ } /* Generate gimme messages for phantoms and leaf messages ** for all leaves. */ - if( pullFlag ){ + if( pullFlag || cloneFlag ){ request_phantoms(&xfer); } if( pushFlag ){ send_unsent(&xfer); nMsg += send_unclustered(&xfer); @@ -777,11 +837,11 @@ && blob_eq(&xfer.aToken[0], "igot") && blob_is_uuid(&xfer.aToken[1]) ){ int rid = 0; nMsg++; - if( pullFlag ){ + if( pullFlag || cloneFlag ){ if( !db_exists("SELECT 1 FROM blob WHERE uuid='%b' AND size>=0", &xfer.aToken[1]) ){ rid = content_put(0, blob_str(&xfer.aToken[1]), 0); newPhantom = 1; } @@ -808,15 +868,13 @@ fossil_fatal("server loop"); } nMsg++; if( zPCode==0 ){ zPCode = mprintf("%b", &xfer.aToken[2]); - db_set("project-code", zPCode); + db_set("project-code", zPCode, 0); } - cloneFlag = 0; - pullFlag = 1; - blob_appendf(&send, "pull %s %s\n", zSCode, zPCode); + blob_appendf(&send, "clone\n"); nMsg++; }else /* cookie TEXT ** @@ -826,16 +884,26 @@ ** ** Each cookie received overwrites the prior cookie from the ** same server. */ if( blob_eq(&xfer.aToken[0], "cookie") && xfer.nToken==2 ){ - db_set("cookie", blob_str(&xfer.aToken[1])); + db_set("cookie", blob_str(&xfer.aToken[1]), 0); + }else + + /* message MESSAGE + ** + ** Print a message. Similar to "error" but does not stop processing + */ + if( blob_eq(&xfer.aToken[0],"message") && xfer.nToken==2 ){ + char *zMsg = blob_terminate(&xfer.aToken[1]); + defossilize(zMsg); + printf("Server says: %s\n", zMsg); }else /* error MESSAGE ** - ** Report an error + ** Report an error and abandon the sync session */ if( blob_eq(&xfer.aToken[0],"error") && xfer.nToken==2 ){ char *zMsg = blob_terminate(&xfer.aToken[1]); defossilize(zMsg); blob_appendf(&xfer.err, "server says: %s", zMsg); @@ -880,7 +948,8 @@ if( xfer.nFileSent+xfer.nDeltaSent>0 ){ go = 1; } }; http_close(); + db_multi_exec("DROP TABLE onremote"); db_end_transaction(0); }
Modified src/zip.c from [a6ead783d2] to [359cf5b931].
@@ -322,23 +322,24 @@ blob_write_to_file(&zip, g.argv[3]); } /* ** WEBPAGE: zip +** URL: /zip/RID.zip ** -** Generate a ZIP archive for the baseline specified by g.zExtra -** and return that ZIP archive as the HTTP reply content. +** Generate a ZIP archive for the baseline. +** Return that ZIP archive as the HTTP reply content. */ void baseline_zip_page(void){ int rid; char *zName; int i; Blob zip; login_check_credentials(); if( !g.okRead || !g.okHistory ){ login_needed(); return; } - zName = mprintf("%s", g.zExtra); + zName = mprintf("%s", PD("name","")); i = strlen(zName); for(i=strlen(zName)-1; i>5; i--){ if( zName[i]=='.' ){ zName[i] = 0; break;
Modified test/merge1.test from [419c5c1aa7] to [eed9903dc2].
@@ -77,18 +77,31 @@ 333 - This is a test of the merging algohm - 3333 444 - If all goes well, we will be pleased - 4444 555 - we think it well and other stuff too - 5555 } write_file_indented t23 { - 111 - This is line ONE OF the demo program - 1111 + >>>>>>>> BEGIN MERGE CONFLICT <<<<<<<< + 111 - This is line ONE of the demo program - 1111 + 111 - This is line one OF the demo program - 1111 + >>>>>>>>> END MERGE CONFLICT <<<<<<<<< + 222 - The second line program line in code - 2222 + 333 - This is a test of the merging algohm - 3333 + 444 - If all goes well, we will be pleased - 4444 + 555 - we think it well and other stuff too - 5555 +} +write_file_indented t32 { + >>>>>>>> BEGIN MERGE CONFLICT <<<<<<<< + 111 - This is line one OF the demo program - 1111 + 111 - This is line ONE of the demo program - 1111 + >>>>>>>>> END MERGE CONFLICT <<<<<<<<< 222 - The second line program line in code - 2222 333 - This is a test of the merging algohm - 3333 444 - If all goes well, we will be pleased - 4444 555 - we think it well and other stuff too - 5555 } fossil test-3 t1 t3 t2 a32 -test merge1-2.1 {[same_file t23 a32]} +test merge1-2.1 {[same_file t32 a32]} fossil test-3 t1 t2 t3 a23 test merge1-2.2 {[same_file t23 a23]} write_file_indented t1 { 111 - This is line one of the demo program - 1111 @@ -222,37 +235,5 @@ } fossil test-3 t1 t3 t2 a32 test merge1-6.1 {[same_file t32 a32]} fossil test-3 t1 t2 t3 a23 test merge1-6.2 {[same_file t32 a23]} - -# 123456789 123456789 123456789 123456789 123456789 123456789 -write_file_indented t1 { - 111 - This is line one of the demo program - 1111 - 222 - The second line program line in code - 2222 - 333 - This is a test of the merging algohm - 3333 - 444 - If all goes well, we will be pleased - 4444 - 555 - we think it well and other stuff too - 5555 -} -write_file_indented t2 { - 222 - The second line program line in code - 2222 - 333 - This is a test of THREE rging algohm - 3333 - 444 - If all goes well, we will be pleased - 4444 - 111 - This is line one of the demo program - 1111 - 555 - we think it well and other stuff too - 5555 -} -write_file_indented t3 { - 111 - This is line ONEONE the demo program - 1111 - 222 - The second line program line in code - 2222 - 333 - This is a test of the merging algohm - 3333 - 444 - If all goes well, we will be pleased - 4444 - 555 - we think it FIVEFIVE other stuff too - 5555 -} -write_file_indented t32 { - 222 - The second line program line in code - 2222 - 333 - This is a test of THREE rging algohm - 3333 - 444 - If all goes well, we will be pleased - 4444 - 111 - This is line ONEONE the demo program - 1111 - 555 - we think it FIVEFIVE other stuff too - 5555 -} -fossil test-3 t1 t3 t2 a32 -test merge1-6.1 {[same_file t32 a32]}
Modified test/tester.tcl from [8cd24c134d] to [ba01105cd0].
@@ -87,11 +87,15 @@ } # Return true if two files are the same # proc same_file {a b} { - return [expr {[read_file $a]==[read_file $b]}] + set x [read_file $a] + regsub -all { +\n} $x \n x + set y [read_file $b] + regsub -all { +\n} $y \n y + return [expr {$x==$y}] } # Perform a test # proc test {name expr} {
Modified todo.txt from [55905ed361] to [5e00e8293a].
@@ -1,5 +1,32 @@ +Bugs: + + * When doing an update, if a file is not found that should be there + then the update aborts, only after it has written several files. It + does not update your checked out version, thus when doing a fossil + changes, you see everything that has come over from your update + command. Steps to reproduce: + + $ rm src/main.c + $ fossil update 9b30 + UPDATE ... etc ... + fossil: no such file: src/main.c + $ fossil info + (shows version you were on prior to update) + $ fossil changes + EDITED ... many ... + + * Bug: If the server closes the socket unexpectedly, the + fwrite() in http.c:103 throws a signal and kills the child + process. fwrite() is not suppose to do this. Need to figure + out what is going wrong. + + * Bug: Make sure merge and other commands (check-out) do not try + to use a phantom. + + * Bug: When clone use incorrect http URL, local repo file is still created. + Things to work on: * Use the wiki_convert() routine to render comments and other text on web pages. @@ -11,25 +38,15 @@ * If the server returns an error (for example if the outbound /xfer message exceeds the maximum POST size of the server) the client does not report this error back to the user as it should. - * Bug: If the server closes the socket unexpectedly, the - fwrite() in http.c:103 throws a signal and kills the child - process. fwrite() is not suppose to do this. Need to figure - out what is going wrong. - - * Bug: pull is ending prematurely. - - * Bug: Make sure merge and other commands (check-out) do not try - to use a phantom. -¿ * The ipaddr field of the rcvfrom table is not being set. This field should be the IP address from which information is received for the local repository. So when somebody does a push of new files we record the ipaddr. Or when we do a pull, we record - the ipaddr. + the ipaddr. (I think this has been fixed. Need to test.) * Additional information displayed for the "vinfo" page: + All leaves of this version that are not included in the descendant list. With date, user, comment, and hyperlink. @@ -36,23 +53,14 @@ Leaves in the descendant table should be marked as such. See the compute_leaves() function to see how to find all leaves. + Add file diff links to the file change list. - * Timeline enhanced so that you can specify a range of dates. - - * The /xfer handler (for push, pull, and clone) does not do - delta compression. This results in excess bandwidth usage. - There are some pieces in xfer.c that are sketches of ideas on - how to do delta compression, but nothing has been implemented. - * Enhancements to the diff and tkdiff commands in the cli. Allow the entire tree or a subtree to be diffed, not just a single file. Allow diffs against any two arbitrary versions, - not just diffs against the current check-out. Allow - configuration options to replace tkdiff with some other - visual differ of the users choice. Example: eskil. + not just diffs against the current check-out. * Ticketing interface (expand this bullet) + Create new tickets as files in the file hierarchy + Append remarks to a ticket @@ -115,11 +123,12 @@ hash. But you can add a new record to the repository that overloads a check-in comment with a new comment. Comment changes should be GPG clearsigned at the very least. Comment changes only apply if the user who made the change has the right permissions. - * Get a build working for win32. Perhaps use cygwin. Or omit - the server component from win32 (to eliminate the need for fork()). - * Make the interface to fossil look pretty and be customizable so that other people will be attracted to it, will take over maintenance of it, and we can eventually move on to other things. + + This has begun, but I wonder if we need to use a templating system for + full customization. If the CSS is done correctly, you can change 99.9% + of everything. See: http://www.csszengarden.com/
Added tools/fossil_chat.tcl version [c673398270]
@@ -1,1 +1,257 @@ +#!/home/drh/bin/tobe +# +# Simple chat client for Tcl/Tk. +# +package require Tk + +set SERVERHOST fossil-scm.hwaci.com +# set SERVERHOST 127.0.0.1 +#set SERVERHOST 64.5.53.192 +set SERVERPORT 8615 + +# set to correct values if you have to use a proxy +set PROXYHOST {} +set PROXYPORT {} + +# Setup the user interface +wm title . Fossil-Chat +wm iconname . [wm title .] + +menu .mb -type menubar +if {$tcl_platform(platform)=="unix" && $tcl_platform(os)!="Darwin"} { + pack .mb -side top -fill x +} else { + . config -menu .mb +} +.mb add cascade -label File -underline 0 -menu .mb.file +menu .mb.file -tearoff 0 +.mb.file add command -label Send -command send_message +.mb.file add command -label {Remove older messages} -command cleanup_record +.mb.file add separator +.mb.file add command -label {Exit} -command exit + +frame .who +pack .who -side right -anchor n -fill y +label .who.title -text {Users: } +pack .who.title -side top -anchor nw +label .who.list -anchor w -justify left -text {} +pack .who.list -side top -anchor nw -expand 1 -padx 5 +label .who.time -text {} -justify right +proc update_time {} { + after 1000 update_time + set now [clock seconds] + set time [clock format $now -format %H:%M -gmt 1] + .who.time config -text "UTC: $time" +} +update_time +pack .who.time -side bottom -anchor sw + +frame .input +pack .input -side bottom -fill x +text .input.t -bd 1 -relief sunken -bg white -fg black -width 60 -height 3 \ + -wrap word -yscrollcommand [list .input.sb set] -takefocus 1 +bind .input.t <Key-Return> {send_message; break} +pack .input.t -side left -fill both -expand 1 +scrollbar .input.sb -orient vertical -command [list .input.t yview] +pack .input.sb -side left -fill y + +frame .msg +pack .msg -side top -fill both -expand 1 +text .msg.t -bd 1 -relief sunken -bg white -fg black -width 60 -height 20 \ + -wrap word -yscrollcommand [list .msg.sb set] -takefocus 0 +bindtags .msg.t [list .msg.t . all] +.msg.t tag config error -foreground red +.msg.t tag config meta -foreground forestgreen +.msg.t tag config norm -foreground black +pack .msg.t -side left -fill both -expand 1 +scrollbar .msg.sb -orient vertical -command [list .msg.t yview] +pack .msg.sb -side left -fill y + +update + +# Send periodic messages to keep the TCP/IP link up +# +proc keep_alive {} { + global TIMER SOCKET + catch {after cancel $TIMER} + set TIMER [after 300000 keep_alive] + catch {puts $SOCKET noop; flush $SOCKET} +} + +# Connect to the server +proc connect {} { + global SOCKET tcl_platform + catch {close $SOCKET} + if {[catch { + if {$::PROXYHOST ne {}} { + set SOCKET [socket $::PROXYHOST $::PROXYPORT] + puts $SOCKET "CONNECT $::SERVERHOST:$::SERVERPORT HTTP/1.1" + puts $SOCKET "Host: $::SERVERHOST:$::SERVERPORT" + puts $SOCKET "" + } else { + set SOCKET [socket $::SERVERHOST $::SERVERPORT] + } + fconfigure $SOCKET -translation binary -blocking 0 + puts $SOCKET [list login $tcl_platform(user) fact,fuzz] + flush $SOCKET + fileevent $SOCKET readable handle_input + keep_alive + } errmsg]} { + if {[tk_messageBox -icon error -type yesno -parent . -message \ + "Unable to connect to server. $errmsg.\n\nTry again?"]=="yes"} { + after 100 connect + } + } +} +connect + +# Send the message text contained in the .input.t widget to the server. +# +proc send_message {} { + set txt [.input.t get 1.0 end] + .input.t delete 1.0 end + regsub -all "\[ \t\n\f\r\]+" [string trim $txt] { } txt + if {$txt==""} return + global SOCKET + puts $SOCKET [list message $txt] + flush $SOCKET +} + +.mb add cascade -label "Transfer" -underline 0 -menu .mb.files +menu .mb.files -tearoff 0 +.mb.files add command -label "Send file..." -command send_file +.mb.files add command -label "Delete files" -command delete_files \ + -state disabled +.mb.files add separator + +# Encode a string (possibly containing binary and \000 characters) into +# single line of text. +# +proc encode {txt} { + return [string map [list % %25 + %2b " " + \n %0a \t %09 \000 %00] $txt] +} + +# Undo the work of encode. Convert an encoded string back into its original +# form. +# +proc decode {txt} { + return [string map [list %00 \000 %09 \t %0a \n + " " %2b + %25 %] $txt] +} + +# Delete all of the downloaded files we are currently holding. +# +proc delete_files {} { + global FILES + .mb.files delete 3 end + array unset FILES + .mb.files entryconfigure 1 -state disabled +} + +# Prompt the user to select a file from the disk. Then send that +# file to all chat participants. +# +proc send_file {} { + global SOCKET + set openfile [tk_getOpenFile] + if {$openfile==""} return + set f [open $openfile] + fconfigure $f -translation binary + set data [read $f] + close $f + puts $SOCKET [list file [file tail $openfile] [encode $data]] + flush $SOCKET + set time [clock format [clock seconds] -format {%H:%M} -gmt 1] + .msg.t insert end "\[$time\] sent file [file tail $openfile]\ + - [string length $data] bytes\n" meta + .msg.t see end +} + +# Save the named file to the disk. +# + proc save_file {filename} { + global FILES + set savefile [tk_getSaveFile -initialfile $filename] + if {$savefile==""} return + set f [open $savefile w] + fconfigure $f -translation binary + puts -nonewline $f [decode $FILES($filename)] + close $f +} + +# Handle a "file" message from the chat server. +# +proc handle_file {from filename data} { + global FILES + foreach prior [array names FILES] { + if {$filename==$prior} break + } + if {![info exists prior] || $filename!=$prior} { + .mb.files add command -label "Save \"$filename\"" \ + -command [list save_file $filename] + } + set FILES($filename) $data + .mb.files entryconfigure 1 -state active + set time [clock format [clock seconds] -format {%H:%M} -gmt 1] + .msg.t insert end "\[$time $from\] " meta "File: \"$filename\"\n" norm + .msg.t see end +} + +# Handle input from the server +# +proc handle_input {} { + global SOCKET + if {[eof $SOCKET]} { + disconnect + return + } + set line [gets $SOCKET] + if {$line==""} return + set cmd [lindex $line 0] + if {$cmd=="userlist"} { + set ulist {} + foreach u [lrange $line 1 end] { + append ulist $u\n + } + .who.list config -text [string trim $ulist] + } elseif {$cmd=="message"} { + set time [clock format [clock seconds] -format {%H:%M} -gmt 1] + set from [lindex $line 1] + .msg.t insert end "\[$time $from\] " meta [lindex $line 2]\n norm + .msg.t see end + bell + wm deiconify . + update + raise . + } elseif {$cmd=="noop"} { + # do nothing + } elseif {$cmd=="meta"} { + set now [clock seconds] + set time [clock format $now -format {%H:%M} -gmt 1] + .msg.t insert end "\[$time\] [lindex $line 1]\n" meta + .msg.t see end + } elseif {$cmd=="file"} { + if {[info commands handle_file]=="handle_file"} { + handle_file [lindex $line 1] [lindex $line 2] [lindex $line 3] + } + } +} + +# Handle a broken socket connection +# +proc disconnect {} { + global SOCKET + close $SOCKET + set q [tk_messageBox -icon error -type yesno -parent . -message \ + "TCP/IP link lost. Try to reconnet?"] + if {$q=="yes"} { + connect + } else { + exit + } +} +# Remove all but the most recent 100 message from the message log +# +proc cleanup_record {} { + .msg.t delete 1.0 {end -100 lines} +}
Added win32.txt version [ee38ffb58e]
@@ -1,1 +1,105 @@ +Fossil on Win32 +====================================================================== + +Setting up the build environment: +---------------------------------------------------------------------- + + Install: + MinGW 5.1.3 + MSYS 1.0.10 + + Download/compile/install zlib (configure --prefix=/mingw) + Download/compile/install tclsh (configure --prefix=/) (for tests) + + Installing zlib and tclsh was done in the MSYS shell so I could + easily use the configure scripts. Tcl is only required to run the + tests. You could install a binary distribution of Tcl/Tk and use + that to run the tests, or you could opt to simply trust that + everything worked and not run the tests. + + There is a contributed zlib package on the MinGW site. + + Downloading and installing a binary Tcl/Tk package and the + contributed zlib package would remove the requirement of MSYS. + + +Building on Windows: +---------------------------------------------------------------------- + + Ensure you have read "Setting up the build environment" first. + + Building is as simple as one command: + + C:\fossil-src> make -f Makefile.w32 + + +Outstanding Issues: +---------------------------------------------------------------------- + +* server is totally non-functional - #if/#end'd out of the code + + +Commands status: +---------------------------------------------------------------------- + +add OK +cgi Not tested +changes OK +checkout BAD #1 +clean OK +clone OK +close OK +commit OK +config OK +deconstruct OK +del OK +descendents OK +diff OK +extra OK +help OK +http Not Tested +info OK +leaves OK +ls OK +merge OK +new OK +open OK +pull OK +push OK +rebuild OK +redo BAD #3 +rm OK +server BAD #4 +status OK +sync OK +timeline OK +tkdiff OK +undo OK +update OK +user capabilities OK +user default OK +user list OK +user new OK +user password OK + +#1 Have a repo where I removed a file. I did a fossil checkout 123abc, + which is the last version that had the file. The file does not + appear. fossil checkout --force 123abc does things, but still the + file does not appear. + + Make a new dir, fossil open ../repo.fsl && fossil checkout 123abc and + the file appears. + + Is that normal operation? + +#3 In test1/ I edited a file, test2/ I updated, type file.txt changes + were there. I then did fossil undo file.txt. The changes were gone + and fossil status said I had edited file.txt. A fossil redo did not + print anything to the screen and the changes for file.txt are not + in the file. fossil status still reports that the file was edited. + There was no commit/update or any other command inbetween these + actions. +#4 There were various difficulties in this function beyond simple socket + problems. The major one being fork. This will probably be the last + command to be functional in fossil on windows.
Modified www/concepts.html from [d53cc73d6e] to [d4951ef603].
@@ -30,11 +30,12 @@ <p>A software project normally consists of a "source tree". A source tree is a hierarchy of files that are used to generate the end product. The source tree changes over time as the software grows and expands and as features are added and bugs are fixed. A snapshot of the source tree at any point in time -is called a "version" or a "baseline" of the product.</p> +is called a "version" or "revision" or a "baseline" of the product. +In fossil, we use the name "baseline".</p> <p>A "repository" is a database that contains copies of all historical versions or baselines for a project. Baselines are normally stored in the repository in a highly space-efficient compressed format (delta encoding). But that is an implementation detail that you the user need not worry over. @@ -53,11 +54,11 @@ source trees to a single repository if you want (though one tree per repository is the most common configuration.) So a single repository can be associated with many source trees, but each source tree is associated with only one repository.</p> -<p>Fossil source tree may not overlap. A fossil source tree is identified +<p>Fossil source trees may not overlap. A fossil source tree is identified by a file named "_FOSSIL_" in the root directory of the source tree. Every file that is a sibling of _FOSSIL_ and every file in every subfolder is considered potentially a part of the source tree. The _FOSSIL_ file contains (among other things) the pathname of the repository with which the source tree is associated. On the other hand, the repository has @@ -75,11 +76,11 @@ remote repository into a local repository. Or one can do a "sync" which is a shortcut for doing both a push and a pull at the same time. Fossil also has the concept of "cloning". A "clone" is like a "pull", except that instead of beginning with an existing local repository, a clone begins with nothing and creates a new local repository that -is a replicate of a remote repository.</p> +is a duplicate of a remote repository.</p> <p>Communication between repositories is via HTTP. Remote repositories are identified by URL. You can also point a webbrowser at a repository and get human-readable status, history, and tracking information about the project.</p> @@ -93,11 +94,11 @@ a hash is referred to as the Universally Unique Identifier or UUID for the artifact. The SHA1 algorithm is created with the purpose of providing a highly forgery-resistent identifier for a file. Given any file it is simple to find the UUID for that file. But given a UUID it is computationally intractable to generate a file that will -generate that UUID.</p> +have that UUID.</p> <p>UUIDs look something like this:</p> <blockquote><b> @@ -140,13 +141,14 @@ manifest for that baseline.</p> <p>Fossil automatically generates a manifest whenever you "commit" a new baseline. So this is not something that you, the developer, need to worry with. The format of a manifest is intentionally -designed to be simple to parse, however, so that if +designed to be simple to parse, so that if you want to read and interpret a manifest, either by hand or -with a script, that is easy to do.</p> +with a script, that is easy to do. But you will probably never +need to do so.</p> <p>In addition to identifying all files in the baseline, a manifest also contains a check-in comment, the date and time when the baseline was established, who created the baseline, and links to other baselines from which the current baseline @@ -155,11 +157,11 @@ be PGP clearsigned.</p> <h3>2.3 Key concepts</h3> <ul> -<li>A <b>baseline</b> or <b>version</b> is a set of files arranged +<li>A <b>baseline</b> is a set of files arranged in a hierarchy.</li> <li>A <b>repository</b> keeps a record of historical baselines.</li> <li>Repositories share their changes using <b>push</b>, <b>pull</b>, <b>sync</b>, and <b>clone</b>.</li> <li>A particular version of a particular file is an <b>artifact</b> @@ -184,12 +186,14 @@ SQLite, patch, or any similar software on your system in order to use fossil effectively. You will want to have some kind of text editor for entering check-in comments. Fossil will use whatever text editor is identified by your VISUAL environment variable. Fossil will also use GPG to clearsign your manifests if you happen to have it installed, -but fossil will skip that step if you do not have GPG so it is not -essential.</p> +but fossil will skip that step if GPG missing from your system. +You can optionally set up fossil to use external "diff" programs, +though a perfectly functional "diff" algorithm is built it and works +find for most people.</p> <p>To uninstall fossil, simply delete the executable.</p> <p>To upgrade an older version of fossil to a newer version, just replace the old executable with the new one. You might need to @@ -274,10 +278,42 @@ <li><p> Repeat all of the above until you have generated great software. </p></li> </ol> + +<h3>4.1 Variations</h3> + +<p>The <b>settings</b> lets you view and modify various operating +properties of fossil. Among the available settings is "autosync" +mode. When autosync is enabled, the push and pull of content from +your local server is largely automated. Whenever you use the <b>update</b> +command, fossil first does a <b>pull</b> to see if other users have +perhaps added new baselines to the central repository. When you +<b>commit</b>, fossil also does a <b>pull</b> and issues a warning +if your check-in would cause a fork. After a <b>commit</b>, fossil +automatically does a <b>push</b> to send your changes up to the +central server.</p> + +<p>With autosync enabled, fossil works like +<a href="http://www.nongnu.org/cvs/">CVS</a> or +<a href="http://subversion.tigris.org/">Subversion</a>. +When autosync disabled, fossil works more like +<a href="http://monotone.ca/">Monotone</a>, +<a href="http://git.or.cz">GIT</a>, or +<a href="http://www.selenic.com/mercurial/wiki/">Mercurial</a>. +The fun thing about fossil is that it will work either +way, depending on your needs of the moment. You can freely switch +between these operating modes using commands like:</p> + +<blockquote> +<b>fossil setting autosync off<br /> +fossil setting autosync on</b> +</blockquote> + +<p>For additional information about autosync and other settings +using the <b>help</b> command.</p> <h2>5.0 Setting Up A Fossil Server</h2> <p>With other configuration management software, setting up a server is a lot of work and normally takes time, patience, and a lot of system
Modified www/fileformat.html from [65db56924d] to [66d0102569].
@@ -9,60 +9,76 @@ Fossil File Formats </h1> <p> The global state of a fossil repository is determined by an unordered -set of files. Some files are used to represent wiki pages, trouble tickets, -and the special "manifest" file has a specific and well-defined format. -Other files are just data. Files can be text or binary. -</p> - -<p> -Each file in the repository is named by its SHA1 hash. -No prefixes or meta information is added to a file before -its hash is computed. The name of a file in the repository +set of files. A file in fossil is called an "artifact". +An artifact might be a source code file, the text of a wiki page, +part of a trouble ticket, or one of several special control artifacts +used to show the relationships between other artifacts within the +project. Artifacts can be text or binary. +</p> + +<p> +Each artifact in the repository is named by its SHA1 hash. +No prefixes or meta information is added to a artifact before +its hash is computed. The name of a artifact in the repository is exactly the same SHA1 hash that is computed by sha1sum on the file as it exists in your source tree.</p> <p> -Some files have a particular format which qualifies them -as "manifests". A manifest assigns filenames to a subset -of the files in the repository, in order to provide a -snapshot of the state of the project at a point in time. -Each manifest file corresponds to a version or baseline -of the project. -</p> - -<h2>1.0 The Manifest File</h2> - -<p> -Any file in the repository that follows the syntactic rules +Some artifacts have a particular format which gives them special +meaning to fossil. Fossil recognizes:</p> + +<ul> +<li> Manifests </li> +<li> Clusters </li> +<li> Control Artifacts </li> +<li> Wiki Pages </li> +<li> Ticket Changes </li> +</ul> + +<p>These five artifact types are described in the sequel.</p> + +<h2>1.0 The Manifest</h2> + +<p>A manifest defines a baseline or version of the project +source tree. The manifest contains a list of artifacts for +each file in the project and the corresponding filenames, as +well as information such as parent baselines, the name of the +programmer who created the baseline, the date and time when +the baseline was created, and any check-in comments associated +with the baseline.</p> + +<p> +Any artifact in the repository that follows the syntactic rules of a manifest is a manifest. Note that a manifest can be both a real manifest and also a content file, though this is rare. </p> <p> -A manifest is a line-oriented text file. Newline characters -(ASCII 0x0a) separate lines. Each line begins with a single -character "line type". Zero or more arguments may follow -the line type. All arguments are separated from each other -and from the line-type character by a single space +A manifest is a text file. Newline characters +(ASCII 0x0a) separate the file into "cards". +Each card begins with a single +character "card type". Zero or more arguments may follow +the card type. All arguments are separated from each other +and from the card-type character by a single space character. There is no surplus white space between arguments and no leading or trailing whitespace except for the newline -character that acts as the line separator. -</p> - -<p> -All lines of the manifest occur in strict sorted lexicographical order. -No line may be duplicated. -The entire manifest file may be PGP clear-signed, but otherwise it +character that acts as the card separator. +</p> + +<p> +All cards of the manifest occur in strict sorted lexicographical order. +No card may be duplicated. +The entire manifest may be PGP clear-signed, but otherwise it may contain no additional text or data beyond what is described here. </p> <p> -Allowed lines in the manifest are as follows: +Allowed cards in the manifest are as follows: </p> <blockquote> <b>C</b> <i>checkin-comment</i><br> <b>D</b> <i>time-and-date-stamp</i><br> @@ -72,12 +88,12 @@ <b>U</b> <i>user-login</i><br> <b>Z</b> <i>manifest-checksum</i> </blockquote> <p> -A manifest must have exactly one C-line. The sole argument to -the C-line is a check-in comment that describes the baseline that +A manifest must have exactly one C-card. The sole argument to +the C-card is a check-in comment that describes the check-in that the manifest defines. The check-in comment is text. The following escape sequences are applied to the text: A space (ASCII 0x20) is represented as "\s" (ASCII 0x5C, 0x73). A newline (ASCII 0x0a) is "\n" (ASCII 0x6C, x6E). A backslash (ASCII 0x5C) is represented as two backslashes "\\". Apart from @@ -85,51 +101,50 @@ the check-in comment. Nor are any unprintable characters allowed in the comment. </p> <p> -A manifest must have exactly one D-line. The sole argument to -the D-line is a date-time stamp in the ISO8601 format. The +A manifest must have exactly one D-card. The sole argument to +the D-card is a date-time stamp in the ISO8601 format. The date and time should be in coordinated universal time (UTC). The format is: </p> <blockquote> <i>YYYY</i><b>-</b><i>MM</i><b>-</b><i>DD</i><b>T</b><i>HH</i><b>:</b><i>MM</i><b>:</b><i>SS</i> </blockquote> <p> -A manifest has zero or more F-lines. Each F-line defines a file +A manifest has zero or more F-cards. Each F-card defines a file (other than the manifest itself) which is part of the baseline that the manifest defines. There are two arguments. The first argment is the pathname of the file in the baseline relative to the root of the project file hierarchy. No ".." or "." directories are allowed -within the filename. Space characters are escaped as in C-line +within the filename. Space characters are escaped as in C-card comment text. Backslash characters and newlines are not allowed within filenames. The directory separator character is a forward -slash (ASCII 0x2F). The second argument to the F-line is the -full 40-character hexadecimal SHA1 hash of the file content. -Upper-case letters ABCDEF are used for the higher digits of the -hexadecimal. -</p> - -<p> -A manifest has zero or one P-lines. Most manifests have one P-line. -The P-line has a varying number of arguments that +slash (ASCII 0x2F). The second argument to the F-card is the +full 40-character lower-case hexadecimal SHA1 hash of the content +artifact. +</p> + +<p> +A manifest has zero or one P-cards. Most manifests have one P-card. +The P-card has a varying number of arguments that defines other manifests from which the current manifest is derived. Each argument is an 40-character lowercase hexadecimal SHA1 of the predecessor manifest. All arguments -to the P-line must be unique to that line. -The first predecessor is the manifests direct ancestor. +to the P-card must be unique to that line. +The first predecessor is the direct ancestor of the manifest. Other arguments define manifests with which the first was merged to yield the current manifest. Most manifests have -a P-line with a single argument. The first manifest in the -project has no ancestors and thus has no P-line. +a P-card with a single argument. The first manifest in the +project has no ancestors and thus has no P-card. </p> <p> -A manifest may optionally have a single R-line. The R-line has +A manifest may optionally have a single R-card. The R-card has a single argument which is the MD5 checksum of all files in the baseline except the manifest itself. The checksum is expressed as 32-characters of lowercase hexadecimal. The checksum is computed as follows: For each file in the baseline (except for the manifest itself) in strict sorted lexicographical order, @@ -139,48 +154,188 @@ character (ASCII 0x0A), and the complete text of the file. Compute the MD5 checksum of the the result. </p> <p> -Each manifest has a single U-line. The argument to the U-line is +Each manifest has a single U-card. The argument to the U-card is the login of the user who created the manifest. The login name is encoded using the same character escapes as is used for the -check-in comment argument to the C-line. +check-in comment argument to the C-card. </p> <p> -A manifest has an option Z-line as its last line. The argument -to the Z-line is a 32-character lowercase hexadecimal MD5 hash +A manifest has an option Z-card as its last line. The argument +to the Z-card is a 32-character lowercase hexadecimal MD5 hash of all prior lines of the manifest up to and including the newline -character that immediately preceeds the "Z". The Z-line is just +character that immediately preceeds the "Z". The Z-card is just a sanity check to prove that the manifest is well-formed and consistent. </p> -<h2>2.0 Trouble Tickets</h2> +<h2>2.0 Clusters</h2> + +<p> +A cluster is a artifact that declares the existance of other artifacts. +Clusters are used during repository synchronization to help +reduce network traffic. +</p> + +<p> +Clusters follow a syntax that is very similar to manifests. +A Cluster is a line-oriented text file. Newline characters +(ASCII 0x0a) separate the artifact into cards. Each card begins with a single +character "card type". Zero or more arguments may follow +the card type. All arguments are separated from each other +and from the card-type character by a single space +character. There is no surplus white space between arguments +and no leading or trailing whitespace except for the newline +character that acts as the card separator. +All cards of a cluter occur in strict sorted lexicographical order. +No card may be duplicated. +The cluster may not contain additional text or data beyond +what is described here. +Unlike manifests, clusters are never PGP signed. +</p> + +<p> +Allowed cards in the cluster are as follows: +</p> + +<blockquote> +<b>M</b> <i>uuid</i><br /> +<b>Z</b> <i>checksum</i> +</blockquote> <p> -Each trouble ticket is a file in the repository and appears in -a manifest for every baseline in which the ticket exists. -Trouble tickets occur in a specific subdirectory of the file -heirarchy. The name of the subdirectory that contains tickets -is part of the local state of each repository. The filename -of each trouble ticket has a ".tkt" suffix. The trouble ticket -has a particular file format defined below. +A cluster contains one or more "M" cards followed by a single "Z" +line. Each M card has a single argument which is the UUID of +another artifact in the repository. The Z card work exactly like +the Z card of a manifest. The argument to the Z card is the +lower-case hexadecimal representation of the MD5 checksum of all +prior cards in the cluster. Note that the Z card is required +on a cluster. </p> -<i>To be continued...</i> - -<h2>3.0 Wiki Pages</h2> + +<h2>3.0 Control Artifacts</h2> + +<p> +Control artifacts are used to assign properties to other artifacts +within the repository. The basic format of a control artifact is +the same as a manifest or cluster. A control artifact is a text +files divided into cards by newline characters. Each card has a +single-character card type followed by arguments. Spaces separate +the card type and the arguments. No surplus whitespace is allowed. +All cards must occur in strict lexigraphical order. +</p> <p> -Each wiki is a file in the repository and appears in -a manifest for every baseline in which that wiki page exists. -Wiki pages occur in a specific subdirectory of the file -heirarchy. The name of the subdirectory that contains wiki pages -is part of the local state of each repository. The filename -of each wiki page has a ".wiki" suffix. The base name of -the file is the name of the wiki page. The wiki pages -have a particular file format defined below. +Allowed cards in a control artifact are as follows: </p> -<i>To be continued...</i> +<blockquote> +<b>D</b> <i>time-and-date-stamp</i><br /> +<b>T</b> (<b>+</b>|<b>-</b>|<b>*</b>)<i>tag-name uuid ?value?</i><br /> +<b>Z</b> <i>checksum</i><br /> +</blockquote> + +<p> +A control artifact must have one D card and one Z card and +one or more or more T cards. No other cards or other text is +allowed in a control artifact. Control artifacts might be PGP +clearsigned.</p> + +<p>The D card and the Z card of a control artifact are the same +as in a manifest.</p> + +<p>The T card represents a "tag" or property that is applied to +some other artifact. The T card has two or three values. The +second argument is the 40 character lowercase UUID of the artifact +to which the tag is to be applied. The +first value is the tag name. The first character of the tag +is either "+", "-", or "*". A "+" means the tag should be added +to the artifact. The "-" means the tag should be removed. +The "*" character means the tag should be added to the artifact +and all direct decendents (but not branches) of the artifact down +to but not including the first decendent that contains a +more recent "-" tag with the same name. +The optional third argument is the value of the tag. A tag +without a value is a boolean.</p> + +<p>When two or more tags with the same name are applied to the +same artifact, the tag with the latest (most recent) date is +used.</p> + +<p>Some tags have special meaning. The "comment" tag when applied +to a baseline will override the check-in comment of that baseline +for display purposes.</p> + +<h2>4.0 Wiki Pages</h2> + +<p>A wiki page is an artifact with a format similar to manifests, +clusters, and control artifacts. The artifact is divided into +cards by newline characters. The format of each card is as in +manifests, clusters, and control artifacts. Wiki artifacts accept +the following card types:</p> + +<blockquote> +<b>D</b> <i>time-and-date-stamp</i><br /> +<b>L</b> <i>wiki-title</i><br /> +<b>P</b> <i>parent-uuid</i>+<br /> +<b>U</b> <i>user-name</i><br /> +<b>W</b> <i>size</i> <b>\n</b> <i>text</i> <b>\n</b><br /> +<b>Z</b> <i>checksum</i> +</blockquote> + +<p>The D card is the date and time when the wiki page was edited. +The P card specifies the parent wiki pages, if any. The L card +gives the name of the wiki page. The U card specifies the login +of the user who made this edit to the wiki page. The Z card is +the usual checksum over the either artifact.</p> + +<p>The W card is used to specify the text of the wiki page. The +argument to the W card is an integer which is the number of bytes +of text in the wiki page. That text follows the newline character +that terminates the W card. The wiki text is always followed by one +extra newline.</p> + +<h2>5.0 Ticket Changes</h2> + +<p>A ticket-change artifact represents a change to a trouble ticket. +The following cards are allowed on a ticket change artifact:</p> + +<blockquote> +<b>D</b> <i>time-and-date-stamp</i><br /> +<b>J</b> ?<b>+</b>?<i>name value</i><br /> +<b>K</b> <i>ticket-uuid</i><br /> +<b>U</b> <i>user-name</i><br /> +<b>Z</b> <i>checksum</i> +</blockquote> + +<p> +The D card is the usual date and time stamp and represents the point +in time when the change was entered. The U card is the login of the +programmer who entered this change. The Z card is the checksum over +the entire artifact.</p> + +<p> +Every ticket has a UUID. The ticket to which this change is applied +is specified by the K card. A ticket exists if it contains one or +more changes. The first "change" to a ticket is what brings the +ticket into existance.</p> + +<p> +J cards specify changes to "fields" of the ticket. Each fossil +server has a ticket configuration which specifies the fields its +understands. This is not a limit on the fields that can appear +on the J cards, however. If a J card specifies a field that a +particular fossil server does not recognize, then that J card +is simply ignored.</p> + +<p> +The first argument of the J card is the field name. The second +value is the field value. If the field name begins with "+" then +the value is appended to the prior value. Otherwise, the value +on the J card replaces any previous value of the field. +The field name and value are both encoded using the character +escapes defined for the C card of a manifest. +</p>
Modified www/quickstart.html from [427965635d] to [feb3fa22b5].
@@ -220,13 +220,12 @@ <p>Try these commands:</p> <blockquote><b> fossil help<br> - fossil commands<br> fossil test-commands </b></blockquote> <p>Explore and have fun!</p> </blockquote></body></html>
Modified www/selfcheck.html from [48d9461817] to [82d080c276].
@@ -15,10 +15,16 @@ of integrity so that you can have confidence that you will not lose your files. This note describes the defensive measures that fossil uses to help prevent file loss due to bugs. </p> +<p><i>Follow-up as of 2007-11-24:</i> +Fossil has been hosting itself and several other projects for +months now. Many bugs have been encountered. But, thanks in large +part to the defensive measures described here, no data has been +lost. The integrity checks are doing their job well.</p> + <h2>Atomic Check-ins With Rollback</h2> <p> The fossil repository is an <a href="http://www.sqlite.org/">SQLite version 3</a> database file. @@ -42,11 +48,11 @@ <p> The content files that comprise the global state of a fossil respository are stored in the repository as a tree. The leaves of the tree are stored as zlib-compressed BLOBs. Interior nodes are deltas from their -decendents. There is a lot of encoding going on here. There is +decendents. A lot of encoding is going on. There is zlib-compression which is relatively well-tested but still might cause corruption if used improperly. And there is the relatively new delta-encoding mechanism designed expressly for fossil. We want to make sure that bugs in these encoding mechanisms do not lead to loss of data. @@ -54,11 +60,12 @@ <p> To increase our confidence that everything in the repository is recoverable, fossil makes sure it can extract an exact replicate of every content file that it changes just prior to transaction -commit. So during the course of check-in, many different files +commit. So during the course of check-in (or other repository +operation) many different files in the repository might be modified. Some files are simply compressed. Other files are delta encoded and then compressed. While all this is going on, fossil makes a record of every file that is encoded and the SHA1 hash of the original content of that file. Then just before transaction commit, fossil re-extracts @@ -68,25 +75,25 @@ message is printed and the transaction rolls back. </p> <p> So, in other words, fossil always checks to make sure it can -re-extract a file before it commits a check-in of that file. +re-extract a file before it commits a change to that file. Hence bugs in fossil are unlikely to corrupt the repository in a way that prevents us from extracting historical versions of files. </p> <h2>Checksum Over All Files In A Baseline</h2> <p> -Manifest files that define a baseline have two fields (the -R-line and Z-line) that record MD5 hashs of the manifest itself +Manifest artifacts that define a baseline have two fields (the +R-card and Z-card) that record MD5 hashs of the manifest itself and of all other files in the manifest. Prior to any check-in commit, these checksums are verified to ensure that the baseline checked in agrees exactly with what is on disk. Similarly, the repository checksum is verified after a checkout to make sure that the entire repository was checked out correctly. Note that these added checks use a different hash (MD5 instead of SHA1) in order to avoid common-mode failures in the hash algorithm implementation. </p>