⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 shell.c

📁 sqlite 嵌入式数据库的源码
💻 C
📖 第 1 页 / 共 4 页
字号:
      zShellStatic = 0;    }    if( zErrMsg ){      fprintf(stderr,"Error: %s\n", zErrMsg);      sqlite3_free(zErrMsg);    }    if( rc==SQLITE_OK ){      int len, maxlen = 0;      int i, j;      int nPrintCol, nPrintRow;      for(i=1; i<=nRow; i++){        if( azResult[i]==0 ) continue;        len = strlen(azResult[i]);        if( len>maxlen ) maxlen = len;      }      nPrintCol = 80/(maxlen+2);      if( nPrintCol<1 ) nPrintCol = 1;      nPrintRow = (nRow + nPrintCol - 1)/nPrintCol;      for(i=0; i<nPrintRow; i++){        for(j=i+1; j<=nRow; j+=nPrintRow){          char *zSp = j<=nPrintRow ? "" : "  ";          printf("%s%-*s", zSp, maxlen, azResult[j] ? azResult[j] : "");        }        printf("\n");      }    }    sqlite3_free_table(azResult);  }else  if( c=='t' && n>1 && strncmp(azArg[0], "timeout", n)==0 && nArg>=2 ){    open_db(p);    sqlite3_busy_timeout(p->db, atoi(azArg[1]));  }else  if( c=='w' && strncmp(azArg[0], "width", n)==0 ){    int j;    for(j=1; j<nArg && j<ArraySize(p->colWidth); j++){      p->colWidth[j-1] = atoi(azArg[j]);    }  }else  {    fprintf(stderr, "unknown command or invalid arguments: "      " \"%s\". Enter \".help\" for help\n", azArg[0]);  }  return rc;}/*** Return TRUE if the last non-whitespace character in z[] is a semicolon.** z[] is N characters long.*/static int _ends_with_semicolon(const char *z, int N){  while( N>0 && isspace((unsigned char)z[N-1]) ){ N--; }  return N>0 && z[N-1]==';';}/*** Test to see if a line consists entirely of whitespace.*/static int _all_whitespace(const char *z){  for(; *z; z++){    if( isspace(*(unsigned char*)z) ) continue;    if( *z=='/' && z[1]=='*' ){      z += 2;      while( *z && (*z!='*' || z[1]!='/') ){ z++; }      if( *z==0 ) return 0;      z++;      continue;    }    if( *z=='-' && z[1]=='-' ){      z += 2;      while( *z && *z!='\n' ){ z++; }      if( *z==0 ) return 1;      continue;    }    return 0;  }  return 1;}/*** Return TRUE if the line typed in is an SQL command terminator other** than a semi-colon.  The SQL Server style "go" command is understood** as is the Oracle "/".*/static int _is_command_terminator(const char *zLine){  while( isspace(*(unsigned char*)zLine) ){ zLine++; };  if( zLine[0]=='/' && _all_whitespace(&zLine[1]) ) return 1;  /* Oracle */  if( tolower(zLine[0])=='g' && tolower(zLine[1])=='o'         && _all_whitespace(&zLine[2]) ){    return 1;  /* SQL Server */  }  return 0;}/*** Read input from *in and process it.  If *in==0 then input** is interactive - the user is typing it it.  Otherwise, input** is coming from a file or device.  A prompt is issued and history** is saved only if input is interactive.  An interrupt signal will** cause this routine to exit immediately, unless input is interactive.*/static void process_input(struct callback_data *p, FILE *in){  char *zLine;  char *zSql = 0;  int nSql = 0;  char *zErrMsg;  int rc;  while( fflush(p->out), (zLine = one_input_line(zSql, in))!=0 ){    if( seenInterrupt ){      if( in!=0 ) break;      seenInterrupt = 0;    }    if( p->echoOn ) printf("%s\n", zLine);    if( (zSql==0 || zSql[0]==0) && _all_whitespace(zLine) ) continue;    if( zLine && zLine[0]=='.' && nSql==0 ){      int rc = do_meta_command(zLine, p);      free(zLine);      if( rc ) break;      continue;    }    if( _is_command_terminator(zLine) ){      strcpy(zLine,";");    }    if( zSql==0 ){      int i;      for(i=0; zLine[i] && isspace((unsigned char)zLine[i]); i++){}      if( zLine[i]!=0 ){        nSql = strlen(zLine);        zSql = malloc( nSql+1 );        strcpy(zSql, zLine);      }    }else{      int len = strlen(zLine);      zSql = realloc( zSql, nSql + len + 2 );      if( zSql==0 ){        fprintf(stderr,"%s: out of memory!\n", Argv0);        exit(1);      }      strcpy(&zSql[nSql++], "\n");      strcpy(&zSql[nSql], zLine);      nSql += len;    }    free(zLine);    if( zSql && _ends_with_semicolon(zSql, nSql) && sqlite3_complete(zSql) ){      p->cnt = 0;      open_db(p);      rc = sqlite3_exec(p->db, zSql, callback, p, &zErrMsg);      if( rc || zErrMsg ){        if( in!=0 && !p->echoOn ) printf("%s\n",zSql);        if( zErrMsg!=0 ){          printf("SQL error: %s\n", zErrMsg);          sqlite3_free(zErrMsg);          zErrMsg = 0;        }else{          printf("SQL error: %s\n", sqlite3_errmsg(p->db));        }      }      free(zSql);      zSql = 0;      nSql = 0;    }  }  if( zSql ){    if( !_all_whitespace(zSql) ) printf("Incomplete SQL: %s\n", zSql);    free(zSql);  }}/*** Return a pathname which is the user's home directory.  A** 0 return indicates an error of some kind.  Space to hold the** resulting string is obtained from malloc().  The calling** function should free the result.*/static char *find_home_dir(void){  char *home_dir = NULL;#if !defined(_WIN32) && !defined(WIN32) && !defined(__MACOS__)  struct passwd *pwent;  uid_t uid = getuid();  if( (pwent=getpwuid(uid)) != NULL) {    home_dir = pwent->pw_dir;  }#endif#ifdef __MACOS__  char home_path[_MAX_PATH+1];  home_dir = getcwd(home_path, _MAX_PATH);#endif  if (!home_dir) {    home_dir = getenv("HOME");    if (!home_dir) {      home_dir = getenv("HOMEPATH"); /* Windows? */    }  }#if defined(_WIN32) || defined(WIN32)  if (!home_dir) {    home_dir = "c:";  }#endif  if( home_dir ){    char *z = malloc( strlen(home_dir)+1 );    if( z ) strcpy(z, home_dir);    home_dir = z;  }  return home_dir;}/*** Read input from the file given by sqliterc_override.  Or if that** parameter is NULL, take input from ~/.sqliterc*/static void process_sqliterc(  struct callback_data *p,        /* Configuration data */  const char *sqliterc_override   /* Name of config file. NULL to use default */){  char *home_dir = NULL;  const char *sqliterc = sqliterc_override;  char *zBuf;  FILE *in = NULL;  if (sqliterc == NULL) {    home_dir = find_home_dir();    if( home_dir==0 ){      fprintf(stderr,"%s: cannot locate your home directory!\n", Argv0);      return;    }    zBuf = malloc(strlen(home_dir) + 15);    if( zBuf==0 ){      fprintf(stderr,"%s: out of memory!\n", Argv0);      exit(1);    }    sprintf(zBuf,"%s/.sqliterc",home_dir);    free(home_dir);    sqliterc = (const char*)zBuf;  }  in = fopen(sqliterc,"rb");  if( in ){    if( isatty(fileno(stdout)) ){      printf("Loading resources from %s\n",sqliterc);    }    process_input(p,in);    fclose(in);  }  return;}/*** Show available command line options*/static const char zOptions[] =   "   -init filename       read/process named file\n"  "   -echo                print commands before execution\n"  "   -[no]header          turn headers on or off\n"  "   -column              set output mode to 'column'\n"  "   -html                set output mode to HTML\n"#ifdef SQLITE_HAS_CODEC  "   -key KEY             encryption key\n"#endif                   "   -line                set output mode to 'line'\n"  "   -list                set output mode to 'list'\n"  "   -separator 'x'       set output field separator (|)\n"  "   -nullvalue 'text'    set text string for NULL values\n"  "   -version             show SQLite version\n"  "   -help                show this text, also show dot-commands\n";static void usage(int showDetail){  fprintf(stderr, "Usage: %s [OPTIONS] FILENAME [SQL]\n", Argv0);  if( showDetail ){    fprintf(stderr, "Options are:\n%s", zOptions);  }else{    fprintf(stderr, "Use the -help option for additional information\n");  }  exit(1);}/*** Initialize the state information in data*/void main_init(struct callback_data *data) {  memset(data, 0, sizeof(*data));  data->mode = MODE_List;  strcpy(data->separator,"|");  data->showHeader = 0;  strcpy(mainPrompt,"sqlite> ");  strcpy(continuePrompt,"   ...> ");}int main(int argc, char **argv){  char *zErrMsg = 0;  struct callback_data data;  const char *zInitFile = 0;  char *zFirstCmd = 0;  int i;#ifdef __MACOS__  argc = ccommand(&argv);#endif  Argv0 = argv[0];  main_init(&data);  /* Make sure we have a valid signal handler early, before anything  ** else is done.  */#ifdef SIGINT  signal(SIGINT, interrupt_handler);#endif  /* Do an initial pass through the command-line argument to locate  ** the name of the database file, the name of the initialization file,  ** and the first command to execute.  */  for(i=1; i<argc-1; i++){    if( argv[i][0]!='-' ) break;    if( strcmp(argv[i],"-separator")==0 || strcmp(argv[i],"-nullvalue")==0 ){      i++;    }else if( strcmp(argv[i],"-init")==0 ){      i++;      zInitFile = argv[i];    }else if( strcmp(argv[i],"-key")==0 ){      i++;      data.zKey = sqlite3_mprintf("%s",argv[i]);    }  }  if( i<argc ){    data.zDbFilename = argv[i++];  }else{#ifndef SQLITE_OMIT_MEMORYDB    data.zDbFilename = ":memory:";#else    data.zDbFilename = 0;#endif  }  if( i<argc ){    zFirstCmd = argv[i++];  }  data.out = stdout;  /* Go ahead and open the database file if it already exists.  If the  ** file does not exist, delay opening it.  This prevents empty database  ** files from being created if a user mistypes the database name argument  ** to the sqlite command-line tool.  */  if( access(data.zDbFilename, 0)==0 ){    open_db(&data);  }  /* Process the initialization file if there is one.  If no -init option  ** is given on the command line, look for a file named ~/.sqliterc and  ** try to process it.  */  process_sqliterc(&data,zInitFile);  /* Make a second pass through the command-line argument and set  ** options.  This second pass is delayed until after the initialization  ** file is processed so that the command-line arguments will override  ** settings in the initialization file.  */  for(i=1; i<argc && argv[i][0]=='-'; i++){    char *z = argv[i];    if( strcmp(z,"-init")==0 || strcmp(z,"-key")==0 ){      i++;    }else if( strcmp(z,"-html")==0 ){      data.mode = MODE_Html;    }else if( strcmp(z,"-list")==0 ){      data.mode = MODE_List;    }else if( strcmp(z,"-line")==0 ){      data.mode = MODE_Line;    }else if( strcmp(z,"-column")==0 ){      data.mode = MODE_Column;    }else if( strcmp(z,"-separator")==0 ){      i++;      sprintf(data.separator,"%.*s",(int)sizeof(data.separator)-1,argv[i]);    }else if( strcmp(z,"-nullvalue")==0 ){      i++;      sprintf(data.nullvalue,"%.*s",(int)sizeof(data.nullvalue)-1,argv[i]);    }else if( strcmp(z,"-header")==0 ){      data.showHeader = 1;    }else if( strcmp(z,"-noheader")==0 ){      data.showHeader = 0;    }else if( strcmp(z,"-echo")==0 ){      data.echoOn = 1;    }else if( strcmp(z,"-version")==0 ){      printf("%s\n", sqlite3_libversion());      return 1;    }else if( strcmp(z,"-help")==0 ){      usage(1);    }else{      fprintf(stderr,"%s: unknown option: %s\n", Argv0, z);      fprintf(stderr,"Use -help for a list of options.\n");      return 1;    }  }  if( zFirstCmd ){    /* Run just the command that follows the database name    */    if( zFirstCmd[0]=='.' ){      do_meta_command(zFirstCmd, &data);      exit(0);    }else{      int rc;      open_db(&data);      rc = sqlite3_exec(data.db, zFirstCmd, callback, &data, &zErrMsg);      if( rc!=0 && zErrMsg!=0 ){        fprintf(stderr,"SQL error: %s\n", zErrMsg);        exit(1);      }    }  }else{    /* Run commands received from standard input    */    if( isatty(fileno(stdout)) && isatty(fileno(stdin)) ){      char *zHome;      char *zHistory = 0;      printf(        "SQLite version %s\n"        "Enter \".help\" for instructions\n",        sqlite3_libversion()      );      zHome = find_home_dir();      if( zHome && (zHistory = malloc(strlen(zHome)+20))!=0 ){        sprintf(zHistory,"%s/.sqlite_history", zHome);      }#if defined(HAVE_READLINE) && HAVE_READLINE==1      if( zHistory ) read_history(zHistory);#endif      process_input(&data, 0);      if( zHistory ){        stifle_history(100);        write_history(zHistory);      }    }else{      process_input(&data, stdin);    }  }  set_table_name(&data, 0);  if( db ) sqlite3_close(db);  return 0;}

⌨️ 快捷键说明

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