BLOB | TEXT | Add a zero terminator if needed
**
** )^
@@ -3776,7 +3912,7 @@
** described above, or until [sqlite3_step()] or [sqlite3_reset()] or
** [sqlite3_finalize()] is called. ^The memory space used to hold strings
** and BLOBs is freed automatically. Do not pass the pointers returned
-** [sqlite3_column_blob()], [sqlite3_column_text()], etc. into
+** from [sqlite3_column_blob()], [sqlite3_column_text()], etc. into
** [sqlite3_free()].
**
** ^(If a memory allocation error occurs during the evaluation of any
@@ -3885,15 +4021,24 @@
**
** ^The fourth parameter, eTextRep, specifies what
** [SQLITE_UTF8 | text encoding] this SQL function prefers for
-** its parameters. Every SQL function implementation must be able to work
-** with UTF-8, UTF-16le, or UTF-16be. But some implementations may be
-** more efficient with one encoding than another. ^An application may
-** invoke sqlite3_create_function() or sqlite3_create_function16() multiple
-** times with the same function but with different values of eTextRep.
+** its parameters. The application should set this parameter to
+** [SQLITE_UTF16LE] if the function implementation invokes
+** [sqlite3_value_text16le()] on an input, or [SQLITE_UTF16BE] if the
+** implementation invokes [sqlite3_value_text16be()] on an input, or
+** [SQLITE_UTF16] if [sqlite3_value_text16()] is used, or [SQLITE_UTF8]
+** otherwise. ^The same SQL function may be registered multiple times using
+** different preferred text encodings, with different implementations for
+** each encoding.
** ^When multiple implementations of the same function are available, SQLite
** will pick the one that involves the least amount of data conversion.
-** If there is only a single implementation which does not care what text
-** encoding is used, then the fourth argument should be [SQLITE_ANY].
+**
+** ^The fourth parameter may optionally be ORed with [SQLITE_DETERMINISTIC]
+** to signal that the function will always return the same result given
+** the same inputs within a single SQL statement. Most SQL functions are
+** deterministic. The built-in [random()] SQL function is an example of a
+** function that is not deterministic. The SQLite query planner is able to
+** perform additional optimizations on deterministic functions, so use
+** of the [SQLITE_DETERMINISTIC] flag is recommended where possible.
**
** ^(The fifth parameter is an arbitrary pointer. The implementation of the
** function can gain access to this pointer using [sqlite3_user_data()].)^
@@ -3979,10 +4124,20 @@
#define SQLITE_UTF16LE 2
#define SQLITE_UTF16BE 3
#define SQLITE_UTF16 4 /* Use native byte order */
-#define SQLITE_ANY 5 /* sqlite3_create_function only */
+#define SQLITE_ANY 5 /* Deprecated */
#define SQLITE_UTF16_ALIGNED 8 /* sqlite3_create_collation only */
/*
+** CAPI3REF: Function Flags
+**
+** These constants may be ORed together with the
+** [SQLITE_UTF8 | preferred text encoding] as the fourth argument
+** to [sqlite3_create_function()], [sqlite3_create_function16()], or
+** [sqlite3_create_function_v2()].
+*/
+#define SQLITE_DETERMINISTIC 0x800
+
+/*
** CAPI3REF: Deprecated Functions
** DEPRECATED
**
@@ -3998,7 +4153,8 @@
SQLITE_API SQLITE_DEPRECATED int sqlite3_transfer_bindings(sqlite3_stmt*, sqlite3_stmt*);
SQLITE_API SQLITE_DEPRECATED int sqlite3_global_recover(void);
SQLITE_API SQLITE_DEPRECATED void sqlite3_thread_cleanup(void);
-SQLITE_API SQLITE_DEPRECATED int sqlite3_memory_alarm(void(*)(void*,sqlite3_int64,int),void*,sqlite3_int64);
+SQLITE_API SQLITE_DEPRECATED int sqlite3_memory_alarm(void(*)(void*,sqlite3_int64,int),
+ void*,sqlite3_int64);
#endif
/*
@@ -4078,14 +4234,17 @@
** In those cases, sqlite3_aggregate_context() might be called for the
** first time from within xFinal().)^
**
-** ^The sqlite3_aggregate_context(C,N) routine returns a NULL pointer if N is
-** less than or equal to zero or if a memory allocate error occurs.
+** ^The sqlite3_aggregate_context(C,N) routine returns a NULL pointer
+** when first called if N is less than or equal to zero or if a memory
+** allocate error occurs.
**
** ^(The amount of space allocated by sqlite3_aggregate_context(C,N) is
** determined by the N parameter on first successful call. Changing the
** value of N in subsequent call to sqlite3_aggregate_context() within
** the same aggregate function instance will not resize the memory
-** allocation.)^
+** allocation.)^ Within the xFinal callback, it is customary to set
+** N=0 in calls to sqlite3_aggregate_context(C,N) so that no
+** pointless memory allocations occur.
**
** ^SQLite automatically frees the memory allocated by
** sqlite3_aggregate_context() when the aggregate query concludes.
@@ -4128,41 +4287,49 @@
/*
** CAPI3REF: Function Auxiliary Data
**
-** The following two functions may be used by scalar SQL functions to
+** These functions may be used by (non-aggregate) SQL functions to
** associate metadata with argument values. If the same value is passed to
** multiple invocations of the same SQL function during query execution, under
-** some circumstances the associated metadata may be preserved. This may
-** be used, for example, to add a regular-expression matching scalar
-** function. The compiled version of the regular expression is stored as
-** metadata associated with the SQL value passed as the regular expression
-** pattern. The compiled regular expression can be reused on multiple
-** invocations of the same function so that the original pattern string
-** does not need to be recompiled on each invocation.
+** some circumstances the associated metadata may be preserved. An example
+** of where this might be useful is in a regular-expression matching
+** function. The compiled version of the regular expression can be stored as
+** metadata associated with the pattern string.
+** Then as long as the pattern string remains the same,
+** the compiled regular expression can be reused on multiple
+** invocations of the same function.
**
** ^The sqlite3_get_auxdata() interface returns a pointer to the metadata
** associated by the sqlite3_set_auxdata() function with the Nth argument
-** value to the application-defined function. ^If no metadata has been ever
-** been set for the Nth argument of the function, or if the corresponding
-** function parameter has changed since the meta-data was set,
-** then sqlite3_get_auxdata() returns a NULL pointer.
-**
-** ^The sqlite3_set_auxdata() interface saves the metadata
-** pointed to by its 3rd parameter as the metadata for the N-th
-** argument of the application-defined function. Subsequent
-** calls to sqlite3_get_auxdata() might return this data, if it has
-** not been destroyed.
-** ^If it is not NULL, SQLite will invoke the destructor
-** function given by the 4th parameter to sqlite3_set_auxdata() on
-** the metadata when the corresponding function parameter changes
-** or when the SQL statement completes, whichever comes first.
-**
-** SQLite is free to call the destructor and drop metadata on any
-** parameter of any function at any time. ^The only guarantee is that
-** the destructor will be called before the metadata is dropped.
+** value to the application-defined function. ^If there is no metadata
+** associated with the function argument, this sqlite3_get_auxdata() interface
+** returns a NULL pointer.
+**
+** ^The sqlite3_set_auxdata(C,N,P,X) interface saves P as metadata for the N-th
+** argument of the application-defined function. ^Subsequent
+** calls to sqlite3_get_auxdata(C,N) return P from the most recent
+** sqlite3_set_auxdata(C,N,P,X) call if the metadata is still valid or
+** NULL if the metadata has been discarded.
+** ^After each call to sqlite3_set_auxdata(C,N,P,X) where X is not NULL,
+** SQLite will invoke the destructor function X with parameter P exactly
+** once, when the metadata is discarded.
+** SQLite is free to discard the metadata at any time, including:
+** - when the corresponding function parameter changes, or
+**
- when [sqlite3_reset()] or [sqlite3_finalize()] is called for the
+** SQL statement, or
+**
- when sqlite3_set_auxdata() is invoked again on the same parameter, or
+**
- during the original sqlite3_set_auxdata() call when a memory
+** allocation error occurs.
)^
+**
+** Note the last bullet in particular. The destructor X in
+** sqlite3_set_auxdata(C,N,P,X) might be called immediately, before the
+** sqlite3_set_auxdata() interface even returns. Hence sqlite3_set_auxdata()
+** should be called near the end of the function implementation and the
+** function implementation should not make any use of P after
+** sqlite3_set_auxdata() has been called.
**
** ^(In practice, metadata is preserved between function calls for
-** expressions that are constant at compile time. This includes literal
-** values and [parameters].)^
+** function parameters that are compile-time constants, including literal
+** values and [parameters] and expressions composed from the same.)^
**
** These routines must be called from the same thread in which
** the SQL function is running.
@@ -4183,7 +4350,7 @@
** the content before returning.
**
** The typedef is necessary to work around problems in certain
-** C++ compilers. See ticket #2191.
+** C++ compilers.
*/
typedef void (*sqlite3_destructor_type)(void*);
#define SQLITE_STATIC ((sqlite3_destructor_type)0)
@@ -4467,6 +4634,11 @@
sqlite3 *db, /* Database to be rekeyed */
const void *pKey, int nKey /* The key */
);
+SQLITE_API int sqlite3_key_v2(
+ sqlite3 *db, /* Database to be rekeyed */
+ const char *zDbName, /* Name of the database */
+ const void *pKey, int nKey /* The key */
+);
/*
** Change the key on an open database. If the current database is not
@@ -4480,6 +4652,11 @@
sqlite3 *db, /* Database to be rekeyed */
const void *pKey, int nKey /* The new key */
);
+SQLITE_API int sqlite3_rekey_v2(
+ sqlite3 *db, /* Database to be rekeyed */
+ const char *zDbName, /* Name of the database */
+ const void *pKey, int nKey /* The new key */
+);
/*
** Specify the activation key for a SEE database. Unless
@@ -4731,12 +4908,13 @@
**
** ^The sqlite3_update_hook() interface registers a callback function
** with the [database connection] identified by the first argument
-** to be invoked whenever a row is updated, inserted or deleted.
+** to be invoked whenever a row is updated, inserted or deleted in
+** a rowid table.
** ^Any callback set by a previous call to this function
** for the same database connection is overridden.
**
** ^The second argument is a pointer to the function to invoke when a
-** row is updated, inserted or deleted.
+** row is updated, inserted or deleted in a rowid table.
** ^The first argument to the callback is a copy of the third argument
** to sqlite3_update_hook().
** ^The second callback argument is one of [SQLITE_INSERT], [SQLITE_DELETE],
@@ -4749,6 +4927,7 @@
**
** ^(The update hook is not invoked when internal system tables are
** modified (i.e. sqlite_master and sqlite_sequence).)^
+** ^The update hook is not invoked when [WITHOUT ROWID] tables are modified.
**
** ^In the current implementation, the update hook
** is not invoked when duplication rows are deleted because of an
@@ -4830,8 +5009,8 @@
**
** ^The sqlite3_db_release_memory(D) interface attempts to free as much heap
** memory as possible from database connection D. Unlike the
-** [sqlite3_release_memory()] interface, this interface is effect even
-** when then [SQLITE_ENABLE_MEMORY_MANAGEMENT] compile-time option is
+** [sqlite3_release_memory()] interface, this interface is in effect even
+** when the [SQLITE_ENABLE_MEMORY_MANAGEMENT] compile-time option is
** omitted.
**
** See also: [sqlite3_release_memory()]
@@ -4982,11 +5161,20 @@
** ^This interface loads an SQLite extension library from the named file.
**
** ^The sqlite3_load_extension() interface attempts to load an
-** SQLite extension library contained in the file zFile.
+** [SQLite extension] library contained in the file zFile. If
+** the file cannot be loaded directly, attempts are made to load
+** with various operating-system specific extensions added.
+** So for example, if "samplelib" cannot be loaded, then names like
+** "samplelib.so" or "samplelib.dylib" or "samplelib.dll" might
+** be tried also.
**
** ^The entry point is zProc.
-** ^zProc may be 0, in which case the name of the entry point
-** defaults to "sqlite3_extension_init".
+** ^(zProc may be 0, in which case SQLite will try to come up with an
+** entry point name on its own. It first tries "sqlite3_extension_init".
+** If that does not work, it constructs a name "sqlite3_X_init" where the
+** X is consists of the lower-case equivalent of all ASCII alphabetic
+** characters in the filename from the last "/" to the first following
+** "." and omitting any initial "lib".)^
** ^The sqlite3_load_extension() interface returns
** [SQLITE_OK] on success and [SQLITE_ERROR] if something goes wrong.
** ^If an error occurs and pzErrMsg is not 0, then the
@@ -5012,11 +5200,11 @@
** CAPI3REF: Enable Or Disable Extension Loading
**
** ^So as not to open security holes in older applications that are
-** unprepared to deal with extension loading, and as a means of disabling
-** extension loading while evaluating user-entered SQL, the following API
+** unprepared to deal with [extension loading], and as a means of disabling
+** [extension loading] while evaluating user-entered SQL, the following API
** is provided to turn the [sqlite3_load_extension()] mechanism on and off.
**
-** ^Extension loading is off by default. See ticket #1863.
+** ^Extension loading is off by default.
** ^Call the sqlite3_enable_load_extension() routine with onoff==1
** to turn extension loading on and call it with onoff==0 to turn
** it back off again.
@@ -5028,7 +5216,7 @@
**
** ^This interface causes the xEntryPoint() function to be invoked for
** each new [database connection] that is created. The idea here is that
-** xEntryPoint() is the entry point for a statically linked SQLite extension
+** xEntryPoint() is the entry point for a statically linked [SQLite extension]
** that is to be automatically loaded into all new database connections.
**
** ^(Even though the function prototype shows that xEntryPoint() takes
@@ -5056,11 +5244,24 @@
** on the list of automatic extensions is a harmless no-op. ^No entry point
** will be called more than once for each database connection that is opened.
**
-** See also: [sqlite3_reset_auto_extension()].
+** See also: [sqlite3_reset_auto_extension()]
+** and [sqlite3_cancel_auto_extension()]
*/
SQLITE_API int sqlite3_auto_extension(void (*xEntryPoint)(void));
/*
+** CAPI3REF: Cancel Automatic Extension Loading
+**
+** ^The [sqlite3_cancel_auto_extension(X)] interface unregisters the
+** initialization routine X that was registered using a prior call to
+** [sqlite3_auto_extension(X)]. ^The [sqlite3_cancel_auto_extension(X)]
+** routine returns 1 if initialization routine X was successfully
+** unregistered and it returns 0 if X was not on the list of initialization
+** routines.
+*/
+SQLITE_API int sqlite3_cancel_auto_extension(void (*xEntryPoint)(void));
+
+/*
** CAPI3REF: Reset Automatic Extension Loading
**
** ^This interface disables all automatic extensions previously
@@ -5184,10 +5385,22 @@
** the correct order to satisfy the ORDER BY clause so that no separate
** sorting step is required.
**
-** ^The estimatedCost value is an estimate of the cost of doing the
-** particular lookup. A full scan of a table with N entries should have
-** a cost of N. A binary search of a table of N entries should have a
-** cost of approximately log(N).
+** ^The estimatedCost value is an estimate of the cost of a particular
+** strategy. A cost of N indicates that the cost of the strategy is similar
+** to a linear scan of an SQLite table with N rows. A cost of log(N)
+** indicates that the expense of the operation is similar to that of a
+** binary search on a unique indexed field of an SQLite table with N rows.
+**
+** ^The estimatedRows value is an estimate of the number of rows that
+** will be returned by the strategy.
+**
+** IMPORTANT: The estimatedRows field was added to the sqlite3_index_info
+** structure for SQLite version 3.8.2. If a virtual table extension is
+** used with an SQLite version earlier than 3.8.2, the results of attempting
+** to read or write the estimatedRows field are undefined (but are likely
+** to included crashing the application). The estimatedRows field should
+** therefore only be used if [sqlite3_libversion_number()] returns a
+** value greater than or equal to 3008002.
*/
struct sqlite3_index_info {
/* Inputs */
@@ -5212,7 +5425,9 @@
char *idxStr; /* String, possibly obtained from sqlite3_malloc */
int needToFreeIdxStr; /* Free idxStr using sqlite3_free() if true */
int orderByConsumed; /* True if output is already ordered */
- double estimatedCost; /* Estimated cost of using this index */
+ double estimatedCost; /* Estimated cost of using this index */
+ /* Fields below are only available in SQLite 3.8.2 and later */
+ sqlite3_int64 estimatedRows; /* Estimated number of rows returned */
};
/*
@@ -5416,6 +5631,9 @@
** interface. Use the [UPDATE] SQL command to change the size of a
** blob.
**
+** ^The [sqlite3_blob_open()] interface will fail for a [WITHOUT ROWID]
+** table. Incremental BLOB I/O is not possible on [WITHOUT ROWID] tables.
+**
** ^The [sqlite3_bind_zeroblob()] and [sqlite3_result_zeroblob()] interfaces
** and the built-in [zeroblob] SQL function can be used, if desired,
** to create an empty, zero-filled blob in which to read or write using
@@ -5939,7 +6157,10 @@
#define SQLITE_TESTCTRL_SCRATCHMALLOC 17
#define SQLITE_TESTCTRL_LOCALTIME_FAULT 18
#define SQLITE_TESTCTRL_EXPLAIN_STMT 19
-#define SQLITE_TESTCTRL_LAST 19
+#define SQLITE_TESTCTRL_NEVER_CORRUPT 20
+#define SQLITE_TESTCTRL_VDBE_COVERAGE 21
+#define SQLITE_TESTCTRL_BYTEORDER 22
+#define SQLITE_TESTCTRL_LAST 22
/*
** CAPI3REF: SQLite Runtime Status
@@ -6172,6 +6393,12 @@
** on subsequent SQLITE_DBSTATUS_CACHE_WRITE requests is undefined.)^ ^The
** highwater mark associated with SQLITE_DBSTATUS_CACHE_WRITE is always 0.
**
+**
+** [[SQLITE_DBSTATUS_DEFERRED_FKS]] ^(SQLITE_DBSTATUS_DEFERRED_FKS
+** This parameter returns zero for the current value if and only if
+** all foreign key constraints (deferred or immediate) have been
+** resolved.)^ ^The highwater mark is always 0.
+**
**
*/
#define SQLITE_DBSTATUS_LOOKASIDE_USED 0
@@ -6184,7 +6411,8 @@
#define SQLITE_DBSTATUS_CACHE_HIT 7
#define SQLITE_DBSTATUS_CACHE_MISS 8
#define SQLITE_DBSTATUS_CACHE_WRITE 9
-#define SQLITE_DBSTATUS_MAX 9 /* Largest defined DBSTATUS */
+#define SQLITE_DBSTATUS_DEFERRED_FKS 10
+#define SQLITE_DBSTATUS_MAX 10 /* Largest defined DBSTATUS */
/*
@@ -6238,11 +6466,21 @@
** A non-zero value in this counter may indicate an opportunity to
** improvement performance by adding permanent indices that do not
** need to be reinitialized each time the statement is run.
+**
+** [[SQLITE_STMTSTATUS_VM_STEP]] SQLITE_STMTSTATUS_VM_STEP
+** ^This is the number of virtual machine operations executed
+** by the prepared statement if that number is less than or equal
+** to 2147483647. The number of virtual machine operations can be
+** used as a proxy for the total work done by the prepared statement.
+** If the number of virtual machine operations exceeds 2147483647
+** then the value returned by this statement status code is undefined.
+**
**
*/
#define SQLITE_STMTSTATUS_FULLSCAN_STEP 1
#define SQLITE_STMTSTATUS_SORT 2
#define SQLITE_STMTSTATUS_AUTOINDEX 3
+#define SQLITE_STMTSTATUS_VM_STEP 4
/*
** CAPI3REF: Custom Page Cache Object
@@ -6379,7 +6617,7 @@
** parameter to help it determined what action to take:
**
**
-** createFlag | Behaviour when page is not already in cache
+** |
---|
createFlag | Behavior when page is not already in cache
** |
---|
0 | Do not allocate a new page. Return NULL.
** | 1 | Allocate a new page if it easy and convenient to do so.
** Otherwise return NULL.
@@ -6809,9 +7047,24 @@
SQLITE_API int sqlite3_strnicmp(const char *, const char *, int);
/*
+** CAPI3REF: String Globbing
+*
+** ^The [sqlite3_strglob(P,X)] interface returns zero if string X matches
+** the glob pattern P, and it returns non-zero if string X does not match
+** the glob pattern P. ^The definition of glob pattern matching used in
+** [sqlite3_strglob(P,X)] is the same as for the "X GLOB P" operator in the
+** SQL dialect used by SQLite. ^The sqlite3_strglob(P,X) function is case
+** sensitive.
+**
+** Note that this routine returns zero on a match and non-zero if the strings
+** do not match, the same as [sqlite3_stricmp()] and [sqlite3_strnicmp()].
+*/
+SQLITE_API int sqlite3_strglob(const char *zGlob, const char *zStr);
+
+/*
** CAPI3REF: Error Logging Interface
**
-** ^The [sqlite3_log()] interface writes a message into the error log
+** ^The [sqlite3_log()] interface writes a message into the [error log]
** established by the [SQLITE_CONFIG_LOG] option to [sqlite3_config()].
** ^If logging is enabled, the zFormat string and subsequent arguments are
** used with [sqlite3_snprintf()] to generate the final output string.
@@ -7106,7 +7359,7 @@
#ifdef __cplusplus
} /* End of the 'extern "C"' block */
#endif
-#endif
+#endif /* _SQLITE3_H_ */
/*
** 2010 August 30
@@ -7130,6 +7383,16 @@
#endif
typedef struct sqlite3_rtree_geometry sqlite3_rtree_geometry;
+typedef struct sqlite3_rtree_query_info sqlite3_rtree_query_info;
+
+/* The double-precision datatype used by RTree depends on the
+** SQLITE_RTREE_INT_ONLY compile-time option.
+*/
+#ifdef SQLITE_RTREE_INT_ONLY
+ typedef sqlite3_int64 sqlite3_rtree_dbl;
+#else
+ typedef double sqlite3_rtree_dbl;
+#endif
/*
** Register a geometry callback named zGeom that can be used as part of an
@@ -7140,11 +7403,7 @@
SQLITE_API int sqlite3_rtree_geometry_callback(
sqlite3 *db,
const char *zGeom,
-#ifdef SQLITE_RTREE_INT_ONLY
- int (*xGeom)(sqlite3_rtree_geometry*, int n, sqlite3_int64 *a, int *pRes),
-#else
- int (*xGeom)(sqlite3_rtree_geometry*, int n, double *a, int *pRes),
-#endif
+ int (*xGeom)(sqlite3_rtree_geometry*, int, sqlite3_rtree_dbl*,int*),
void *pContext
);
@@ -7156,11 +7415,60 @@
struct sqlite3_rtree_geometry {
void *pContext; /* Copy of pContext passed to s_r_g_c() */
int nParam; /* Size of array aParam[] */
- double *aParam; /* Parameters passed to SQL geom function */
+ sqlite3_rtree_dbl *aParam; /* Parameters passed to SQL geom function */
void *pUser; /* Callback implementation user data */
void (*xDelUser)(void *); /* Called by SQLite to clean up pUser */
};
+/*
+** Register a 2nd-generation geometry callback named zScore that can be
+** used as part of an R-Tree geometry query as follows:
+**
+** SELECT ... FROM WHERE MATCH $zQueryFunc(... params ...)
+*/
+SQLITE_API int sqlite3_rtree_query_callback(
+ sqlite3 *db,
+ const char *zQueryFunc,
+ int (*xQueryFunc)(sqlite3_rtree_query_info*),
+ void *pContext,
+ void (*xDestructor)(void*)
+);
+
+
+/*
+** A pointer to a structure of the following type is passed as the
+** argument to scored geometry callback registered using
+** sqlite3_rtree_query_callback().
+**
+** Note that the first 5 fields of this structure are identical to
+** sqlite3_rtree_geometry. This structure is a subclass of
+** sqlite3_rtree_geometry.
+*/
+struct sqlite3_rtree_query_info {
+ void *pContext; /* pContext from when function registered */
+ int nParam; /* Number of function parameters */
+ sqlite3_rtree_dbl *aParam; /* value of function parameters */
+ void *pUser; /* callback can use this, if desired */
+ void (*xDelUser)(void*); /* function to free pUser */
+ sqlite3_rtree_dbl *aCoord; /* Coordinates of node or entry to check */
+ unsigned int *anQueue; /* Number of pending entries in the queue */
+ int nCoord; /* Number of coordinates */
+ int iLevel; /* Level of current node or entry */
+ int mxLevel; /* The largest iLevel value in the tree */
+ sqlite3_int64 iRowid; /* Rowid for current entry */
+ sqlite3_rtree_dbl rParentScore; /* Score of parent node */
+ int eParentWithin; /* Visibility of parent node */
+ int eWithin; /* OUT: Visiblity */
+ sqlite3_rtree_dbl rScore; /* OUT: Write the score here */
+};
+
+/*
+** Allowed values for sqlite3_rtree_query.eWithin and .eParentWithin.
+*/
+#define NOT_WITHIN 0 /* Object completely outside of query region */
+#define PARTLY_WITHIN 1 /* Object partially overlaps query region */
+#define FULLY_WITHIN 2 /* Object fully contained within query region */
+
#ifdef __cplusplus
} /* end of the 'extern "C"' block */
diff -r 226774bf49fc -r a2ad87cad48b src/about.cpp
--- a/src/about.cpp Mon Dec 08 19:47:42 2014 +0900
+++ b/src/about.cpp Wed Dec 17 00:52:43 2014 +0900
@@ -1,5 +1,5 @@
// Filename : about.cpp
-// Last Change: 17-Oct-2013.
+// Last Change: 15-Dec-2014.
//
#include "common.h"
@@ -19,7 +19,7 @@
m_bitmap = new wxStaticBitmap( this, wxID_ANY, bmp, wxDefaultPosition, wxDefaultSize, 0 );
bSizerOK->Add( m_bitmap, 0, wxALL, 5 );
- m_staticTextDesc = new wxStaticText( this, wxID_ANY, wxT("我に自由を!\rLet me free !"), wxDefaultPosition, wxSize(-1,50), 0 );
+ m_staticTextDesc = new wxStaticText( this, wxID_ANY, wxT("我に自由を!\rLet me free !"), wxDefaultPosition, wxSize( -1, 50 ), 0 );
bSizerOK->Add( m_staticTextDesc, 0, wxALL|wxALIGN_CENTRE, 5 );
m_buttonOK = new wxButton( this, wxID_OK, wxT("OK"), wxDefaultPosition, wxDefaultSize, 0 );
@@ -27,6 +27,10 @@
bSizerOK->Add( m_buttonOK, 0, wxALL|wxALIGN_BOTTOM, 5 );
bSizer->Add( bSizerOK, 0, wxEXPAND, 5 );
+
+ wxString build;
+ m_staticTextBuild = new wxStaticText( this, wxID_ANY, build.Format( wxT("Build with %s\n") wxT("running under %s."), wxVERSION_STRING, wxGetOsDescription().c_str() ), wxDefaultPosition, wxDefaultSize, 0 );
+ bSizer->Add( m_staticTextBuild, 0, wxALL, 5 );
m_richText = new wxRichTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxVSCROLL|wxBORDER_NONE|wxWANTS_CHARS );
bSizer->Add( m_richText, 1, wxEXPAND|wxALL, 5 );
@@ -47,7 +51,7 @@
{
wxTextFile textfile;
textfile.Open( wxGetCwd() + wxFILE_SEP_PATH + wxT("Changes") );
- for ( int i=0; iBeginBold();
m_richText->BeginFontSize(16);
@@ -56,22 +60,23 @@
m_richText->EndTextColour();
m_richText->EndFontSize();
m_richText->EndBold();
- m_richText->Newline();
}
else if ( textfile[i].StartsWith( wxT("20")) ) { // year
- m_richText->BeginAlignment( wxTEXT_ALIGNMENT_RIGHT );
+ m_richText->WriteText( wxT("\t\t") );
m_richText->BeginItalic();
m_richText->WriteText( textfile[i] );
m_richText->EndItalic();
- m_richText->EndAlignment();
m_richText->Newline();
}
else if ( textfile[i].StartsWith( wxT("----")) ) {
m_richText->WriteText( textfile[i] );
m_richText->Newline();
}
+ else if ( textfile[i].IsEmpty() ) {
+ m_richText->Newline();
+ }
else {
- m_richText->BeginSymbolBullet( wxT("* "), 60, 0, wxTEXT_ATTR_BULLET_STYLE_SYMBOL );
+ m_richText->BeginSymbolBullet( '*', 60, 0, wxTEXT_ATTR_BULLET_STYLE_SYMBOL );
m_richText->WriteText( textfile[i] );
m_richText->EndSymbolBullet();
m_richText->Newline();
diff -r 226774bf49fc -r a2ad87cad48b src/bprint.cpp
--- a/src/bprint.cpp Mon Dec 08 19:47:42 2014 +0900
+++ b/src/bprint.cpp Wed Dec 17 00:52:43 2014 +0900
@@ -1,5 +1,5 @@
// Filename : bprint.cpp
-// Last Change: 21-May-2014.
+// Last Change: 12-Aug-2014.
//
#include "bprint.h"
@@ -174,6 +174,8 @@
wxCopyFile( file, tmpjpg, true );
}
html = html + wxT(" ");
+ html = html + wxT("") + m_grid->GetCellValue( r, 0 ) + wxT(" ");
+
cout = dir.GetNext( &file );
n++;
}
diff -r 226774bf49fc -r a2ad87cad48b src/cache.cpp
--- a/src/cache.cpp Mon Dec 08 19:47:42 2014 +0900
+++ b/src/cache.cpp Wed Dec 17 00:52:43 2014 +0900
@@ -1,33 +1,165 @@
// Filename : cache.cpp
-// Last Change: 21-Nov-2014.
+// Last Change: 15-Dec-2014.
//
#include "cache.h"
#include "db.h"
+// キャッシュ取得ダイアログ
+CacheGetDialog::CacheGetDialog( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style )
+ : wxDialog( parent, id, title, pos, size, style )
+{
+ this->SetSizeHints( wxDefaultSize, wxDefaultSize );
+ this->SetBackgroundColour( wxColour( wxT("WHEAT") ) );
+
+ wxBoxSizer* bSizerTop = new wxBoxSizer( wxVERTICAL );
+
+ m_dirPicker = new wxDirPickerCtrl( this, wxID_ANY, wxEmptyString, wxT("Select a directory") );
+ bSizerTop->Add( m_dirPicker, 0, wxALL|wxEXPAND, 5 );
+
+ wxBoxSizer* bSizerButton = new wxBoxSizer( wxHORIZONTAL );
+
+ m_buttonGet = new wxButton( this, ID_GETCACHE, wxT("コピィ"), wxDefaultPosition, wxDefaultSize, 0 );
+ bSizerButton->Add( m_buttonGet, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 );
+
+ m_buttonCancel = new wxButton( this, wxID_CANCEL, wxT("閉じる"), wxDefaultPosition, wxDefaultSize, 0 );
+ bSizerButton->Add( m_buttonCancel, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 );
+
+ bSizerTop->Add( bSizerButton, 0, wxALIGN_RIGHT, 5 );
+
+ this->SetSizer( bSizerTop );
+ this->Layout();
+
+ this->Centre( wxBOTH );
+}
+
+CacheGetDialog::~CacheGetDialog()
+{
+}
+
+// Event Table
+BEGIN_EVENT_TABLE( CacheGetDialog, wxDialog )
+ EVT_BUTTON( ID_GETCACHE, CacheGetDialog::OnGetCache )
+END_EVENT_TABLE()
+
+// Event Handlers & Functions
+void CacheGetDialog::OnGetCache( wxCommandEvent& WXUNUSED(event) )
+{
+ wxString fromdir = m_dirPicker->GetPath();
+
+ wxString cachedir = wxGetCwd() + wxFILE_SEP_PATH + wxT("cache");
+
+ for ( int i = 0; i < m_nocache.GetCount(); i++ ) {
+
+ wxString year = m_nocache[i].Left( 4 );
+ wxString month = m_nocache[i].Mid( 4, 2 );
+
+ if ( month.IsSameAs(wxT("01")) || month.IsSameAs(wxT("02")) || month.IsSameAs(wxT("03")) ) {
+ long y;
+ year.ToLong( &y, 10 );
+ y--;
+ year = wxString::Format( wxT("%d"), y );
+ }
+
+ wxString from = fromdir + wxFILE_SEP_PATH + year + wxFILE_SEP_PATH + m_nocache[i];
+ wxString to = cachedir + wxFILE_SEP_PATH + year + wxFILE_SEP_PATH + m_nocache[i];
+
+ wxArrayString files;
+ wxDir::GetAllFiles( from, &files, wxT("*.png"), wxDIR_DEFAULT );
+
+ wxProgressDialog pd( wxT("進行状況"), wxT("処理開始..."), files.GetCount(), NULL, wxPD_APP_MODAL|wxPD_REMAINING_TIME|wxPD_AUTO_HIDE );
+ pd.SetSize( wxSize( 320, 140 ) );
+
+ for ( int j = 0; j < files.GetCount(); j++ ) {
+ wxFileName fn( files[j] );
+
+ wxString ccn = fn.GetPath().BeforeLast( wxFILE_SEP_PATH ).AfterLast( wxFILE_SEP_PATH );
+ wxString hhs = fn.GetPath().AfterLast( wxFILE_SEP_PATH );
+ wxString buf = to + wxFILE_SEP_PATH + ccn + wxFILE_SEP_PATH + hhs + wxFILE_SEP_PATH + fn.GetFullName();
+
+ wxFileName td( buf );
+ if ( !td.Exists() ) td.Mkdir( wxS_DIR_DEFAULT, wxPATH_MKDIR_FULL );
+
+ wxCopyFile( files[j], buf, true );
+ if ( j % 5 == 0 ) wxSleep( 2 ); // ディスクの負荷軽減
+
+ pd.Update( j, hhs + wxT("@") + ccn + wxT("@") + m_nocache[i] + wxT("を処理しました.") );
+ }
+ }
+
+ wxMessageBox( wxT("Getting cache done."), wxT("Message"), wxOK|wxSTAY_ON_TOP );
+ Close();
+}
+
+void CacheGetDialog::SetSyncDates( wxArrayString dates )
+{
+ m_nocache = dates;
+}
+
+// メインダイアログ
CacheDialog::CacheDialog( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style )
: wxDialog( parent, id, title, pos, size, style )
{
this->SetSizeHints( wxDefaultSize, wxDefaultSize );
- wxBoxSizer* bSizerTop = new wxBoxSizer( wxVERTICAL );
+ wxBoxSizer* bSizerTop = new wxBoxSizer( wxHORIZONTAL );
+
+ //
+ wxBoxSizer* bSizerList = new wxBoxSizer( wxVERTICAL );
+
+ m_staticText = new wxStaticText( this, wxID_ANY, wxT("作成対象選択"), wxDefaultPosition, wxDefaultSize, 0 );
+ bSizerList->Add( m_staticText, 0, wxALL, 5 );
- m_datePickerBgn = new wxDatePickerCtrl( this, wxID_ANY, wxDefaultDateTime, wxDefaultPosition, wxDefaultSize, wxDP_DEFAULT );
- bSizerTop->Add( m_datePickerBgn, 0, wxALL, 5 );
+ m_listCtrl = new wxListCtrl( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLC_REPORT );
+ wxListItem itemCol;
+ itemCol.SetText( wxT("通番") );
+ m_listCtrl->InsertColumn( 0, itemCol );
+ m_listCtrl->SetColumnWidth( 0, 50 );
+ itemCol.SetText( wxT("審査会年月日") );
+ m_listCtrl->InsertColumn( 1, itemCol );
+ m_listCtrl->SetColumnWidth( 1, 100 );
+ itemCol.SetText( wxT("キャッシュ有無") );
+ m_listCtrl->InsertColumn( 2, itemCol );
+ m_listCtrl->SetColumnWidth( 2, 100 );
+ bSizerList->Add( m_listCtrl, 1, wxALL|wxEXPAND, 5 );
- m_datePickerEnd = new wxDatePickerCtrl( this, wxID_ANY, wxDefaultDateTime, wxDefaultPosition, wxDefaultSize, wxDP_DEFAULT );
- bSizerTop->Add( m_datePickerEnd, 0, wxALL, 5 );
+ //
+ wxBoxSizer* bSizerRange = new wxBoxSizer( wxHORIZONTAL );
+
+ m_staticTextRange = new wxStaticText( this, wxID_ANY, wxT("表示範囲指定"), wxDefaultPosition, wxDefaultSize, 0 );
+ bSizerRange->Add( m_staticTextRange, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 );
+
+ m_datePickerBgn = new wxDatePickerCtrl( this, ID_RGBGN, wxDefaultDateTime, wxDefaultPosition, wxDefaultSize, wxDP_DROPDOWN );
+ bSizerRange->Add( m_datePickerBgn, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 );
+
+ m_staticTextBetween = new wxStaticText( this, wxID_ANY, wxT("~"), wxDefaultPosition, wxDefaultSize, 0 );
+ bSizerRange->Add( m_staticTextBetween, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 );
+
+ m_datePickerEnd = new wxDatePickerCtrl( this, ID_RGEND, wxDefaultDateTime, wxDefaultPosition, wxDefaultSize, wxDP_DROPDOWN );
+ bSizerRange->Add( m_datePickerEnd, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 );
- m_buttonMake = new wxButton( this, ID_MKCACHE, wxT("作成"), wxDefaultPosition, wxDefaultSize, 0 );
- bSizerTop->Add( m_buttonMake, 0, wxALL|wxALIGN_CENTER_HORIZONTAL|wxEXPAND, 5 );
+ bSizerList->Add( bSizerRange, 0, wxALL|wxEXPAND, 5 );
+
+ bSizerTop->Add( bSizerList, 1, wxEXPAND, 5 );
+
+ //
+ wxBoxSizer* bSizerButton = new wxBoxSizer( wxVERTICAL );
+
+ m_buttonCache = new wxButton( this, ID_MKCACHE, wxT("作成"), wxDefaultPosition, wxDefaultSize, 0 );
+ bSizerButton->Add( m_buttonCache, 0, wxALL, 5 );
- m_buttonClose = new wxButton( this, ID_CLOSE, wxT("閉じる"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_buttonGet = new wxButton( this, ID_GET, wxT("取得"), wxDefaultPosition, wxDefaultSize, 0 );
+ bSizerButton->Add( m_buttonGet, 0, wxALL, 5 );
+
+ m_buttonClose = new wxButton( this, wxID_CANCEL, wxT("閉じる"), wxDefaultPosition, wxDefaultSize, 0 );
+ bSizerButton->Add( m_buttonClose, 0, wxALL, 5 );
m_buttonClose->SetDefault();
- bSizerTop->Add( m_buttonClose, 0, wxALL|wxALIGN_CENTER_HORIZONTAL|wxEXPAND, 5 );
+
+ bSizerTop->Add( bSizerButton, 0, 0, 5 );
+
this->SetSizer( bSizerTop );
this->Layout();
- bSizerTop->Fit( this );
this->Centre( wxBOTH );
}
@@ -38,8 +170,10 @@
// Event Table
BEGIN_EVENT_TABLE( CacheDialog, wxDialog )
- EVT_BUTTON( ID_MKCACHE, CacheDialog::OnMakeCache )
- EVT_BUTTON( ID_CLOSE, CacheDialog::OnClose )
+ EVT_DATE_CHANGED( ID_RGBGN, CacheDialog::OnDateChange )
+ EVT_DATE_CHANGED( ID_RGEND, CacheDialog::OnDateChange )
+ EVT_BUTTON( ID_MKCACHE, CacheDialog::OnMakeCache )
+ EVT_BUTTON( ID_GET, CacheDialog::OnGetCache )
END_EVENT_TABLE()
// Event Handlers & Functions
@@ -48,46 +182,122 @@
m_rootdir = rootdir;
m_width = w;
m_height = h;
+
+ m_datePickerBgn->SetValue( wxDateTime::Today() - wxDateSpan::Month() * 2 );
+ m_datePickerEnd->SetValue( wxDateTime::Today() );
+}
+
+void CacheDialog::Listup( void )
+{
+ nocache.Clear();
+ wxDateTime b = m_datePickerBgn->GetValue();
+ wxDateTime e = m_datePickerEnd->GetValue();
+ wxArrayString ccn = GetCcnDate();
+
+ wxDateTime dt;
+ wxRegEx reDate( wxT("(^20[0-9]{2})([0-1][0-9])([0-3][0-9])$") );
+ m_listCtrl->DeleteAllItems();
+
+ for ( int i = 0; i < ccn.GetCount(); i++ ) {
+
+ dt.ParseFormat( ccn[i], wxT("%Y%m%d") );
+
+ if ( dt.IsBetween( b, e ) ) {
+
+ // cache exists ?
+ wxString month = dt.Format( wxT("%m") );
+ wxString year = dt.Format( wxT("%Y") );
+
+ if ( month.IsSameAs(wxT("01")) || month.IsSameAs(wxT("02")) || month.IsSameAs(wxT("03")) ) {
+ long y;
+ year.ToLong( &y, 10 );
+ y--;
+ year = wxString::Format( wxT("%d"), y );
+ }
+ wxString cache_dir = wxGetCwd() + wxFILE_SEP_PATH + wxT("cache") + wxFILE_SEP_PATH + year + wxFILE_SEP_PATH + dt.Format( wxT("%Y%m%d") );
+
+ wxString cache_ok;
+ wxFileName cd( cache_dir );
+ if ( cd.Exists() )
+ cache_ok = wxT("○");
+ else
+ nocache.Insert( dt.Format( wxT("%Y%m%d") ), 0 );
+
+ m_listCtrl->InsertItem( i, -1 );
+ m_listCtrl->SetItem( i, 0, wxString::Format( wxT("%d"), i + 1 ) , -1 ); // No
+ reDate.Replace( &ccn[i], wxT("\\1-\\2-\\3") );
+ m_listCtrl->SetItem( i, 1, ccn[i], -1 );
+ if ( !cache_ok.IsEmpty() ) m_listCtrl->SetItem( i, 2, cache_ok, -1 );
+
+ if ( i % 2 ) m_listCtrl->SetItemBackgroundColour( i, wxColour( wxT("WHEAT") ) );
+ }
+ }
+}
+
+void CacheDialog::OnDateChange( wxDateEvent& WXUNUSED(event) )
+{
+ Listup();
}
void CacheDialog::OnMakeCache( wxCommandEvent& WXUNUSED(event) )
{
- wxDateTime b = m_datePickerBgn->GetValue();
- wxDateTime e = m_datePickerEnd->GetValue();
-
- MakeCache( b.Format( wxT("%Y%m%d")), e.Format( wxT("%Y%m%d")) );
-}
-
-void CacheDialog::MakeCache( wxString from, wxString to )
-{
- wxArrayString path = GetPathes( from, to );
+ if ( m_listCtrl->GetSelectedItemCount() < 1 ) {
+ wxMessageBox( wxT("項目を少なくともひとつ選択してください.") );
+ return;
+ }
wxString cachedir = wxGetCwd() + wxFILE_SEP_PATH + wxT("cache");
- for ( int i = 0; i < path.GetCount(); i++ ) {
+ long item = -1;
+ bool done = false;
+ for ( ;; ) {
+ item = m_listCtrl->GetNextItem( item, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED );
+ if ( item == -1 ) break;
- wxArrayString files;
- wxDir::GetAllFiles( path[i], &files, wxT("*.jpg"), wxDIR_DEFAULT );
+ wxString c = m_listCtrl->GetItemText( item, 2 );
+ if ( c.IsEmpty() ) {
+ wxString date = m_listCtrl->GetItemText( item, 1 );
+ date.Replace( wxT("-"), wxEmptyString, true );
- for ( int j = 0; j < files.GetCount(); j++ ) {
- wxImage image( files[j], wxBITMAP_TYPE_JPEG );
- wxImage output = image.Scale( m_width, m_height, wxIMAGE_QUALITY_HIGH );
+ wxArrayString path = GetPathesByDate( date );
+
+ wxProgressDialog pd( wxT("進行状況"), wxT("処理開始..."), path.GetCount(), NULL, wxPD_APP_MODAL|wxPD_REMAINING_TIME|wxPD_AUTO_HIDE );
+ pd.SetSize( wxSize( 320, 140 ) );
+
+ for ( int i = 0; i < path.GetCount(); i++ ) {
- wxString buf = files[j];
- buf.Replace( m_rootdir, cachedir, false );
- buf = buf.BeforeLast( '.' ) + wxT(".png");
+ wxArrayString files;
+ wxDir::GetAllFiles( path[i], &files, wxT("*.jpg"), wxDIR_DEFAULT );
+
+ for ( int j = 0; j < files.GetCount(); j++ ) {
+ wxImage image( files[j], wxBITMAP_TYPE_JPEG );
+ wxImage output = image.Scale( m_width, m_height, wxIMAGE_QUALITY_HIGH );
- wxFileName tf( buf );
- if ( !tf.Exists() ) tf.Mkdir( wxS_DIR_DEFAULT, wxPATH_MKDIR_FULL );
- output.SaveFile( buf, wxBITMAP_TYPE_PNG );
+ wxString buf = files[j];
+ buf.Replace( m_rootdir, cachedir, false );
+ buf = buf.BeforeLast( '.' ) + wxT(".png");
+
+ wxFileName tf( buf );
+ if ( !tf.Exists() ) tf.Mkdir( wxS_DIR_DEFAULT, wxPATH_MKDIR_FULL );
+ output.SaveFile( buf, wxBITMAP_TYPE_PNG );
+ }
+ pd.Update( i, path[i] + wxT("を処理しました.") );
+ wxSleep( 10 );
+ }
+ done = true;
}
- wxSleep( 30 );
}
- wxMessageBox( wxT("cache updated.") );
+ if ( done ) {
+ wxMessageBox( wxT("cache updated."), wxT("Message"), wxOK|wxSTAY_ON_TOP );
+ Listup();
+ }
}
-void CacheDialog::OnClose( wxCommandEvent& WXUNUSED(event) )
+void CacheDialog::OnGetCache( wxCommandEvent& WXUNUSED(event) )
{
- Close();
+ CacheGetDialog* cd = new CacheGetDialog( this, wxID_ANY, wxT("キャッシュ取得"), wxDefaultPosition, wxSize( 500, 100 ), wxCAPTION|wxFRAME_NO_TASKBAR );
+ cd->SetSyncDates( nocache );
+ cd->ShowModal();
+ Listup();
}
diff -r 226774bf49fc -r a2ad87cad48b src/db.cpp
--- a/src/db.cpp Mon Dec 08 19:47:42 2014 +0900
+++ b/src/db.cpp Wed Dec 17 00:52:43 2014 +0900
@@ -1,5 +1,5 @@
// Filename : db.cpp
-// Last Change: 23-May-2014.
+// Last Change: 12-Dec-2014.
//
#include
@@ -243,13 +243,14 @@
wxSQLite3Database ccndb;
ccndb.Open( gszFile );
- wxSQLite3Statement stmt = ccndb.PrepareStatement( "SELECT date, count(*) FROM ccn GROUP BY date ORDER BY date desc" );
+ wxSQLite3Statement stmt = ccndb.PrepareStatement( "SELECT date, count(*) FROM path GROUP BY date ORDER BY date desc" );
wxSQLite3ResultSet q = stmt.ExecuteQuery();
wxString str;
if ( !q.IsNull(0) ) {
while ( q.NextRow() ) {
- str = q.GetString(0) + "_" + q.GetString(1);
+ //str = q.GetString(0) + "_" + q.GetString(1);
+ str = q.GetString(0);
date_cnt.Add( str );
}
}
@@ -285,8 +286,8 @@
return data;
}
-/* 範囲日時のパスを取得 */
-wxArrayString GetPathes( wxString from, wxString to )
+/* 指定した範囲の日付のパスを取得 */
+wxArrayString GetPathesByPeriod( wxString from, wxString to )
{
wxArrayString path;
@@ -310,6 +311,30 @@
return path;
}
+/* 指定日のパスを取得 */
+wxArrayString GetPathesByDate( wxString date )
+{
+ wxArrayString path;
+
+ wxString gszFile = wxGetCwd() + wxFILE_SEP_PATH + wxT("db") + wxFILE_SEP_PATH + wxT("ccn.db");
+ wxSQLite3Database ccndb;
+ ccndb.Open( gszFile );
+
+ wxSQLite3Statement stmt = ccndb.PrepareStatement( "SELECT path FROM path WHERE date = ?" );
+ stmt.Bind( 1, date );
+ wxSQLite3ResultSet q = stmt.ExecuteQuery();
+
+ if ( !q.IsNull(0) ) {
+ while ( q.NextRow() ) {
+ path.Add( q.GetString(0) );
+ }
+ }
+ stmt.Finalize();
+ ccndb.Close();
+
+ return path;
+}
+
/* 合議体から被保険者番号を取得 */
wxArrayString GetHhsNoByCcn( wxString ccn, wxString date )
{
diff -r 226774bf49fc -r a2ad87cad48b src/hhsdb.cpp
--- a/src/hhsdb.cpp Mon Dec 08 19:47:42 2014 +0900
+++ b/src/hhsdb.cpp Wed Dec 17 00:52:43 2014 +0900
@@ -1,5 +1,5 @@
// Filename : hhsdb.cpp
-// Last Change: 23-May-2014.
+// Last Change: 12-Dec-2014.
//
#include "hhsdb.h"
@@ -11,14 +11,12 @@
this->SetSizeHints( wxDefaultSize, wxDefaultSize );
this->SetBackgroundColour( wxColour( wxT("WHEAT") ) );
- wxBoxSizer* bSizerTop;
- bSizerTop = new wxBoxSizer( wxVERTICAL );
+ wxBoxSizer* bSizerTop = new wxBoxSizer( wxVERTICAL );
- m_filePicker = new wxFilePickerCtrl( this, ID_FPICKR, wxEmptyString, wxT("Select a file"), wxT("*.*"), wxDefaultPosition, wxDefaultSize, wxFLP_FILE_MUST_EXIST|wxFLP_OPEN|wxFLP_USE_TEXTCTRL );
+ m_filePicker = new wxFilePickerCtrl( this, wxID_ANY, wxEmptyString, wxT("Select a file"), wxT("*.*"), wxDefaultPosition, wxDefaultSize, wxFLP_FILE_MUST_EXIST|wxFLP_OPEN|wxFLP_USE_TEXTCTRL );
bSizerTop->Add( m_filePicker, 0, wxALL|wxEXPAND, 5 );
- wxBoxSizer* bSizerButton;
- bSizerButton = new wxBoxSizer( wxHORIZONTAL );
+ wxBoxSizer* bSizerButton = new wxBoxSizer( wxHORIZONTAL );
m_buttonUpdate = new wxButton( this, ID_UPDATE, wxT("更新処理開始"), wxDefaultPosition, wxDefaultSize, 0 );
bSizerButton->Add( m_buttonUpdate, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 );
diff -r 226774bf49fc -r a2ad87cad48b src/kana.cpp
--- a/src/kana.cpp Mon Dec 08 19:47:42 2014 +0900
+++ b/src/kana.cpp Wed Dec 17 00:52:43 2014 +0900
@@ -1,5 +1,5 @@
// Filename : kana.cpp
-// Last Change: 22-Aug-2013.
+// Last Change: 12-Dec-2014.
//
#include "kana.h"
@@ -20,10 +20,10 @@
m_searchCtrl->ShowSearchButton( true );
#endif
m_searchCtrl->ShowCancelButton( false );
- bSizerSearch->Add( m_searchCtrl, 1, wxALL|wxEXPAND, 5 );
+ bSizerSearch->Add( m_searchCtrl, 1, wxALL|wxALIGN_CENTER_VERTICAL, 5 );
m_checkBox = new wxCheckBox( this, ID_FUZZY, wxT("部分一致"), wxDefaultPosition, wxDefaultSize, 0 );
- bSizerSearch->Add( m_checkBox, 0, wxALL|wxEXPAND, 5 );
+ bSizerSearch->Add( m_checkBox, 0, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 );
bSizerTop->Add( bSizerSearch, 0, wxALL|wxEXPAND, 5 );
@@ -71,9 +71,11 @@
this->Centre( wxBOTH );
+ wxString message = wxT("全角で入力してネ! (性と名の間は全角スペースで)");
+ m_searchCtrl->SetDescriptiveText( message );
+ m_searchCtrl->SetValue( message );
+ m_searchCtrl->SelectAll();
m_searchCtrl->SetFocus();
- m_searchCtrl->SetValue( wxT("全角で入力してネ! (性と名の間は全角スペースで)") );
- m_searchCtrl->SelectAll();
}
KanaDialog::~KanaDialog()
diff -r 226774bf49fc -r a2ad87cad48b src/miniframe.cpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/miniframe.cpp Wed Dec 17 00:52:43 2014 +0900
@@ -0,0 +1,251 @@
+// Filename : mini.cpp
+// Last Change: 12-Dec-2014.
+//
+#include "main.h"
+#include "db.h"
+#include "hhsdb.h"
+#include "miniframe.h"
+#include "update.h"
+
+///////////////////////////////////////////////////////////////
+// カスタム検索ボックス
+MiniSearchBox::MiniSearchBox( wxWindow* parent, wxWindowID id, const wxString& value, const wxPoint& pos, const wxSize& size, long style )
+ : wxSearchCtrl( parent, id, value, pos, size, style )
+{
+ SetMaxLength( 11 );
+ #ifndef __WXMAC__
+ ShowSearchButton( true );
+ #endif
+ ShowCancelButton( false );
+}
+
+MiniSearchBox::~MiniSearchBox()
+{
+}
+
+// Event Table
+BEGIN_EVENT_TABLE( MiniSearchBox, wxSearchCtrl )
+ EVT_CHAR( MiniSearchBox::OnKey )
+END_EVENT_TABLE()
+
+// Event Handlers & Functions
+void MiniSearchBox::OnKey( wxKeyEvent& event )
+{
+ int kc = event.GetKeyCode();
+ wxString s = GetValue();
+
+ if ( kc == 13 ) {
+ event.Skip();
+ return;
+ }
+
+ if ( kc == 45 ) { // テンキーの '-' キーで1文字削除
+ wxString t = GetStringSelection();
+ if ( t.IsEmpty() ) {
+ long p = GetInsertionPoint();
+ if ( p > 0 ) Remove( p - 1, p );
+ }
+ else {
+ Cut();
+ }
+ return;
+ }
+
+ if ( kc == WXK_ESCAPE ) { // clear by ESC
+ this->Clear();
+ return;
+ }
+
+ Cut();
+ event.Skip();
+}
+
+
+///////////////////////////////////////////////////////////////
+// メインフレーム
+
+// resources
+#if !defined(__WXMSW__) && !defined(__WXPM__)
+ #include "sample.xpm"
+#endif
+
+MiniFrame::MiniFrame( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style )
+ : wxFrame( parent, id, title, pos, size, style )
+{
+ this->SetSizeHints( wxSize( 100, 45 ), wxSize( 100, 45 ) );
+ this->SetBackgroundColour( wxColour(wxT("WHITE")) );
+
+ // set the frame icon
+ SetIcon(wxICON(sample));
+
+ //
+ wxBoxSizer* bSizerTop = new wxBoxSizer( wxHORIZONTAL );
+
+ m_staticText = new wxStaticText( this, wxID_ANY, wxT("?"), wxDefaultPosition, wxDefaultSize, 0 );
+ bSizerTop->Add( m_staticText, 0, wxALL|wxALIGN_CENTER_VERTICAL, 0 );
+
+ m_searchBox = new MiniSearchBox( this, ID_MSEARCH, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_PROCESS_ENTER );
+ m_searchBox->SetFocus();
+ bSizerTop->Add( m_searchBox, 1, wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL, 0 );
+
+ //
+ this->SetSizer( bSizerTop );
+ this->Layout();
+
+ this->Centre( wxBOTH );
+ LoadParam();
+ if ( CheckNewFiles( m_shared ) != 0 )
+ Close();
+}
+
+MiniFrame::~MiniFrame()
+{
+}
+
+// Event Table
+BEGIN_EVENT_TABLE( MiniFrame, wxFrame )
+ EVT_TEXT_ENTER( ID_MSEARCH, MiniFrame::OnCommand )
+END_EVENT_TABLE()
+
+// Event Handlers & Functions
+/* エンターキーフック */
+void MiniFrame::OnCommand( wxCommandEvent& event )
+{
+ wxString s = m_searchBox->GetLineText(0);
+
+ if ( s.IsSameAs( wxT(".") ) ) {
+ OpenAppDir();
+ return;
+ }
+
+ if ( s.IsSameAs( wxT("z") ) ) {
+ Transform( wxT("full mode") );
+ return;
+ }
+
+ if ( s.StartsWith( wxT("9") ) || s.IsSameAs( wxT("q") ) ) {
+ Close();
+ return;
+ }
+
+ wxRegEx reHhs( wxT("^0[1238][0-9]{8}.?$") );
+ if ( reHhs.Matches( s ) ) {
+
+ if ( s.Len() == 10 ) {
+ m_hhsno = s;
+ }
+ else {
+ m_hhsno = s.Left( 10 );
+ }
+
+ wxArrayString pathes = GetPathByHhsNo( m_hhsno );
+ if ( pathes.IsEmpty() ) {
+ m_searchBox->SetValue( wxT("No data.") );
+ m_searchBox->SelectAll();
+ }
+ else {
+ if ( s.Right( 1 ).IsSameAs( wxT("+") ) ) {
+ PrintImages( pathes[0] );
+ return;
+ }
+ OpenHhsDir( pathes[0] );
+ }
+ return;
+ }
+ m_searchBox->SelectAll();
+}
+/* パラメータを設定ファイルから読み込む */
+void MiniFrame::LoadParam( void )
+{
+ conf_file = wxGetCwd() + wxFILE_SEP_PATH + wxT("app.conf");
+ config = new wxFileConfig( wxT("MyApp"), wxT("T.Mutoh"), conf_file, wxEmptyString, wxCONFIG_USE_LOCAL_FILE );
+
+ int x, y;
+
+ // Shaerd
+ config->SetPath( wxT("/Index") );
+ config->Read( wxT("shared"), &m_shared );
+
+}
+/* アプリフォルダを開く */
+void MiniFrame::OnOpenAppDir( wxCommandEvent& WXUNUSED(event) )
+{
+ OpenAppDir();
+}
+void MiniFrame::OpenAppDir( )
+{
+ wxString appdir = wxGetCwd();
+ wxString execmd = wxT("explorer ") + appdir;
+ wxExecute( execmd );
+}
+/* 被保険者フォルダを開く */
+void MiniFrame::OpenHhsDir( wxString path )
+{
+ wxString execmd = wxT("explorer ") + path;
+ wxExecute( execmd );
+}
+/* 印刷 */
+void MiniFrame::PrintImages( wxString path )
+{
+ wxDir dir( path );
+ if ( !dir.IsOpened() ) return;
+
+ wxString html;
+ html = html + wxT("\n");
+
+ wxString file;
+ bool cout = dir.GetFirst( &file, wxT("*.jpg"), wxDIR_FILES );
+ int n = 0;
+ wxString tmpdir = wxGetCwd() + wxFILE_SEP_PATH + wxT("tmp") + wxFILE_SEP_PATH;
+ while ( cout ) {
+ file = path + wxFILE_SEP_PATH + file;
+ file.Replace( wxFILE_SEP_PATH, wxT("/") );
+ wxString tmpjpg = wxString::Format( wxT("%stmp%d.jpg"), tmpdir, n );
+ wxCopyFile( file, tmpjpg, true );
+ html = html + wxT(" ");
+ html = html + wxT("") + path.Right( 10 ) + wxT(" ");
+ cout = dir.GetNext( &file );
+ n++;
+ }
+ html = html + wxT("");
+
+ // start printing
+ wxHtmlPrintout hpout( wxT("Searcher03") );
+ hpout.SetMargins( 0, 0, 0, 0, 0 );
+ wxPrintDialogData pd;
+ wxPrinter p( &pd );
+
+ hpout.SetHtmlText( html, wxEmptyString, false );
+ p.Print( NULL, &hpout, true );
+}
+/* フルモードに変形 */
+void MiniFrame::Transform( wxString mode )
+{
+ wxTextFile textfile;
+ textfile.Open( wxGetCwd() + wxFILE_SEP_PATH + wxT("app.conf") );
+ for ( int i=0; iSetBitmap( bmp );
+ m_bitmap1->SetBitmap( bmp );
+ m_bitmap2->SetBitmap( bmp );
+ m_bitmap3->SetBitmap( bmp );
+ m_bitmap4->SetBitmap( bmp );
+ m_bitmap5->SetBitmap( bmp );
+}
/* サムネイル表示 */
void ThumbnailPanel::SetCacheImages( wxString dirpath )
{
@@ -156,7 +177,10 @@
wxString thumb = wxGetCwd() + wxFILE_SEP_PATH + wxT("image") + wxFILE_SEP_PATH + wxT("thumbnail.png");
wxDir dir( dirpath );
- if ( !dir.IsOpened() ) return;
+ if ( !dir.IsOpened() ) {
+ Initialize();
+ return;
+ }
m_imagefiles.Clear();
wxDir::GetAllFiles( dirpath, &m_imagefiles, wxT("*.jpg"), wxDIR_FILES );
@@ -165,13 +189,7 @@
wxString cachedir = wxT("cache") + dirpath.AfterLast( ':' );
wxDir cdir( cachedir );
if ( !cdir.IsOpened() ) {
- bmp.LoadFile( thumb, wxBITMAP_TYPE_PNG );
- m_bitmap0->SetBitmap( bmp );
- m_bitmap1->SetBitmap( bmp );
- m_bitmap2->SetBitmap( bmp );
- m_bitmap3->SetBitmap( bmp );
- m_bitmap4->SetBitmap( bmp );
- m_bitmap5->SetBitmap( bmp );
+ Initialize();
return;
}
@@ -315,14 +333,10 @@
m_staticText = new wxStaticText( m_panelMain, wxID_ANY, wxT("コマンド?"), wxDefaultPosition, wxDefaultSize, 0 );
bSizerCmd->Add( m_staticText, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 );
- m_searchBox = new MySearchBox( m_panelMain, ID_SEARCH, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_PROCESS_ENTER );
+ m_searchBox = new MySearchBox( m_panelMain, ID_SEARCH, wxEmptyString, wxDefaultPosition, wxSize( -1, 24 ), wxTE_PROCESS_ENTER );
m_searchBox->SetJudgedHhs( GetJudgedHhsNo() );
- #ifndef __WXMAC__
- m_searchBox->ShowSearchButton( true );
- #endif
- m_searchBox->ShowCancelButton( false );
m_searchBox->SetFocus();
- bSizerCmd->Add( m_searchBox, 1, wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL, 5 );
+ bSizerCmd->Add( m_searchBox, 1, wxRIGHT|wxLEFT|wxALIGN_CENTER_VERTICAL, 5 );
m_buttonPaste = new wxButton( m_panelMain, ID_PASTE, wxT("貼付検索"), wxDefaultPosition, wxSize( 65, -1 ), 0 );
bSizerCmd->Add( m_buttonPaste, 0, wxLEFT|wxALIGN_CENTER_VERTICAL, 10 );
@@ -331,7 +345,7 @@
bSizerCmd->Add( m_buttonKana, 0, wxLEFT|wxALIGN_CENTER_VERTICAL, 5 );
m_buttonHist = new wxButton( m_panelMain, ID_HIST, wxT("検索履歴"), wxDefaultPosition, wxSize( 65, -1 ), 0 );
- bSizerCmd->Add( m_buttonHist, 0, wxALL, 5 );
+ bSizerCmd->Add( m_buttonHist, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 );
//
bSizerMain->Add( bSizerCmd, 0, wxEXPAND, 5 );
@@ -596,6 +610,7 @@
CacheDialog* cache = new CacheDialog( this, wxID_ANY, wxT("キャッシュ作成"), wxDefaultPosition, wxDefaultSize, wxCAPTION|wxSTAY_ON_TOP );
cache->Setting( rootdir, THUMB_W, THUMB_H );
+ cache->Listup();
cache->ShowModal();
}
/* 被保険者DB更新 */
@@ -763,7 +778,7 @@
/* カナ検索ダイアログ */
void MyFrame::OnKana( wxCommandEvent& WXUNUSED(event) )
{
- KanaDialog* kana = new KanaDialog( this, wxID_ANY, wxT("カナ氏名で被保番を検索"), wxDefaultPosition, wxSize( 640, 600 ), wxCAPTION|wxFRAME_NO_TASKBAR|wxRESIZE_BORDER|wxSTAY_ON_TOP|wxTAB_TRAVERSAL );
+ KanaDialog* kana = new KanaDialog( this, wxID_ANY, wxT("カナ氏名で被保番を検索"), wxDefaultPosition, wxSize( 680, 600 ), wxCAPTION|wxFRAME_NO_TASKBAR|wxRESIZE_BORDER|wxSTAY_ON_TOP|wxTAB_TRAVERSAL );
kana->ShowWithEffect( wxSHOW_EFFECT_SLIDE_TO_BOTTOM );
if ( kana->ShowModal() == wxID_OK ) {
@@ -815,13 +830,13 @@
return;
}
- wxRegEx reDate(wxT("(^.*20[0-9]{2}.)(20[0-9]{2})([0-2][0-9])([0-9]{2})(.*$)"));
+ wxRegEx reDate( wxT("(^.*20[0-9]{2}.)(20[0-9]{2})([0-1][0-9])([0-3][0-9])(.*$)") );
for ( int i = 0; i < path.GetCount(); i++ ) {
wxString date = path[i];
reDate.ReplaceAll( &date, wxT("\\2-\\3-\\4") );
m_listCtrl->InsertItem( i, -1 );
- m_listCtrl->SetItem( i, 0,wxString::Format( wxT("%d"), i + 1 ) , -1 ); // No
+ m_listCtrl->SetItem( i, 0, wxString::Format( wxT("%d"), i + 1 ) , -1 ); // No
m_listCtrl->SetItem( i, 1, date, -1 );
m_listCtrl->SetItem( i, 2, path[i], -1 );
@@ -908,7 +923,7 @@
/* アバウトダイアログ */
void MyFrame::OnAbout( wxCommandEvent& WXUNUSED(event) )
{
- AboutDialog* aboutDlg = new AboutDialog( this, wxID_ANY, wxT("About this Software"), wxDefaultPosition, wxSize(320,280), wxDEFAULT_DIALOG_STYLE|wxSTAY_ON_TOP );
+ AboutDialog* aboutDlg = new AboutDialog( this, wxID_ANY, wxT("About this Software"), wxDefaultPosition, wxSize( 360, 280 ), wxDEFAULT_DIALOG_STYLE|wxSTAY_ON_TOP );
aboutDlg->ShowModal();
}
diff -r 226774bf49fc -r a2ad87cad48b src/wxsqlite3.cpp
--- a/src/wxsqlite3.cpp Mon Dec 08 19:47:42 2014 +0900
+++ b/src/wxsqlite3.cpp Wed Dec 17 00:52:43 2014 +0900
@@ -97,6 +97,19 @@
#include "wx/wxsqlite3dyn.h"
#undef DYNFUNC
+#else
+// Define Windows specific SQLite API functions (not defined in sqlite3.h)
+#if SQLITE_VERSION_NUMBER >= 3007014
+#if defined(__WXMSW__)
+#ifdef __cplusplus
+extern "C" {
+#endif
+SQLITE_API int sqlite3_win32_set_directory(DWORD type, LPCWSTR zValue);
+#ifdef __cplusplus
+}
+#endif
+#endif
+#endif
#endif // wxUSE_DYNAMIC_SQLITE3_LOAD
// Error messages
@@ -137,10 +150,11 @@
const char* wxERRMSG_INITIALIZE = wxTRANSLATE("Initialization of SQLite failed");
const char* wxERRMSG_SHUTDOWN = wxTRANSLATE("Shutdown of SQLite failed");
-
-const char* wxERRMSG_SOURCEDB_BUSY = wxTRANSLATE("Source database is busy");
-const char* wxERRMSG_DBOPEN_FAILED = wxTRANSLATE("Database open failed");
-const char* wxERRMSG_DBCLOSE_FAILED = wxTRANSLATE("Database close failed");
+const char* wxERRMSG_TEMPDIR = wxTRANSLATE("Setting temporary directory failed");
+
+const char* wxERRMSG_SOURCEDB_BUSY = wxTRANSLATE("Source database is busy");
+const char* wxERRMSG_DBOPEN_FAILED = wxTRANSLATE("Database open failed");
+const char* wxERRMSG_DBCLOSE_FAILED = wxTRANSLATE("Database close failed");
const char* wxERRMSG_DBASSIGN_FAILED = wxTRANSLATE("Database assignment failed");
const char* wxERRMSG_FINALIZE_FAILED = wxTRANSLATE("Finalize failed");
#else
@@ -179,10 +193,11 @@
const wxChar* wxERRMSG_INITIALIZE = wxTRANSLATE("Initialization of SQLite failed");
const wxChar* wxERRMSG_SHUTDOWN = wxTRANSLATE("Shutdown of SQLite failed");
+const wxChar* wxERRMSG_TEMPDIR = wxTRANSLATE("Setting temporary directory failed");
const wxChar* wxERRMSG_SOURCEDB_BUSY = wxTRANSLATE("Source database is busy");
const wxChar* wxERRMSG_DBOPEN_FAILED = wxTRANSLATE("Database open failed");
-const wxChar* wxERRMSG_DBCLOSE_FAILED = wxTRANSLATE("Database close failed");
+const wxChar* wxERRMSG_DBCLOSE_FAILED = wxTRANSLATE("Database close failed");
const wxChar* wxERRMSG_DBASSIGN_FAILED = wxTRANSLATE("Database assignment failed");
const wxChar* wxERRMSG_FINALIZE_FAILED = wxTRANSLATE("Finalize failed");
#endif
@@ -2206,6 +2221,16 @@
#endif
}
+int wxSQLite3Statement::Status(wxSQLite3StatementStatus opCode, bool resetFlag)
+{
+ int count = 0;
+#if SQLITE_VERSION_NUMBER >= 3007000
+ CheckStmt();
+ count = sqlite3_stmt_status(m_stmt->m_stmt, (int) opCode, (resetFlag) ? 1 : 0 );
+#endif
+ return count;
+}
+
void wxSQLite3Statement::CheckDatabase()
{
if (m_db == NULL || m_db->m_db == NULL || !m_db->m_isValid)
@@ -3503,24 +3528,38 @@
#endif
}
-bool wxSQLite3Database::CreateFunction(const wxString& funcName, int argCount, wxSQLite3ScalarFunction& function)
+bool wxSQLite3Database::CreateFunction(const wxString& funcName, int argCount, wxSQLite3ScalarFunction& function, bool isDeterministic)
{
CheckDatabase();
wxCharBuffer strFuncName = funcName.ToUTF8();
const char* localFuncName = strFuncName;
+ int flags = SQLITE_UTF8;
+#if SQLITE_VERSION_NUMBER >= 3008003
+ if (isDeterministic)
+ {
+ flags |= SQLITE_DETERMINISTIC;
+ }
+#endif
int rc = sqlite3_create_function(m_db->m_db, localFuncName, argCount,
- SQLITE_UTF8, &function,
+ flags, &function,
(void (*)(sqlite3_context*,int,sqlite3_value**)) wxSQLite3FunctionContext::ExecScalarFunction, NULL, NULL);
return rc == SQLITE_OK;
}
-bool wxSQLite3Database::CreateFunction(const wxString& funcName, int argCount, wxSQLite3AggregateFunction& function)
+bool wxSQLite3Database::CreateFunction(const wxString& funcName, int argCount, wxSQLite3AggregateFunction& function, bool isDeterministic)
{
CheckDatabase();
wxCharBuffer strFuncName = funcName.ToUTF8();
const char* localFuncName = strFuncName;
+ int flags = SQLITE_UTF8;
+#if SQLITE_VERSION_NUMBER >= 3008003
+ if (isDeterministic)
+ {
+ flags |= SQLITE_DETERMINISTIC;
+ }
+#endif
int rc = sqlite3_create_function(m_db->m_db, localFuncName, argCount,
- SQLITE_UTF8, &function,
+ flags, &function,
NULL,
(void (*)(sqlite3_context*,int,sqlite3_value**)) wxSQLite3FunctionContext::ExecAggregateStep,
(void (*)(sqlite3_context*)) wxSQLite3FunctionContext::ExecAggregateFinalize);
@@ -3916,6 +3955,31 @@
}
/* static */
+bool wxSQLite3Database::SetTemporaryDirectory(const wxString& tempDirectory)
+{
+ bool ok = false;
+#if SQLITE_VERSION_NUMBER >= 3007014
+#if defined(__WXMSW__)
+ DWORD SQLITE_WIN32_TEMP_DIRECTORY_TYPE = 2;
+#if wxUSE_UNICODE
+ const wxChar* zValue = tempDirectory.wc_str();
+#else
+ const wxWCharBuffer zValue = tempDirectory.wc_str(wxConvLocal);
+#endif
+ int rc = sqlite3_win32_set_directory(SQLITE_WIN32_TEMP_DIRECTORY_TYPE, zValue);
+ ok = (rc == SQLITE_OK);
+#if 0
+ if (rc != SQLITE_OK)
+ {
+ throw wxSQLite3Exception(rc, wxERRMSG_TEMPDIR);
+ }
+#endif
+#endif
+#endif
+ return ok;
+}
+
+/* static */
bool wxSQLite3Database::Randomness(int n, wxMemoryBuffer& random)
{
bool ok = false;
@@ -4232,7 +4296,8 @@
wxT("SQLITE_SELECT"), wxT("SQLITE_TRANSACTION"), wxT("SQLITE_UPDATE"),
wxT("SQLITE_ATTACH"), wxT("SQLITE_DETACH"), wxT("SQLITE_ALTER_TABLE"),
wxT("SQLITE_REINDEX"), wxT("SQLITE_ANALYZE"), wxT("SQLITE_CREATE_VTABLE"),
- wxT("SQLITE_DROP_VTABLE"), wxT("SQLITE_FUNCTION"), wxT("SQLITE_SAVEPOINT")
+ wxT("SQLITE_DROP_VTABLE"), wxT("SQLITE_FUNCTION"), wxT("SQLITE_SAVEPOINT"),
+ wxT("SQLITE_RECURSIVE")
};
| |