PHP  
 PHP: Test and Code Coverage Analysis
downloads | QA | documentation | faq | getting help | mailing lists | reporting bugs | php.net sites | links | my php.net 
 

LTP GCOV extension - code coverage report
Current view: directory - pdo_sqlite/sqlite/src - callback.c
Test: PHP Code Coverage
Date: 2009-11-19 Instrumented lines: 127
Code covered: 70.9 % Executed lines: 90
Legend: not executed executed

       1                 : /*
       2                 : ** 2005 May 23 
       3                 : **
       4                 : ** The author disclaims copyright to this source code.  In place of
       5                 : ** a legal notice, here is a blessing:
       6                 : **
       7                 : **    May you do good and not evil.
       8                 : **    May you find forgiveness for yourself and forgive others.
       9                 : **    May you share freely, never taking more than you give.
      10                 : **
      11                 : *************************************************************************
      12                 : **
      13                 : ** This file contains functions used to access the internal hash tables
      14                 : ** of user defined functions and collation sequences.
      15                 : **
      16                 : ** $Id: callback.c 234062 2007-04-18 22:53:46Z iliaa $
      17                 : */
      18                 : 
      19                 : #include "sqliteInt.h"
      20                 : 
      21                 : /*
      22                 : ** Invoke the 'collation needed' callback to request a collation sequence
      23                 : ** in the database text encoding of name zName, length nName.
      24                 : ** If the collation sequence
      25                 : */
      26               0 : static void callCollNeeded(sqlite3 *db, const char *zName, int nName){
      27                 :   assert( !db->xCollNeeded || !db->xCollNeeded16 );
      28               0 :   if( nName<0 ) nName = strlen(zName);
      29               0 :   if( db->xCollNeeded ){
      30               0 :     char *zExternal = sqliteStrNDup(zName, nName);
      31               0 :     if( !zExternal ) return;
      32               0 :     db->xCollNeeded(db->pCollNeededArg, db, (int)ENC(db), zExternal);
      33               0 :     sqliteFree(zExternal);
      34                 :   }
      35                 : #ifndef SQLITE_OMIT_UTF16
      36               0 :   if( db->xCollNeeded16 ){
      37                 :     char const *zExternal;
      38               0 :     sqlite3_value *pTmp = sqlite3ValueNew();
      39               0 :     sqlite3ValueSetStr(pTmp, nName, zName, SQLITE_UTF8, SQLITE_STATIC);
      40               0 :     zExternal = sqlite3ValueText(pTmp, SQLITE_UTF16NATIVE);
      41               0 :     if( zExternal ){
      42               0 :       db->xCollNeeded16(db->pCollNeededArg, db, (int)ENC(db), zExternal);
      43                 :     }
      44               0 :     sqlite3ValueFree(pTmp);
      45                 :   }
      46                 : #endif
      47                 : }
      48                 : 
      49                 : /*
      50                 : ** This routine is called if the collation factory fails to deliver a
      51                 : ** collation function in the best encoding but there may be other versions
      52                 : ** of this collation function (for other text encodings) available. Use one
      53                 : ** of these instead if they exist. Avoid a UTF-8 <-> UTF-16 conversion if
      54                 : ** possible.
      55                 : */
      56               0 : static int synthCollSeq(sqlite3 *db, CollSeq *pColl){
      57                 :   CollSeq *pColl2;
      58               0 :   char *z = pColl->zName;
      59               0 :   int n = strlen(z);
      60                 :   int i;
      61                 :   static const u8 aEnc[] = { SQLITE_UTF16BE, SQLITE_UTF16LE, SQLITE_UTF8 };
      62               0 :   for(i=0; i<3; i++){
      63               0 :     pColl2 = sqlite3FindCollSeq(db, aEnc[i], z, n, 0);
      64               0 :     if( pColl2->xCmp!=0 ){
      65               0 :       memcpy(pColl, pColl2, sizeof(CollSeq));
      66               0 :       return SQLITE_OK;
      67                 :     }
      68                 :   }
      69               0 :   return SQLITE_ERROR;
      70                 : }
      71                 : 
      72                 : /*
      73                 : ** This function is responsible for invoking the collation factory callback
      74                 : ** or substituting a collation sequence of a different encoding when the
      75                 : ** requested collation sequence is not available in the database native
      76                 : ** encoding.
      77                 : ** 
      78                 : ** If it is not NULL, then pColl must point to the database native encoding 
      79                 : ** collation sequence with name zName, length nName.
      80                 : **
      81                 : ** The return value is either the collation sequence to be used in database
      82                 : ** db for collation type name zName, length nName, or NULL, if no collation
      83                 : ** sequence can be found.
      84                 : */
      85                 : CollSeq *sqlite3GetCollSeq(
      86                 :   sqlite3* db, 
      87                 :   CollSeq *pColl, 
      88                 :   const char *zName, 
      89                 :   int nName
      90             106 : ){
      91                 :   CollSeq *p;
      92                 : 
      93             106 :   p = pColl;
      94             106 :   if( !p ){
      95               0 :     p = sqlite3FindCollSeq(db, ENC(db), zName, nName, 0);
      96                 :   }
      97             106 :   if( !p || !p->xCmp ){
      98                 :     /* No collation sequence of this type for this encoding is registered.
      99                 :     ** Call the collation factory to see if it can supply us with one.
     100                 :     */
     101               0 :     callCollNeeded(db, zName, nName);
     102               0 :     p = sqlite3FindCollSeq(db, ENC(db), zName, nName, 0);
     103                 :   }
     104             106 :   if( p && !p->xCmp && synthCollSeq(db, p) ){
     105               0 :     p = 0;
     106                 :   }
     107                 :   assert( !p || p->xCmp );
     108             106 :   return p;
     109                 : }
     110                 : 
     111                 : /*
     112                 : ** This routine is called on a collation sequence before it is used to
     113                 : ** check that it is defined. An undefined collation sequence exists when
     114                 : ** a database is loaded that contains references to collation sequences
     115                 : ** that have not been defined by sqlite3_create_collation() etc.
     116                 : **
     117                 : ** If required, this routine calls the 'collation needed' callback to
     118                 : ** request a definition of the collating sequence. If this doesn't work, 
     119                 : ** an equivalent collating sequence that uses a text encoding different
     120                 : ** from the main database is substituted, if one is available.
     121                 : */
     122             106 : int sqlite3CheckCollSeq(Parse *pParse, CollSeq *pColl){
     123             106 :   if( pColl ){
     124             106 :     const char *zName = pColl->zName;
     125             106 :     CollSeq *p = sqlite3GetCollSeq(pParse->db, pColl, zName, -1);
     126             106 :     if( !p ){
     127               0 :       if( pParse->nErr==0 ){
     128               0 :         sqlite3ErrorMsg(pParse, "no such collation sequence: %s", zName);
     129                 :       }
     130               0 :       pParse->nErr++;
     131               0 :       return SQLITE_ERROR;
     132                 :     }
     133                 :     assert( p==pColl );
     134                 :   }
     135             106 :   return SQLITE_OK;
     136                 : }
     137                 : 
     138                 : 
     139                 : 
     140                 : /*
     141                 : ** Locate and return an entry from the db.aCollSeq hash table. If the entry
     142                 : ** specified by zName and nName is not found and parameter 'create' is
     143                 : ** true, then create a new entry. Otherwise return NULL.
     144                 : **
     145                 : ** Each pointer stored in the sqlite3.aCollSeq hash table contains an
     146                 : ** array of three CollSeq structures. The first is the collation sequence
     147                 : ** prefferred for UTF-8, the second UTF-16le, and the third UTF-16be.
     148                 : **
     149                 : ** Stored immediately after the three collation sequences is a copy of
     150                 : ** the collation sequence name. A pointer to this string is stored in
     151                 : ** each collation sequence structure.
     152                 : */
     153                 : static CollSeq *findCollSeqEntry(
     154                 :   sqlite3 *db,
     155                 :   const char *zName,
     156                 :   int nName,
     157                 :   int create
     158            1451 : ){
     159                 :   CollSeq *pColl;
     160            1451 :   if( nName<0 ) nName = strlen(zName);
     161            1451 :   pColl = sqlite3HashFind(&db->aCollSeq, zName, nName);
     162                 : 
     163            1451 :   if( 0==pColl && create ){
     164             260 :     pColl = sqliteMalloc( 3*sizeof(*pColl) + nName + 1 );
     165             260 :     if( pColl ){
     166             260 :       CollSeq *pDel = 0;
     167             260 :       pColl[0].zName = (char*)&pColl[3];
     168             260 :       pColl[0].enc = SQLITE_UTF8;
     169             260 :       pColl[1].zName = (char*)&pColl[3];
     170             260 :       pColl[1].enc = SQLITE_UTF16LE;
     171             260 :       pColl[2].zName = (char*)&pColl[3];
     172             260 :       pColl[2].enc = SQLITE_UTF16BE;
     173             260 :       memcpy(pColl[0].zName, zName, nName);
     174             260 :       pColl[0].zName[nName] = 0;
     175             260 :       pDel = sqlite3HashInsert(&db->aCollSeq, pColl[0].zName, nName, pColl);
     176                 : 
     177                 :       /* If a malloc() failure occured in sqlite3HashInsert(), it will 
     178                 :       ** return the pColl pointer to be deleted (because it wasn't added
     179                 :       ** to the hash table).
     180                 :       */
     181                 :       assert( !pDel || (sqlite3MallocFailed() && pDel==pColl) );
     182             260 :       if( pDel ){
     183               0 :         sqliteFree(pDel);
     184               0 :         pColl = 0;
     185                 :       }
     186                 :     }
     187                 :   }
     188            1451 :   return pColl;
     189                 : }
     190                 : 
     191                 : /*
     192                 : ** Parameter zName points to a UTF-8 encoded string nName bytes long.
     193                 : ** Return the CollSeq* pointer for the collation sequence named zName
     194                 : ** for the encoding 'enc' from the database 'db'.
     195                 : **
     196                 : ** If the entry specified is not found and 'create' is true, then create a
     197                 : ** new entry.  Otherwise return NULL.
     198                 : **
     199                 : ** A separate function sqlite3LocateCollSeq() is a wrapper around
     200                 : ** this routine.  sqlite3LocateCollSeq() invokes the collation factory
     201                 : ** if necessary and generates an error message if the collating sequence
     202                 : ** cannot be found.
     203                 : */
     204                 : CollSeq *sqlite3FindCollSeq(
     205                 :   sqlite3 *db,
     206                 :   u8 enc,
     207                 :   const char *zName,
     208                 :   int nName,
     209                 :   int create
     210            1877 : ){
     211                 :   CollSeq *pColl;
     212            1877 :   if( zName ){
     213            1451 :     pColl = findCollSeqEntry(db, zName, nName, create);
     214                 :   }else{
     215             426 :     pColl = db->pDfltColl;
     216                 :   }
     217                 :   assert( SQLITE_UTF8==1 && SQLITE_UTF16LE==2 && SQLITE_UTF16BE==3 );
     218                 :   assert( enc>=SQLITE_UTF8 && enc<=SQLITE_UTF16BE );
     219            1877 :   if( pColl ) pColl += enc-1;
     220            1877 :   return pColl;
     221                 : }
     222                 : 
     223                 : /*
     224                 : ** Locate a user function given a name, a number of arguments and a flag
     225                 : ** indicating whether the function prefers UTF-16 over UTF-8.  Return a
     226                 : ** pointer to the FuncDef structure that defines that function, or return
     227                 : ** NULL if the function does not exist.
     228                 : **
     229                 : ** If the createFlag argument is true, then a new (blank) FuncDef
     230                 : ** structure is created and liked into the "db" structure if a
     231                 : ** no matching function previously existed.  When createFlag is true
     232                 : ** and the nArg parameter is -1, then only a function that accepts
     233                 : ** any number of arguments will be returned.
     234                 : **
     235                 : ** If createFlag is false and nArg is -1, then the first valid
     236                 : ** function found is returned.  A function is valid if either xFunc
     237                 : ** or xStep is non-zero.
     238                 : **
     239                 : ** If createFlag is false, then a function with the required name and
     240                 : ** number of arguments may be returned even if the eTextRep flag does not
     241                 : ** match that requested.
     242                 : */
     243                 : FuncDef *sqlite3FindFunction(
     244                 :   sqlite3 *db,       /* An open database */
     245                 :   const char *zName, /* Name of the function.  Not null-terminated */
     246                 :   int nName,         /* Number of characters in the name */
     247                 :   int nArg,          /* Number of arguments.  -1 means any number */
     248                 :   u8 enc,            /* Preferred text encoding */
     249                 :   int createFlag     /* Create new entry if true and does not otherwise exist */
     250           16548 : ){
     251                 :   FuncDef *p;         /* Iterator variable */
     252                 :   FuncDef *pFirst;    /* First function with this name */
     253           16548 :   FuncDef *pBest = 0; /* Best match found so far */
     254           16548 :   int bestmatch = 0;  
     255                 : 
     256                 : 
     257                 :   assert( enc==SQLITE_UTF8 || enc==SQLITE_UTF16LE || enc==SQLITE_UTF16BE );
     258           16548 :   if( nArg<-1 ) nArg = -1;
     259                 : 
     260           16548 :   pFirst = (FuncDef*)sqlite3HashFind(&db->aFunc, zName, nName);
     261           23238 :   for(p=pFirst; p; p=p->pNext){
     262                 :     /* During the search for the best function definition, bestmatch is set
     263                 :     ** as follows to indicate the quality of the match with the definition
     264                 :     ** pointed to by pBest:
     265                 :     **
     266                 :     ** 0: pBest is NULL. No match has been found.
     267                 :     ** 1: A variable arguments function that prefers UTF-8 when a UTF-16
     268                 :     **    encoding is requested, or vice versa.
     269                 :     ** 2: A variable arguments function that uses UTF-16BE when UTF-16LE is
     270                 :     **    requested, or vice versa.
     271                 :     ** 3: A variable arguments function using the same text encoding.
     272                 :     ** 4: A function with the exact number of arguments requested that
     273                 :     **    prefers UTF-8 when a UTF-16 encoding is requested, or vice versa.
     274                 :     ** 5: A function with the exact number of arguments requested that
     275                 :     **    prefers UTF-16LE when UTF-16BE is requested, or vice versa.
     276                 :     ** 6: An exact match.
     277                 :     **
     278                 :     ** A larger value of 'matchqual' indicates a more desirable match.
     279                 :     */
     280            6690 :     if( p->nArg==-1 || p->nArg==nArg || nArg==-1 ){
     281            3674 :       int match = 1;          /* Quality of this match */
     282            3674 :       if( p->nArg==nArg || nArg==-1 ){
     283            1590 :         match = 4;
     284                 :       }
     285            3674 :       if( enc==p->iPrefEnc ){
     286            3414 :         match += 2;
     287                 :       }
     288             260 :       else if( (enc==SQLITE_UTF16LE && p->iPrefEnc==SQLITE_UTF16BE) ||
     289                 :                (enc==SQLITE_UTF16BE && p->iPrefEnc==SQLITE_UTF16LE) ){
     290               0 :         match += 1;
     291                 :       }
     292                 : 
     293            3674 :       if( match>bestmatch ){
     294            3154 :         pBest = p;
     295            3154 :         bestmatch = match;
     296                 :       }
     297                 :     }
     298                 :   }
     299                 : 
     300                 :   /* If the createFlag parameter is true, and the seach did not reveal an
     301                 :   ** exact match for the name, number of arguments and encoding, then add a
     302                 :   ** new entry to the hash table and return it.
     303                 :   */
     304           16548 :   if( createFlag && bestmatch<6 && 
     305                 :       (pBest = sqliteMalloc(sizeof(*pBest)+nName))!=0 ){
     306            7542 :     pBest->nArg = nArg;
     307            7542 :     pBest->pNext = pFirst;
     308            7542 :     pBest->iPrefEnc = enc;
     309            7542 :     memcpy(pBest->zName, zName, nName);
     310            7542 :     pBest->zName[nName] = 0;
     311            7542 :     if( pBest==sqlite3HashInsert(&db->aFunc,pBest->zName,nName,(void*)pBest) ){
     312               0 :       sqliteFree(pBest);
     313               0 :       return 0;
     314                 :     }
     315                 :   }
     316                 : 
     317           16548 :   if( pBest && (pBest->xStep || pBest->xFunc || createFlag) ){
     318            9526 :     return pBest;
     319                 :   }
     320            7022 :   return 0;
     321                 : }
     322                 : 
     323                 : /*
     324                 : ** Free all resources held by the schema structure. The void* argument points
     325                 : ** at a Schema struct. This function does not call sqliteFree() on the 
     326                 : ** pointer itself, it just cleans up subsiduary resources (i.e. the contents
     327                 : ** of the schema hash tables).
     328                 : */
     329             516 : void sqlite3SchemaFree(void *p){
     330                 :   Hash temp1;
     331                 :   Hash temp2;
     332                 :   HashElem *pElem;
     333             516 :   Schema *pSchema = (Schema *)p;
     334                 : 
     335             516 :   temp1 = pSchema->tblHash;
     336             516 :   temp2 = pSchema->trigHash;
     337             516 :   sqlite3HashInit(&pSchema->trigHash, SQLITE_HASH_STRING, 0);
     338             516 :   sqlite3HashClear(&pSchema->aFKey);
     339             516 :   sqlite3HashClear(&pSchema->idxHash);
     340             516 :   for(pElem=sqliteHashFirst(&temp2); pElem; pElem=sqliteHashNext(pElem)){
     341               0 :     sqlite3DeleteTrigger((Trigger*)sqliteHashData(pElem));
     342                 :   }
     343             516 :   sqlite3HashClear(&temp2);
     344             516 :   sqlite3HashInit(&pSchema->tblHash, SQLITE_HASH_STRING, 0);
     345             782 :   for(pElem=sqliteHashFirst(&temp1); pElem; pElem=sqliteHashNext(pElem)){
     346             266 :     Table *pTab = sqliteHashData(pElem);
     347             266 :     sqlite3DeleteTable(pTab);
     348                 :   }
     349             516 :   sqlite3HashClear(&temp1);
     350             516 :   pSchema->pSeqTab = 0;
     351             516 :   pSchema->flags &= ~DB_SchemaLoaded;
     352             516 : }
     353                 : 
     354                 : /*
     355                 : ** Find and return the schema associated with a BTree.  Create
     356                 : ** a new one if necessary.
     357                 : */
     358             260 : Schema *sqlite3SchemaGet(Btree *pBt){
     359                 :   Schema * p;
     360             260 :   if( pBt ){
     361             130 :     p = (Schema *)sqlite3BtreeSchema(pBt,sizeof(Schema),sqlite3SchemaFree);
     362                 :   }else{
     363             130 :     p = (Schema *)sqliteMalloc(sizeof(Schema));
     364                 :   }
     365             260 :   if( p && 0==p->file_format ){
     366             260 :     sqlite3HashInit(&p->tblHash, SQLITE_HASH_STRING, 0);
     367             260 :     sqlite3HashInit(&p->idxHash, SQLITE_HASH_STRING, 0);
     368             260 :     sqlite3HashInit(&p->trigHash, SQLITE_HASH_STRING, 0);
     369             260 :     sqlite3HashInit(&p->aFKey, SQLITE_HASH_STRING, 1);
     370             260 :     p->enc = SQLITE_UTF8;
     371                 :   }
     372             260 :   return p;
     373                 : }

Generated by: LTP GCOV extension version 1.5

Generated at Thu, 19 Nov 2009 08:20:16 +0000 (5 days ago)

Copyright © 2005-2009 The PHP Group
All rights reserved.