Пример #1
0
/*
** EXPERIMENTAL - This is not an official function.  The interface may
** change.  This function may disappear.  Do not write code that depends
** on this function.
**
** Implementation of the QUOTE() function.  This function takes a single
** argument.  If the argument is numeric, the return value is the same as
** the argument.  If the argument is NULL, the return value is the string
** "NULL".  Otherwise, the argument is enclosed in single quotes with
** single-quote escapes.
*/
static void quoteFunc(sqlite_func *context, int argc, const char **argv){
  if( argc<1 ) return;
  if( argv[0]==0 ){
    sqlite_set_result_string(context, "NULL", 4);
  }else if( sqliteIsNumber(argv[0]) ){
    sqlite_set_result_string(context, argv[0], -1);
  }else{
    int i,j,n;
    char *z;
    for(i=n=0; argv[0][i]; i++){ if( argv[0][i]=='\'' ) n++; }
    z = sqliteMalloc( i+n+3 );
    if( z==0 ) return;
    z[0] = '\'';
    for(i=0, j=1; argv[0][i]; i++){
      z[j++] = argv[0][i];
      if( argv[0][i]=='\'' ){
        z[j++] = '\'';
      }
    }
    z[j++] = '\'';
    z[j] = 0;
    sqlite_set_result_string(context, z, j);
    sqliteFree(z);
  }
}
Пример #2
0
/*
** Compute the soundex encoding of a word.
*/
static void soundexFunc(sqlite_func *context, int argc, const char **argv){
  char zResult[8];
  const char *zIn;
  int i, j;
  static const unsigned char iCode[] = {
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 1, 2, 3, 0, 1, 2, 0, 0, 2, 2, 4, 5, 5, 0,
    1, 2, 6, 2, 3, 0, 1, 0, 2, 0, 2, 0, 0, 0, 0, 0,
    0, 0, 1, 2, 3, 0, 1, 2, 0, 0, 2, 2, 4, 5, 5, 0,
    1, 2, 6, 2, 3, 0, 1, 0, 2, 0, 2, 0, 0, 0, 0, 0,
  };
  assert( argc==1 );
  zIn = argv[0];
  for(i=0; zIn[i] && !isalpha(zIn[i]); i++){}
  if( zIn[i] ){
    zResult[0] = toupper(zIn[i]);
    for(j=1; j<4 && zIn[i]; i++){
      int code = iCode[zIn[i]&0x7f];
      if( code>0 ){
        zResult[j++] = code + '0';
      }
    }
    while( j<4 ){
      zResult[j++] = '0';
    }
    zResult[j] = 0;
    sqlite_set_result_string(context, zResult, 4);
  }else{
    sqlite_set_result_string(context, "?000", 4);
  }
}
Пример #3
0
/*
** Implementation of the abs() function
*/
static void absFunc(sqlite_func *context, int argc, const char **argv){
  const char *z;
  assert( argc==1 );
  z = argv[0];
  if( z==0 ) return;
  if( z[0]=='-' && isdigit(z[1]) ) z++;
  sqlite_set_result_string(context, z, -1);
}
Пример #4
0
/*
** Implementation of the x_sqlite_exec() function.  This function takes
** a single argument and attempts to execute that argument as SQL code.
** This is illegal and should set the SQLITE_MISUSE flag on the database.
**
** 2004-Jan-07:  We have changed this to make it legal to call sqlite_exec()
** from within a function call.  
** 
** This routine simulates the effect of having two threads attempt to
** use the same database at the same time.
*/
static void sqliteExecFunc(sqlite_func *context, int argc, const char **argv){
  struct dstr x;
  memset(&x, 0, sizeof(x));
  sqlite_exec((sqlite*)sqlite_user_data(context), argv[0], 
      execFuncCallback, &x, 0);
  sqlite_set_result_string(context, x.z, x.nUsed);
  sqliteFree(x.z);
}
Пример #5
0
/*
** Implementation of the IFNULL(), NVL(), and COALESCE() functions.  
** All three do the same thing.  They return the first non-NULL
** argument.
*/
static void ifnullFunc(sqlite_func *context, int argc, const char **argv){
  int i;
  for(i=0; i<argc; i++){
    if( argv[i] ){
      sqlite_set_result_string(context, argv[i], -1);
      break;
    }
  }
}
Пример #6
0
/*
**    time( TIMESTRING, MOD, MOD, ...)
**
** Return HH:MM:SS
*/
static void timeFunc(sqlite_func *context, int argc, const char **argv){
  DateTime x;
  if( isDate(argc, argv, &x)==0 ){
    char zBuf[100];
    computeHMS(&x);
    sprintf(zBuf, "%02d:%02d:%02d", x.h, x.m, (int)x.s);
    sqlite_set_result_string(context, zBuf, -1);
  }
}
Пример #7
0
/*
**    date( TIMESTRING, MOD, MOD, ...)
**
** Return YYYY-MM-DD
*/
static void dateFunc(sqlite_func *context, int argc, const char **argv){
  DateTime x;
  if( isDate(argc, argv, &x)==0 ){
    char zBuf[100];
    computeYMD(&x);
    sprintf(zBuf, "%04d-%02d-%02d", x.Y, x.M, x.D);
    sqlite_set_result_string(context, zBuf, -1);
  }
}
Пример #8
0
static void minMaxFinalize(sqlite_func *context){
  MinMaxCtx *p;
  p = sqlite_aggregate_context(context, sizeof(*p));
  if( p && p->z && p->zBuf[0]<2 ){
    sqlite_set_result_string(context, p->z, strlen(p->z));
  }
  if( p && p->zBuf[0] ){
    sqliteFree(p->z);
  }
}
Пример #9
0
static void lowerFunc(sqlite_func *context, int argc, const char **argv){
  unsigned char *z;
  int i;
  if( argc<1 || argv[0]==0 ) return;
  z = (unsigned char*)sqlite_set_result_string(context, argv[0], -1);
  if( z==0 ) return;
  for(i=0; z[i]; i++){
    if( isupper(z[i]) ) z[i] = tolower(z[i]);
  }
}
Пример #10
0
/*
** Implementation of the round() function
*/
static void roundFunc(sqlite_func *context, int argc, const char **argv){
  int n;
  double r;
  char zBuf[100];
  assert( argc==1 || argc==2 );
  if( argv[0]==0 || (argc==2 && argv[1]==0) ) return;
  n = argc==2 ? atoi(argv[1]) : 0;
  if( n>30 ) n = 30;
  if( n<0 ) n = 0;
  r = sqliteAtoF(argv[0], 0);
  sprintf(zBuf,"%.*f",n,r);
  sqlite_set_result_string(context, zBuf, -1);
}
Пример #11
0
/*
** Implementation of the substr() function
*/
static void substrFunc(sqlite_func *context, int argc, const char **argv) {
    const char *z;
#ifdef SQLITE_UTF8
    const char *z2;
    int i;
#endif
    int p1, p2, len;
    assert( argc==3 );
    z = argv[0];
    if( z==0 ) return;
    p1 = atoi(argv[1]?argv[1]:0);
    p2 = atoi(argv[2]?argv[2]:0);
#ifdef SQLITE_UTF8
    for(len=0, z2=z; *z2; z2++) {
        if( (0xc0&*z2)!=0x80 ) len++;
    }
#else
    len = strlen(z);
#endif
    if( p1<0 ) {
        p1 += len;
        if( p1<0 ) {
            p2 += p1;
            p1 = 0;
        }
    } else if( p1>0 ) {
        p1--;
    }
    if( p1+p2>len ) {
        p2 = len-p1;
    }
#ifdef SQLITE_UTF8
    for(i=0; i<p1 && z[i]; i++) {
        if( (z[i]&0xc0)==0x80 ) p1++;
    }
    while( z[i] && (z[i]&0xc0)==0x80 ) {
        i++;
        p1++;
    }
    for(; i<p1+p2 && z[i]; i++) {
        if( (z[i]&0xc0)==0x80 ) p2++;
    }
    while( z[i] && (z[i]&0xc0)==0x80 ) {
        i++;
        p2++;
    }
#endif
    if( p2<0 ) p2 = 0;
    sqlite_set_result_string(context, &z[p1], p2);
}
Пример #12
0
/*
** This routine is called to evaluate an SQL function implemented
** using TCL script.
*/
static void tclSqlFunc(sqlite_func *context, int argc, const char **argv){
  SqlFunc *p = sqlite_user_data(context);
  Tcl_DString cmd;
  int i;
  int rc;

  Tcl_DStringInit(&cmd);
  Tcl_DStringAppend(&cmd, p->zScript, -1);
  for(i=0; i<argc; i++){
    Tcl_DStringAppendElement(&cmd, argv[i] ? argv[i] : "");
  }
  rc = Tcl_Eval(p->interp, Tcl_DStringValue(&cmd));
  if( rc ){
    sqlite_set_result_error(context, Tcl_GetStringResult(p->interp), -1); 
  }else{
    sqlite_set_result_string(context, Tcl_GetStringResult(p->interp), -1);
  }
}
Пример #13
0
/*
** The following routine is a user-defined SQL function whose purpose
** is to test the sqlite_set_result() API.
*/
static void testFunc(sqlite_func *context, int argc, const char **argv){
  while( argc>=2 ){
    if( argv[0]==0 ){
      sqlite_set_result_error(context, "first argument to test function "
         "may not be NULL", -1);
    }else if( sqliteStrICmp(argv[0],"string")==0 ){
      sqlite_set_result_string(context, argv[1], -1);
    }else if( argv[1]==0 ){
      sqlite_set_result_error(context, "2nd argument may not be NULL if the "
         "first argument is not \"string\"", -1);
    }else if( sqliteStrICmp(argv[0],"int")==0 ){
      sqlite_set_result_int(context, atoi(argv[1]));
    }else if( sqliteStrICmp(argv[0],"double")==0 ){
      sqlite_set_result_double(context, sqliteAtoF(argv[1], 0));
    }else{
      sqlite_set_result_error(context,"first argument should be one of: "
          "string int double", -1);
    }
    argc -= 2;
    argv += 2;
  }
}
Пример #14
0
/*
** Implementation of the non-aggregate min() and max() functions
*/
static void minmaxFunc(sqlite_func *context, int argc, const char **argv){
  const char *zBest; 
  int i;
  int (*xCompare)(const char*, const char*);
  int mask;    /* 0 for min() or 0xffffffff for max() */

  if( argc==0 ) return;
  mask = (int)sqlite_user_data(context);
  zBest = argv[0];
  if( zBest==0 ) return;
  if( argv[1][0]=='n' ){
    xCompare = sqliteCompare;
  }else{
    xCompare = strcmp;
  }
  for(i=2; i<argc; i+=2){
    if( argv[i]==0 ) return;
    if( (xCompare(argv[i], zBest)^mask)<0 ){
      zBest = argv[i];
    }
  }
  sqlite_set_result_string(context, zBest, -1);
}
Пример #15
0
/*
** This function generates a string of random characters.  Used for
** generating test data.
*/
static void randStr(sqlite_func *context, int argc, const char **argv){
  static const unsigned char zSrc[] = 
     "abcdefghijklmnopqrstuvwxyz"
     "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
     "0123456789"
     ".-!,:*^+=_|?/<> ";
  int iMin, iMax, n, r, i;
  unsigned char zBuf[1000];
  if( argc>=1 ){
    iMin = atoi(argv[0]);
    if( iMin<0 ) iMin = 0;
    if( iMin>=sizeof(zBuf) ) iMin = sizeof(zBuf)-1;
  }else{
    iMin = 1;
  }
  if( argc>=2 ){
    iMax = atoi(argv[1]);
    if( iMax<iMin ) iMax = iMin;
    if( iMax>=sizeof(zBuf) ) iMax = sizeof(zBuf)-1;
  }else{
    iMax = 50;
  }
  n = iMin;
  if( iMax>iMin ){
    sqliteRandomness(sizeof(r), &r);
    r &= 0x7fffffff;
    n += r%(iMax + 1 - iMin);
  }
  assert( n<sizeof(zBuf) );
  sqliteRandomness(n, zBuf);
  for(i=0; i<n; i++){
    zBuf[i] = zSrc[zBuf[i]%(sizeof(zSrc)-1)];
  }
  zBuf[n] = 0;
  sqlite_set_result_string(context, zBuf, n);
}
Пример #16
0
/*
** Return the type of the argument.
*/
static void typeofFunc(sqlite_func *context, int argc, const char **argv){
  assert( argc==2 );
  sqlite_set_result_string(context, argv[1], -1);
}
Пример #17
0
/*
** Implementation of the VERSION(*) function.  The result is the version
** of the SQLite library that is running.
*/
static void versionFunc(sqlite_func *context, int argc, const char **argv){
  sqlite_set_result_string(context, sqlite_version, -1);
}
Пример #18
0
/*
** Implementation of the NULLIF(x,y) function.  The result is the first
** argument if the arguments are different.  The result is NULL if the
** arguments are equal to each other.
*/
static void nullifFunc(sqlite_func *context, int argc, const char **argv){
  if( argv[0]!=0 && sqliteCompare(argv[0],argv[1])!=0 ){
    sqlite_set_result_string(context, argv[0], -1);
  }
}
Пример #19
0
void sqlite_set_result_error(sqlite_func *p, const char *zMsg, int n){
  assert( !p->isStep );
  sqlite_set_result_string(p, zMsg, n);
  p->isError = 1;
}
Пример #20
0
/*
**    strftime( FORMAT, TIMESTRING, MOD, MOD, ...)
**
** Return a string described by FORMAT.  Conversions as follows:
**
**   %d  day of month
**   %f  ** fractional seconds  SS.SSS
**   %H  hour 00-24
**   %j  day of year 000-366
**   %J  ** Julian day number
**   %m  month 01-12
**   %M  minute 00-59
**   %s  seconds since 1970-01-01
**   %S  seconds 00-59
**   %w  day of week 0-6  sunday==0
**   %W  week of year 00-53
**   %Y  year 0000-9999
**   %%  %
*/
static void strftimeFunc(sqlite_func *context, int argc, const char **argv){
  DateTime x;
  int n, i, j;
  char *z;
  const char *zFmt = argv[0];
  char zBuf[100];
  if( argv[0]==0 || isDate(argc-1, argv+1, &x) ) return;
  for(i=0, n=1; zFmt[i]; i++, n++){
    if( zFmt[i]=='%' ){
      switch( zFmt[i+1] ){
        case 'd':
        case 'H':
        case 'm':
        case 'M':
        case 'S':
        case 'W':
          n++;
          /* fall thru */
        case 'w':
        case '%':
          break;
        case 'f':
          n += 8;
          break;
        case 'j':
          n += 3;
          break;
        case 'Y':
          n += 8;
          break;
        case 's':
        case 'J':
          n += 50;
          break;
        default:
          return;  /* ERROR.  return a NULL */
      }
      i++;
    }
  }
  if( n<sizeof(zBuf) ){
    z = zBuf;
  }else{
    z = sqliteMalloc( n );
    if( z==0 ) return;
  }
  computeJD(&x);
  computeYMD_HMS(&x);
  for(i=j=0; zFmt[i]; i++){
    if( zFmt[i]!='%' ){
      z[j++] = zFmt[i];
    }else{
      i++;
      switch( zFmt[i] ){
        case 'd':  sprintf(&z[j],"%02d",x.D); j+=2; break;
        case 'f': {
          int s = x.s;
          int ms = (x.s - s)*1000.0;
          sprintf(&z[j],"%02d.%03d",s,ms);
          j += strlen(&z[j]);
          break;
        }
        case 'H':  sprintf(&z[j],"%02d",x.h); j+=2; break;
        case 'W': /* Fall thru */
        case 'j': {
          int n;
          DateTime y = x;
          y.validJD = 0;
          y.M = 1;
          y.D = 1;
          computeJD(&y);
          n = x.rJD - y.rJD + 1;
          if( zFmt[i]=='W' ){
            sprintf(&z[j],"%02d",(n+6)/7);
            j += 2;
          }else{
            sprintf(&z[j],"%03d",n);
            j += 3;
          }
          break;
        }
        case 'J':  sprintf(&z[j],"%.16g",x.rJD); j+=strlen(&z[j]); break;
        case 'm':  sprintf(&z[j],"%02d",x.M); j+=2; break;
        case 'M':  sprintf(&z[j],"%02d",x.m); j+=2; break;
        case 's': {
          sprintf(&z[j],"%d",(int)((x.rJD-2440587.5)*86400.0 + 0.5));
          j += strlen(&z[j]);
          break;
        }
        case 'S':  sprintf(&z[j],"%02d",(int)(x.s+0.5)); j+=2; break;
        case 'w':  z[j++] = (((int)(x.rJD+1.5)) % 7) + '0'; break;
        case 'Y':  sprintf(&z[j],"%04d",x.Y); j+=strlen(&z[j]); break;
        case '%':  z[j++] = '%'; break;
      }
    }
  }
  z[j] = 0;
  sqlite_set_result_string(context, z, -1);
  if( z!=zBuf ){
    sqliteFree(z);
  }
}