Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Add experimental support for resolving relative database file paths using a fixed user-defined directory. |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | winrt |
Files: | files | file ages | folders |
SHA1: |
7354ae8fd3eccee2cf9f6501da5b1a01 |
User & Date: | mistachkin 2012-03-14 00:44:01.952 |
Context
2012-03-14
| ||
01:28 | Add warning to the docs about changing the data directory when a database connection is open. (check-in: c07cd85ca9 user: mistachkin tags: winrt) | |
00:44 | Add experimental support for resolving relative database file paths using a fixed user-defined directory. (check-in: 7354ae8fd3 user: mistachkin tags: winrt) | |
2012-03-13
| ||
03:38 | Add assert to verify the number of characters to write in sqlite3_win32_write_debug. (check-in: 8083f6164f user: mistachkin tags: winrt) | |
Changes
Changes to src/main.c.
︙ | ︙ | |||
70 71 72 73 74 75 76 77 78 79 80 81 82 83 | ** name of a directory, then that directory will be used to store ** temporary files. ** ** See also the "PRAGMA temp_store_directory" SQL command. */ char *sqlite3_temp_directory = 0; /* ** Initialize SQLite. ** ** This routine must be called to initialize the memory allocation, ** VFS, and mutex subsystems prior to doing any serious work with ** SQLite. But as long as you do not compile with SQLITE_OMIT_AUTOINIT ** this routine will be called automatically by key routines such as | > > > > > > > > > | 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 | ** name of a directory, then that directory will be used to store ** temporary files. ** ** See also the "PRAGMA temp_store_directory" SQL command. */ char *sqlite3_temp_directory = 0; /* ** If the following global variable points to a string which is the ** name of a directory, then that directory will be used to store ** all database files specified with a relative pathname. ** ** See also the "PRAGMA data_store_directory" SQL command. */ char *sqlite3_data_directory = 0; /* ** Initialize SQLite. ** ** This routine must be called to initialize the memory allocation, ** VFS, and mutex subsystems prior to doing any serious work with ** SQLite. But as long as you do not compile with SQLITE_OMIT_AUTOINIT ** this routine will be called automatically by key routines such as |
︙ | ︙ |
Changes to src/os_win.c.
︙ | ︙ | |||
3698 3699 3700 3701 3702 3703 3704 3705 3706 3707 3708 3709 3710 3711 3712 3713 3714 3715 3716 3717 3718 3719 3720 | default: assert(!"Invalid flags argument"); } *pResOut = rc; return SQLITE_OK; } /* ** Turn a relative pathname into a full pathname. Write the full ** pathname into zOut[]. zOut[] will be at least pVfs->mxPathname ** bytes in size. */ static int winFullPathname( sqlite3_vfs *pVfs, /* Pointer to vfs object */ const char *zRelative, /* Possibly relative input path */ int nFull, /* Size of output buffer in bytes */ char *zFull /* Output buffer */ ){ #if defined(__CYGWIN__) SimulateIOError( return SQLITE_ERROR ); UNUSED_PARAMETER(nFull); | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | > | < > > > > > > > > > > | > | 3698 3699 3700 3701 3702 3703 3704 3705 3706 3707 3708 3709 3710 3711 3712 3713 3714 3715 3716 3717 3718 3719 3720 3721 3722 3723 3724 3725 3726 3727 3728 3729 3730 3731 3732 3733 3734 3735 3736 3737 3738 3739 3740 3741 3742 3743 3744 3745 3746 3747 3748 3749 3750 3751 3752 3753 3754 3755 3756 3757 3758 3759 3760 3761 3762 3763 3764 3765 3766 3767 3768 3769 3770 3771 3772 3773 3774 3775 3776 3777 3778 3779 3780 3781 3782 3783 3784 3785 3786 3787 3788 3789 3790 3791 3792 3793 3794 3795 3796 3797 3798 3799 3800 3801 3802 3803 3804 3805 | default: assert(!"Invalid flags argument"); } *pResOut = rc; return SQLITE_OK; } /* ** Returns non-zero if the specified path name should be used verbatim. If ** non-zero is returned from this function, the calling function must simply ** use the provided path name verbatim -OR- resolve it into a full path name ** using the GetFullPathName Win32 API function (if available). */ static BOOL winIsVerbatimPathname( const char *zPathname ){ /* ** If the path name starts with a forward slash or a backslash, it is either ** a legal UNC name, a volume relative path, or an absolute path name in the ** "Unix" format on Windows. There is no easy way to differentiate between ** the final two cases; therefore, we return the safer return value of TRUE ** so that callers of this function will simply use it verbatim. */ if ( zPathname[0]=='/' || zPathname[0]=='\\' ){ return TRUE; } /* ** If the path name starts with a letter and a colon it is either a volume ** relative path or an absolute path. Callers of this function must not ** attempt to treat it as a relative path name (i.e. they should simply use ** it verbatim). */ if ( sqlite3Isalpha(zPathname[0]) && zPathname[1]==':' ){ return TRUE; } /* ** If we get to this point, the path name should almost certainly be a purely ** relative one (i.e. not a UNC name, not absolute, and not volume relative). */ return FALSE; } /* ** Turn a relative pathname into a full pathname. Write the full ** pathname into zOut[]. zOut[] will be at least pVfs->mxPathname ** bytes in size. */ static int winFullPathname( sqlite3_vfs *pVfs, /* Pointer to vfs object */ const char *zRelative, /* Possibly relative input path */ int nFull, /* Size of output buffer in bytes */ char *zFull /* Output buffer */ ){ #if defined(__CYGWIN__) SimulateIOError( return SQLITE_ERROR ); UNUSED_PARAMETER(nFull); assert( pVfs->mxPathname>=MAX_PATH ); assert( nFull>=pVfs->mxPathname ); if ( sqlite3_data_directory && !winIsVerbatimPathname(zRelative) ){ /* ** NOTE: We are dealing with a relative path name and the data ** directory has been set. Therefore, use it as the basis ** for converting the relative path name to an absolute ** one by prepending the data directory and a slash. */ char zOut[MAX_PATH+1]; memset(zOut, 0, MAX_PATH+1); cygwin_conv_to_win32_path(zRelative, zOut); /* POSIX to Win32 */ sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s\\%s", sqlite3_data_directory, zOut); }else{ /* ** NOTE: The Cygwin docs state that the maximum length needed ** for the buffer passed to cygwin_conv_to_full_win32_path ** is MAX_PATH. */ cygwin_conv_to_full_win32_path(zRelative, zFull); } return SQLITE_OK; #endif #if (SQLITE_OS_WINCE || SQLITE_OS_WINRT) && !defined(__CYGWIN__) SimulateIOError( return SQLITE_ERROR ); /* WinCE has no concept of a relative pathname, or so I am told. */ /* WinRT has no way to convert a relative path to an absolute one. */ if ( sqlite3_data_directory && !winIsVerbatimPathname(zRelative) ){ /* ** NOTE: We are dealing with a relative path name and the data ** directory has been set. Therefore, use it as the basis ** for converting the relative path name to an absolute ** one by prepending the data directory and a backslash. */ sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s\\%s", sqlite3_data_directory, zRelative); }else{ sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s", zRelative); } return SQLITE_OK; #endif #if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && !defined(__CYGWIN__) int nByte; void *zConverted; char *zOut; |
︙ | ︙ | |||
3745 3746 3747 3748 3749 3750 3751 | /* It's odd to simulate an io-error here, but really this is just ** using the io-error infrastructure to test that SQLite handles this ** function failing. This function could fail if, for example, the ** current working directory has been unlinked. */ SimulateIOError( return SQLITE_ERROR ); | > > > > > > > | > > > | 3813 3814 3815 3816 3817 3818 3819 3820 3821 3822 3823 3824 3825 3826 3827 3828 3829 3830 3831 3832 3833 3834 3835 3836 3837 | /* It's odd to simulate an io-error here, but really this is just ** using the io-error infrastructure to test that SQLite handles this ** function failing. This function could fail if, for example, the ** current working directory has been unlinked. */ SimulateIOError( return SQLITE_ERROR ); if ( sqlite3_data_directory && !winIsVerbatimPathname(zRelative) ){ /* ** NOTE: We are dealing with a relative path name and the data ** directory has been set. Therefore, use it as the basis ** for converting the relative path name to an absolute ** one by prepending the data directory and a backslash. */ sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s\\%s", sqlite3_data_directory, zRelative); return SQLITE_OK; } zConverted = convertUtf8Filename(zRelative); if( zConverted==0 ){ return SQLITE_IOERR_NOMEM; } if( isNT() ){ LPWSTR zTemp; nByte = osGetFullPathNameW((LPCWSTR)zConverted, 0, 0, 0) + 3; |
︙ | ︙ | |||
3779 3780 3781 3782 3783 3784 3785 | osGetFullPathNameA((char*)zConverted, nByte, zTemp, 0); sqlite3_free(zConverted); zOut = sqlite3_win32_mbcs_to_utf8(zTemp); sqlite3_free(zTemp); } #endif if( zOut ){ | | | 3857 3858 3859 3860 3861 3862 3863 3864 3865 3866 3867 3868 3869 3870 3871 | osGetFullPathNameA((char*)zConverted, nByte, zTemp, 0); sqlite3_free(zConverted); zOut = sqlite3_win32_mbcs_to_utf8(zTemp); sqlite3_free(zTemp); } #endif if( zOut ){ sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s", zOut); sqlite3_free(zOut); return SQLITE_OK; }else{ return SQLITE_IOERR_NOMEM; } #endif } |
︙ | ︙ |
Changes to src/pragma.c.
︙ | ︙ | |||
800 801 802 803 804 805 806 807 808 809 810 811 812 813 | }else{ sqlite3_temp_directory = 0; } #endif /* SQLITE_OMIT_WSD */ } }else #if !defined(SQLITE_ENABLE_LOCKING_STYLE) # if defined(__APPLE__) # define SQLITE_ENABLE_LOCKING_STYLE 1 # else # define SQLITE_ENABLE_LOCKING_STYLE 0 # endif #endif | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 | }else{ sqlite3_temp_directory = 0; } #endif /* SQLITE_OMIT_WSD */ } }else /* ** PRAGMA data_store_directory ** PRAGMA data_store_directory = ""|"directory_name" ** ** Return or set the local value of the data_store_directory flag. Changing ** the value sets a specific directory to be used for database files that ** were specified with a relative pathname. Setting to a null string reverts ** to the default database directory, which for database files specified with ** a relative path will probably be based on the current directory for the ** process. Database file specified with an absolute path are not impacted ** by this setting, regardless of its value. ** */ if( sqlite3StrICmp(zLeft, "data_store_directory")==0 ){ if( !zRight ){ if( sqlite3_data_directory ){ sqlite3VdbeSetNumCols(v, 1); sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "data_store_directory", SQLITE_STATIC); sqlite3VdbeAddOp4(v, OP_String8, 0, 1, 0, sqlite3_data_directory, 0); sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 1); } }else{ #ifndef SQLITE_OMIT_WSD if( zRight[0] ){ int res; rc = sqlite3OsAccess(db->pVfs, zRight, SQLITE_ACCESS_READWRITE, &res); if( rc!=SQLITE_OK || res==0 ){ sqlite3ErrorMsg(pParse, "not a writable directory"); goto pragma_out; } } sqlite3_free(sqlite3_data_directory); if( zRight[0] ){ sqlite3_data_directory = sqlite3_mprintf("%s", zRight); }else{ sqlite3_data_directory = 0; } #endif /* SQLITE_OMIT_WSD */ } }else #if !defined(SQLITE_ENABLE_LOCKING_STYLE) # if defined(__APPLE__) # define SQLITE_ENABLE_LOCKING_STYLE 1 # else # define SQLITE_ENABLE_LOCKING_STYLE 0 # endif #endif |
︙ | ︙ |
Changes to src/sqlite.h.in.
︙ | ︙ | |||
4439 4440 4441 4442 4443 4444 4445 4446 4447 4448 4449 4450 4451 4452 | ** using [sqlite3_free]. ** Hence, if this variable is modified directly, either it should be ** made NULL or made to point to memory obtained from [sqlite3_malloc] ** or else the use of the [temp_store_directory pragma] should be avoided. */ SQLITE_EXTERN char *sqlite3_temp_directory; /* ** CAPI3REF: Test For Auto-Commit Mode ** KEYWORDS: {autocommit mode} ** ** ^The sqlite3_get_autocommit() interface returns non-zero or ** zero if the given database connection is or is not in autocommit mode, ** respectively. ^Autocommit mode is on by default. | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 4439 4440 4441 4442 4443 4444 4445 4446 4447 4448 4449 4450 4451 4452 4453 4454 4455 4456 4457 4458 4459 4460 4461 4462 4463 4464 4465 4466 4467 4468 4469 4470 4471 4472 4473 4474 4475 4476 4477 4478 4479 4480 4481 4482 4483 4484 4485 | ** using [sqlite3_free]. ** Hence, if this variable is modified directly, either it should be ** made NULL or made to point to memory obtained from [sqlite3_malloc] ** or else the use of the [temp_store_directory pragma] should be avoided. */ SQLITE_EXTERN char *sqlite3_temp_directory; /* ** CAPI3REF: Name Of The Folder Holding Database Files ** ** ^(If this global variable is made to point to a string which is ** the name of a folder (a.k.a. directory), then all database files ** specified with a relative pathname and created or accessed by ** SQLite when using a built-in [sqlite3_vfs | VFS] will be assumed ** to be relative to that directory.)^ ^If this variable is a NULL ** pointer, then SQLite assumes that all database files specified ** with a relative pathname are relative to the current directory ** for the process. ** ** It is not safe to read or modify this variable in more than one ** thread at a time. It is not safe to read or modify this variable ** if a [database connection] is being used at the same time in a separate ** thread. ** It is intended that this variable be set once ** as part of process initialization and before any SQLite interface ** routines have been called and that this variable remain unchanged ** thereafter. ** ** ^The [data_store_directory pragma] may modify this variable and cause ** it to point to memory obtained from [sqlite3_malloc]. ^Furthermore, ** the [data_store_directory pragma] always assumes that any string ** that this variable points to is held in memory obtained from ** [sqlite3_malloc] and the pragma may attempt to free that memory ** using [sqlite3_free]. ** Hence, if this variable is modified directly, either it should be ** made NULL or made to point to memory obtained from [sqlite3_malloc] ** or else the use of the [data_store_directory pragma] should be avoided. */ SQLITE_EXTERN char *sqlite3_data_directory; /* ** CAPI3REF: Test For Auto-Commit Mode ** KEYWORDS: {autocommit mode} ** ** ^The sqlite3_get_autocommit() interface returns non-zero or ** zero if the given database connection is or is not in autocommit mode, ** respectively. ^Autocommit mode is on by default. |
︙ | ︙ |
Changes to src/test1.c.
︙ | ︙ | |||
6257 6258 6259 6260 6261 6262 6263 6264 6265 6266 6267 6268 6269 6270 | #endif Tcl_LinkVar(interp, "sqlite_static_bind_value", (char*)&sqlite_static_bind_value, TCL_LINK_STRING); Tcl_LinkVar(interp, "sqlite_static_bind_nbyte", (char*)&sqlite_static_bind_nbyte, TCL_LINK_INT); Tcl_LinkVar(interp, "sqlite_temp_directory", (char*)&sqlite3_temp_directory, TCL_LINK_STRING); Tcl_LinkVar(interp, "bitmask_size", (char*)&bitmask_size, TCL_LINK_INT|TCL_LINK_READ_ONLY); Tcl_LinkVar(interp, "sqlite_sync_count", (char*)&sqlite3_sync_count, TCL_LINK_INT); Tcl_LinkVar(interp, "sqlite_fullsync_count", (char*)&sqlite3_fullsync_count, TCL_LINK_INT); #if defined(SQLITE_ENABLE_FTS3) && defined(SQLITE_TEST) | > > | 6257 6258 6259 6260 6261 6262 6263 6264 6265 6266 6267 6268 6269 6270 6271 6272 | #endif Tcl_LinkVar(interp, "sqlite_static_bind_value", (char*)&sqlite_static_bind_value, TCL_LINK_STRING); Tcl_LinkVar(interp, "sqlite_static_bind_nbyte", (char*)&sqlite_static_bind_nbyte, TCL_LINK_INT); Tcl_LinkVar(interp, "sqlite_temp_directory", (char*)&sqlite3_temp_directory, TCL_LINK_STRING); Tcl_LinkVar(interp, "sqlite_data_directory", (char*)&sqlite3_data_directory, TCL_LINK_STRING); Tcl_LinkVar(interp, "bitmask_size", (char*)&bitmask_size, TCL_LINK_INT|TCL_LINK_READ_ONLY); Tcl_LinkVar(interp, "sqlite_sync_count", (char*)&sqlite3_sync_count, TCL_LINK_INT); Tcl_LinkVar(interp, "sqlite_fullsync_count", (char*)&sqlite3_fullsync_count, TCL_LINK_INT); #if defined(SQLITE_ENABLE_FTS3) && defined(SQLITE_TEST) |
︙ | ︙ |
Changes to test/pragma.test.
︙ | ︙ | |||
36 37 38 39 40 41 42 43 44 45 46 47 48 49 | # pragma-9.*: Test temp_store and temp_store_directory. # pragma-10.*: Test the count_changes pragma in the presence of triggers. # pragma-11.*: Test the collation_list pragma. # pragma-14.*: Test the page_count pragma. # pragma-15.*: Test that the value set using the cache_size pragma is not # reset when the schema is reloaded. # pragma-16.*: Test proxy locking # ifcapable !pragma { finish_test return } | > | 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 | # pragma-9.*: Test temp_store and temp_store_directory. # pragma-10.*: Test the count_changes pragma in the presence of triggers. # pragma-11.*: Test the collation_list pragma. # pragma-14.*: Test the page_count pragma. # pragma-15.*: Test that the value set using the cache_size pragma is not # reset when the schema is reloaded. # pragma-16.*: Test proxy locking # pragma-20.*: Test data_store_directory. # ifcapable !pragma { finish_test return } |
︙ | ︙ | |||
1506 1507 1508 1509 1510 1511 1512 | do_test pragma-19.4 { catchsql {PRAGMA error=7} } {1 {out of memory}} do_test pragma-19.5 { file tail [lindex [execsql {PRAGMA filename}] 0] } {test.db} | > | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 | do_test pragma-19.4 { catchsql {PRAGMA error=7} } {1 {out of memory}} do_test pragma-19.5 { file tail [lindex [execsql {PRAGMA filename}] 0] } {test.db} # Test data_store_directory pragma # db close sqlite3 db test.db file mkdir data_dir do_test pragma-20.1 { catchsql {PRAGMA data_store_directory} } {0 {}} do_test pragma-20.2 { set pwd [string map {' ''} [file nativename [get_pwd]]] catchsql "PRAGMA data_store_directory='$pwd';" } {0 {}} do_test pragma-20.3 { catchsql {PRAGMA data_store_directory} } [list 0 [list [file nativename [get_pwd]]]] do_test pragma-20.4 { set pwd [string map {' ''} [file nativename \ [file join [get_pwd] data_dir]]] catchsql "PRAGMA data_store_directory='$pwd';" } {0 {}} do_test pragma-20.5 { sqlite3 db2 test2.db catchsql "PRAGMA database_list;" db2 } [list 0 [list 0 main [file nativename \ [file join [get_pwd] data_dir test2.db]]]] catch {db2 close} do_test pragma-20.6 { sqlite3 db2 [file join [get_pwd] test2.db] catchsql "PRAGMA database_list;" db2 } [list 0 [list 0 main [file nativename \ [file join [get_pwd] test2.db]]]] catch {db2 close} do_test pragma-20.7 { catchsql "PRAGMA data_store_directory='';" } {0 {}} do_test pragma-20.8 { catchsql {PRAGMA data_store_directory} } {0 {}} forcedelete data_dir finish_test |