From 2f6b6efc04ae5154d4ae20f4e09436dd4211b5ae Mon Sep 17 00:00:00 2001 From: "varga%nixcorp.com" Date: Tue, 31 Aug 2004 10:42:13 +0000 Subject: [PATCH] Fix for bug 254886. SQLite3 support for sql module r=varga patch by Valia V. Vaneeva --- extensions/sql/Makefile.in | 5 + extensions/sql/build/Makefile.in | 2 + extensions/sql/build/src/Makefile.in | 12 + extensions/sql/build/src/mozSqlModule.cpp | 18 +- extensions/sql/sqlite/Makefile.in | 45 +++ extensions/sql/sqlite/public/Makefile.in | 50 +++ .../sqlite/public/mozISqlConnectionSqlite.idl | 44 ++ .../sql/sqlite/public/mozISqlResultSqlite.idl | 44 ++ extensions/sql/sqlite/src/Makefile.in | 68 ++++ .../sql/sqlite/src/mozSqlConnectionSqlite.cpp | 379 ++++++++++++++++++ .../sql/sqlite/src/mozSqlConnectionSqlite.h | 86 ++++ .../sql/sqlite/src/mozSqlResultSqlite.cpp | 160 ++++++++ .../sql/sqlite/src/mozSqlResultSqlite.h | 75 ++++ 13 files changed, 986 insertions(+), 2 deletions(-) create mode 100644 extensions/sql/sqlite/Makefile.in create mode 100644 extensions/sql/sqlite/public/Makefile.in create mode 100644 extensions/sql/sqlite/public/mozISqlConnectionSqlite.idl create mode 100644 extensions/sql/sqlite/public/mozISqlResultSqlite.idl create mode 100644 extensions/sql/sqlite/src/Makefile.in create mode 100644 extensions/sql/sqlite/src/mozSqlConnectionSqlite.cpp create mode 100644 extensions/sql/sqlite/src/mozSqlConnectionSqlite.h create mode 100644 extensions/sql/sqlite/src/mozSqlResultSqlite.cpp create mode 100644 extensions/sql/sqlite/src/mozSqlResultSqlite.h diff --git a/extensions/sql/Makefile.in b/extensions/sql/Makefile.in index cf4c5b1ea3e1..0218af88b7bb 100644 --- a/extensions/sql/Makefile.in +++ b/extensions/sql/Makefile.in @@ -18,6 +18,7 @@ # the Initial Developer. All Rights Reserved. # # Contributor(s): +# Valia Vaneeva # # Alternatively, the contents of this file may be used under the terms of # either the GNU General Public License Version 2 or later (the "GPL"), or @@ -46,6 +47,10 @@ ifdef MOZ_ENABLE_PGSQL DIRS += pgsql endif +ifdef MOZ_ENABLE_SQLITE +DIRS += sqlite +endif + DIRS += build ifdef ENABLE_TESTS diff --git a/extensions/sql/build/Makefile.in b/extensions/sql/build/Makefile.in index 264d24171cdf..ae8dad26d627 100644 --- a/extensions/sql/build/Makefile.in +++ b/extensions/sql/build/Makefile.in @@ -18,6 +18,7 @@ # the Initial Developer. All Rights Reserved. # # Contributor(s): +# Valia Vaneeva # # Alternatively, the contents of this file may be used under the terms of # either the GNU General Public License Version 2 or later (the "GPL"), or @@ -52,5 +53,6 @@ xpi: cd $(DIST); zip -r $(XPI_FILE) \ bin/components/sql.xpt \ bin/components/sqlpgsql.xpt \ + bin/components/sqlsqlite.xpt \ bin/components/$(LIB_PREFIX)sql$(DLL_SUFFIX) \ bin/chrome/sql.jar diff --git a/extensions/sql/build/src/Makefile.in b/extensions/sql/build/src/Makefile.in index 76f969b9f0d6..08b457c5b4d7 100644 --- a/extensions/sql/build/src/Makefile.in +++ b/extensions/sql/build/src/Makefile.in @@ -18,6 +18,7 @@ # the Initial Developer. All Rights Reserved. # # Contributor(s): +# Valia Vaneeva # # Alternatively, the contents of this file may be used under the terms of # either the GNU General Public License Version 2 or later (the "GPL"), or @@ -68,8 +69,19 @@ SHARED_LIBRARY_LIBS += $(DIST)/lib/$(LIB_PREFIX)sqlpgsql_s.$(LIB_SUFFIX) EXTRA_DSO_LDOPTS += -L$(MOZ_PGSQL_LIBS) -lpq endif +ifdef MOZ_ENABLE_SQLITE +DEFINES += -DMOZ_ENABLE_SQLITE +SHARED_LIBRARY_LIBS += $(DIST)/lib/$(LIB_PREFIX)sqlsqlite_s.$(LIB_SUFFIX) +EXTRA_DSO_LDOPTS += -L$(MOZ_SQLITE_LIBS) -lsqlite3 +endif + include $(topsrcdir)/config/rules.mk ifdef MOZ_ENABLE_PGSQL INCLUDES += -I$(MOZ_PGSQL_INCLUDES) endif + +ifdef MOZ_ENABLE_SQLITE +INCLUDES += -I$(MOZ_SQLITE_INCLUDES) +endif + diff --git a/extensions/sql/build/src/mozSqlModule.cpp b/extensions/sql/build/src/mozSqlModule.cpp index e3421da3dc18..f9025af00119 100644 --- a/extensions/sql/build/src/mozSqlModule.cpp +++ b/extensions/sql/build/src/mozSqlModule.cpp @@ -18,6 +18,7 @@ * the Initial Developer. All Rights Reserved. * * Contributor(s): + * Valia Vaneeva * * Alternatively, the contents of this file may be used under the terms of * either the GNU General Public License Version 2 or later (the "GPL"), or @@ -38,11 +39,17 @@ #ifdef MOZ_ENABLE_PGSQL #include "mozSqlConnectionPgsql.h" #endif +#ifdef MOZ_ENABLE_SQLITE +#include "mozSqlConnectionSqlite.h" +#endif NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(mozSqlService, Init) #ifdef MOZ_ENABLE_PGSQL NS_GENERIC_FACTORY_CONSTRUCTOR(mozSqlConnectionPgsql) #endif +#ifdef MOZ_ENABLE_SQLITE +NS_GENERIC_FACTORY_CONSTRUCTOR(mozSqlConnectionSqlite) +#endif static nsModuleComponentInfo components[] = { @@ -55,14 +62,21 @@ static nsModuleComponentInfo components[] = MOZ_SQLSERVICE_CID, MOZ_SQLDATASOURCE_CONTRACTID, mozSqlServiceConstructor - }, + } #ifdef MOZ_ENABLE_PGSQL - { MOZ_SQLCONNECTIONPGSQL_CLASSNAME, + ,{ MOZ_SQLCONNECTIONPGSQL_CLASSNAME, MOZ_SQLCONNECTIONPGSQL_CID, MOZ_SQLCONNECTIONPGSQL_CONTRACTID, mozSqlConnectionPgsqlConstructor } #endif +#ifdef MOZ_ENABLE_SQLITE + ,{ MOZ_SQLCONNECTIONSQLITE_CLASSNAME, + MOZ_SQLCONNECTIONSQLITE_CID, + MOZ_SQLCONNECTIONSQLITE_CONTRACTID, + mozSqlConnectionSqliteConstructor + } +#endif }; NS_IMPL_NSGETMODULE("mozSqlModule", components) diff --git a/extensions/sql/sqlite/Makefile.in b/extensions/sql/sqlite/Makefile.in new file mode 100644 index 000000000000..9fbe6a352cc3 --- /dev/null +++ b/extensions/sql/sqlite/Makefile.in @@ -0,0 +1,45 @@ +# ***** BEGIN LICENSE BLOCK ***** +# Version: MPL 1.1/GPL 2.0/LGPL 2.1 +# +# The contents of this file are subject to the Mozilla Public License Version +# 1.1 (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# http://www.mozilla.org/MPL/ +# +# Software distributed under the License is distributed on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License +# for the specific language governing rights and limitations under the +# License. +# +# The Original Code is mozilla.org code. +# +# The Initial Developer of the Original Code is Jan Varga +# Portions created by the Initial Developer are Copyright (C) 2003 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# +# Alternatively, the contents of this file may be used under the terms of +# either the GNU General Public License Version 2 or later (the "GPL"), or +# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), +# in which case the provisions of the GPL or the LGPL are applicable instead +# of those above. If you wish to allow use of your version of this file only +# under the terms of either the GPL or the LGPL, and not to allow others to +# use your version of this file under the terms of the MPL, indicate your +# decision by deleting the provisions above and replace them with the notice +# and other provisions required by the GPL or the LGPL. If you do not delete +# the provisions above, a recipient may use your version of this file under +# the terms of any one of the MPL, the GPL or the LGPL. +# +# ***** END LICENSE BLOCK ***** */ + +DEPTH = ../../.. +topsrcdir = @top_srcdir@ +srcdir = @srcdir@ +VPATH = @srcdir@ + +DIRS = \ + public \ + src + +include $(topsrcdir)/config/rules.mk diff --git a/extensions/sql/sqlite/public/Makefile.in b/extensions/sql/sqlite/public/Makefile.in new file mode 100644 index 000000000000..7a45e344c846 --- /dev/null +++ b/extensions/sql/sqlite/public/Makefile.in @@ -0,0 +1,50 @@ +# ***** BEGIN LICENSE BLOCK ***** +# Version: MPL 1.1/GPL 2.0/LGPL 2.1 +# +# The contents of this file are subject to the Mozilla Public License Version +# 1.1 (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# http://www.mozilla.org/MPL/ +# +# Software distributed under the License is distributed on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License +# for the specific language governing rights and limitations under the +# License. +# +# The Original Code is mozilla.org code. +# +# The Initial Developer of the Original Code is Jan Varga +# Portions created by the Initial Developer are Copyright (C) 2003 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Valia Vaneeva +# +# Alternatively, the contents of this file may be used under the terms of +# either the GNU General Public License Version 2 or later (the "GPL"), or +# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), +# in which case the provisions of the GPL or the LGPL are applicable instead +# of those above. If you wish to allow use of your version of this file only +# under the terms of either the GPL or the LGPL, and not to allow others to +# use your version of this file under the terms of the MPL, indicate your +# decision by deleting the provisions above and replace them with the notice +# and other provisions required by the GPL or the LGPL. If you do not delete +# the provisions above, a recipient may use your version of this file under +# the terms of any one of the MPL, the GPL or the LGPL. +# +# ***** END LICENSE BLOCK ***** */ + +DEPTH = ../../../.. +topsrcdir = @top_srcdir@ +srcdir = @srcdir@ +VPATH = @srcdir@ + +MODULE = sql +XPIDL_MODULE = sqlsqlite + +XPIDLSRCS = \ + mozISqlConnectionSqlite.idl \ + mozISqlResultSqlite.idl \ + $(NULL) + +include $(topsrcdir)/config/rules.mk diff --git a/extensions/sql/sqlite/public/mozISqlConnectionSqlite.idl b/extensions/sql/sqlite/public/mozISqlConnectionSqlite.idl new file mode 100644 index 000000000000..a9edaa27c30e --- /dev/null +++ b/extensions/sql/sqlite/public/mozISqlConnectionSqlite.idl @@ -0,0 +1,44 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is Jan Varga + * Portions created by the Initial Developer are Copyright (C) 2003 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Valia Vaneeva + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#include "nsISupports.idl" + +[scriptable, uuid(b00f42b4-8902-428c-ab13-9d066ff15aed)] + +interface mozISqlConnectionSqlite : nsISupports +{ + +}; diff --git a/extensions/sql/sqlite/public/mozISqlResultSqlite.idl b/extensions/sql/sqlite/public/mozISqlResultSqlite.idl new file mode 100644 index 000000000000..d00668147805 --- /dev/null +++ b/extensions/sql/sqlite/public/mozISqlResultSqlite.idl @@ -0,0 +1,44 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is Jan Varga + * Portions created by the Initial Developer are Copyright (C) 2003 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Valia Vaneeva + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#include "nsISupports.idl" + +[scriptable, uuid(96d1248b-608c-4b63-a718-b214200e4738)] + +interface mozISqlResultSqlite : nsISupports +{ + +}; diff --git a/extensions/sql/sqlite/src/Makefile.in b/extensions/sql/sqlite/src/Makefile.in new file mode 100644 index 000000000000..320c3f4f0179 --- /dev/null +++ b/extensions/sql/sqlite/src/Makefile.in @@ -0,0 +1,68 @@ +# ***** BEGIN LICENSE BLOCK ***** +# Version: MPL 1.1/GPL 2.0/LGPL 2.1 +# +# The contents of this file are subject to the Mozilla Public License Version +# 1.1 (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# http://www.mozilla.org/MPL/ +# +# Software distributed under the License is distributed on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License +# for the specific language governing rights and limitations under the +# License. +# +# The Original Code is mozilla.org code. +# +# The Initial Developer of the Original Code is Jan Varga +# Portions created by the Initial Developer are Copyright (C) 2003 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Valia Vaneeva +# +# Alternatively, the contents of this file may be used under the terms of +# either the GNU General Public License Version 2 or later (the "GPL"), or +# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), +# in which case the provisions of the GPL or the LGPL are applicable instead +# of those above. If you wish to allow use of your version of this file only +# under the terms of either the GPL or the LGPL, and not to allow others to +# use your version of this file under the terms of the MPL, indicate your +# decision by deleting the provisions above and replace them with the notice +# and other provisions required by the GPL or the LGPL. If you do not delete +# the provisions above, a recipient may use your version of this file under +# the terms of any one of the MPL, the GPL or the LGPL. +# +# ***** END LICENSE BLOCK ***** */ + +DEPTH = ../../../.. +topsrcdir = @top_srcdir@ +srcdir = @srcdir@ +VPATH = @srcdir@ + +include $(DEPTH)/config/autoconf.mk + +MODULE = sql +LIBRARY_NAME = sqlsqlite_s + +REQUIRES = xpcom \ + string \ + locale \ + rdf \ + dom \ + unicharutil \ + layout \ + $(NULL) + +CPPSRCS = \ + mozSqlConnectionSqlite.cpp \ + mozSqlResultSqlite.cpp + +EXPORTS = \ + mozSqlConnectionSqlite.h \ + mozSqlResultSqlite.h + +FORCE_STATIC_LIB=1 + +include $(topsrcdir)/config/rules.mk + +INCLUDES += -I$(MOZ_SQLITE_INCLUDES) diff --git a/extensions/sql/sqlite/src/mozSqlConnectionSqlite.cpp b/extensions/sql/sqlite/src/mozSqlConnectionSqlite.cpp new file mode 100644 index 000000000000..9908e3a0c5fc --- /dev/null +++ b/extensions/sql/sqlite/src/mozSqlConnectionSqlite.cpp @@ -0,0 +1,379 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is Jan Varga + * Portions created by the Initial Developer are Copyright (C) 2003 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Valia Vaneeva + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#include "nsReadableUtils.h" +#include "mozSqlConnectionSqlite.h" +#include "mozSqlResultSqlite.h" +#include +#include "nsLocalFile.h" +#include "nsAppDirectoryServiceDefs.h" +#include "nsUnicharUtils.h" + +mozSqlConnectionSqlite::mozSqlConnectionSqlite() + : mConnection(nsnull) +{ +} + +mozSqlConnectionSqlite::~mozSqlConnectionSqlite() +{ + if (mConnection) + sqlite3_close(mConnection); +} + +NS_IMPL_ADDREF_INHERITED(mozSqlConnectionSqlite, mozSqlConnection) +NS_IMPL_RELEASE_INHERITED(mozSqlConnectionSqlite, mozSqlConnection) + +// QueryInterface +NS_INTERFACE_MAP_BEGIN(mozSqlConnectionSqlite) + NS_INTERFACE_MAP_ENTRY(mozISqlConnectionSqlite) +NS_INTERFACE_MAP_END_INHERITING(mozSqlConnection) + +NS_IMETHODIMP +mozSqlConnectionSqlite::Init(const nsAString& aHost, + PRInt32 aPort, + const nsAString& aDatabase, + const nsAString& aUsername, + const nsAString& aPassword) +{ + if (mConnection) + return NS_OK; + + nsAString::const_iterator start; + nsresult rv; + nsAutoString path; + aDatabase.BeginReading(start); + + nsCOMPtr file(do_CreateInstance(NS_LOCAL_FILE_CONTRACTID, &rv)); + if (NS_FAILED(rv)) + return rv; + + rv = file->InitWithPath(aDatabase); + + if (rv == NS_ERROR_FILE_UNRECOGNIZED_PATH) { + nsCOMPtr directoryService = do_GetService( + NS_DIRECTORY_SERVICE_CONTRACTID, + &rv); + if (NS_FAILED(rv)) + return rv; + rv = directoryService->Get(NS_APP_USER_PROFILE_50_DIR, + NS_GET_IID(nsILocalFile), + getter_AddRefs(file)); + if (NS_FAILED(rv)) + return rv; + rv = file->Append(aDatabase); + if (NS_FAILED(rv)) + return rv; + file->GetPath(path); + if (path.IsEmpty()) + return NS_ERROR_FAILURE; + } + else if (NS_FAILED(rv)) + return NS_ERROR_FAILURE; + else + path = aDatabase; + + PRBool exists; + rv = file->Exists(&exists); + if (NS_FAILED(rv)) + return NS_ERROR_FAILURE; + + rv = file->IsWritable(&mWritable); + if (NS_FAILED(rv)) + return NS_ERROR_FAILURE; + + rv = sqlite3_open(NS_ConvertUCS2toUTF8(path).get(), &mConnection); + if (rv != SQLITE_OK) + return rv; + + return Setup(); +} + +NS_IMETHODIMP +mozSqlConnectionSqlite::GetPrimaryKeys(const nsAString& aSchema, + const nsAString& aTable, + mozISqlResult** _retval) +{ + if (! mConnection) + return NS_ERROR_NOT_INITIALIZED; + + /* the purpose of this all is to get primary keys in a structure used in + * GetPrimaryKeys() for pgsql. as sqlite3 doesn't allow to do it using a + * single select query, we have to create it by hand + * i thought of other variants but this one seems to be the easiest, if you + * know how to implement GetPrimaryKeys() in a better way, please tell me + */ + char **r, *errmsg; + PRInt32 stat, nrow, ncolumn; + nsAutoString preselect, select1, select2, uni, select, common; + + common.AssignLiteral("select NULL as TABLE_SCHEM, '"); + select1.AssignLiteral("' as COLUMN_NAME, "); + select2.AssignLiteral(" as KEY_SEQ, NULL as PK_NAME"); + uni.AssignLiteral(" UNION "); + + // first select: we need it to get the "create table" statement + preselect.AssignLiteral("select sql from sqlite_master where type='table' and name='"); + if (!aTable.IsEmpty()) { + preselect.Append(aTable); + common.Append(aTable); + } + else + return NS_ERROR_FAILURE; + preselect.Append(NS_LITERAL_STRING("';")); + common.Append(NS_LITERAL_STRING("' as TABLE_NAME, '")); + + stat = sqlite3_get_table(mConnection, NS_ConvertUCS2toUTF8(preselect).get(), + &r, &nrow, &ncolumn, &errmsg); + if (stat != SQLITE_OK) { + CopyUTF8toUTF16(errmsg, mErrorMessage); + sqlite3_free_table(r); + return NS_ERROR_FAILURE; + } + + // now we parse that statement in order to find primary key columns + nsAutoString aToken = NS_ConvertUTF8toUCS2(nsDependentCString("PRIMARY KEY")); + nsAutoString aKeyColumn; + NS_ConvertUTF8toUCS2 buffer(r[1]); + nsAString::const_iterator start, end, iter, iter2; + buffer.BeginReading(start); + buffer.EndReading(end); + + if (CaseInsensitiveFindInReadable(aToken, start, end)) + iter = end; + else + return NS_ERROR_FAILURE; + buffer.BeginReading(start); + buffer.EndReading(end); + + PRInt32 count = 1; + while (iter != end && (*iter == PRUnichar(' ') || *iter == PRUnichar('\t') || + *iter == PRUnichar('\n'))) + ++iter; + + // if we have "primary key (colname1, colname2, ...)" we can have multiple + // columns + if (*iter == PRUnichar('(')) { + char str[16]; + ++iter; + while (iter != end && *iter != PRUnichar(')')) { + while ((*iter == PRUnichar(' ') || *iter == PRUnichar('\n') || + *iter == PRUnichar('\t') || *iter == PRUnichar(',')) && + *iter != PRUnichar(')') && iter != end) + ++iter; + if (iter != end && *iter != PRUnichar(')')) { + // we get column names and create a fake select which selects nothing + if (count > 1) + select.Append(uni); + select.Append(common); + iter2 = iter; + while (iter2 != end && *iter2 != PRUnichar(',') && + *iter2 != PRUnichar(' ') && *iter2 != PRUnichar('\n') && + *iter2 != PRUnichar('\t') && *iter2 != PRUnichar(')')) + ++iter2; + aKeyColumn = Substring(iter,iter2); + select.Append(aKeyColumn); + iter = iter2; + select.Append(select1); + PRInt32 i = 0, j, tmp, cnt = count; + do { + str[i++] = cnt % 10 + 48; + str[i] = '\0'; + } while ((cnt /= 10) > 0); + for (i = 0, j = strlen(str) - 1; i < j; i++, j--) { + tmp = str[i]; + str[i] = str[j]; + str[j] = tmp; + } + select.Append(UTF8ToNewUnicode(nsDependentCString(str))); + select.Append(select2); + count++; + } + } + } + // we have only one primary key column: "colname ... primary key ..." + else { + PRInt32 openParenth = 0; + while (iter != start && (*iter != PRUnichar(',') && openParenth == 0)) { + if (*iter == PRUnichar(')')) + openParenth++; + else if (*iter == PRUnichar('(')) + openParenth--; + --iter; + } + if (iter == start) { + while (*iter != PRUnichar('(') && iter != end) + ++iter; + } + ++iter; + while ((*iter == PRUnichar(' ') || *iter == PRUnichar('\n') || + *iter == PRUnichar('\t')) && iter != end) + ++iter; + select.Append(common); + iter2 = iter; + while (iter2 != end && *iter2 != PRUnichar(' ') && + *iter2 != PRUnichar('\n') && *iter2 != PRUnichar('\t')) + ++iter2; + aKeyColumn = Substring(iter,iter2); + select.Append(aKeyColumn); + select.Append(select1); + select.Append(PRUnichar('1')); + select.Append(select2); + } + select.Append(PRUnichar(';')); + + sqlite3_free_table(r); + + /* by this time we have either this select: + * select NULL as TABLE_SCHEM, 'table_name' as TABLE_NAME, 'colname1' as + * COLUMN_NAME, 1 as KEY_SEQ, NULL as PK_NAME UNION select NULL as + * TABLE_SCHEM, 'table_name' as TABLE_NAME, 'colname2' as COLUMN_NAME, 2 as + * KEY_SEQ, NULL as PK_NAME ...; + * or this one: + * select NULL as TABLE_SCHEM, 'table_name' as TABLE_NAME, 'colname' as + * COLUMN_NAME, 1 as KEY_SEQ, NULL as PK_NAME; + * anyway, they do not select anything, they just assign the values + */ + return RealExec(select, _retval, nsnull); +} + +nsresult +mozSqlConnectionSqlite::Setup() +{ + if (sqlite3_errcode(mConnection) != SQLITE_OK) { + CopyUTF8toUTF16(sqlite3_errmsg(mConnection), mErrorMessage); + + mConnection = nsnull; + return NS_ERROR_FAILURE; + } + + NS_ConvertUTF8toUCS2 buffer(sqlite3_version); + nsAString::const_iterator start, end, iter; + PRInt32 numbers[3] = {0,0,0}; + buffer.BeginReading(iter); + buffer.EndReading(end); + for (PRInt32 i = 0; i < 3; i++) { + start = iter; + while (iter != end && *iter != PRUnichar('.')) + ++iter; + nsAutoString v(Substring(start,iter)); + PRInt32 err; + numbers[i] = v.ToInteger(&err); + while (iter != end && *iter == PRUnichar('.')) + ++iter; + } + mVersion = SERVER_VERSION(numbers[0], numbers[1], numbers[2]); + + if (mVersion < SERVER_VERSION(3,0,2)) + return NS_ERROR_FAILURE; + + return NS_OK; +} + +nsresult +mozSqlConnectionSqlite::RealExec(const nsAString& aQuery, + mozISqlResult** aResult, + PRInt32* aAffectedRows) +{ + //sqlite3_changes doesn't reset its count to 0 after selects + static PRInt32 oldChange = 0; + + if (! mConnection) + return NS_ERROR_NOT_INITIALIZED; + + char **r, *errmsg; + PRInt32 stat, nrow, ncolumn; + + stat = sqlite3_get_table(mConnection, NS_ConvertUCS2toUTF8(aQuery).get(), &r, + &nrow, &ncolumn, &errmsg); + PRInt32 changed = sqlite3_total_changes(mConnection) - oldChange; + oldChange += changed; + + if (stat == SQLITE_OK && !changed) { + if (!aResult) + return NS_ERROR_NULL_POINTER; + + if (*aResult) { + ((mozSqlResultSqlite*)*aResult)->SetResult(r, nrow, ncolumn, mWritable); + nsresult rv = ((mozSqlResult*)*aResult)->Rebuild(); + if (NS_FAILED(rv)) + return rv; + NS_ADDREF(*aResult); + } + else { + mozSqlResult* result = new mozSqlResultSqlite(this, aQuery); + if (!result) + return NS_ERROR_OUT_OF_MEMORY; + ((mozSqlResultSqlite*)result)->SetResult(r, nrow, ncolumn, mWritable); + nsresult rv = result->Init(); + if (NS_FAILED(rv)) + return rv; + NS_ADDREF(*aResult = result); + } + } + else if (stat == SQLITE_OK && changed) { + if (!aAffectedRows) + return NS_ERROR_NULL_POINTER; + *aAffectedRows = changed; + mLastID = sqlite3_last_insert_rowid(mConnection); + } + else { + CopyUTF8toUTF16(errmsg, mErrorMessage); + sqlite3_free_table(r); + return NS_ERROR_FAILURE; + } + + return NS_OK; +} + +nsresult +mozSqlConnectionSqlite::CancelExec() +{ + sqlite3_interrupt(mConnection); + + if (sqlite3_errcode(mConnection) != SQLITE_OK) { + CopyUTF8toUTF16(sqlite3_errmsg(mConnection), mErrorMessage); + return NS_ERROR_FAILURE; + } + + return NS_OK; +} + +nsresult +mozSqlConnectionSqlite::GetIDName(nsAString& aIDName) +{ + aIDName.AssignLiteral("OID"); + return NS_OK; +} diff --git a/extensions/sql/sqlite/src/mozSqlConnectionSqlite.h b/extensions/sql/sqlite/src/mozSqlConnectionSqlite.h new file mode 100644 index 000000000000..d3a719b1dc12 --- /dev/null +++ b/extensions/sql/sqlite/src/mozSqlConnectionSqlite.h @@ -0,0 +1,86 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is Jan Varga + * Portions created by the Initial Developer are Copyright (C) 2003 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Valia Vaneeva + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#ifndef mozSqlConnectionSqlite_h +#define mozSqlConnectionSqlite_h + +#include "sqlite3.h" +#include "mozSqlConnection.h" +#include "mozISqlConnectionSqlite.h" + +#define MOZ_SQLCONNECTIONSQLITE_CLASSNAME "SQLite SQL Connection" +#define MOZ_SQLCONNECTIONSQLITE_CID \ +{0xb00f42b4, 0x8902, 0x428c, {0xab, 0x13, 0x9d, 0x06, 0x6f, 0xf1, 0x5a, 0xed }} + +#define MOZ_SQLCONNECTIONSQLITE_CONTRACTID "@mozilla.org/sql/connection;1?type=sqlite" + +#define SERVER_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c)) + +class mozSqlConnectionSqlite : public mozSqlConnection, + public mozISqlConnectionSqlite +{ + public: + mozSqlConnectionSqlite(); + virtual ~mozSqlConnectionSqlite(); + + NS_DECL_ISUPPORTS + + NS_IMETHOD Init(const nsAString& aHost, PRInt32 aPort, + const nsAString& aDatabase, const nsAString& aUsername, + const nsAString& aPassword); + + NS_IMETHOD GetPrimaryKeys(const nsAString& aSchema, const nsAString& aTable, + mozISqlResult** _retval); + + NS_DECL_MOZISQLCONNECTIONSQLITE + + protected: + nsresult Setup(); + + virtual nsresult RealExec(const nsAString& aQuery, mozISqlResult** aResult, + PRInt32* aAffectedRows); + + virtual nsresult CancelExec(); + + virtual nsresult GetIDName(nsAString& aIDName); + + private: + sqlite3* mConnection; + PRInt32 mVersion; + PRBool mWritable; +}; + +#endif // mozSqlConnectionSqlite_h diff --git a/extensions/sql/sqlite/src/mozSqlResultSqlite.cpp b/extensions/sql/sqlite/src/mozSqlResultSqlite.cpp new file mode 100644 index 000000000000..1605950333bb --- /dev/null +++ b/extensions/sql/sqlite/src/mozSqlResultSqlite.cpp @@ -0,0 +1,160 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is Jan Varga + * Portions created by the Initial Developer are Copyright (C) 2003 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Valia Vaneeva + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#include "nsReadableUtils.h" +#include "mozSqlResultSqlite.h" + +mozSqlResultSqlite::mozSqlResultSqlite(mozISqlConnection* aConnection, + const nsAString& aQuery) + : mozSqlResult(aConnection, aQuery), + mResult(nsnull), + mColumnCount(0), + mRowCount(0), + mWritable(PR_FALSE) +{ +} + +void +mozSqlResultSqlite::SetResult(char** aResult, PRInt32 aRowCount, + PRInt32 aColumnCount, PRBool aWritable) +{ + mResult = aResult; + mColumnCount = aColumnCount; + mRowCount = aRowCount; + mWritable = aWritable; +} + +mozSqlResultSqlite::~mozSqlResultSqlite() +{ + ClearNativeResult(); +} + +NS_IMPL_ADDREF_INHERITED(mozSqlResultSqlite, mozSqlResult) +NS_IMPL_RELEASE_INHERITED(mozSqlResultSqlite, mozSqlResult) + +// QueryInterface +NS_INTERFACE_MAP_BEGIN(mozSqlResultSqlite) + NS_INTERFACE_MAP_ENTRY(mozISqlResultSqlite) +NS_INTERFACE_MAP_END_INHERITING(mozSqlResult) + +PRInt32 +mozSqlResultSqlite::GetColType(PRInt32 aColumnIndex) +{ + return mozISqlResult::TYPE_STRING; +} + +nsresult +mozSqlResultSqlite::BuildColumnInfo() +{ + for (PRInt32 i = 0; i < mColumnCount; i++) { + char* n = mResult[i]; + PRUnichar* name = UTF8ToNewUnicode(nsDependentCString(n)); + PRInt32 type = GetColType(i); + PRInt32 size = -1; + PRInt32 mod = -1; + + nsCAutoString uri(NS_LITERAL_CSTRING("http://www.mozilla.org/SQL-rdf#")); + uri.Append(n); + nsCOMPtr property; + gRDFService->GetResource(uri, getter_AddRefs(property)); + + ColumnInfo* columnInfo = ColumnInfo::Create(mAllocator, name, type, size, + mod, property); + mColumnInfo.AppendElement(columnInfo); + } + + return NS_OK; +} + +nsresult +mozSqlResultSqlite::BuildRows() +{ + for(PRInt32 i = 1; i <= mRowCount; i++) { + nsCOMPtr resource; + nsresult rv = gRDFService->GetAnonymousResource(getter_AddRefs(resource)); + if (NS_FAILED(rv)) return rv; + + Row* row = Row::Create(mAllocator, resource, mColumnInfo); + + for (PRInt32 j = 0; j < mColumnInfo.Count(); j++) { + if (mResult[j+i*mColumnCount]) { + char* value = mResult[j+i*mColumnCount]; + Cell* cell = row->mCells[j]; + cell->SetNull(PR_FALSE); + cell->SetString(UTF8ToNewUnicode(nsDependentCString(value))); + } + } + + mRows.AppendElement(row); + nsVoidKey key(resource); + mSources.Put(&key, row); + } + + return NS_OK; +} + +void +mozSqlResultSqlite::ClearNativeResult() +{ + if (mResult) { + sqlite3_free_table(mResult); + mResult = nsnull; + } +} + +nsresult +mozSqlResultSqlite::CanInsert(PRBool* _retval) +{ + *_retval = mWritable; + + return NS_OK; +} + +nsresult +mozSqlResultSqlite::CanUpdate(PRBool* _retval) +{ + *_retval = mWritable; + + return NS_OK; +} + +nsresult +mozSqlResultSqlite::CanDelete(PRBool* _retval) +{ + *_retval = mWritable; + + return NS_OK; +} diff --git a/extensions/sql/sqlite/src/mozSqlResultSqlite.h b/extensions/sql/sqlite/src/mozSqlResultSqlite.h new file mode 100644 index 000000000000..366c1b288919 --- /dev/null +++ b/extensions/sql/sqlite/src/mozSqlResultSqlite.h @@ -0,0 +1,75 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is Jan Varga + * Portions created by the Initial Developer are Copyright (C) 2003 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Valia Vaneeva + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#ifndef mozSqlResultSqlite_h +#define mozSqlResultSqlite_h + +#include "sqlite3.h" +#include "mozSqlResult.h" +#include "mozISqlResultSqlite.h" + +class mozSqlResultSqlite : public mozSqlResult, + public mozISqlResultSqlite +{ + public: + mozSqlResultSqlite(mozISqlConnection* aConnection, const nsAString& aQuery); + void SetResult(char** aResult, PRInt32 nrow, PRInt32 ncolumn, + PRBool aWritable); + virtual ~mozSqlResultSqlite(); + + NS_DECL_ISUPPORTS + + NS_DECL_MOZISQLRESULTSQLITE + + protected: + PRInt32 GetColType(PRInt32 aColumnIndex); + + virtual nsresult BuildColumnInfo(); + virtual nsresult BuildRows(); + virtual void ClearNativeResult(); + + virtual nsresult CanInsert(PRBool* _retval); + virtual nsresult CanUpdate(PRBool* _retval); + virtual nsresult CanDelete(PRBool* _retval); + + private: + char** mResult; + PRInt32 mColumnCount; + PRInt32 mRowCount; + PRInt32 mWritable; +}; + +#endif // mozSqlResultSqlite_h