Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Change the sqlite3_namelist() interface to return a pointer to an array of pointers to strings, and to avoid duplicates. |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | experimental-namelist |
Files: | files | file ages | folders |
SHA3-256: |
702911104424f03f6ebe3beb9090f73b |
User & Date: | drh 2017-07-06 18:52:36.337 |
Context
2017-07-06
| ||
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) | |
18:25 | The sqlite3_namelist() routine now works for all name types. (check-in: e41d62175b user: drh tags: experimental-namelist) | |
Changes
Changes to src/hash.h.
︙ | ︙ | |||
87 88 89 90 91 92 93 | #define sqliteHashData(E) ((E)->data) /* #define sqliteHashKey(E) ((E)->pKey) // NOT USED */ /* #define sqliteHashKeysize(E) ((E)->nKey) // NOT USED */ /* ** Number of entries in a hash table */ | | | 87 88 89 90 91 92 93 94 95 96 | #define sqliteHashData(E) ((E)->data) /* #define sqliteHashKey(E) ((E)->pKey) // NOT USED */ /* #define sqliteHashKeysize(E) ((E)->nKey) // NOT USED */ /* ** Number of entries in a hash table */ #define sqliteHashCount(H) ((H)->count) #endif /* SQLITE_HASH_H */ |
Changes to src/sqlite.h.in.
︙ | ︙ | |||
8468 8469 8470 8471 8472 8473 8474 | int sqlite3_preupdate_depth(sqlite3 *); int sqlite3_preupdate_new(sqlite3 *, int, sqlite3_value **); #endif /* ** CAPI3REF: List Of Symbolic Names ** | | > > | < < | | 8468 8469 8470 8471 8472 8473 8474 8475 8476 8477 8478 8479 8480 8481 8482 8483 8484 8485 8486 8487 8488 8489 8490 8491 8492 8493 8494 8495 8496 8497 8498 8499 8500 8501 | int sqlite3_preupdate_depth(sqlite3 *); int sqlite3_preupdate_new(sqlite3 *, int, sqlite3_value **); #endif /* ** CAPI3REF: List Of Symbolic Names ** ** ^The sqlite3_namelist(D,P,F,N) interface returns a list of symbolic names ** and keywords that might appear in valid SQL statements for [connection] ** D and that all begin with the prefix P. ^The F parameter is a bitmask ** that determines the kinds of symbolic names and keywords that are found ** in the list. ^Matching against the prefix P is performed using ** [sqlite3_strnicmp()] and is thus case insensitive for ASCII characters. ** ^If the pointer N is not NULL, then the number of matching names is ** stored in *N. ** ** ^The value returned by sqlite3_namelist() is stored in memory obtained ** from [sqlite3_malloc()] and must be released by the caller using ** [sqlite3_free()]. ^The sqlite3_namelist() interface returns NULL if a ** memory allocation error occurs. ** ** ^Elements of the list are unique but are in no particular order. ** ** This interface is intended to facilitate tab-completion for interactive ** interfaces for SQLite. */ char **sqlite3_namelist(sqlite3 *db, const char *zPrefix, int typeMask, int*); /* ** CAPI3REF: Symbolic Name Typemask Values ** ** ^These bitmask values are used to determine the kinds of symbolic names ** and keywords that are returned by [sqlite3_namelist()]. The third ** parameter to [sqlite3_namelist()] should be an OR-ed combination of |
︙ | ︙ |
Changes to src/tclsqlite.c.
︙ | ︙ | |||
2666 2667 2668 2669 2670 2671 2672 | /* ** $db namelist PREFIX MASK */ case DB_NAMELIST: { const char *zPrefix; int mask; | | > | | | < | < | > > | | 2666 2667 2668 2669 2670 2671 2672 2673 2674 2675 2676 2677 2678 2679 2680 2681 2682 2683 2684 2685 2686 2687 2688 2689 2690 2691 2692 2693 2694 2695 2696 | /* ** $db namelist PREFIX MASK */ case DB_NAMELIST: { const char *zPrefix; int mask; char **azList; int nList, i; if( objc!=4 ){ Tcl_WrongNumArgs(interp, 2, objv, "PREFIX MASK"); return TCL_ERROR; } zPrefix = Tcl_GetString(objv[2]); if( Tcl_GetIntFromObj(interp, objv[3], &mask) ) return TCL_ERROR; azList = sqlite3_namelist(pDb->db, zPrefix, mask, &nList); if( azList ){ Tcl_Obj *pList = Tcl_NewListObj(nList, 0); for(i=0; azList[i]; i++){ Tcl_ListObjAppendElement(interp, pList, Tcl_NewStringObj(azList[i],-1)); } assert( i==nList ); sqlite3_free(azList); Tcl_SetObjResult(interp, pList); } break; } /* ** $db nullvalue ?STRING? |
︙ | ︙ |
Changes to src/tokenize.c.
︙ | ︙ | |||
615 616 617 618 619 620 621 | return nErr; } /* An instance of the following object is used to accumulate a list ** of names for the sqlite3_namelist() interface */ struct NameAccum { | | > > > | | | > > > > > | > > | | 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 | return nErr; } /* An instance of the following object is used to accumulate a list ** of names for the sqlite3_namelist() interface */ struct NameAccum { Hash x; /* Hash table of all names */ const char *zPrefix; /* All names must start with this prefix */ int nPrefix; /* Size of the prefix in bytes */ }; /* ** Examine zName to see if it belongs on the list (if it has a matching ** prefix) and add it to the list if it belongs. nName is the length ** of the name in bytes, or -1 if zName is zero-terminated. */ static void addName(struct NameAccum *p, const char *zName, int nName){ char *zCopy; char *zOld; if( nName<0 ) nName = sqlite3Strlen30(zName); if( nName<p->nPrefix ) return; if( sqlite3StrNICmp(p->zPrefix, zName, p->nPrefix)!=0 ) return; zCopy = sqlite3_mprintf("%.*s", nName, zName); zOld = sqlite3HashInsert(&p->x, zCopy, zCopy); sqlite3_free(zOld); } /* ** Return a list of text words or identifiers that might appear in an ** SQL statement. The typeMask parameter is a bitmask that determines ** specifically what kinds of names should be returned. All names ** returned must begin with zPrefix. ** ** The returned list is from a single memory allocation. The caller owns ** the allocation and should release it using sqlite3_free() when it has ** finished using the list. ** ** Each word is separated from the next by a single 0x00 byte. The list ** is terminated by two 0x00 bytes in a row. */ char **sqlite3_namelist( sqlite3 *db, /* Database from which to extract names */ const char *zPrefix, /* Only extract names matching this prefix */ int typeMask, /* Mask of the types of names to extract */ int *pCount /* Write the number of names here */ ){ struct NameAccum x; int i, n, nEntry; HashElem *j; char **azAns; char *zFree; x.zPrefix = zPrefix; x.nPrefix = sqlite3Strlen30(zPrefix); sqlite3HashInit(&x.x); if( typeMask & SQLITE_NAMETYPE_KEYWORD ){ for(i=0; i<ArraySize(aKWOffset); i++){ addName(&x, zKWText + aKWOffset[i], aKWLen[i]); } } if( typeMask & SQLITE_NAMETYPE_FUNCTION ){ for(i=0; i<SQLITE_FUNC_HASH_SZ; i++){ |
︙ | ︙ | |||
720 721 722 723 724 725 726 | if( typeMask & SQLITE_NAMETYPE_TRIGGER ){ for(j=sqliteHashFirst(&pDb->pSchema->trigHash); j; j=sqliteHashNext(j)){ Trigger *p = (Trigger*)sqliteHashData(j); addName(&x, p->zName, -1); } } } | > > | > > > > > > > > > > > > > > > > > > > > > > > > | | 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 | if( typeMask & SQLITE_NAMETYPE_TRIGGER ){ for(j=sqliteHashFirst(&pDb->pSchema->trigHash); j; j=sqliteHashNext(j)){ Trigger *p = (Trigger*)sqliteHashData(j); addName(&x, p->zName, -1); } } } if( typeMask & SQLITE_NAMETYPE_COLUMN ){ addName(&x, "rowid", -1); } } 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; } } for(j=sqliteHashFirst(&x.x); j; j=sqliteHashNext(j)){ sqlite3_free(sqliteHashData(j)); } sqlite3HashClear(&x.x); return azAns; } |