зеркало из https://github.com/mozilla/pjs.git
Bug 489018 - Rename mozStorageUnicodeFunctions.* to mozStorageSQLFunctions.*
New filename better reflects current (and future) contents. Also updates the files to follow the storage style guidelines. r=asuth --HG-- rename : storage/src/mozStorageUnicodeFunctions.cpp => storage/src/mozStorageSQLFunctions.cpp rename : storage/src/mozStorageUnicodeFunctions.h => storage/src/mozStorageSQLFunctions.h
This commit is contained in:
Родитель
0209974108
Коммит
b0eccdda0d
|
@ -69,7 +69,7 @@ CPPSRCS = \
|
|||
mozStorageStatementParams.cpp \
|
||||
mozStorageStatementRow.cpp \
|
||||
mozStorageValueArray.cpp \
|
||||
mozStorageUnicodeFunctions.cpp \
|
||||
mozStorageSQLFunctions.cpp \
|
||||
mozStorageRow.cpp \
|
||||
mozStorageResultSet.cpp \
|
||||
mozStorageError.cpp \
|
||||
|
|
|
@ -56,7 +56,7 @@
|
|||
#include "mozIStorageFunction.h"
|
||||
|
||||
#include "mozStorageEvents.h"
|
||||
#include "mozStorageUnicodeFunctions.h"
|
||||
#include "mozStorageSQLFunctions.h"
|
||||
#include "mozStorageConnection.h"
|
||||
#include "mozStorageService.h"
|
||||
#include "mozStorageStatement.h"
|
||||
|
@ -369,9 +369,8 @@ Connection::initialize(nsIFile *aDatabaseFile)
|
|||
leafName.get(), this));
|
||||
#endif
|
||||
|
||||
// Hook up i18n functions
|
||||
srv = StorageUnicodeFunctions::RegisterFunctions(mDBConn);
|
||||
if (srv != SQLITE_OK) {
|
||||
// Register our built-in SQL functions.
|
||||
if (registerFunctions(mDBConn) != SQLITE_OK) {
|
||||
mDBConn = nsnull;
|
||||
return ConvertResultCode(srv);
|
||||
}
|
||||
|
|
|
@ -40,65 +40,39 @@
|
|||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "mozStorageUnicodeFunctions.h"
|
||||
#include "mozStorageSQLFunctions.h"
|
||||
#include "nsUnicharUtils.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace storage {
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//// Local Helper Functions
|
||||
|
||||
namespace {
|
||||
|
||||
/**
|
||||
* Performs the LIKE comparison of a string against a pattern. For more detail
|
||||
* see http://www.sqlite.org/lang_expr.html#like.
|
||||
*
|
||||
* @param aPatternItr
|
||||
* An iterator at the start of the pattern to check for.
|
||||
* @param aPatternEnd
|
||||
* An iterator at the end of the pattern to check for.
|
||||
* @param aStringItr
|
||||
* An iterator at the start of the string to check for the pattern.
|
||||
* @param aStringEnd
|
||||
* An iterator at the end of the string to check for the pattern.
|
||||
* @param aEscapeChar
|
||||
* The character to use for escaping symbols in the pattern.
|
||||
* @returns 1 if the pattern is found, 0 otherwise.
|
||||
*/
|
||||
int
|
||||
StorageUnicodeFunctions::RegisterFunctions(sqlite3 *aDB)
|
||||
{
|
||||
struct Functions {
|
||||
const char *zName;
|
||||
int nArg;
|
||||
int enc;
|
||||
void *pContext;
|
||||
void (*xFunc)(sqlite3_context*, int, sqlite3_value**);
|
||||
} functions[] = {
|
||||
{"lower", 1, SQLITE_UTF16, 0, caseFunction},
|
||||
{"lower", 1, SQLITE_UTF8, 0, caseFunction},
|
||||
{"upper", 1, SQLITE_UTF16, (void*)1, caseFunction},
|
||||
{"upper", 1, SQLITE_UTF8, (void*)1, caseFunction},
|
||||
|
||||
{"like", 2, SQLITE_UTF16, 0, likeFunction},
|
||||
{"like", 2, SQLITE_UTF8, 0, likeFunction},
|
||||
{"like", 3, SQLITE_UTF16, 0, likeFunction},
|
||||
{"like", 3, SQLITE_UTF8, 0, likeFunction},
|
||||
};
|
||||
|
||||
int rv = SQLITE_OK;
|
||||
for (unsigned i = 0; SQLITE_OK == rv && i < NS_ARRAY_LENGTH(functions); ++i) {
|
||||
struct Functions *p = &functions[i];
|
||||
rv = sqlite3_create_function(aDB, p->zName, p->nArg, p->enc, p->pContext,
|
||||
p->xFunc, NULL, NULL);
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
void
|
||||
StorageUnicodeFunctions::caseFunction(sqlite3_context *p,
|
||||
int aArgc,
|
||||
sqlite3_value **aArgv)
|
||||
{
|
||||
NS_ASSERTION(1 == aArgc, "Invalid number of arguments!");
|
||||
|
||||
nsAutoString data(static_cast<const PRUnichar *>(sqlite3_value_text16(aArgv[0])));
|
||||
PRBool toUpper = sqlite3_user_data(p) ? PR_TRUE : PR_FALSE;
|
||||
|
||||
if (toUpper)
|
||||
ToUpperCase(data);
|
||||
else
|
||||
ToLowerCase(data);
|
||||
|
||||
// Give sqlite our result
|
||||
sqlite3_result_text16(p, data.get(), -1, SQLITE_TRANSIENT);
|
||||
}
|
||||
|
||||
static int
|
||||
likeCompare(nsAString::const_iterator aPatternItr,
|
||||
nsAString::const_iterator aPatternEnd,
|
||||
nsAString::const_iterator aStringItr,
|
||||
nsAString::const_iterator aStringEnd,
|
||||
PRUnichar aEscape)
|
||||
PRUnichar aEscapeChar)
|
||||
{
|
||||
const PRUnichar MATCH_ALL('%');
|
||||
const PRUnichar MATCH_ONE('_');
|
||||
|
@ -135,7 +109,8 @@ likeCompare(nsAString::const_iterator aPatternItr,
|
|||
return 1;
|
||||
|
||||
while (aStringItr != aStringEnd) {
|
||||
if (likeCompare(aPatternItr, aPatternEnd, aStringItr, aStringEnd, aEscape)) {
|
||||
if (likeCompare(aPatternItr, aPatternEnd, aStringItr, aStringEnd,
|
||||
aEscapeChar)) {
|
||||
// we've hit a match, so indicate this
|
||||
return 1;
|
||||
}
|
||||
|
@ -144,7 +119,8 @@ likeCompare(nsAString::const_iterator aPatternItr,
|
|||
|
||||
// No match
|
||||
return 0;
|
||||
} else if (!lastWasEscape && *aPatternItr == MATCH_ONE) {
|
||||
}
|
||||
else if (!lastWasEscape && *aPatternItr == MATCH_ONE) {
|
||||
// CASE 2
|
||||
if (aStringItr == aStringEnd) {
|
||||
// If we've hit the end of the string we are testing, no match
|
||||
|
@ -152,12 +128,14 @@ likeCompare(nsAString::const_iterator aPatternItr,
|
|||
}
|
||||
aStringItr++;
|
||||
lastWasEscape = PR_FALSE;
|
||||
} else if (!lastWasEscape && *aPatternItr == aEscape) {
|
||||
}
|
||||
else if (!lastWasEscape && *aPatternItr == aEscapeChar) {
|
||||
// CASE 3
|
||||
lastWasEscape = PR_TRUE;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
// CASE 4
|
||||
if (ToUpperCase(*aStringItr) != ToUpperCase(*aPatternItr)) {
|
||||
if (::ToUpperCase(*aStringItr) != ::ToUpperCase(*aPatternItr)) {
|
||||
// If we've hit a point where the strings don't match, there is no match
|
||||
return 0;
|
||||
}
|
||||
|
@ -171,33 +149,92 @@ likeCompare(nsAString::const_iterator aPatternItr,
|
|||
return aStringItr == aStringEnd;
|
||||
}
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//// Exposed Functions
|
||||
|
||||
int
|
||||
registerFunctions(sqlite3 *aDB)
|
||||
{
|
||||
struct Functions {
|
||||
const char *zName;
|
||||
int nArg;
|
||||
int enc;
|
||||
void *pContext;
|
||||
void (*xFunc)(::sqlite3_context*, int, sqlite3_value**);
|
||||
} functions[] = {
|
||||
{"lower", 1, SQLITE_UTF16, 0, caseFunction},
|
||||
{"lower", 1, SQLITE_UTF8, 0, caseFunction},
|
||||
{"upper", 1, SQLITE_UTF16, (void*)1, caseFunction},
|
||||
{"upper", 1, SQLITE_UTF8, (void*)1, caseFunction},
|
||||
|
||||
{"like", 2, SQLITE_UTF16, 0, likeFunction},
|
||||
{"like", 2, SQLITE_UTF8, 0, likeFunction},
|
||||
{"like", 3, SQLITE_UTF16, 0, likeFunction},
|
||||
{"like", 3, SQLITE_UTF8, 0, likeFunction},
|
||||
};
|
||||
|
||||
int rv = SQLITE_OK;
|
||||
for (unsigned i = 0; SQLITE_OK == rv && i < NS_ARRAY_LENGTH(functions); ++i) {
|
||||
struct Functions *p = &functions[i];
|
||||
rv = ::sqlite3_create_function(aDB, p->zName, p->nArg, p->enc, p->pContext,
|
||||
p->xFunc, NULL, NULL);
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//// SQL Functions
|
||||
|
||||
void
|
||||
caseFunction(sqlite3_context *aCtx,
|
||||
int aArgc,
|
||||
sqlite3_value **aArgv)
|
||||
{
|
||||
NS_ASSERTION(1 == aArgc, "Invalid number of arguments!");
|
||||
|
||||
nsAutoString data(static_cast<const PRUnichar *>(::sqlite3_value_text16(aArgv[0])));
|
||||
PRBool toUpper = ::sqlite3_user_data(aCtx) ? PR_TRUE : PR_FALSE;
|
||||
|
||||
if (toUpper)
|
||||
::ToUpperCase(data);
|
||||
else
|
||||
::ToLowerCase(data);
|
||||
|
||||
// Set the result.
|
||||
::sqlite3_result_text16(aCtx, data.get(), -1, SQLITE_TRANSIENT);
|
||||
}
|
||||
|
||||
/**
|
||||
* This implements the like() SQL function. This is used by the LIKE operator.
|
||||
* The SQL statement 'A LIKE B' is implemented as 'like(B, A)', and if there is
|
||||
* an escape character, say E, it is implemented as 'like(B, A, E)'.
|
||||
*/
|
||||
void
|
||||
StorageUnicodeFunctions::likeFunction(sqlite3_context *p,
|
||||
likeFunction(sqlite3_context *aCtx,
|
||||
int aArgc,
|
||||
sqlite3_value **aArgv)
|
||||
{
|
||||
NS_ASSERTION(2 == aArgc || 3 == aArgc, "Invalid number of arguments!");
|
||||
|
||||
if (sqlite3_value_bytes(aArgv[0]) > SQLITE_MAX_LIKE_PATTERN_LENGTH) {
|
||||
sqlite3_result_error(p, "LIKE or GLOB pattern too complex", SQLITE_TOOBIG);
|
||||
if (::sqlite3_value_bytes(aArgv[0]) > SQLITE_MAX_LIKE_PATTERN_LENGTH) {
|
||||
::sqlite3_result_error(aCtx, "LIKE or GLOB pattern too complex",
|
||||
SQLITE_TOOBIG);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!sqlite3_value_text16(aArgv[0]) || !sqlite3_value_text16(aArgv[1]))
|
||||
if (!::sqlite3_value_text16(aArgv[0]) || !::sqlite3_value_text16(aArgv[1]))
|
||||
return;
|
||||
|
||||
nsDependentString A(static_cast<const PRUnichar *>(sqlite3_value_text16(aArgv[1])));
|
||||
nsDependentString B(static_cast<const PRUnichar *>(sqlite3_value_text16(aArgv[0])));
|
||||
nsDependentString A(static_cast<const PRUnichar *>(::sqlite3_value_text16(aArgv[1])));
|
||||
nsDependentString B(static_cast<const PRUnichar *>(::sqlite3_value_text16(aArgv[0])));
|
||||
NS_ASSERTION(!B.IsEmpty(), "LIKE string must not be null!");
|
||||
|
||||
PRUnichar E = 0;
|
||||
if (3 == aArgc)
|
||||
E = static_cast<const PRUnichar *>(sqlite3_value_text16(aArgv[2]))[0];
|
||||
E = static_cast<const PRUnichar *>(::sqlite3_value_text16(aArgv[2]))[0];
|
||||
|
||||
nsAString::const_iterator itrString, endString;
|
||||
A.BeginReading(itrString);
|
||||
|
@ -205,7 +242,9 @@ StorageUnicodeFunctions::likeFunction(sqlite3_context *p,
|
|||
nsAString::const_iterator itrPattern, endPattern;
|
||||
B.BeginReading(itrPattern);
|
||||
B.EndReading(endPattern);
|
||||
sqlite3_result_int(p, likeCompare(itrPattern, endPattern,
|
||||
itrString, endString, E));
|
||||
::sqlite3_result_int(aCtx, likeCompare(itrPattern, endPattern, itrString,
|
||||
endString, E));
|
||||
}
|
||||
|
||||
} // namespace storage
|
||||
} // namespace mozilla
|
|
@ -37,51 +37,58 @@
|
|||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#ifndef _mozStorageUnicodeFunctions_h_
|
||||
#ifndef _mozStorageSQLFunctions_h_
|
||||
#define _mozStorageUnicodeFunctions_h_
|
||||
|
||||
#include "sqlite3.h"
|
||||
#include "nscore.h"
|
||||
|
||||
namespace StorageUnicodeFunctions {
|
||||
namespace mozilla {
|
||||
namespace storage {
|
||||
|
||||
/**
|
||||
* Registers the functions with sqlite.
|
||||
/**
|
||||
* Registers the functions declared here with the specified database.
|
||||
*
|
||||
* @param aDB
|
||||
* The database we'll be registering the functions with.
|
||||
* @return the sqlite status code.
|
||||
* @return the SQLite status code indicating success or failure.
|
||||
*/
|
||||
NS_HIDDEN_(int) RegisterFunctions(sqlite3 *aDB);
|
||||
NS_HIDDEN_(int) registerFunctions(sqlite3 *aDB);
|
||||
|
||||
/**
|
||||
* Does the upper and lowercase conversions for the SQL functions upper() and
|
||||
* lower().
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//// Predefined Functions
|
||||
|
||||
/**
|
||||
* Overridden function to perform the SQL functions UPPER and LOWER. These
|
||||
* support unicode, which the default implementations do not do.
|
||||
*
|
||||
* @param p
|
||||
* @param aCtx
|
||||
* The sqlite_context that this function is being called on.
|
||||
* @param aArgc
|
||||
* The number of arguments the function is being called with.
|
||||
* @param aArgv
|
||||
* An array of the arguments the functions is being called with.
|
||||
*/
|
||||
NS_HIDDEN_(void) caseFunction(sqlite3_context *p,
|
||||
NS_HIDDEN_(void) caseFunction(sqlite3_context *aCtx,
|
||||
int aArgc,
|
||||
sqlite3_value **aArgv);
|
||||
|
||||
/**
|
||||
* Performs the LIKE comparison in sqlite.
|
||||
/**
|
||||
* Overridden function to perform the SQL function LIKE. This supports unicode,
|
||||
* which the default implementation does not do.
|
||||
*
|
||||
* @param p
|
||||
* @param aCtx
|
||||
* The sqlite_context that this function is being called on.
|
||||
* @param aArgc
|
||||
* The number of arguments the function is being called with.
|
||||
* @param aArgv
|
||||
* An array of the arguments the functions is being called with.
|
||||
*/
|
||||
NS_HIDDEN_(void) likeFunction(sqlite3_context *p,
|
||||
NS_HIDDEN_(void) likeFunction(sqlite3_context *aCtx,
|
||||
int aArgc,
|
||||
sqlite3_value **aArgv);
|
||||
}
|
||||
|
||||
#endif // _mozStorageUnicodeFunctions_h_
|
||||
} // namespace storage
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // _mozStorageSQLFunctions_h_
|
Загрузка…
Ссылка в новой задаче