func.c

来自「sqlite源码wince移植版」· C语言 代码 · 共 659 行 · 第 1/2 页

C
659
字号
    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);  }}#endif#ifdef SQLITE_TEST/*** 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);}#endif/*** An instance of the following structure holds the context of a** sum() or avg() aggregate computation.*/typedef struct SumCtx SumCtx;struct SumCtx {  double sum;     /* Sum of terms */  int cnt;        /* Number of elements summed */};/*** Routines used to compute the sum or average.*/static void sumStep(sqlite_func *context, int argc, const char **argv){  SumCtx *p;  if( argc<1 ) return;  p = sqlite_aggregate_context(context, sizeof(*p));  if( p && argv[0] ){    p->sum += sqliteAtoF(argv[0], 0);    p->cnt++;  }}static void sumFinalize(sqlite_func *context){  SumCtx *p;  p = sqlite_aggregate_context(context, sizeof(*p));  sqlite_set_result_double(context, p ? p->sum : 0.0);}static void avgFinalize(sqlite_func *context){  SumCtx *p;  p = sqlite_aggregate_context(context, sizeof(*p));  if( p && p->cnt>0 ){    sqlite_set_result_double(context, p->sum/(double)p->cnt);  }}/*** An instance of the following structure holds the context of a** variance or standard deviation computation.*/typedef struct StdDevCtx StdDevCtx;struct StdDevCtx {  double sum;     /* Sum of terms */  double sum2;    /* Sum of the squares of terms */  int cnt;        /* Number of terms counted */};#if 0   /* Omit because math library is required *//*** Routines used to compute the standard deviation as an aggregate.*/static void stdDevStep(sqlite_func *context, int argc, const char **argv){  StdDevCtx *p;  double x;  if( argc<1 ) return;  p = sqlite_aggregate_context(context, sizeof(*p));  if( p && argv[0] ){    x = sqliteAtoF(argv[0], 0);    p->sum += x;    p->sum2 += x*x;    p->cnt++;  }}static void stdDevFinalize(sqlite_func *context){  double rN = sqlite_aggregate_count(context);  StdDevCtx *p = sqlite_aggregate_context(context, sizeof(*p));  if( p && p->cnt>1 ){    double rCnt = cnt;    sqlite_set_result_double(context,        sqrt((p->sum2 - p->sum*p->sum/rCnt)/(rCnt-1.0)));  }}#endif/*** The following structure keeps track of state information for the** count() aggregate function.*/typedef struct CountCtx CountCtx;struct CountCtx {  int n;};/*** Routines to implement the count() aggregate function.*/static void countStep(sqlite_func *context, int argc, const char **argv){  CountCtx *p;  p = sqlite_aggregate_context(context, sizeof(*p));  if( (argc==0 || argv[0]) && p ){    p->n++;  }}   static void countFinalize(sqlite_func *context){  CountCtx *p;  p = sqlite_aggregate_context(context, sizeof(*p));  sqlite_set_result_int(context, p ? p->n : 0);}/*** This function tracks state information for the min() and max()** aggregate functions.*/typedef struct MinMaxCtx MinMaxCtx;struct MinMaxCtx {  char *z;         /* The best so far */  char zBuf[28];   /* Space that can be used for storage */};/*** Routines to implement min() and max() aggregate functions.*/static void minmaxStep(sqlite_func *context, int argc, const char **argv){  MinMaxCtx *p;  int (*xCompare)(const char*, const char*);  int mask;    /* 0 for min() or 0xffffffff for max() */  assert( argc==2 );  if( argv[0]==0 ) return;  /* Ignore NULL values */  if( argv[1][0]=='n' ){    xCompare = sqliteCompare;  }else{    xCompare = strcmp;  }  mask = (int)sqlite_user_data(context);  assert( mask==0 || mask==-1 );  p = sqlite_aggregate_context(context, sizeof(*p));  if( p==0 || argc<1 ) return;  if( p->z==0 || (xCompare(argv[0],p->z)^mask)<0 ){    int len;    if( p->zBuf[0] ){      sqliteFree(p->z);    }    len = strlen(argv[0]);    if( len < sizeof(p->zBuf)-1 ){      p->z = &p->zBuf[1];      p->zBuf[0] = 0;    }else{      p->z = sqliteMalloc( len+1 );      p->zBuf[0] = 1;      if( p->z==0 ) return;    }    strcpy(p->z, argv[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);  }}/*** This function registered all of the above C functions as SQL** functions.  This should be the only routine in this file with** external linkage.*/void sqliteRegisterBuiltinFunctions(sqlite *db){  static struct {     char *zName;     signed char nArg;     signed char dataType;     u8 argType;               /* 0: none.  1: db  2: (-1) */     void (*xFunc)(sqlite_func*,int,const char**);  } aFuncs[] = {    { "min",       -1, SQLITE_ARGS,    0, minmaxFunc },    { "min",        0, 0,              0, 0          },    { "max",       -1, SQLITE_ARGS,    2, minmaxFunc },    { "max",        0, 0,              2, 0          },    { "typeof",     1, SQLITE_TEXT,    0, typeofFunc },    { "length",     1, SQLITE_NUMERIC, 0, lengthFunc },    { "substr",     3, SQLITE_TEXT,    0, substrFunc },    { "abs",        1, SQLITE_NUMERIC, 0, absFunc    },    { "round",      1, SQLITE_NUMERIC, 0, roundFunc  },    { "round",      2, SQLITE_NUMERIC, 0, roundFunc  },    { "upper",      1, SQLITE_TEXT,    0, upperFunc  },    { "lower",      1, SQLITE_TEXT,    0, lowerFunc  },    { "coalesce",  -1, SQLITE_ARGS,    0, ifnullFunc },    { "coalesce",   0, 0,              0, 0          },    { "coalesce",   1, 0,              0, 0          },    { "ifnull",     2, SQLITE_ARGS,    0, ifnullFunc },    { "random",    -1, SQLITE_NUMERIC, 0, randomFunc },    { "like",       2, SQLITE_NUMERIC, 0, likeFunc   },    { "glob",       2, SQLITE_NUMERIC, 0, globFunc   },    { "nullif",     2, SQLITE_ARGS,    0, nullifFunc },    { "sqlite_version",0,SQLITE_TEXT,  0, versionFunc},    { "quote",      1, SQLITE_ARGS,    0, quoteFunc  },    { "last_insert_rowid", 0, SQLITE_NUMERIC, 1, last_insert_rowid },    { "change_count",      0, SQLITE_NUMERIC, 1, change_count      },    { "last_statement_change_count",                           0, SQLITE_NUMERIC, 1, last_statement_change_count },#ifdef SQLITE_SOUNDEX    { "soundex",    1, SQLITE_TEXT,    0, soundexFunc},#endif#ifdef SQLITE_TEST    { "randstr",    2, SQLITE_TEXT,    0, randStr    },#endif  };  static struct {    char *zName;    signed char nArg;    signed char dataType;    u8 argType;    void (*xStep)(sqlite_func*,int,const char**);    void (*xFinalize)(sqlite_func*);  } aAggs[] = {    { "min",    1, 0,              0, minmaxStep,   minMaxFinalize },    { "max",    1, 0,              2, minmaxStep,   minMaxFinalize },    { "sum",    1, SQLITE_NUMERIC, 0, sumStep,      sumFinalize    },    { "avg",    1, SQLITE_NUMERIC, 0, sumStep,      avgFinalize    },    { "count",  0, SQLITE_NUMERIC, 0, countStep,    countFinalize  },    { "count",  1, SQLITE_NUMERIC, 0, countStep,    countFinalize  },#if 0    { "stddev", 1, SQLITE_NUMERIC, 0, stdDevStep,   stdDevFinalize },#endif  };  static const char *azTypeFuncs[] = { "min", "max", "typeof" };  int i;  for(i=0; i<sizeof(aFuncs)/sizeof(aFuncs[0]); i++){    void *pArg;    switch( aFuncs[i].argType ){      case 0:  pArg = 0;           break;      case 1:  pArg = db;          break;      case 2:  pArg = (void*)(-1); break;    }    sqlite_create_function(db, aFuncs[i].zName,           aFuncs[i].nArg, aFuncs[i].xFunc, pArg);    if( aFuncs[i].xFunc ){      sqlite_function_type(db, aFuncs[i].zName, aFuncs[i].dataType);    }  }  for(i=0; i<sizeof(aAggs)/sizeof(aAggs[0]); i++){    void *pArg;    switch( aAggs[i].argType ){      case 0:  pArg = 0;           break;      case 1:  pArg = db;          break;      case 2:  pArg = (void*)(-1); break;    }    sqlite_create_aggregate(db, aAggs[i].zName,           aAggs[i].nArg, aAggs[i].xStep, aAggs[i].xFinalize, pArg);    sqlite_function_type(db, aAggs[i].zName, aAggs[i].dataType);  }  for(i=0; i<sizeof(azTypeFuncs)/sizeof(azTypeFuncs[0]); i++){    int n = strlen(azTypeFuncs[i]);    FuncDef *p = sqliteHashFind(&db->aFunc, azTypeFuncs[i], n);    while( p ){      p->includeTypes = 1;      p = p->pNext;    }  }  sqliteRegisterDateTimeFunctions(db);}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?