engine/sqlite/src/func.cpp
author Lars Persson <lars.persson@embeddev.se>
Wed, 31 Mar 2010 18:09:02 +0200
changeset 64 b52f6033af15
parent 2 29cda98b007e
permissions -rw-r--r--
Add so image conversion is done in feedinfo if image already exist. Check in feedengine if image exist from previous database(files might exist, even though the db is corrupt.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
2
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
     1
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
     2
** 2002 February 23
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
     3
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
     4
** The author disclaims copyright to this source code.  In place of
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
     5
** a legal notice, here is a blessing:
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
     6
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
     7
**    May you do good and not evil.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
     8
**    May you find forgiveness for yourself and forgive others.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
     9
**    May you share freely, never taking more than you give.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    10
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    11
*************************************************************************
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    12
** This file contains the C functions that implement various SQL
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    13
** functions of SQLite.  
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    14
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    15
** There is only one exported symbol in this file - the function
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    16
** sqliteRegisterBuildinFunctions() found at the bottom of the file.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    17
** All other code has file scope.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    18
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    19
** $Id: func.cpp 1282 2008-11-13 09:31:33Z LarsPson $
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    20
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    21
#include "sqliteInt.h"
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    22
#include <ctype.h>
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    23
#include <stdlib.h>
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    24
#include <assert.h>
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    25
#include "vdbeInt.h"
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    26
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    27
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    28
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    29
** Return the collating function associated with a function.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    30
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    31
static CollSeq *sqlite3GetFuncCollSeq(sqlite3_context *context){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    32
  return context->pColl;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    33
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    34
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    35
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    36
** Implementation of the non-aggregate min() and max() functions
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    37
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    38
static void minmaxFunc(
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    39
  sqlite3_context *context,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    40
  int argc,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    41
  sqlite3_value **argv
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    42
){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    43
  int i;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    44
  int mask;    /* 0 for min() or 0xffffffff for max() */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    45
  int iBest;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    46
  CollSeq *pColl;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    47
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    48
  if( argc==0 ) return;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    49
  mask = sqlite3_user_data(context)==0 ? 0 : -1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    50
  pColl = sqlite3GetFuncCollSeq(context);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    51
  assert( pColl );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    52
  assert( mask==-1 || mask==0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    53
  iBest = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    54
  if( sqlite3_value_type(argv[0])==SQLITE_NULL ) return;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    55
  for(i=1; i<argc; i++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    56
    if( sqlite3_value_type(argv[i])==SQLITE_NULL ) return;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    57
    if( (sqlite3MemCompare(argv[iBest], argv[i], pColl)^mask)>=0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    58
      iBest = i;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    59
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    60
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    61
  sqlite3_result_value(context, argv[iBest]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    62
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    63
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    64
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    65
** Return the type of the argument.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    66
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    67
static void typeofFunc(
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    68
  sqlite3_context *context,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    69
  int argc,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    70
  sqlite3_value **argv
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    71
){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    72
  const char *z = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    73
  switch( sqlite3_value_type(argv[0]) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    74
    case SQLITE_NULL:    z = "null";    break;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    75
    case SQLITE_INTEGER: z = "integer"; break;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    76
    case SQLITE_TEXT:    z = "text";    break;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    77
    case SQLITE_FLOAT:   z = "real";    break;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    78
    case SQLITE_BLOB:    z = "blob";    break;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    79
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    80
  sqlite3_result_text(context, z, -1, SQLITE_STATIC);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    81
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    82
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    83
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    84
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    85
** Implementation of the length() function
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    86
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    87
static void lengthFunc(
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    88
  sqlite3_context *context,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    89
  int argc,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    90
  sqlite3_value **argv
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    91
){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    92
  int len;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    93
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    94
  assert( argc==1 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    95
  switch( sqlite3_value_type(argv[0]) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    96
    case SQLITE_BLOB:
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    97
    case SQLITE_INTEGER:
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    98
    case SQLITE_FLOAT: {
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    99
      sqlite3_result_int(context, sqlite3_value_bytes(argv[0]));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   100
      break;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   101
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   102
    case SQLITE_TEXT: {
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   103
      const unsigned char *z = sqlite3_value_text(argv[0]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   104
      if( z==0 ) return;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   105
      len = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   106
      while( *z ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   107
        len++;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   108
        SQLITE_SKIP_UTF8(z);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   109
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   110
      sqlite3_result_int(context, len);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   111
      break;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   112
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   113
    default: {
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   114
      sqlite3_result_null(context);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   115
      break;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   116
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   117
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   118
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   119
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   120
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   121
** Implementation of the abs() function
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   122
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   123
static void absFunc(sqlite3_context *context, int argc, sqlite3_value **argv){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   124
  assert( argc==1 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   125
  switch( sqlite3_value_type(argv[0]) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   126
    case SQLITE_INTEGER: {
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   127
      i64 iVal = sqlite3_value_int64(argv[0]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   128
      if( iVal<0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   129
        if( (iVal<<1)==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   130
          sqlite3_result_error(context, "integer overflow", -1);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   131
          return;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   132
        }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   133
        iVal = -iVal;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   134
      } 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   135
      sqlite3_result_int64(context, iVal);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   136
      break;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   137
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   138
    case SQLITE_NULL: {
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   139
      sqlite3_result_null(context);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   140
      break;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   141
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   142
    default: {
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   143
      double rVal = sqlite3_value_double(argv[0]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   144
      if( rVal<0 ) rVal = -rVal;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   145
      sqlite3_result_double(context, rVal);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   146
      break;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   147
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   148
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   149
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   150
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   151
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   152
** Implementation of the substr() function.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   153
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   154
** substr(x,p1,p2)  returns p2 characters of x[] beginning with p1.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   155
** p1 is 1-indexed.  So substr(x,1,1) returns the first character
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   156
** of x.  If x is text, then we actually count UTF-8 characters.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   157
** If x is a blob, then we count bytes.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   158
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   159
** If p1 is negative, then we begin abs(p1) from the end of x[].
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   160
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   161
static void substrFunc(
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   162
  sqlite3_context *context,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   163
  int argc,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   164
  sqlite3_value **argv
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   165
){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   166
  const unsigned char *z;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   167
  const unsigned char *z2;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   168
  int len;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   169
  int p0type;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   170
  i64 p1, p2;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   171
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   172
  assert( argc==3 || argc==2 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   173
  p0type = sqlite3_value_type(argv[0]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   174
  if( p0type==SQLITE_BLOB ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   175
    len = sqlite3_value_bytes(argv[0]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   176
    z = (const unsigned char*)sqlite3_value_blob(argv[0]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   177
    if( z==0 ) return;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   178
    assert( len==sqlite3_value_bytes(argv[0]) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   179
  }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   180
    z = sqlite3_value_text(argv[0]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   181
    if( z==0 ) return;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   182
    len = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   183
    for(z2=z; *z2; len++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   184
      SQLITE_SKIP_UTF8(z2);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   185
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   186
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   187
  p1 = sqlite3_value_int(argv[1]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   188
  if( argc==3 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   189
    p2 = sqlite3_value_int(argv[2]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   190
  }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   191
    p2 = SQLITE_MAX_LENGTH;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   192
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   193
  if( p1<0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   194
    p1 += len;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   195
    if( p1<0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   196
      p2 += p1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   197
      p1 = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   198
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   199
  }else if( p1>0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   200
    p1--;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   201
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   202
  if( p1+p2>len ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   203
    p2 = len-p1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   204
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   205
  if( p0type!=SQLITE_BLOB ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   206
    while( *z && p1 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   207
      SQLITE_SKIP_UTF8(z);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   208
      p1--;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   209
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   210
    for(z2=z; *z2 && p2; p2--){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   211
      SQLITE_SKIP_UTF8(z2);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   212
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   213
    sqlite3_result_text(context, (char*)z, z2-z, SQLITE_TRANSIENT);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   214
  }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   215
    if( p2<0 ) p2 = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   216
    sqlite3_result_blob(context, (char*)&z[p1], p2, SQLITE_TRANSIENT);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   217
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   218
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   219
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   220
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   221
** Implementation of the round() function
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   222
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   223
static void roundFunc(sqlite3_context *context, int argc, sqlite3_value **argv){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   224
  int n = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   225
  double r;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   226
  char zBuf[500];  /* larger than the %f representation of the largest double */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   227
  assert( argc==1 || argc==2 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   228
  if( argc==2 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   229
    if( SQLITE_NULL==sqlite3_value_type(argv[1]) ) return;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   230
    n = sqlite3_value_int(argv[1]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   231
    if( n>30 ) n = 30;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   232
    if( n<0 ) n = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   233
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   234
  if( sqlite3_value_type(argv[0])==SQLITE_NULL ) return;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   235
  r = sqlite3_value_double(argv[0]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   236
  sqlite3_snprintf(sizeof(zBuf),zBuf,"%.*f",n,r);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   237
  sqlite3AtoF(zBuf, &r);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   238
  sqlite3_result_double(context, r);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   239
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   240
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   241
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   242
** Allocate nByte bytes of space using sqlite3_malloc(). If the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   243
** allocation fails, call sqlite3_result_error_nomem() to notify
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   244
** the database handle that malloc() has failed.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   245
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   246
static void *contextMalloc(sqlite3_context *context, int nByte){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   247
  char *z = (char*)sqlite3_malloc(nByte);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   248
  if( !z && nByte>0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   249
    sqlite3_result_error_nomem(context);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   250
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   251
  return z;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   252
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   253
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   254
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   255
** Implementation of the upper() and lower() SQL functions.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   256
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   257
static void upperFunc(sqlite3_context *context, int argc, sqlite3_value **argv){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   258
  char *z1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   259
  const char *z2;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   260
  int i, n;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   261
  if( argc<1 || SQLITE_NULL==sqlite3_value_type(argv[0]) ) return;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   262
  z2 = (char*)sqlite3_value_text(argv[0]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   263
  n = sqlite3_value_bytes(argv[0]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   264
  /* Verify that the call to _bytes() does not invalidate the _text() pointer */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   265
  assert( z2==(char*)sqlite3_value_text(argv[0]) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   266
  if( z2 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   267
    z1 = (char*)contextMalloc(context, n+1);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   268
    if( z1 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   269
      memcpy(z1, z2, n+1);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   270
      for(i=0; z1[i]; i++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   271
        z1[i] = toupper(z1[i]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   272
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   273
      sqlite3_result_text(context, z1, -1, sqlite3_free);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   274
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   275
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   276
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   277
static void lowerFunc(sqlite3_context *context, int argc, sqlite3_value **argv){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   278
  char *z1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   279
  const char *z2;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   280
  int i, n;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   281
  if( argc<1 || SQLITE_NULL==sqlite3_value_type(argv[0]) ) return;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   282
  z2 = (char*)sqlite3_value_text(argv[0]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   283
  n = sqlite3_value_bytes(argv[0]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   284
  /* Verify that the call to _bytes() does not invalidate the _text() pointer */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   285
  assert( z2==(char*)sqlite3_value_text(argv[0]) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   286
  if( z2 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   287
    z1 = (char*)contextMalloc(context, n+1);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   288
    if( z1 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   289
      memcpy(z1, z2, n+1);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   290
      for(i=0; z1[i]; i++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   291
        z1[i] = tolower(z1[i]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   292
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   293
      sqlite3_result_text(context, z1, -1, sqlite3_free);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   294
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   295
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   296
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   297
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   298
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   299
** Implementation of the IFNULL(), NVL(), and COALESCE() functions.  
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   300
** All three do the same thing.  They return the first non-NULL
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   301
** argument.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   302
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   303
static void ifnullFunc(
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   304
  sqlite3_context *context,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   305
  int argc,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   306
  sqlite3_value **argv
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   307
){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   308
  int i;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   309
  for(i=0; i<argc; i++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   310
    if( SQLITE_NULL!=sqlite3_value_type(argv[i]) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   311
      sqlite3_result_value(context, argv[i]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   312
      break;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   313
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   314
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   315
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   316
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   317
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   318
** Implementation of random().  Return a random integer.  
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   319
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   320
static void randomFunc(
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   321
  sqlite3_context *context,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   322
  int argc,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   323
  sqlite3_value **argv
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   324
){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   325
  sqlite_int64 r;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   326
  sqlite3Randomness(sizeof(r), &r);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   327
  if( (r<<1)==0 ) r = 0;  /* Prevent 0x8000.... as the result so that we */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   328
                          /* can always do abs() of the result */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   329
  sqlite3_result_int64(context, r);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   330
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   331
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   332
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   333
** Implementation of randomblob(N).  Return a random blob
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   334
** that is N bytes long.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   335
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   336
static void randomBlob(
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   337
  sqlite3_context *context,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   338
  int argc,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   339
  sqlite3_value **argv
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   340
){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   341
  int n;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   342
  unsigned char *p;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   343
  assert( argc==1 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   344
  n = sqlite3_value_int(argv[0]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   345
  if( n<1 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   346
    n = 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   347
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   348
  if( n>SQLITE_MAX_LENGTH ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   349
    sqlite3_result_error_toobig(context);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   350
    return;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   351
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   352
  p = (unsigned char*)contextMalloc(context, n);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   353
  if( p ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   354
    sqlite3Randomness(n, p);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   355
    sqlite3_result_blob(context, (char*)p, n, sqlite3_free);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   356
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   357
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   358
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   359
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   360
** Implementation of the last_insert_rowid() SQL function.  The return
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   361
** value is the same as the sqlite3_last_insert_rowid() API function.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   362
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   363
static void last_insert_rowid(
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   364
  sqlite3_context *context, 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   365
  int arg, 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   366
  sqlite3_value **argv
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   367
){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   368
  sqlite3 *db = (sqlite3*)sqlite3_user_data(context);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   369
  sqlite3_result_int64(context, sqlite3_last_insert_rowid(db));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   370
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   371
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   372
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   373
** Implementation of the changes() SQL function.  The return value is the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   374
** same as the sqlite3_changes() API function.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   375
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   376
static void changes(
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   377
  sqlite3_context *context,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   378
  int arg,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   379
  sqlite3_value **argv
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   380
){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   381
  sqlite3 *db = (sqlite3*)sqlite3_user_data(context);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   382
  sqlite3_result_int(context, sqlite3_changes(db));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   383
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   384
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   385
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   386
** Implementation of the total_changes() SQL function.  The return value is
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   387
** the same as the sqlite3_total_changes() API function.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   388
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   389
static void total_changes(
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   390
  sqlite3_context *context,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   391
  int arg,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   392
  sqlite3_value **argv
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   393
){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   394
  sqlite3 *db = (sqlite3*)sqlite3_user_data(context);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   395
  sqlite3_result_int(context, sqlite3_total_changes(db));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   396
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   397
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   398
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   399
** A structure defining how to do GLOB-style comparisons.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   400
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   401
struct compareInfo {
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   402
  u8 matchAll;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   403
  u8 matchOne;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   404
  u8 matchSet;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   405
  u8 noCase;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   406
};
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   407
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   408
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   409
** For LIKE and GLOB matching on EBCDIC machines, assume that every
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   410
** character is exactly one byte in size.  Also, all characters are
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   411
** able to participate in upper-case-to-lower-case mappings in EBCDIC
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   412
** whereas only characters less than 0x80 do in ASCII.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   413
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   414
#if defined(SQLITE_EBCDIC)
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   415
# define sqlite3Utf8Read(A,B,C)  (*(A++))
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   416
# define GlogUpperToLower(A)     A = sqlite3UpperToLower[A]
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   417
#else
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   418
# define GlogUpperToLower(A)     if( A<0x80 ){ A = sqlite3UpperToLower[A]; }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   419
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   420
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   421
static const struct compareInfo globInfo = { '*', '?', '[', 0 };
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   422
/* The correct SQL-92 behavior is for the LIKE operator to ignore
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   423
** case.  Thus  'a' LIKE 'A' would be true. */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   424
static const struct compareInfo likeInfoNorm = { '%', '_',   0, 1 };
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   425
/* If SQLITE_CASE_SENSITIVE_LIKE is defined, then the LIKE operator
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   426
** is case sensitive causing 'a' LIKE 'A' to be false */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   427
static const struct compareInfo likeInfoAlt = { '%', '_',   0, 0 };
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   428
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   429
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   430
** Compare two UTF-8 strings for equality where the first string can
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   431
** potentially be a "glob" expression.  Return true (1) if they
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   432
** are the same and false (0) if they are different.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   433
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   434
** Globbing rules:
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   435
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   436
**      '*'       Matches any sequence of zero or more characters.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   437
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   438
**      '?'       Matches exactly one character.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   439
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   440
**     [...]      Matches one character from the enclosed list of
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   441
**                characters.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   442
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   443
**     [^...]     Matches one character not in the enclosed list.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   444
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   445
** With the [...] and [^...] matching, a ']' character can be included
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   446
** in the list by making it the first character after '[' or '^'.  A
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   447
** range of characters can be specified using '-'.  Example:
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   448
** "[a-z]" matches any single lower-case letter.  To match a '-', make
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   449
** it the last character in the list.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   450
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   451
** This routine is usually quick, but can be N**2 in the worst case.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   452
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   453
** Hints: to match '*' or '?', put them in "[]".  Like this:
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   454
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   455
**         abc[*]xyz        Matches "abc*xyz" only
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   456
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   457
static int patternCompare(
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   458
  const u8 *zPattern,              /* The glob pattern */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   459
  const u8 *zString,               /* The string to compare against the glob */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   460
  const struct compareInfo *pInfo, /* Information about how to do the compare */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   461
  const int esc                    /* The escape character */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   462
){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   463
  int c, c2;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   464
  int invert;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   465
  int seen;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   466
  u8 matchOne = pInfo->matchOne;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   467
  u8 matchAll = pInfo->matchAll;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   468
  u8 matchSet = pInfo->matchSet;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   469
  u8 noCase = pInfo->noCase; 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   470
  int prevEscape = 0;     /* True if the previous character was 'escape' */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   471
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   472
  while( (c = sqlite3Utf8Read(zPattern,0,&zPattern))!=0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   473
    if( !prevEscape && c==matchAll ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   474
      while( (c=sqlite3Utf8Read(zPattern,0,&zPattern)) == matchAll
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   475
               || c == matchOne ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   476
        if( c==matchOne && sqlite3Utf8Read(zString, 0, &zString)==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   477
          return 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   478
        }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   479
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   480
      if( c==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   481
        return 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   482
      }else if( c==esc ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   483
        c = sqlite3Utf8Read(zPattern, 0, &zPattern);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   484
        if( c==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   485
          return 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   486
        }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   487
      }else if( c==matchSet ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   488
        assert( esc==0 );         /* This is GLOB, not LIKE */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   489
        assert( matchSet<0x80 );  /* '[' is a single-byte character */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   490
        while( *zString && patternCompare(&zPattern[-1],zString,pInfo,esc)==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   491
          SQLITE_SKIP_UTF8(zString);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   492
        }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   493
        return *zString!=0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   494
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   495
      while( (c2 = sqlite3Utf8Read(zString,0,&zString))!=0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   496
        if( noCase ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   497
          GlogUpperToLower(c2);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   498
          GlogUpperToLower(c);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   499
          while( c2 != 0 && c2 != c ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   500
            c2 = sqlite3Utf8Read(zString, 0, &zString);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   501
            GlogUpperToLower(c2);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   502
          }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   503
        }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   504
          while( c2 != 0 && c2 != c ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   505
            c2 = sqlite3Utf8Read(zString, 0, &zString);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   506
          }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   507
        }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   508
        if( c2==0 ) return 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   509
        if( patternCompare(zPattern,zString,pInfo,esc) ) return 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   510
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   511
      return 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   512
    }else if( !prevEscape && c==matchOne ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   513
      if( sqlite3Utf8Read(zString, 0, &zString)==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   514
        return 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   515
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   516
    }else if( c==matchSet ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   517
      int prior_c = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   518
      assert( esc==0 );    /* This only occurs for GLOB, not LIKE */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   519
      seen = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   520
      invert = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   521
      c = sqlite3Utf8Read(zString, 0, &zString);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   522
      if( c==0 ) return 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   523
      c2 = sqlite3Utf8Read(zPattern, 0, &zPattern);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   524
      if( c2=='^' ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   525
        invert = 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   526
        c2 = sqlite3Utf8Read(zPattern, 0, &zPattern);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   527
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   528
      if( c2==']' ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   529
        if( c==']' ) seen = 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   530
        c2 = sqlite3Utf8Read(zPattern, 0, &zPattern);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   531
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   532
      while( c2 && c2!=']' ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   533
        if( c2=='-' && zPattern[0]!=']' && zPattern[0]!=0 && prior_c>0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   534
          c2 = sqlite3Utf8Read(zPattern, 0, &zPattern);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   535
          if( c>=prior_c && c<=c2 ) seen = 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   536
          prior_c = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   537
        }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   538
          if( c==c2 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   539
            seen = 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   540
          }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   541
          prior_c = c2;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   542
        }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   543
        c2 = sqlite3Utf8Read(zPattern, 0, &zPattern);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   544
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   545
      if( c2==0 || (seen ^ invert)==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   546
        return 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   547
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   548
    }else if( esc==c && !prevEscape ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   549
      prevEscape = 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   550
    }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   551
      c2 = sqlite3Utf8Read(zString, 0, &zString);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   552
      if( noCase ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   553
        GlogUpperToLower(c);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   554
        GlogUpperToLower(c2);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   555
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   556
      if( c!=c2 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   557
        return 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   558
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   559
      prevEscape = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   560
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   561
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   562
  return *zString==0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   563
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   564
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   565
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   566
** Count the number of times that the LIKE operator (or GLOB which is
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   567
** just a variation of LIKE) gets called.  This is used for testing
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   568
** only.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   569
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   570
#ifdef SQLITE_TEST
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   571
int sqlite3_like_count = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   572
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   573
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   574
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   575
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   576
** Implementation of the like() SQL function.  This function implements
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   577
** the build-in LIKE operator.  The first argument to the function is the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   578
** pattern and the second argument is the string.  So, the SQL statements:
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   579
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   580
**       A LIKE B
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   581
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   582
** is implemented as like(B,A).
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   583
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   584
** This same function (with a different compareInfo structure) computes
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   585
** the GLOB operator.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   586
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   587
static void likeFunc(
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   588
  sqlite3_context *context, 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   589
  int argc, 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   590
  sqlite3_value **argv
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   591
){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   592
  const unsigned char *zA, *zB;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   593
  int escape = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   594
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   595
  zB = sqlite3_value_text(argv[0]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   596
  zA = sqlite3_value_text(argv[1]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   597
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   598
  /* Limit the length of the LIKE or GLOB pattern to avoid problems
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   599
  ** of deep recursion and N*N behavior in patternCompare().
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   600
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   601
  if( sqlite3_value_bytes(argv[0])>SQLITE_MAX_LIKE_PATTERN_LENGTH ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   602
    sqlite3_result_error(context, "LIKE or GLOB pattern too complex", -1);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   603
    return;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   604
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   605
  assert( zB==sqlite3_value_text(argv[0]) );  /* Encoding did not change */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   606
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   607
  if( argc==3 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   608
    /* The escape character string must consist of a single UTF-8 character.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   609
    ** Otherwise, return an error.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   610
    */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   611
    const unsigned char *zEsc = sqlite3_value_text(argv[2]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   612
    if( zEsc==0 ) return;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   613
    if( sqlite3Utf8CharLen((char*)zEsc, -1)!=1 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   614
      sqlite3_result_error(context, 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   615
          "ESCAPE expression must be a single character", -1);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   616
      return;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   617
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   618
    escape = sqlite3Utf8Read(zEsc, 0, &zEsc);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   619
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   620
  if( zA && zB ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   621
    compareInfo *pInfo = (compareInfo*)sqlite3_user_data(context);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   622
#ifdef SQLITE_TEST
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   623
    sqlite3_like_count++;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   624
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   625
    
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   626
    sqlite3_result_int(context, patternCompare(zB, zA, pInfo, escape));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   627
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   628
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   629
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   630
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   631
** Implementation of the NULLIF(x,y) function.  The result is the first
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   632
** argument if the arguments are different.  The result is NULL if the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   633
** arguments are equal to each other.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   634
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   635
static void nullifFunc(
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   636
  sqlite3_context *context,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   637
  int argc,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   638
  sqlite3_value **argv
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   639
){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   640
  CollSeq *pColl = sqlite3GetFuncCollSeq(context);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   641
  if( sqlite3MemCompare(argv[0], argv[1], pColl)!=0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   642
    sqlite3_result_value(context, argv[0]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   643
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   644
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   645
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   646
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   647
** Implementation of the VERSION(*) function.  The result is the version
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   648
** of the SQLite library that is running.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   649
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   650
static void versionFunc(
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   651
  sqlite3_context *context,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   652
  int argc,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   653
  sqlite3_value **argv
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   654
){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   655
  sqlite3_result_text(context, sqlite3_version, -1, SQLITE_STATIC);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   656
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   657
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   658
/* Array for converting from half-bytes (nybbles) into ASCII hex
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   659
** digits. */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   660
static const char hexdigits[] = {
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   661
  '0', '1', '2', '3', '4', '5', '6', '7',
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   662
  '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   663
};
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   664
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   665
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   666
** EXPERIMENTAL - This is not an official function.  The interface may
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   667
** change.  This function may disappear.  Do not write code that depends
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   668
** on this function.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   669
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   670
** Implementation of the QUOTE() function.  This function takes a single
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   671
** argument.  If the argument is numeric, the return value is the same as
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   672
** the argument.  If the argument is NULL, the return value is the string
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   673
** "NULL".  Otherwise, the argument is enclosed in single quotes with
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   674
** single-quote escapes.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   675
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   676
static void quoteFunc(sqlite3_context *context, int argc, sqlite3_value **argv){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   677
  if( argc<1 ) return;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   678
  switch( sqlite3_value_type(argv[0]) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   679
    case SQLITE_NULL: {
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   680
      sqlite3_result_text(context, "NULL", 4, SQLITE_STATIC);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   681
      break;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   682
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   683
    case SQLITE_INTEGER:
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   684
    case SQLITE_FLOAT: {
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   685
      sqlite3_result_value(context, argv[0]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   686
      break;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   687
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   688
    case SQLITE_BLOB: {
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   689
      char *zText = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   690
      char const *zBlob = (const char*)sqlite3_value_blob(argv[0]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   691
      int nBlob = sqlite3_value_bytes(argv[0]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   692
      assert( zBlob==sqlite3_value_blob(argv[0]) ); /* No encoding change */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   693
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   694
      if( 2*nBlob+4>SQLITE_MAX_LENGTH ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   695
        sqlite3_result_error_toobig(context);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   696
        return;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   697
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   698
      zText = (char *)contextMalloc(context, (2*nBlob)+4); 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   699
      if( zText ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   700
        int i;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   701
        for(i=0; i<nBlob; i++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   702
          zText[(i*2)+2] = hexdigits[(zBlob[i]>>4)&0x0F];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   703
          zText[(i*2)+3] = hexdigits[(zBlob[i])&0x0F];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   704
        }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   705
        zText[(nBlob*2)+2] = '\'';
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   706
        zText[(nBlob*2)+3] = '\0';
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   707
        zText[0] = 'X';
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   708
        zText[1] = '\'';
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   709
        sqlite3_result_text(context, zText, -1, SQLITE_TRANSIENT);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   710
        sqlite3_free(zText);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   711
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   712
      break;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   713
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   714
    case SQLITE_TEXT: {
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   715
      int i,j;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   716
      u64 n;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   717
      const unsigned char *zArg = sqlite3_value_text(argv[0]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   718
      char *z;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   719
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   720
      if( zArg==0 ) return;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   721
      for(i=0, n=0; zArg[i]; i++){ if( zArg[i]=='\'' ) n++; }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   722
      if( i+n+3>SQLITE_MAX_LENGTH ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   723
        sqlite3_result_error_toobig(context);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   724
        return;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   725
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   726
      z = (char*)contextMalloc(context, i+n+3);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   727
      if( z ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   728
        z[0] = '\'';
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   729
        for(i=0, j=1; zArg[i]; i++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   730
          z[j++] = zArg[i];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   731
          if( zArg[i]=='\'' ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   732
            z[j++] = '\'';
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   733
          }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   734
        }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   735
        z[j++] = '\'';
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   736
        z[j] = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   737
        sqlite3_result_text(context, z, j, sqlite3_free);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   738
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   739
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   740
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   741
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   742
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   743
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   744
** The hex() function.  Interpret the argument as a blob.  Return
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   745
** a hexadecimal rendering as text.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   746
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   747
static void hexFunc(
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   748
  sqlite3_context *context,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   749
  int argc,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   750
  sqlite3_value **argv
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   751
){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   752
  int i, n;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   753
  const unsigned char *pBlob;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   754
  char *zHex, *z;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   755
  assert( argc==1 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   756
  pBlob = (const unsigned char*)sqlite3_value_blob(argv[0]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   757
  n = sqlite3_value_bytes(argv[0]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   758
  if( n*2+1>SQLITE_MAX_LENGTH ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   759
    sqlite3_result_error_toobig(context);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   760
    return;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   761
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   762
  assert( pBlob==sqlite3_value_blob(argv[0]) );  /* No encoding change */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   763
  z = zHex = (char*)contextMalloc(context, n*2 + 1);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   764
  if( zHex ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   765
    for(i=0; i<n; i++, pBlob++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   766
      unsigned char c = *pBlob;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   767
      *(z++) = hexdigits[(c>>4)&0xf];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   768
      *(z++) = hexdigits[c&0xf];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   769
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   770
    *z = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   771
    sqlite3_result_text(context, zHex, n*2, sqlite3_free);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   772
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   773
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   774
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   775
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   776
** The zeroblob(N) function returns a zero-filled blob of size N bytes.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   777
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   778
static void zeroblobFunc(
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   779
  sqlite3_context *context,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   780
  int argc,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   781
  sqlite3_value **argv
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   782
){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   783
  i64 n;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   784
  assert( argc==1 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   785
  n = sqlite3_value_int64(argv[0]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   786
  if( n>SQLITE_MAX_LENGTH ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   787
    sqlite3_result_error_toobig(context);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   788
  }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   789
    sqlite3_result_zeroblob(context, n);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   790
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   791
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   792
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   793
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   794
** The replace() function.  Three arguments are all strings: call
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   795
** them A, B, and C. The result is also a string which is derived
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   796
** from A by replacing every occurance of B with C.  The match
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   797
** must be exact.  Collating sequences are not used.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   798
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   799
static void replaceFunc(
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   800
  sqlite3_context *context,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   801
  int argc,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   802
  sqlite3_value **argv
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   803
){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   804
  const unsigned char *zStr;        /* The input string A */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   805
  const unsigned char *zPattern;    /* The pattern string B */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   806
  const unsigned char *zRep;        /* The replacement string C */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   807
  unsigned char *zOut;              /* The output */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   808
  int nStr;                /* Size of zStr */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   809
  int nPattern;            /* Size of zPattern */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   810
  int nRep;                /* Size of zRep */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   811
  i64 nOut;                /* Maximum size of zOut */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   812
  int loopLimit;           /* Last zStr[] that might match zPattern[] */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   813
  int i, j;                /* Loop counters */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   814
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   815
  assert( argc==3 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   816
  zStr = sqlite3_value_text(argv[0]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   817
  if( zStr==0 ) return;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   818
  nStr = sqlite3_value_bytes(argv[0]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   819
  assert( zStr==sqlite3_value_text(argv[0]) );  /* No encoding change */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   820
  zPattern = sqlite3_value_text(argv[1]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   821
  if( zPattern==0 || zPattern[0]==0 ) return;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   822
  nPattern = sqlite3_value_bytes(argv[1]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   823
  assert( zPattern==sqlite3_value_text(argv[1]) );  /* No encoding change */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   824
  zRep = sqlite3_value_text(argv[2]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   825
  if( zRep==0 ) return;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   826
  nRep = sqlite3_value_bytes(argv[2]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   827
  assert( zRep==sqlite3_value_text(argv[2]) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   828
  nOut = nStr + 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   829
  assert( nOut<SQLITE_MAX_LENGTH );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   830
  zOut = (unsigned char*)contextMalloc(context, (int)nOut);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   831
  if( zOut==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   832
    return;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   833
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   834
  loopLimit = nStr - nPattern;  
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   835
  for(i=j=0; i<=loopLimit; i++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   836
    if( zStr[i]!=zPattern[0] || memcmp(&zStr[i], zPattern, nPattern) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   837
      zOut[j++] = zStr[i];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   838
    }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   839
      u8 *zOld;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   840
      nOut += nRep - nPattern;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   841
      if( nOut>=SQLITE_MAX_LENGTH ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   842
        sqlite3_result_error_toobig(context);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   843
        sqlite3_free(zOut);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   844
        return;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   845
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   846
      zOld = zOut;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   847
      zOut = (unsigned char*)sqlite3_realloc(zOut, (int)nOut);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   848
      if( zOut==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   849
        sqlite3_result_error_nomem(context);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   850
        sqlite3_free(zOld);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   851
        return;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   852
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   853
      memcpy(&zOut[j], zRep, nRep);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   854
      j += nRep;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   855
      i += nPattern-1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   856
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   857
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   858
  assert( j+nStr-i+1==nOut );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   859
  memcpy(&zOut[j], &zStr[i], nStr-i);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   860
  j += nStr - i;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   861
  assert( j<=nOut );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   862
  zOut[j] = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   863
  sqlite3_result_text(context, (char*)zOut, j, sqlite3_free);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   864
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   865
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   866
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   867
** Implementation of the TRIM(), LTRIM(), and RTRIM() functions.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   868
** The userdata is 0x1 for left trim, 0x2 for right trim, 0x3 for both.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   869
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   870
static void trimFunc(
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   871
  sqlite3_context *context,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   872
  int argc,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   873
  sqlite3_value **argv
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   874
){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   875
  const unsigned char *zIn;         /* Input string */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   876
  const unsigned char *zCharSet;    /* Set of characters to trim */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   877
  int nIn;                          /* Number of bytes in input */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   878
  int flags;                        /* 1: trimleft  2: trimright  3: trim */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   879
  int i;                            /* Loop counter */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   880
  unsigned char *aLen;              /* Length of each character in zCharSet */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   881
  unsigned char **azChar;           /* Individual characters in zCharSet */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   882
  int nChar;                        /* Number of characters in zCharSet */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   883
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   884
  if( sqlite3_value_type(argv[0])==SQLITE_NULL ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   885
    return;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   886
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   887
  zIn = sqlite3_value_text(argv[0]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   888
  if( zIn==0 ) return;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   889
  nIn = sqlite3_value_bytes(argv[0]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   890
  assert( zIn==sqlite3_value_text(argv[0]) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   891
  if( argc==1 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   892
    static const unsigned char lenOne[] = { 1 };
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   893
    static const unsigned char *azOne[] = { (u8*)" " };
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   894
    nChar = 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   895
    aLen = (u8*)lenOne;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   896
    azChar = (unsigned char **)azOne;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   897
    zCharSet = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   898
  }else if( (zCharSet = sqlite3_value_text(argv[1]))==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   899
    return;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   900
  }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   901
    const unsigned char *z;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   902
    for(z=zCharSet, nChar=0; *z; nChar++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   903
      SQLITE_SKIP_UTF8(z);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   904
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   905
    if( nChar>0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   906
      azChar = (unsigned char**)contextMalloc(context, nChar*(sizeof(char*)+1));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   907
      if( azChar==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   908
        return;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   909
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   910
      aLen = (unsigned char*)&azChar[nChar];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   911
      for(z=zCharSet, nChar=0; *z; nChar++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   912
        azChar[nChar] = (unsigned char *)z;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   913
        SQLITE_SKIP_UTF8(z);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   914
        aLen[nChar] = z - azChar[nChar];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   915
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   916
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   917
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   918
  if( nChar>0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   919
    flags = (int)sqlite3_user_data(context);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   920
    if( flags & 1 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   921
      while( nIn>0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   922
        int len;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   923
        for(i=0; i<nChar; i++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   924
          len = aLen[i];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   925
          if( memcmp(zIn, azChar[i], len)==0 ) break;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   926
        }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   927
        if( i>=nChar ) break;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   928
        zIn += len;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   929
        nIn -= len;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   930
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   931
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   932
    if( flags & 2 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   933
      while( nIn>0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   934
        int len;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   935
        for(i=0; i<nChar; i++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   936
          len = aLen[i];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   937
          if( len<=nIn && memcmp(&zIn[nIn-len],azChar[i],len)==0 ) break;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   938
        }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   939
        if( i>=nChar ) break;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   940
        nIn -= len;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   941
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   942
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   943
    if( zCharSet ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   944
      sqlite3_free(azChar);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   945
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   946
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   947
  sqlite3_result_text(context, (char*)zIn, nIn, SQLITE_TRANSIENT);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   948
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   949
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   950
#ifdef SQLITE_SOUNDEX
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   951
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   952
** Compute the soundex encoding of a word.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   953
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   954
static void soundexFunc(
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   955
  sqlite3_context *context,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   956
  int argc,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   957
  sqlite3_value **argv
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   958
){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   959
  char zResult[8];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   960
  const u8 *zIn;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   961
  int i, j;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   962
  static const unsigned char iCode[] = {
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   963
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   964
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   965
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   966
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   967
    0, 0, 1, 2, 3, 0, 1, 2, 0, 0, 2, 2, 4, 5, 5, 0,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   968
    1, 2, 6, 2, 3, 0, 1, 0, 2, 0, 2, 0, 0, 0, 0, 0,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   969
    0, 0, 1, 2, 3, 0, 1, 2, 0, 0, 2, 2, 4, 5, 5, 0,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   970
    1, 2, 6, 2, 3, 0, 1, 0, 2, 0, 2, 0, 0, 0, 0, 0,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   971
  };
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   972
  assert( argc==1 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   973
  zIn = (u8*)sqlite3_value_text(argv[0]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   974
  if( zIn==0 ) zIn = (u8*)"";
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   975
  for(i=0; zIn[i] && !isalpha(zIn[i]); i++){}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   976
  if( zIn[i] ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   977
    u8 prevcode = iCode[zIn[i]&0x7f];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   978
    zResult[0] = toupper(zIn[i]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   979
    for(j=1; j<4 && zIn[i]; i++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   980
      int code = iCode[zIn[i]&0x7f];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   981
      if( code>0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   982
        if( code!=prevcode ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   983
          prevcode = code;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   984
          zResult[j++] = code + '0';
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   985
        }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   986
      }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   987
        prevcode = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   988
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   989
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   990
    while( j<4 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   991
      zResult[j++] = '0';
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   992
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   993
    zResult[j] = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   994
    sqlite3_result_text(context, zResult, 4, SQLITE_TRANSIENT);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   995
  }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   996
    sqlite3_result_text(context, "?000", 4, SQLITE_STATIC);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   997
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   998
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   999
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1000
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1001
#ifndef SQLITE_OMIT_LOAD_EXTENSION
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1002
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1003
** A function that loads a shared-library extension then returns NULL.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1004
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1005
static void loadExt(sqlite3_context *context, int argc, sqlite3_value **argv){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1006
  const char *zFile = (const char *)sqlite3_value_text(argv[0]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1007
  const char *zProc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1008
  sqlite3 *db = (sqlite3*)sqlite3_user_data(context);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1009
  char *zErrMsg = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1010
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1011
  if( argc==2 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1012
    zProc = (const char *)sqlite3_value_text(argv[1]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1013
  }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1014
    zProc = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1015
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1016
  if( zFile && sqlite3_load_extension(db, zFile, zProc, &zErrMsg) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1017
    sqlite3_result_error(context, zErrMsg, -1);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1018
    sqlite3_free(zErrMsg);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1019
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1020
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1021
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1022
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1023
#ifdef SQLITE_TEST
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1024
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1025
** This function generates a string of random characters.  Used for
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1026
** generating test data.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1027
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1028
static void randStr(sqlite3_context *context, int argc, sqlite3_value **argv){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1029
  static const unsigned char zSrc[] = 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1030
     "abcdefghijklmnopqrstuvwxyz"
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1031
     "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1032
     "0123456789"
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1033
     ".-!,:*^+=_|?/<> ";
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1034
  int iMin, iMax, n, r, i;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1035
  unsigned char zBuf[1000];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1036
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1037
  /* It used to be possible to call randstr() with any number of arguments,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1038
  ** but now it is registered with SQLite as requiring exactly 2.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1039
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1040
  assert(argc==2);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1041
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1042
  iMin = sqlite3_value_int(argv[0]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1043
  if( iMin<0 ) iMin = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1044
  if( iMin>=sizeof(zBuf) ) iMin = sizeof(zBuf)-1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1045
  iMax = sqlite3_value_int(argv[1]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1046
  if( iMax<iMin ) iMax = iMin;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1047
  if( iMax>=sizeof(zBuf) ) iMax = sizeof(zBuf)-1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1048
  n = iMin;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1049
  if( iMax>iMin ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1050
    sqlite3Randomness(sizeof(r), &r);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1051
    r &= 0x7fffffff;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1052
    n += r%(iMax + 1 - iMin);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1053
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1054
  assert( n<sizeof(zBuf) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1055
  sqlite3Randomness(n, zBuf);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1056
  for(i=0; i<n; i++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1057
    zBuf[i] = zSrc[zBuf[i]%(sizeof(zSrc)-1)];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1058
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1059
  zBuf[n] = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1060
  sqlite3_result_text(context, (char*)zBuf, n, SQLITE_TRANSIENT);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1061
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1062
#endif /* SQLITE_TEST */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1063
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1064
#ifdef SQLITE_TEST
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1065
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1066
** The following two SQL functions are used to test returning a text
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1067
** result with a destructor. Function 'test_destructor' takes one argument
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1068
** and returns the same argument interpreted as TEXT. A destructor is
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1069
** passed with the sqlite3_result_text() call.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1070
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1071
** SQL function 'test_destructor_count' returns the number of outstanding 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1072
** allocations made by 'test_destructor';
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1073
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1074
** WARNING: Not threadsafe.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1075
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1076
static int test_destructor_count_var = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1077
static void destructor(void *p){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1078
  char *zVal = (char *)p;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1079
  assert(zVal);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1080
  zVal--;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1081
  sqlite3_free(zVal);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1082
  test_destructor_count_var--;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1083
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1084
static void test_destructor(
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1085
  sqlite3_context *pCtx, 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1086
  int nArg,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1087
  sqlite3_value **argv
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1088
){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1089
  char *zVal;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1090
  int len;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1091
  sqlite3 *db = sqlite3_user_data(pCtx);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1092
 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1093
  test_destructor_count_var++;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1094
  assert( nArg==1 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1095
  if( sqlite3_value_type(argv[0])==SQLITE_NULL ) return;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1096
  len = sqlite3ValueBytes(argv[0], ENC(db)); 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1097
  zVal = contextMalloc(pCtx, len+3);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1098
  if( !zVal ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1099
    return;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1100
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1101
  zVal[len+1] = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1102
  zVal[len+2] = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1103
  zVal++;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1104
  memcpy(zVal, sqlite3ValueText(argv[0], ENC(db)), len);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1105
  if( ENC(db)==SQLITE_UTF8 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1106
    sqlite3_result_text(pCtx, zVal, -1, destructor);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1107
#ifndef SQLITE_OMIT_UTF16
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1108
  }else if( ENC(db)==SQLITE_UTF16LE ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1109
    sqlite3_result_text16le(pCtx, zVal, -1, destructor);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1110
  }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1111
    sqlite3_result_text16be(pCtx, zVal, -1, destructor);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1112
#endif /* SQLITE_OMIT_UTF16 */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1113
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1114
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1115
static void test_destructor_count(
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1116
  sqlite3_context *pCtx, 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1117
  int nArg,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1118
  sqlite3_value **argv
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1119
){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1120
  sqlite3_result_int(pCtx, test_destructor_count_var);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1121
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1122
#endif /* SQLITE_TEST */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1123
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1124
#ifdef SQLITE_TEST
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1125
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1126
** Routines for testing the sqlite3_get_auxdata() and sqlite3_set_auxdata()
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1127
** interface.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1128
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1129
** The test_auxdata() SQL function attempts to register each of its arguments
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1130
** as auxiliary data.  If there are no prior registrations of aux data for
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1131
** that argument (meaning the argument is not a constant or this is its first
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1132
** call) then the result for that argument is 0.  If there is a prior
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1133
** registration, the result for that argument is 1.  The overall result
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1134
** is the individual argument results separated by spaces.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1135
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1136
static void free_test_auxdata(void *p) {sqlite3_free(p);}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1137
static void test_auxdata(
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1138
  sqlite3_context *pCtx, 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1139
  int nArg,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1140
  sqlite3_value **argv
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1141
){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1142
  int i;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1143
  char *zRet = contextMalloc(pCtx, nArg*2);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1144
  if( !zRet ) return;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1145
  memset(zRet, 0, nArg*2);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1146
  for(i=0; i<nArg; i++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1147
    char const *z = (char*)sqlite3_value_text(argv[i]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1148
    if( z ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1149
      char *zAux = sqlite3_get_auxdata(pCtx, i);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1150
      if( zAux ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1151
        zRet[i*2] = '1';
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1152
        if( strcmp(zAux, z) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1153
          sqlite3_result_error(pCtx, "Auxilary data corruption", -1);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1154
          return;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1155
        }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1156
      }else {
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1157
        zRet[i*2] = '0';
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1158
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1159
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1160
      zAux = contextMalloc(pCtx, strlen(z)+1);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1161
      if( zAux ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1162
        strcpy(zAux, z);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1163
        sqlite3_set_auxdata(pCtx, i, zAux, free_test_auxdata);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1164
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1165
      zRet[i*2+1] = ' ';
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1166
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1167
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1168
  sqlite3_result_text(pCtx, zRet, 2*nArg-1, free_test_auxdata);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1169
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1170
#endif /* SQLITE_TEST */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1171
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1172
#ifdef SQLITE_TEST
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1173
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1174
** A function to test error reporting from user functions. This function
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1175
** returns a copy of its first argument as an error.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1176
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1177
static void test_error(
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1178
  sqlite3_context *pCtx, 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1179
  int nArg,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1180
  sqlite3_value **argv
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1181
){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1182
  sqlite3_result_error(pCtx, (char*)sqlite3_value_text(argv[0]), 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1183
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1184
#endif /* SQLITE_TEST */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1185
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1186
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1187
** An instance of the following structure holds the context of a
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1188
** sum() or avg() aggregate computation.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1189
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1190
typedef struct SumCtx SumCtx;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1191
struct SumCtx {
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1192
  double rSum;      /* Floating point sum */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1193
  i64 iSum;         /* Integer sum */   
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1194
  i64 cnt;          /* Number of elements summed */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1195
  u8 overflow;      /* True if integer overflow seen */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1196
  u8 approx;        /* True if non-integer value was input to the sum */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1197
};
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1198
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1199
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1200
** Routines used to compute the sum, average, and total.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1201
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1202
** The SUM() function follows the (broken) SQL standard which means
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1203
** that it returns NULL if it sums over no inputs.  TOTAL returns
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1204
** 0.0 in that case.  In addition, TOTAL always returns a float where
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1205
** SUM might return an integer if it never encounters a floating point
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1206
** value.  TOTAL never fails, but SUM might through an exception if
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1207
** it overflows an integer.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1208
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1209
static void sumStep(sqlite3_context *context, int argc, sqlite3_value **argv){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1210
  SumCtx *p;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1211
  int type;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1212
  assert( argc==1 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1213
  p = (SumCtx*)sqlite3_aggregate_context(context, sizeof(*p));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1214
  type = sqlite3_value_numeric_type(argv[0]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1215
  if( p && type!=SQLITE_NULL ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1216
    p->cnt++;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1217
    if( type==SQLITE_INTEGER ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1218
      i64 v = sqlite3_value_int64(argv[0]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1219
      p->rSum += v;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1220
      if( (p->approx|p->overflow)==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1221
        i64 iNewSum = p->iSum + v;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1222
        int s1 = p->iSum >> (sizeof(i64)*8-1);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1223
        int s2 = v       >> (sizeof(i64)*8-1);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1224
        int s3 = iNewSum >> (sizeof(i64)*8-1);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1225
        p->overflow = (s1&s2&~s3) | (~s1&~s2&s3);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1226
        p->iSum = iNewSum;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1227
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1228
    }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1229
      p->rSum += sqlite3_value_double(argv[0]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1230
      p->approx = 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1231
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1232
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1233
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1234
static void sumFinalize(sqlite3_context *context){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1235
  SumCtx *p;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1236
  p = (SumCtx*)sqlite3_aggregate_context(context, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1237
  if( p && p->cnt>0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1238
    if( p->overflow ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1239
      sqlite3_result_error(context,"integer overflow",-1);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1240
    }else if( p->approx ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1241
      sqlite3_result_double(context, p->rSum);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1242
    }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1243
      sqlite3_result_int64(context, p->iSum);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1244
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1245
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1246
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1247
static void avgFinalize(sqlite3_context *context){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1248
  SumCtx *p;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1249
  p = (SumCtx*)sqlite3_aggregate_context(context, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1250
  if( p && p->cnt>0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1251
    sqlite3_result_double(context, p->rSum/(double)p->cnt);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1252
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1253
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1254
static void totalFinalize(sqlite3_context *context){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1255
  SumCtx *p;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1256
  p = (SumCtx*)sqlite3_aggregate_context(context, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1257
  sqlite3_result_double(context, p ? p->rSum : 0.0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1258
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1259
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1260
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1261
** The following structure keeps track of state information for the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1262
** count() aggregate function.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1263
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1264
typedef struct CountCtx CountCtx;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1265
struct CountCtx {
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1266
  i64 n;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1267
};
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1268
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1269
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1270
** Routines to implement the count() aggregate function.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1271
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1272
static void countStep(sqlite3_context *context, int argc, sqlite3_value **argv){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1273
  CountCtx *p;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1274
  p = (CountCtx*)sqlite3_aggregate_context(context, sizeof(*p));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1275
  if( (argc==0 || SQLITE_NULL!=sqlite3_value_type(argv[0])) && p ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1276
    p->n++;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1277
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1278
}   
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1279
static void countFinalize(sqlite3_context *context){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1280
  CountCtx *p;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1281
  p = (CountCtx*)sqlite3_aggregate_context(context, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1282
  sqlite3_result_int64(context, p ? p->n : 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1283
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1284
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1285
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1286
** Routines to implement min() and max() aggregate functions.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1287
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1288
static void minmaxStep(sqlite3_context *context, int argc, sqlite3_value **argv){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1289
  Mem *pArg  = (Mem *)argv[0];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1290
  Mem *pBest;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1291
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1292
  if( sqlite3_value_type(argv[0])==SQLITE_NULL ) return;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1293
  pBest = (Mem *)sqlite3_aggregate_context(context, sizeof(*pBest));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1294
  if( !pBest ) return;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1295
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1296
  if( pBest->flags ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1297
    int max;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1298
    int cmp;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1299
    CollSeq *pColl = sqlite3GetFuncCollSeq(context);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1300
    /* This step function is used for both the min() and max() aggregates,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1301
    ** the only difference between the two being that the sense of the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1302
    ** comparison is inverted. For the max() aggregate, the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1303
    ** sqlite3_user_data() function returns (void *)-1. For min() it
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1304
    ** returns (void *)db, where db is the sqlite3* database pointer.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1305
    ** Therefore the next statement sets variable 'max' to 1 for the max()
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1306
    ** aggregate, or 0 for min().
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1307
    */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1308
    max = sqlite3_user_data(context)!=0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1309
    cmp = sqlite3MemCompare(pBest, pArg, pColl);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1310
    if( (max && cmp<0) || (!max && cmp>0) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1311
      sqlite3VdbeMemCopy(pBest, pArg);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1312
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1313
  }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1314
    sqlite3VdbeMemCopy(pBest, pArg);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1315
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1316
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1317
static void minMaxFinalize(sqlite3_context *context){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1318
  sqlite3_value *pRes;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1319
  pRes = (sqlite3_value *)sqlite3_aggregate_context(context, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1320
  if( pRes ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1321
    if( pRes->flags ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1322
      sqlite3_result_value(context, pRes);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1323
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1324
    sqlite3VdbeMemRelease(pRes);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1325
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1326
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1327
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1328
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1329
** group_concat(EXPR, ?SEPARATOR?)
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1330
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1331
static void groupConcatStep(
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1332
  sqlite3_context *context,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1333
  int argc,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1334
  sqlite3_value **argv
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1335
){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1336
  const char *zVal;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1337
  StrAccum *pAccum;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1338
  const char *zSep;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1339
  int nVal, nSep;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1340
  if( sqlite3_value_type(argv[0])==SQLITE_NULL ) return;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1341
  pAccum = (StrAccum*)sqlite3_aggregate_context(context, sizeof(*pAccum));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1342
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1343
  if( pAccum ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1344
    pAccum->useMalloc = 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1345
    if( pAccum->nChar ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1346
      if( argc==2 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1347
        zSep = (char*)sqlite3_value_text(argv[1]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1348
        nSep = sqlite3_value_bytes(argv[1]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1349
      }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1350
        zSep = ",";
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1351
        nSep = 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1352
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1353
      sqlite3StrAccumAppend(pAccum, zSep, nSep);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1354
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1355
    zVal = (char*)sqlite3_value_text(argv[0]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1356
    nVal = sqlite3_value_bytes(argv[0]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1357
    sqlite3StrAccumAppend(pAccum, zVal, nVal);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1358
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1359
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1360
static void groupConcatFinalize(sqlite3_context *context){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1361
  StrAccum *pAccum;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1362
  pAccum = (StrAccum*)sqlite3_aggregate_context(context, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1363
  if( pAccum ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1364
    if( pAccum->tooBig ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1365
      sqlite3_result_error_toobig(context);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1366
    }else if( pAccum->mallocFailed ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1367
      sqlite3_result_error_nomem(context);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1368
    }else{    
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1369
      sqlite3_result_text(context, sqlite3StrAccumFinish(pAccum), -1, 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1370
                          sqlite3_free);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1371
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1372
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1373
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1374
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1375
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1376
** This function registered all of the above C functions as SQL
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1377
** functions.  This should be the only routine in this file with
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1378
** external linkage.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1379
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1380
void sqlite3RegisterBuiltinFunctions(sqlite3 *db){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1381
  static const struct {
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1382
     char *zName;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1383
     signed char nArg;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1384
     u8 argType;           /* ff: db   1: 0, 2: 1, 3: 2,...  N:  N-1. */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1385
     u8 eTextRep;          /* 1: UTF-16.  0: UTF-8 */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1386
     u8 needCollSeq;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1387
     void (*xFunc)(sqlite3_context*,int,sqlite3_value **);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1388
  } aFuncs[] = {
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1389
    { "min",               -1, 0, SQLITE_UTF8,    1, minmaxFunc },
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1390
    { "min",                0, 0, SQLITE_UTF8,    1, 0          },
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1391
    { "max",               -1, 1, SQLITE_UTF8,    1, minmaxFunc },
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1392
    { "max",                0, 1, SQLITE_UTF8,    1, 0          },
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1393
    { "typeof",             1, 0, SQLITE_UTF8,    0, typeofFunc },
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1394
    { "length",             1, 0, SQLITE_UTF8,    0, lengthFunc },
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1395
    { "substr",             2, 0, SQLITE_UTF8,    0, substrFunc },
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1396
    { "substr",             3, 0, SQLITE_UTF8,    0, substrFunc },
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1397
    { "abs",                1, 0, SQLITE_UTF8,    0, absFunc    },
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1398
    { "round",              1, 0, SQLITE_UTF8,    0, roundFunc  },
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1399
    { "round",              2, 0, SQLITE_UTF8,    0, roundFunc  },
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1400
    { "upper",              1, 0, SQLITE_UTF8,    0, upperFunc  },
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1401
    { "lower",              1, 0, SQLITE_UTF8,    0, lowerFunc  },
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1402
    { "coalesce",          -1, 0, SQLITE_UTF8,    0, ifnullFunc },
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1403
    { "coalesce",           0, 0, SQLITE_UTF8,    0, 0          },
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1404
    { "coalesce",           1, 0, SQLITE_UTF8,    0, 0          },
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1405
    { "hex",                1, 0, SQLITE_UTF8,    0, hexFunc    },
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1406
    { "ifnull",             2, 0, SQLITE_UTF8,    1, ifnullFunc },
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1407
    { "random",            -1, 0, SQLITE_UTF8,    0, randomFunc },
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1408
    { "randomblob",         1, 0, SQLITE_UTF8,    0, randomBlob },
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1409
    { "nullif",             2, 0, SQLITE_UTF8,    1, nullifFunc },
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1410
    { "sqlite_version",     0, 0, SQLITE_UTF8,    0, versionFunc},
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1411
    { "quote",              1, 0, SQLITE_UTF8,    0, quoteFunc  },
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1412
    { "last_insert_rowid",  0, 0xff, SQLITE_UTF8, 0, last_insert_rowid },
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1413
    { "changes",            0, 0xff, SQLITE_UTF8, 0, changes           },
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1414
    { "total_changes",      0, 0xff, SQLITE_UTF8, 0, total_changes     },
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1415
    { "replace",            3, 0, SQLITE_UTF8,    0, replaceFunc       },
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1416
    { "ltrim",              1, 1, SQLITE_UTF8,    0, trimFunc          },
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1417
    { "ltrim",              2, 1, SQLITE_UTF8,    0, trimFunc          },
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1418
    { "rtrim",              1, 2, SQLITE_UTF8,    0, trimFunc          },
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1419
    { "rtrim",              2, 2, SQLITE_UTF8,    0, trimFunc          },
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1420
    { "trim",               1, 3, SQLITE_UTF8,    0, trimFunc          },
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1421
    { "trim",               2, 3, SQLITE_UTF8,    0, trimFunc          },
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1422
    { "zeroblob",           1, 0, SQLITE_UTF8,    0, zeroblobFunc      },
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1423
#ifdef SQLITE_SOUNDEX
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1424
    { "soundex",            1, 0, SQLITE_UTF8,    0, soundexFunc},
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1425
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1426
#ifndef SQLITE_OMIT_LOAD_EXTENSION
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1427
    { "load_extension",     1, 0xff, SQLITE_UTF8, 0, loadExt },
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1428
    { "load_extension",     2, 0xff, SQLITE_UTF8, 0, loadExt },
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1429
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1430
#ifdef SQLITE_TEST
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1431
    { "randstr",               2, 0,    SQLITE_UTF8, 0, randStr    },
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1432
    { "test_destructor",       1, 0xff, SQLITE_UTF8, 0, test_destructor},
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1433
    { "test_destructor_count", 0, 0,    SQLITE_UTF8, 0, test_destructor_count},
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1434
    { "test_auxdata",         -1, 0,    SQLITE_UTF8, 0, test_auxdata},
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1435
    { "test_error",            1, 0,    SQLITE_UTF8, 0, test_error},
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1436
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1437
  };
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1438
  static const struct {
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1439
    char *zName;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1440
    signed char nArg;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1441
    u8 argType;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1442
    u8 needCollSeq;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1443
    void (*xStep)(sqlite3_context*,int,sqlite3_value**);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1444
    void (*xFinalize)(sqlite3_context*);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1445
  } aAggs[] = {
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1446
    { "min",    1, 0, 1, minmaxStep,   minMaxFinalize },
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1447
    { "max",    1, 1, 1, minmaxStep,   minMaxFinalize },
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1448
    { "sum",    1, 0, 0, sumStep,      sumFinalize    },
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1449
    { "total",  1, 0, 0, sumStep,      totalFinalize    },
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1450
    { "avg",    1, 0, 0, sumStep,      avgFinalize    },
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1451
    { "count",  0, 0, 0, countStep,    countFinalize  },
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1452
    { "count",  1, 0, 0, countStep,    countFinalize  },
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1453
    { "group_concat", 1, 0, 0, groupConcatStep, groupConcatFinalize },
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1454
    { "group_concat", 2, 0, 0, groupConcatStep, groupConcatFinalize },
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1455
  };
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1456
  int i;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1457
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1458
  for(i=0; i<sizeof(aFuncs)/sizeof(aFuncs[0]); i++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1459
    void *pArg;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1460
    u8 argType = aFuncs[i].argType;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1461
    if( argType==0xff ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1462
      pArg = db;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1463
    }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1464
      pArg = (void*)(int)argType;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1465
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1466
    sqlite3CreateFunc(db, aFuncs[i].zName, aFuncs[i].nArg,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1467
        aFuncs[i].eTextRep, pArg, aFuncs[i].xFunc, 0, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1468
    if( aFuncs[i].needCollSeq ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1469
      FuncDef *pFunc = sqlite3FindFunction(db, aFuncs[i].zName, 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1470
          strlen(aFuncs[i].zName), aFuncs[i].nArg, aFuncs[i].eTextRep, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1471
      if( pFunc && aFuncs[i].needCollSeq ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1472
        pFunc->needCollSeq = 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1473
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1474
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1475
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1476
#ifndef SQLITE_OMIT_ALTERTABLE
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1477
  sqlite3AlterFunctions(db);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1478
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1479
#ifndef SQLITE_OMIT_PARSER
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1480
  sqlite3AttachFunctions(db);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1481
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1482
  for(i=0; i<sizeof(aAggs)/sizeof(aAggs[0]); i++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1483
    void *pArg = (void*)(int)aAggs[i].argType;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1484
    sqlite3CreateFunc(db, aAggs[i].zName, aAggs[i].nArg, SQLITE_UTF8, 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1485
        pArg, 0, aAggs[i].xStep, aAggs[i].xFinalize);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1486
    if( aAggs[i].needCollSeq ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1487
      FuncDef *pFunc = sqlite3FindFunction( db, aAggs[i].zName,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1488
          strlen(aAggs[i].zName), aAggs[i].nArg, SQLITE_UTF8, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1489
      if( pFunc && aAggs[i].needCollSeq ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1490
        pFunc->needCollSeq = 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1491
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1492
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1493
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1494
  sqlite3RegisterDateTimeFunctions(db);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1495
  if( !db->mallocFailed ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1496
    int rc = sqlite3_overload_function(db, "MATCH", 2);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1497
    assert( rc==SQLITE_NOMEM || rc==SQLITE_OK );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1498
    if( rc==SQLITE_NOMEM ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1499
      db->mallocFailed = 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1500
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1501
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1502
#ifdef SQLITE_SSE
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1503
  (void)sqlite3SseFunctions(db);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1504
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1505
#ifdef SQLITE_CASE_SENSITIVE_LIKE
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1506
  sqlite3RegisterLikeFunctions(db, 1);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1507
#else
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1508
  sqlite3RegisterLikeFunctions(db, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1509
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1510
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1511
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1512
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1513
** Set the LIKEOPT flag on the 2-argument function with the given name.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1514
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1515
static void setLikeOptFlag(sqlite3 *db, const char *zName, int flagVal){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1516
  FuncDef *pDef;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1517
  pDef = sqlite3FindFunction(db, zName, strlen(zName), 2, SQLITE_UTF8, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1518
  if( pDef ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1519
    pDef->flags = flagVal;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1520
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1521
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1522
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1523
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1524
** Register the built-in LIKE and GLOB functions.  The caseSensitive
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1525
** parameter determines whether or not the LIKE operator is case
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1526
** sensitive.  GLOB is always case sensitive.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1527
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1528
void sqlite3RegisterLikeFunctions(sqlite3 *db, int caseSensitive){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1529
  struct compareInfo *pInfo;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1530
  if( caseSensitive ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1531
    pInfo = (struct compareInfo*)&likeInfoAlt;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1532
  }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1533
    pInfo = (struct compareInfo*)&likeInfoNorm;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1534
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1535
  sqlite3CreateFunc(db, "like", 2, SQLITE_UTF8, pInfo, likeFunc, 0, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1536
  sqlite3CreateFunc(db, "like", 3, SQLITE_UTF8, pInfo, likeFunc, 0, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1537
  sqlite3CreateFunc(db, "glob", 2, SQLITE_UTF8, 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1538
      (struct compareInfo*)&globInfo, likeFunc, 0,0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1539
  setLikeOptFlag(db, "glob", SQLITE_FUNC_LIKE | SQLITE_FUNC_CASE);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1540
  setLikeOptFlag(db, "like", 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1541
      caseSensitive ? (SQLITE_FUNC_LIKE | SQLITE_FUNC_CASE) : SQLITE_FUNC_LIKE);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1542
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1543
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1544
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1545
** pExpr points to an expression which implements a function.  If
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1546
** it is appropriate to apply the LIKE optimization to that function
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1547
** then set aWc[0] through aWc[2] to the wildcard characters and
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1548
** return TRUE.  If the function is not a LIKE-style function then
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1549
** return FALSE.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1550
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1551
int sqlite3IsLikeFunction(sqlite3 *db, Expr *pExpr, int *pIsNocase, char *aWc){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1552
  FuncDef *pDef;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1553
  if( pExpr->op!=TK_FUNCTION || !pExpr->pList ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1554
    return 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1555
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1556
  if( pExpr->pList->nExpr!=2 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1557
    return 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1558
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1559
  pDef = sqlite3FindFunction(db, (char*)pExpr->token.z, pExpr->token.n, 2,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1560
                             SQLITE_UTF8, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1561
  if( pDef==0 || (pDef->flags & SQLITE_FUNC_LIKE)==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1562
    return 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1563
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1564
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1565
  /* The memcpy() statement assumes that the wildcard characters are
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1566
  ** the first three statements in the compareInfo structure.  The
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1567
  ** asserts() that follow verify that assumption
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1568
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1569
  memcpy(aWc, pDef->pUserData, 3);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1570
  assert( (char*)&likeInfoAlt == (char*)&likeInfoAlt.matchAll );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1571
  assert( &((char*)&likeInfoAlt)[1] == (char*)&likeInfoAlt.matchOne );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1572
  assert( &((char*)&likeInfoAlt)[2] == (char*)&likeInfoAlt.matchSet );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1573
  *pIsNocase = (pDef->flags & SQLITE_FUNC_CASE)==0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1574
  return 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1575
}