SQLite

Check-in [5cc7b0e2ca]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Use the sqlite3_namelist() interface to implement simple tab-completion using linenoise.
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | experimental-namelist
Files: files | file ages | folders
SHA3-256: 5cc7b0e2ca87220d714f3994a206ca903f5b82daa920fd625de035c646447800
User & Date: drh 2017-07-06 19:26:23.558
Context
2017-07-06
20:08
Tab-completion now also works using readline/editline. (check-in: c906739f0c user: drh tags: experimental-namelist)
19:26
Use the sqlite3_namelist() interface to implement simple tab-completion using linenoise. (check-in: 5cc7b0e2ca user: drh tags: experimental-namelist)
18:52
Change the sqlite3_namelist() interface to return a pointer to an array of pointers to strings, and to avoid duplicates. (check-in: 7029111044 user: drh tags: experimental-namelist)
Changes
Unified Diff Ignore Whitespace Patch
Changes to main.mk.
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484

# Standard options to testfixture
#
TESTOPTS = --verbose=file --output=test-out.txt

# Extra compiler options for various shell tools
#
SHELL_OPT = -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_FTS5
SHELL_OPT += -DSQLITE_ENABLE_EXPLAIN_COMMENTS
SHELL_OPT += -DSQLITE_ENABLE_UNKNOWN_SQL_FUNCTION
SHELL_OPT += -DSQLITE_ENABLE_STMTVTAB
FUZZERSHELL_OPT = -DSQLITE_ENABLE_JSON1
FUZZCHECK_OPT = -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_MEMSYS5
FUZZCHECK_OPT += -DSQLITE_MAX_MEMORY=50000000
DBFUZZ_OPT =







|







470
471
472
473
474
475
476
477
478
479
480
481
482
483
484

# Standard options to testfixture
#
TESTOPTS = --verbose=file --output=test-out.txt

# Extra compiler options for various shell tools
#
SHELL_OPT += -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_FTS5
SHELL_OPT += -DSQLITE_ENABLE_EXPLAIN_COMMENTS
SHELL_OPT += -DSQLITE_ENABLE_UNKNOWN_SQL_FUNCTION
SHELL_OPT += -DSQLITE_ENABLE_STMTVTAB
FUZZERSHELL_OPT = -DSQLITE_ENABLE_JSON1
FUZZCHECK_OPT = -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_MEMSYS5
FUZZCHECK_OPT += -DSQLITE_MAX_MEMORY=50000000
DBFUZZ_OPT =
Changes to src/shell.c.
3595
3596
3597
3598
3599
3600
3601





























3602
3603
3604
3605
3606
3607
3608
                            sha3QueryFunc, 0, 0);
    sqlite3_create_function(p->db, "shell_add_schema", 2, SQLITE_UTF8, 0,
                            shellAddSchemaName, 0, 0);
                            
  }
}






























/*
** Do C-language style dequoting.
**
**    \a    -> alarm
**    \b    -> backspace
**    \t    -> tab
**    \n    -> newline







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







3595
3596
3597
3598
3599
3600
3601
3602
3603
3604
3605
3606
3607
3608
3609
3610
3611
3612
3613
3614
3615
3616
3617
3618
3619
3620
3621
3622
3623
3624
3625
3626
3627
3628
3629
3630
3631
3632
3633
3634
3635
3636
3637
                            sha3QueryFunc, 0, 0);
    sqlite3_create_function(p->db, "shell_add_schema", 2, SQLITE_UTF8, 0,
                            shellAddSchemaName, 0, 0);
                            
  }
}

#ifdef HAVE_LINENOISE
/*
** Linenoise completion callback
*/
static void linenoise_completion(const char *zLine, linenoiseCompletions *lc){
  int nLine = (int)strlen(zLine);
  int i, n, iStart;
  char **az;
  char zBuf[1000];
  if( nLine>sizeof(zBuf)-30 ) return;
  if( zLine[0]=='.' ) return;
  for(i=nLine-1; i>=0 && (isalnum(zLine[i]) || zLine[i]=='_'); i--){}
  if( i==nLine-1 ) return;
  iStart = i+1;
  az = sqlite3_namelist(globalDb, &zLine[iStart], -1, &n);
  if( n>0 ){
    qsort(az, n, sizeof(az[0]),(int(*)(const void*,const void*))sqlite3_stricmp);
    memcpy(zBuf, zLine, iStart);
    for(i=0; az[i]; i++){
      n = (int)strlen(az[i]);
      if( iStart+n+1 >= sizeof(zBuf) ) continue;
      memcpy(zBuf+iStart, az[i], n+1);
      linenoiseAddCompletion(lc, zBuf);
    }
  }
  sqlite3_free(az);
}
#endif

/*
** Do C-language style dequoting.
**
**    \a    -> alarm
**    \b    -> backspace
**    \t    -> tab
**    \n    -> newline
7632
7633
7634
7635
7636
7637
7638



7639
7640
7641
7642
7643
7644
7645
      if( zHome ){
        nHistory = strlen30(zHome) + 20;
        if( (zHistory = malloc(nHistory))!=0 ){
          sqlite3_snprintf(nHistory, zHistory,"%s/.sqlite_history", zHome);
        }
      }
      if( zHistory ){ shell_read_history(zHistory); }



      rc = process_input(&data, 0);
      if( zHistory ){
        shell_stifle_history(100);
        shell_write_history(zHistory);
        free(zHistory);
      }
    }else{







>
>
>







7661
7662
7663
7664
7665
7666
7667
7668
7669
7670
7671
7672
7673
7674
7675
7676
7677
      if( zHome ){
        nHistory = strlen30(zHome) + 20;
        if( (zHistory = malloc(nHistory))!=0 ){
          sqlite3_snprintf(nHistory, zHistory,"%s/.sqlite_history", zHome);
        }
      }
      if( zHistory ){ shell_read_history(zHistory); }
#ifdef HAVE_LINENOISE
      linenoiseSetCompletionCallback(linenoise_completion);
#endif
      rc = process_input(&data, 0);
      if( zHistory ){
        shell_stifle_history(100);
        shell_write_history(zHistory);
        free(zHistory);
      }
    }else{
Changes to src/tokenize.c.
741
742
743
744
745
746
747

748
749
750
751
752
753
754
755
756
757
  nEntry = sqliteHashCount(&x.x);
  if( pCount ) *pCount = nEntry;
  n = 0;
  for(j=sqliteHashFirst(&x.x); j; j=sqliteHashNext(j)){
    n += sqlite3Strlen30((const char*)sqliteHashData(j));
  }
  zFree = sqlite3_malloc( (nEntry+1)*sizeof(char*) + n + nEntry );

  if( zFree ){
    memset(zFree, 0, (nEntry+1)*sizeof(char*) + n + nEntry );
    azAns = (char**)zFree;
    zFree += (nEntry+1)*sizeof(char*);
    for(i=0, j=sqliteHashFirst(&x.x); j; i++, j=sqliteHashNext(j)){
      const char *zName = (const char*)sqliteHashData(j);
      azAns[i] = zFree;
      n = sqlite3Strlen30(zName);
      memcpy(zFree, zName, n+1);
      zFree += n+1;







>


<







741
742
743
744
745
746
747
748
749
750

751
752
753
754
755
756
757
  nEntry = sqliteHashCount(&x.x);
  if( pCount ) *pCount = nEntry;
  n = 0;
  for(j=sqliteHashFirst(&x.x); j; j=sqliteHashNext(j)){
    n += sqlite3Strlen30((const char*)sqliteHashData(j));
  }
  zFree = sqlite3_malloc( (nEntry+1)*sizeof(char*) + n + nEntry );
  azAns = (char**)zFree;
  if( zFree ){
    memset(zFree, 0, (nEntry+1)*sizeof(char*) + n + nEntry );

    zFree += (nEntry+1)*sizeof(char*);
    for(i=0, j=sqliteHashFirst(&x.x); j; i++, j=sqliteHashNext(j)){
      const char *zName = (const char*)sqliteHashData(j);
      azAns[i] = zFree;
      n = sqlite3Strlen30(zName);
      memcpy(zFree, zName, n+1);
      zFree += n+1;