zorba-coders team mailing list archive
-
zorba-coders team
-
Mailing list archive
-
Message #25562
[Merge] lp:~zorba-coders/zorba/bug-1210677-sqlite into lp:zorba
Chris Hillery has proposed merging lp:~zorba-coders/zorba/bug-1210677-sqlite into lp:zorba.
Commit message:
Replace auto_ptr with unique_ptr
Requested reviews:
Zorba Coders (zorba-coders)
For more details, see:
https://code.launchpad.net/~zorba-coders/zorba/bug-1210677-sqlite/+merge/184924
--
https://code.launchpad.net/~zorba-coders/zorba/bug-1210677-sqlite/+merge/184924
Your team Zorba Coders is requested to review the proposed merge of lp:~zorba-coders/zorba/bug-1210677-sqlite into lp:zorba.
=== added file 'CMakeLists.txt'
--- CMakeLists.txt 1970-01-01 00:00:00 +0000
+++ CMakeLists.txt 2013-09-11 04:36:11 +0000
@@ -0,0 +1,66 @@
+# Copyright 2012 The FLWOR Foundation.
+#
+# Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
+
+PROJECT (zorba_sqlite_module)
+ENABLE_TESTING ()
+INCLUDE (CTest)
+
+IF (WIN32)
+ # On Windows we use proxy modules that try to guess first the location
+ # of the required third party libraries. This will search in order in:
+ # 1. the path pointed by ZORBA_THIRD_PARTY_REQUIREMENTS
+ # 2. the Program Files directory available on the users computer
+ # 3. the PATH environment variable
+ # The logic is implemented by the macros in the ProxyFindModule.cmake module.
+ LIST (APPEND CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake_modules/Windows")
+ENDIF (WIN32)
+LIST (APPEND CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake_modules")
+
+FIND_PACKAGE (Zorba REQUIRED HINTS "${ZORBA_BUILD_DIR}")
+MESSAGE(STATUS "Zorba_USE_FILE ${Zorba_USE_FILE}")
+INCLUDE ("${Zorba_USE_FILE}")
+
+IF (ZORBA_SUPPRESS_SQLITE)
+ MESSAGE (STATUS "ZORBA_SUPRESS_SQLITE is true - not searching for SQLite.")
+ELSE (ZORBA_SUPRESS_SQLITE)
+
+ MESSAGE (STATUS "Looking for SQLite")
+ FIND_PACKAGE (SQLite3)
+
+ IF (SQLITE_FOUND)
+ MESSAGE (STATUS "Found SQLite --" ${SQLITE_LIBRARIES})
+
+ # Set SQLITE_WITH_FILE_ACCESS - by default will be the same value as
+ # ZORBA_WITH_FILE ACCESS when built inside Zorba, or "ON" if built
+ # stand-alone.
+ IF (DEFINED ZORBA_WITH_FILE_ACCESS)
+ SET (_file_access ${ZORBA_WITH_FILE_ACCESS})
+ ELSE (DEFINED ZORBA_WITH_FILE_ACCESS)
+ SET (_file_access ON)
+ ENDIF (DEFINED ZORBA_WITH_FILE_ACCESS)
+ SET(SQLITE_WITH_FILE_ACCESS ${_file_access} CACHE BOOL
+ "Allow filesystem-based SQLite databases")
+
+ INCLUDE_DIRECTORIES (${SQLITE_INCLUDE_DIR})
+
+ ADD_SUBDIRECTORY("src")
+ ADD_TEST_DIRECTORY("${PROJECT_SOURCE_DIR}/test")
+ ELSE (SQLITE_FOUND)
+ MESSAGE (STATUS "SQLite library not found == if you want to use the sqlite functionality please set SQLITE_INCLUDE_DIR and SQLITE_LIBRARIES cmake parameters accordingly.")
+ ENDIF (SQLITE_FOUND)
+ENDIF (ZORBA_SUPPRESS_SQLITE)
+
+DONE_DECLARING_ZORBA_URIS()
=== renamed file 'CMakeLists.txt' => 'CMakeLists.txt.moved'
=== added directory 'cmake_modules'
=== renamed directory 'cmake_modules' => 'cmake_modules.moved'
=== added file 'cmake_modules/FindSQLite3.cmake'
--- cmake_modules/FindSQLite3.cmake 1970-01-01 00:00:00 +0000
+++ cmake_modules/FindSQLite3.cmake 2013-09-11 04:36:11 +0000
@@ -0,0 +1,49 @@
+# Copyright 2012 The FLWOR Foundation.
+#
+# Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+IF (SQLITE_INCLUDE_DIR)
+ SET (SQLITE_FIND_QUIETLY TRUE)
+ENDIF (SQLITE_INCLUDE_DIR)
+
+FIND_PATH (
+ SQLITE_INCLUDE_DIR
+ sqlite3.h
+ PATHS ${SQLITE_INCLUDE_DIR} /usr/include/ /usr/local/include /opt/local/include )
+MARK_AS_ADVANCED (SQLITE_INCLUDE_DIR)
+
+FIND_LIBRARY (
+ SQLITE_LIBRARY
+ NAMES sqlite3
+ PATHS ${SQLITE_LIBRARY_DIR} /usr/lib /usr/local/lib /opt/local/lib)
+MARK_AS_ADVANCED (SQLITE_LIBRARY)
+
+IF (SQLITE_INCLUDE_DIR AND SQLITE_LIBRARY)
+ SET (SQLITE_FOUND 1)
+ SET (SQLITE_LIBRARIES ${SQLITE_LIBRARY})
+ SET (SQLITE_INCLUDE_DIRS ${SQLITE_INCLUDE_DIR})
+ IF (NOT SQLITE_FIND_QUIETLY)
+ MESSAGE (STATUS "Found SQLite library: " ${SQLITE_LIBRARY})
+ MESSAGE (STATUS "Found SQLite include path : " ${SQLITE_INCLUDE_DIR})
+ ENDIF (NOT SQLITE_FIND_QUIETLY)
+
+ SET(CMAKE_REQUIRED_INCLUDES "${SQLITE_INCLUDE_DIR}")
+ SET(CMAKE_REQUIRED_LIBRARIES "${SQLITE_LIBRARY}")
+
+ INCLUDE(CheckFunctionExists)
+ CHECK_FUNCTION_EXISTS(sqlite3_column_database_name ZORBA_SQLITE_HAVE_METADATA)
+ELSE (SQLITE_INCLUDE_DIR AND SQLITE_LIBRARY)
+ SET (SQLITE_FOUND 0)
+ SET (SQLITE_LIBRARIES)
+ SET (SQLITE_INCLUDE_DIRS)
+ENDIF (SQLITE_INCLUDE_DIR AND SQLITE_LIBRARY)
=== added directory 'cmake_modules/Windows'
=== added file 'cmake_modules/Windows/FindSQLite3.cmake'
--- cmake_modules/Windows/FindSQLite3.cmake 1970-01-01 00:00:00 +0000
+++ cmake_modules/Windows/FindSQLite3.cmake 2013-09-11 04:36:11 +0000
@@ -0,0 +1,21 @@
+# Copyright 2012 The FLWOR Foundation.
+#
+# Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+FIND_PACKAGE_WIN32 (NAME SQLITE3 FOUND_VAR SQLITE_FOUND SEARCH_NAMES sqlite3)
+
+IF (SQLITE_FOUND)
+ FIND_PACKAGE_DLLS_WIN32 (${FOUND_LOCATION} sqlite3.dll)
+ SET(CMAKE_REQUIRED_INCLUDES "${SQLITE_INCLUDE_DIR}")
+ SET(CMAKE_REQUIRED_LIBRARIES "${SQLITE_LIBRARY}")
+ENDIF (SQLITE_FOUND)
=== added directory 'src'
=== renamed directory 'src' => 'src.moved'
=== added file 'src/CMakeLists.txt'
--- src/CMakeLists.txt 1970-01-01 00:00:00 +0000
+++ src/CMakeLists.txt 2013-09-11 04:36:11 +0000
@@ -0,0 +1,23 @@
+# Copyright 2012 The FLWOR Foundation.
+#
+# Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+CONFIGURE_FILE("${CMAKE_CURRENT_SOURCE_DIR}/config.h.cmake"
+ "${CMAKE_CURRENT_BINARY_DIR}/sqlite_module/config.h")
+INCLUDE_DIRECTORIES("${CMAKE_CURRENT_BINARY_DIR}")
+
+DECLARE_ZORBA_MODULE (
+ URI "http://zorba.io/modules/sqlite";
+ VERSION 1.0
+ FILE "sqlite_module.xq"
+ LINK_LIBRARIES "${SQLITE_LIBRARIES}")
=== added file 'src/config.h.cmake'
--- src/config.h.cmake 1970-01-01 00:00:00 +0000
+++ src/config.h.cmake 2013-09-11 04:36:11 +0000
@@ -0,0 +1,26 @@
+/*
+ * Copyright 2013 The FLWOR Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// This header is configured by the SQLite module's build process
+// -- DO NOT EDIT!
+
+#ifndef ZORBA_SQLITE_CONFIG_H
+#define ZORBA_SQLITE_CONFIG_H
+
+#cmakedefine SQLITE_WITH_FILE_ACCESS
+#cmakedefine ZORBA_SQLITE_HAVE_METADATA
+
+#endif /* ZORBA_SQLITE_CONFIG_H */
=== added file 'src/sqlite_module.xq'
--- src/sqlite_module.xq 1970-01-01 00:00:00 +0000
+++ src/sqlite_module.xq 2013-09-11 04:36:11 +0000
@@ -0,0 +1,378 @@
+jsoniq version "1.0";
+
+(:
+ : Copyright 2012 The FLWOR Foundation.
+ :
+ : Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
+ :
+ : Unless required by applicable law or agreed to in writing, software
+ : distributed under the License is distributed on an "AS IS" BASIS,
+ : WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ : See the License for the specific language governing permissions and
+ : limitations under the License.
+ :)
+
+(:~
+ : This module provides functionality to extract, add and modify data
+ : from SQLite databases.<p/>
+ :
+ : @author Luis Rodgriguez
+ : @library <a href="http://www.sqlite.org/";>SQLite</a>
+ : @project DB Drivers/SQLite
+ :)
+
+module namespace s = "http://zorba.io/modules/sqlite";;
+declare namespace an = "http://zorba.io/annotations";;
+declare namespace ver = "http://zorba.io/options/versioning";;
+declare option ver:module-version "1.0";
+
+(:~
+ : Connect to a SQLite database.
+ :
+ : @param $db-name the SQLite database name to be opened as xs:string.
+ :
+ : @return the SQLite database object as xs:anyURI.
+ :
+ : @error s:CANT-OPEN-DB if the database name doesn't exist or it couldn't be
+ : opened.
+ : @error s:COMPILED-WITHOUT-DISK-ACCESS if a non-in-memory database is
+ : requested and the module is built without filesystem access.
+ : @error s:INTERNAL-SQLITE-PROBLEM if there was an internal error inside
+ : SQLite library.
+ :)
+declare %an:nondeterministic function s:connect(
+ $db-name as xs:string
+ ) as xs:anyURI external;
+
+(:~
+ : Connect to a SQLite database with optional options.<p/>
+ : All options are true/false values. Available options are: open-read-only,
+ : open-create, open-no-mutex, and open-shared-cache.
+ :
+ : The options are of the form:
+ : <pre>
+ : {
+ : "open_read_only" : true,
+ : "open_create : false,
+ : ...
+ : }
+ : </pre>
+ : <p/>
+ :
+ : @param $db-name the SQLite database name to be opened as xs:string.
+ : @param $options a JSON object containing SQLite connection options.
+ :
+ : @return the SQLite database object as xs:anyURI.
+ :
+ : @error s:CANT-OPEN-DB if the database name doesn't exist or it couldn't be
+ : opened.
+ : @error s:UNKNOWN-OPTION if there is any unknown option specified.
+ : @error s:COMPILED-WITHOUT-DISK-ACCESS if a non-in-memory database is
+ : requested and the module is built without filesystem access.
+ : @error s:INTERNAL-SQLITE-PROBLEM if there was an internal error inside SQLite
+ : library.
+ :)
+declare %an:nondeterministic function s:connect(
+ $db-name as xs:string,
+ $options as object()?
+ ) as xs:anyURI external;
+
+(:~
+ : Returns whether on not the passed SQLite database object is connected.
+ :
+ : @param $conn the SQLite database object as xs:anyURI.
+ :
+ : @return true if the given SQLite database object is connected, false
+ : otherwise.
+ :
+ : @error s:INVALID-SQLITE-OBJECT if $conn is not a valid SQLite database object.
+ : @error s:INTERNAL-SQLITE-PROBLEM if there was an internal error inside SQLite
+ : library.
+ :)
+declare %an:nondeterministic function s:is-connected(
+ $conn as xs:anyURI ) as xs:boolean external;
+
+(:~
+ : Commits all pending update operations in this SQLite database.
+ :
+ : @param $conn the SQLite database object as xs:anyURI.
+ :
+ : @return the passed SQLite object.
+ :
+ : @error s:INVALID-SQLITE-OBJECT if $conn is not a valid SQLite database object.
+ : @error s:INTERNAL-SQLITE-PROBLEM if there was an internal error inside SQLite
+ : library.
+ :)
+declare %an:sequential function s:commit(
+ $conn as xs:anyURI ) as xs:anyURI external;
+
+(:~
+ : Rollbacks all pending update operations in this SQLite database.
+ :
+ : @param $conn the SQLite database object as xs:anyURI.
+ :
+ : @return the passed SQLite object.
+ :
+ : @error s:INVALID-SQLITE-OBJECT if $conn is not a valid SQLite database object.
+ : @error s:INTERNAL-SQLITE-PROBLEM if there was an internal error inside SQLite
+ : library.
+ :)
+declare %an:sequential function s:rollback(
+ $conn as xs:anyURI ) as xs:anyURI external;
+
+(:~
+ : Executes a query (select command) over an already opened SQLite database
+ : object.
+ :
+ : @param $conn an already opened SQLite database object as xs:anyURI.
+ : @param $sqlstr the query to be executed as xs:string.
+ :
+ : @return a sequence of JSON objects describing each row returned.
+ :
+ : @error s:INVALID-SQLITE-OBJECT if $conn is not a valid SQLite database object.
+ : @error s:INVALID-SQL-STATEMENT if $stmnt is not a valid sql command.
+ : @error s:INTERNAL-SQLITE-PROBLEM if there was an internal error inside SQLite
+ : library.
+ :)
+declare %an:nondeterministic function s:execute-query(
+ $conn as xs:anyURI,
+ $sqlstr as xs:string ) as object()* external;
+
+(:~
+ : Executes an update command over an already opened SQLite database object.
+ :
+ : @param $conn an already opened SQLite database object as xs:anyURI.
+ : @param $sqlstr the update command to be executed as xs:string.
+ :
+ : @return the amount of rows modified by such update command.
+ :
+ : @error s:INVALID-SQLITE-OBJECT if $conn is not a valid SQLite database object.
+ : @error s:INVALID-SQL-STATEMENT if $stmnt is not a valid sql command.
+ : @error s:INTERNAL-SQLITE-PROBLEM if there was an internal error inside SQLite
+ : library.
+ :)
+declare %an:sequential function s:execute-update(
+ $conn as xs:anyURI,
+ $sqlstr as xs:string ) as xs:integer external;
+
+(:~
+ : Returns the metadata associated to a given prepared SQLite statement.<p/>
+ :
+ : SQLite metadata is returned in the following form:
+ : <pre>
+ : {
+ : "columns" :
+ : [{
+ : "name" : <column name>,
+ : "table" : <table name>,
+ : "database" : <database name>,
+ : "type" : <type name>,
+ : "collation" : [BINARY|NOCASE|RTRIM],
+ : "nullable" : [true|false],
+ : "primary key" : [true|false],
+ : "autoincrement" : [true|false]
+ : }*]
+ : }
+ : </pre>
+ :
+ : @param $pstmnt the sql command as xs:anyURI from which metadata will be
+ : extracted.
+ :
+ : @return a object() with the associated the metadata.
+ :
+ : @error s:INVALID-PREPARED-STATEMENT if $pstmnt is not a valid SQLite prepared
+ : statement.
+ : @error s:UNAVAILABLE-METADATA if no metadata is available (SQLite library
+ : compiled without SQLITE_ENABLE_COLUMN_METADATA).
+ : @error s:INTERNAL-SQLITE-PROBLEM if there was an internal error inside SQLite
+ : library.
+ :)
+declare %an:nondeterministic function s:metadata(
+ $pstmnt as xs:anyURI ) as object() external;
+
+(:~
+ : Compiles a prepared statement based on an already connected SQLite database
+ : and a string that defines the sql command.<p/>
+ :
+ : You can use '?' in the sql command as placeholders so you will
+ : be able to bind variables later to such places.<p/>
+ :
+ : @param $conn the SQLite database object as xs:anyURI.
+ : @param $stmnt the sql command as xs:string.
+ :
+ : @return a xs:anyURI object representing the prepared statement.
+ :
+ : @error s:INVALID-SQLITE-OBJECT if $conn is not a valid SQLite database object.
+ : @error s:INVALID-SQL-STATEMENT if $stmnt is not a valid sql command.
+ : @error s:INTERNAL-SQLITE-PROBLEM if there was an internal error inside SQLite
+ : library.
+ :)
+declare %an:nondeterministic function s:prepare-statement(
+ $conn as xs:anyURI,
+ $stmnt as xs:string ) as xs:anyURI external;
+
+(:~
+ : Binds a value to a placeholder inside a prepared statement using the
+ : same type as the item given.
+ :
+ : @param $pstmnt the prepared statement already compiled as xs:anyURI.
+ : @param $param-num the placeholder position to be set.
+ : @param $val the value to be bind in such placeholder.
+ :
+ : @return nothing.
+ :
+ : @error s:INVALID-PREPARED-STATEMENT if $pstmnt is not a valid SQLite prepared
+ : statement.
+ : @error s:INVALID-PLACEHOLDER-POSITION if $param-num is not a valid position.
+ : @error s:INVALID-VALUE if $val is not a valid value.
+ : @error s:INTERNAL-SQLITE-PROBLEM if there was an internal error inside SQLite
+ : library.
+ :)
+declare %an:sequential function s:set-value(
+ $pstmnt as xs:anyURI,
+ $param-num as xs:integer,
+ $val as item() ) as empty-sequence() external;
+
+(:~
+ : Binds a boolean to a placeholder inside a prepared statement.
+ :
+ : @param $pstmnt the prepared statement already compiled as xs:anyURI.
+ : @param $param-num the placeholder position to be set.
+ : @param $val the boolean to be bind in such placeholder.
+ :
+ : @return nothing.
+ :
+ : @error s:INVALID-PREPARED-STATEMENT if $pstmnt is not a valid SQLite prepared
+ : statement.
+ : @error s:INVALID-PLACEHOLDER-POSITION if $param-num is not a valid position.
+ : @error s:INTERNAL-SQLITE-PROBLEM if there was an internal error inside SQLite
+ : library.
+ :)
+declare %an:sequential function s:set-boolean(
+ $pstmnt as xs:anyURI,
+ $param-num as xs:integer,
+ $val as xs:boolean ) as empty-sequence() external;
+
+(:~
+ : Binds a double variable to a placeholder inside a prepared statement.
+ :
+ : @param $pstmnt the prepared statement already compiled as xs:anyURI.
+ : @param $param-num the placeholder position to be set.
+ : @param $val a xs:double, xs:integer or xs:decimal to be bind in such placeholder.
+ :
+ : @return nothing.
+ :
+ : @error s:INVALID-PREPARED-STATEMENT if $pstmnt is not a valid SQLite prepared
+ : statement.
+ : @error s:INVALID-PLACEHOLDER-POSITION if $param-num is not a valid position.
+ : @error s:INVALID-VALUE if $val is not a valid numeric type.
+ : @error s:INTERNAL-SQLITE-PROBLEM if there was an internal error inside SQLite
+ : library.
+ :)
+declare %an:sequential function s:set-numeric(
+ $pstmnt as xs:anyURI,
+ $param-num as xs:integer,
+ $val as xs:anyAtomicType ) as empty-sequence() external;
+
+(:~
+ : Binds a string variable to a placeholder inside a prepared statement.
+ :
+ : @param $pstmnt the prepared statement already compiled as xs:anyURI.
+ : @param $param-num the placeholder position to be set.
+ : @param $val a string to be bind in such placeholder.
+ :
+ : @return nothing.
+ :
+ : @error s:INVALID-PREPARED-STATEMENT if $pstmnt is not a valid SQLite prepared
+ : statement.
+ : @error s:INVALID-PLACEHOLDER-POSITION if $param-num is not a valid position.
+ : @error s:INTERNAL-SQLITE-PROBLEM if there was an internal error inside SQLite
+ : library.
+ :)
+declare %an:sequential function s:set-string(
+ $pstmnt as xs:anyURI,
+ $param-num as xs:integer,
+ $val as xs:string ) as empty-sequence() external;
+
+(:~
+ : Set a null to a placeholder inside a prepared statement.
+ :
+ : @param $pstmnt the prepared statement already compiled as xs:anyURI.
+ : @param $param-num the placeholder position to be set.
+ :
+ : @return nothing.
+ :
+ : @error s:INVALID-PREPARED-STATEMENT if $pstmnt is not a valid SQLite prepared
+ : statement.
+ : @error s:INVALID-PLACEHOLDER-POSITION if $param-num is not a valid position.
+ : @error s:INTERNAL-SQLITE-PROBLEM if there was an internal error inside SQLite
+ : library.
+ :)
+declare %an:sequential function s:set-null(
+ $pstmnt as xs:anyURI,
+ $param-num as xs:integer ) as empty-sequence() external;
+
+(:~
+ : Set all parameters to null inside a prepared statement.
+ :
+ : @param $pstmnt the prepared statement already compiled as xs:anyURI.
+ :
+ : @return nothing.
+ :
+ : @error s:INVALID-PREPARED-STATEMENT if $pstmnt is not a valid SQLite prepared
+ : statement.
+ : @error s:INTERNAL-SQLITE-PROBLEM if there was an internal error inside SQLite
+ : library.
+ :)
+declare %an:sequential function s:clear-params(
+ $pstmnt as xs:anyURI ) as empty-sequence() external;
+
+(:~
+ : Close and free resources associated to a prepared statement.
+ :
+ : @param $pstmnt the prepared statement to be closed.
+ :
+ : @return nothing.
+ :
+ : @error s:INVALID-PREPARED-STATEMENT if $pstmnt is not a valid SQLite prepared
+ : statement.
+ :)
+declare %an:sequential function s:close-prepared(
+ $pstmnt as xs:anyURI ) as empty-sequence() external;
+
+(:~
+ : Execute a query (select command) over an already connected SQLite
+ : database object.
+ :
+ : @param $pstmnt the query command to be executed as xs:anyURI.
+ :
+ : @return a sequence of JSON objects representing the query results.
+ :
+ : @error s:INVALID-PREPARED-STATEMENT if $pstmnt is not a valid SQLite prepared
+ : statement.
+ : @error s:INTERNAL-SQLITE-PROBLEM if there was an internal error inside SQLite
+ : library.
+ :)
+declare %an:sequential function s:execute-query-prepared(
+ $pstmnt as xs:anyURI ) as object()* external;
+
+(:~
+ : Execute a update command over an already connected SQLite
+ : database object.
+ :
+ : @param $pstmnt the update command to be executed as xs:anyURI.
+ :
+ : @return an integer that represents the amount of rows affected.
+ :
+ : @error s:INVALID-PREPARED-STATEMENT if $pstmnt is not a valid SQLite prepared
+ : statement.
+ : @error s:INTERNAL-SQLITE-PROBLEM if there was an internal error inside SQLite
+ : library.
+ :)
+declare %an:sequential function s:execute-update-prepared(
+ $pstmnt as xs:anyURI ) as xs:integer external;
+
=== added directory 'src/sqlite_module.xq.src'
=== added file 'src/sqlite_module.xq.src/sqlite_module.cpp'
--- src/sqlite_module.xq.src/sqlite_module.cpp 1970-01-01 00:00:00 +0000
+++ src/sqlite_module.xq.src/sqlite_module.cpp 2013-09-11 04:36:11 +0000
@@ -0,0 +1,1433 @@
+/*
+ * Copyright 2012 The FLWOR Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <cstdio>
+#include <sstream>
+#include <string>
+
+#include <sqlite3.h>
+
+#include <zorba/diagnostic_list.h>
+#include <zorba/empty_sequence.h>
+#include <zorba/item_factory.h>
+#include <zorba/singleton_item_sequence.h>
+#include <zorba/user_exception.h>
+#include <zorba/util/base64_stream.h>
+#include <zorba/util/base64_util.h>
+#include <zorba/util/transcode_stream.h>
+#include <zorba/util/uuid.h>
+
+#include "sqlite_module/config.h"
+#include "sqlite_module.h"
+
+namespace zorba { namespace sqlite {
+
+// Allocating global variables
+zorba::Item SqliteModule::globalNameKey;
+zorba::Item SqliteModule::globalDatabaseKey;
+zorba::Item SqliteModule::globalTableKey;
+zorba::Item SqliteModule::globalTypeKey;
+zorba::Item SqliteModule::globalCollationKey;
+zorba::Item SqliteModule::globalNullableKey;
+zorba::Item SqliteModule::globalPrimaryKey;
+zorba::Item SqliteModule::globalAutoincKey;
+zorba::Item SqliteModule::globalAffectedRowsKey;
+
+/*******************************************************************************
+ ******************************************************************************/
+SqliteModule::SqliteModule()
+{
+ globalNameKey = Zorba::getInstance(0)->getItemFactory()->createString("name");
+ globalDatabaseKey = Zorba::getInstance(0)->getItemFactory()->createString("database");
+ globalTableKey = Zorba::getInstance(0)->getItemFactory()->createString("table");
+ globalTypeKey = Zorba::getInstance(0)->getItemFactory()->createString("type");
+ globalCollationKey = Zorba::getInstance(0)->getItemFactory()->createString("collation");
+ globalNullableKey = Zorba::getInstance(0)->getItemFactory()->createString("nullable");
+ globalPrimaryKey = Zorba::getInstance(0)->getItemFactory()->createString("primary key");
+ globalAutoincKey = Zorba::getInstance(0)->getItemFactory()->createString("autoincrement");
+ globalAffectedRowsKey = Zorba::getInstance(0)->getItemFactory()->createString("Affected Rows");
+}
+
+zorba::ExternalFunction*
+SqliteModule::getExternalFunction(const zorba::String& localName)
+{
+ FuncMap_t::iterator lIte = theFunctions.find(localName);
+
+ ExternalFunction*& lFunc = theFunctions[localName];
+
+ if (lIte == theFunctions.end())
+ {
+ if (localName == "connect")
+ {
+ lFunc = new ConnectFunction(this);
+ }
+ else if (localName == "is-connected")
+ {
+ lFunc = new IsConnectedFunction(this);
+ }
+ else if (localName == "commit")
+ {
+ lFunc = new CommitFunction(this);
+ }
+ else if (localName == "rollback")
+ {
+ lFunc = new RollbackFunction(this);
+ }
+ else if (localName == "execute-query")
+ {
+ lFunc = new ExecuteQueryFunction(this);
+ }
+ else if (localName == "execute-update")
+ {
+ lFunc = new ExecuteUpdateFunction(this);
+ }
+ else if (localName == "metadata")
+ {
+ lFunc = new MetadataFunction(this);
+ }
+ else if (localName == "prepare-statement")
+ {
+ lFunc = new PrepareStatementFunction(this);
+ }
+ else if (localName == "set-value")
+ {
+ lFunc = new SetValueFunction(this);
+ }
+ else if (localName == "set-boolean")
+ {
+ lFunc = new SetBooleanFunction(this);
+ }
+ else if (localName == "set-numeric")
+ {
+ lFunc = new SetNumericFunction(this);
+ }
+ else if (localName == "set-string")
+ {
+ lFunc = new SetStringFunction(this);
+ }
+ else if (localName == "set-null")
+ {
+ lFunc = new SetNullFunction(this);
+ }
+ else if (localName == "clear-params")
+ {
+ lFunc = new ClearParamsFunction(this);
+ }
+ else if (localName == "close-prepared")
+ {
+ lFunc = new ClosePreparedFunction(this);
+ }
+ else if (localName == "execute-query-prepared")
+ {
+ lFunc = new ExecuteQueryPreparedFunction(this);
+ }
+ else if (localName == "execute-update-prepared")
+ {
+ lFunc = new ExecuteUpdatePreparedFunction(this);
+ }
+ }
+
+ return lFunc;
+ }
+
+ void SqliteModule::destroy()
+ {
+ delete this;
+ }
+
+ SqliteModule::~SqliteModule()
+ {
+ for (FuncMap_t::const_iterator lIter = theFunctions.begin();
+ lIter != theFunctions.end(); ++lIter)
+ {
+ delete lIter->second;
+ }
+ theFunctions.clear();
+ }
+
+ zorba::Item&
+ SqliteModule::getGlobalKey(GLOBAL_KEYS g)
+ {
+ switch(g)
+ {
+ case NAME: return globalNameKey;
+ case DATABASE: return globalDatabaseKey;
+ case TABLE: return globalTableKey;
+ case TYPE: return globalTypeKey;
+ case COLLATION: return globalCollationKey;
+ case NULLABLE: return globalNullableKey;
+ case PRIMARY_KEY: return globalPrimaryKey;
+ case AUTOINC: return globalAutoincKey;
+ case AFFECTED_ROWS: return globalAffectedRowsKey;
+ // Should never touch this case but still ...
+ default: return globalNameKey;
+ }
+ }
+
+ /***********************
+ * ConnMap *
+ ***********************/
+
+ ConnMap::ConnMap(StmtMap* stmtMap)
+ {
+ ConnMap::connMap = new ConnMap_t();
+ sMap = stmtMap;
+ }
+
+ bool
+ ConnMap::storeConn(const std::string& aKeyName, sqlite3* sql)
+ {
+ std::pair<ConnMap_t::iterator,bool> ret;
+ ret = connMap->insert(std::pair<std::string, sqlite3 *>(aKeyName, sql));
+ return ret.second;
+ }
+
+ sqlite3*
+ ConnMap::getConn(const std::string& aKeyName)
+ {
+ ConnMap_t::iterator lIter = connMap->find(aKeyName);
+
+ if(lIter == connMap->end())
+ return NULL;
+
+ sqlite3 *lSql = lIter->second;
+
+ return lSql;
+ }
+
+ bool
+ ConnMap::deleteConn(const std::string& aKeyName)
+ {
+ ConnMap::ConnMap_t::iterator lIter = connMap->find(aKeyName);
+
+ if(lIter == connMap->end())
+ return false;
+
+ if(sMap != NULL)
+ sMap->deleteAllForConn(lIter->second);
+ sqlite3_close(lIter->second);
+ connMap->erase(lIter);
+ return true;
+ }
+
+ void
+ ConnMap::destroy() throw()
+ {
+ if(connMap)
+ {
+ if(sMap)
+ sMap->deleteAllForConn(NULL); // delete all prep-statements
+
+ for (ConnMap_t::iterator lIter = connMap->begin();
+ lIter != connMap->end(); )
+ {
+ sqlite3_close(lIter->second);
+ connMap->erase(lIter++);
+ }
+ // connMap->clear();
+ delete connMap;
+ }
+ delete this;
+ }
+
+ ConnMap::~ConnMap(){ }
+
+/***********************
+ * StmtMap *
+***********************/
+
+ StmtMap::StmtMap()
+ {
+ StmtMap::stmtMap = new StmtMap_t();
+ }
+
+ bool
+ StmtMap::storeStmt(const std::string& aKeyName, sqlite3_stmt* stmt)
+ {
+ std::pair<StmtMap_t::iterator,bool> ret;
+ ret = stmtMap->insert(std::pair<std::string, sqlite3_stmt *>(aKeyName, stmt));
+ return ret.second;
+ }
+
+ sqlite3_stmt*
+ StmtMap::getStmt(const std::string& aKeyName)
+ {
+ StmtMap_t::iterator lIter = stmtMap->find(aKeyName);
+
+ if(lIter == stmtMap->end())
+ return NULL;
+
+ sqlite3_stmt *lStmt = lIter->second;
+
+ return lStmt;
+ }
+
+ bool
+ StmtMap::deleteStmt(const std::string& aKeyName)
+ {
+ StmtMap::StmtMap_t::iterator lIter = stmtMap->find(aKeyName);
+
+ if(lIter == stmtMap->end())
+ return false;
+
+ sqlite3_finalize(lIter->second);
+ stmtMap->erase(lIter);
+ return true;
+ }
+
+ void
+ StmtMap::destroy() throw()
+ {
+ if(stmtMap)
+ {
+ for (StmtMap_t::iterator lIter = stmtMap->begin();
+ lIter != stmtMap->end(); )
+ {
+ sqlite3_finalize(lIter->second);
+ stmtMap->erase(lIter++);
+ }
+ delete stmtMap;
+ }
+ delete this;
+ }
+
+ void
+ StmtMap::deleteAllForConn(sqlite3* c)
+ {
+ StmtMap_t::iterator it;
+ for(it = stmtMap->begin();
+ it != stmtMap->end(); )
+ {
+ if((c == NULL) || (sqlite3_db_handle(it->second) == c))
+ {
+ sqlite3_finalize(it->second);
+ stmtMap->erase(it++);
+ } else
+ it++;
+ }
+ }
+
+ StmtMap::~StmtMap(){ }
+
+/*******************************************************************************
+ * SqliteFunction *
+ *******************************************************************************/
+ SqliteFunction::SqliteFunction(const SqliteModule* aModule)
+ : theModule(aModule) {}
+
+ SqliteFunction::~SqliteFunction(){}
+
+ ConnMap*
+ SqliteFunction::getConnectionMap(const zorba::DynamicContext* aDctx){
+ DynamicContext* lDynCtx = const_cast<DynamicContext*>(aDctx);
+ ConnMap* lConnMap;
+ StmtMap* lStmtMap;
+ if(!(lConnMap = dynamic_cast<ConnMap*>(lDynCtx->getExternalFunctionParameter("sqliteConnMap"))))
+ {
+ lStmtMap = getStatementMap(lDynCtx);
+ lConnMap = new ConnMap(lStmtMap);
+ lDynCtx->addExternalFunctionParameter("sqliteConnMap", lConnMap);
+ }
+ return lConnMap;
+ }
+
+ StmtMap*
+ SqliteFunction::getStatementMap(const zorba::DynamicContext* aDctx){
+ DynamicContext* lDynCtx = const_cast<DynamicContext*>(aDctx);
+ StmtMap* lStmtMap;
+ if(!(lStmtMap = dynamic_cast<StmtMap*>(lDynCtx->getExternalFunctionParameter("sqliteStmtMap"))))
+ {
+ lStmtMap = new StmtMap();
+ lDynCtx->addExternalFunctionParameter("sqliteStmtMap", lStmtMap);
+ }
+ return lStmtMap;
+ }
+
+ std::string
+ SqliteFunction::createUUID(){
+ uuid lUUID;
+ uuid::create(&lUUID);
+ std::stringstream lStream;
+ lStream << lUUID;
+ return lStream.str();
+ }
+
+ sqlite3_stmt*
+ SqliteFunction::createPreparedStatement(const zorba::DynamicContext* aDctx,
+ std::string aUUID, std::string aQry){
+ sqlite3 *lDb;
+ sqlite3_stmt *lPstmt;
+ int lRc;
+ const char *lTail;
+ ConnMap* lConnMap = SqliteFunction::getConnectionMap(aDctx);
+
+ lDb = lConnMap->getConn(aUUID);
+ if(lDb == NULL){
+ // throw error, ID not recognized
+ throwError("INVALID-SQLITE-OBJECT", getErrorMessage("INVALID-SQLITE-OBJECT"));
+ }
+
+ lRc = sqlite3_prepare_v2(lDb, aQry.c_str(), aQry.size(), &lPstmt, &lTail);
+ if(lRc != 0 && lPstmt != NULL){
+ sqlite3_finalize(lPstmt);
+ }
+ if(lRc == SQLITE_ERROR) {
+ std::string lErr = getErrorMessage("INVALID-SQL-STATEMENT");
+ lErr += "; ";
+ lErr += sqlite3_errmsg(lDb);
+ throwError("INVALID-SQL-STATEMENT", lErr.c_str());
+ } else
+ checkForError(lRc, 0, lDb);
+
+ return lPstmt;
+ }
+
+ void
+ SqliteFunction::setValueToStatement(const zorba::DynamicContext* aDctx,
+ std::string aUUID,
+ int aPos, bool aVal)
+ {
+ sqlite3_stmt *lPstmt;
+ StmtMap *stmtMap = getStatementMap(aDctx);
+ int lRc;
+
+ // Get the prepared statement and then set the value
+ lPstmt = stmtMap->getStmt(aUUID);
+ if(lPstmt == NULL){
+ throwError("INVALID-PREPARED-STATEMENT",
+ getErrorMessage("INVALID-PREPARED-STATEMENT"));
+ }
+ lRc = sqlite3_bind_int(lPstmt, aPos, (aVal==true)?1:0);
+ if(lRc == SQLITE_RANGE)
+ throwError("INVALID-PLACEHOLDER-POSITION",
+ getErrorMessage("INVALID-PLACEHOLDER-POSITION"));
+ else
+ checkForError(lRc, 0, sqlite3_db_handle(lPstmt));
+ }
+
+ void
+ SqliteFunction::setValueToStatement(const zorba::DynamicContext* aDctx,
+ std::string aUUID,
+ int aPos,
+ int aVal)
+ {
+ sqlite3_stmt *lPstmt;
+ StmtMap *stmtMap = getStatementMap(aDctx);
+ int lRc;
+
+ // Get the prepared statement and then set the value
+ lPstmt = stmtMap->getStmt(aUUID);
+ if(lPstmt == NULL){
+ throwError("INVALID-PREPARED-STATEMENT",
+ getErrorMessage("INVALID-PREPARED-STATEMENT"));
+ }
+ lRc = sqlite3_bind_int(lPstmt, aPos, aVal);
+ if(lRc == SQLITE_RANGE)
+ throwError("INVALID-PLACEHOLDER-POSITION",
+ getErrorMessage("INVALID-PLACEHOLDER-POSITION"));
+ else
+ checkForError(lRc, 0, sqlite3_db_handle(lPstmt));
+ }
+
+ void
+ SqliteFunction::setValueToStatement(const zorba::DynamicContext* aDctx,
+ std::string aUUID,
+ int aPos,
+ double aVal)
+ {
+ sqlite3_stmt *lPstmt;
+ StmtMap *stmtMap = getStatementMap(aDctx);\
+ int lRc;
+
+ // Get the prepared statement and then set the value
+ lPstmt = stmtMap->getStmt(aUUID);
+ if(lPstmt == NULL){
+ throwError("INVALID-PREPARED-STATEMENT",
+ getErrorMessage("INVALID-PREPARED-STATEMENT"));
+ }
+ lRc = sqlite3_bind_double(lPstmt, aPos, aVal);
+ if(lRc == SQLITE_RANGE)
+ throwError("INVALID-PLACEHOLDER-POSITION",
+ getErrorMessage("INVALID-PLACEHOLDER-POSITION"));
+ else
+ checkForError(lRc, 0, sqlite3_db_handle(lPstmt));
+ }
+
+ void
+ SqliteFunction::setValueToStatement(const zorba::DynamicContext* aDctx,
+ std::string aUUID,
+ int aPos,
+ std::string aVal)
+ {
+ sqlite3_stmt *lPstmt;
+ StmtMap *stmtMap = getStatementMap(aDctx);
+ int lRc;
+
+ // Get the prepared statement and then set the value
+ lPstmt = stmtMap->getStmt(aUUID);
+ if(lPstmt == NULL){
+ throwError("INVALID-PREPARED-STATEMENT",
+ getErrorMessage("INVALID-PREPARED-STATEMENT"));
+ }
+ lRc = sqlite3_bind_text(lPstmt, aPos, aVal.c_str(), aVal.size(), SQLITE_TRANSIENT);
+ if(lRc == SQLITE_RANGE)
+ throwError("INVALID-PLACEHOLDER-POSITION",
+ getErrorMessage("INVALID-PLACEHOLDER-POSITION"));
+ else
+ checkForError(lRc, 0, sqlite3_db_handle(lPstmt));
+ }
+
+ void
+ SqliteFunction::setValueToStatement(const zorba::DynamicContext* aDctx,
+ std::string aUUID,
+ int aPos)
+ {
+ sqlite3_stmt *lPstmt;
+ StmtMap *stmtMap = getStatementMap(aDctx);
+ int lRc;
+
+ // Get the prepared statement and then set the value
+ lPstmt = stmtMap->getStmt(aUUID);
+ if(lPstmt == NULL){
+ throwError("INVALID-PREPARED-STATEMENT",
+ getErrorMessage("INVALID-PREPARED-STATEMENT"));
+ }
+ lRc = sqlite3_bind_null(lPstmt, aPos);
+ if(lRc == SQLITE_RANGE)
+ throwError("INVALID-PLACEHOLDER-POSITION",
+ getErrorMessage("INVALID-PLACEHOLDER-POSITION"));
+ else
+ checkForError(lRc, 0, sqlite3_db_handle(lPstmt));
+ }
+
+ void
+ SqliteFunction::clearValues(const zorba::DynamicContext* aDctx,
+ std::string aUUID)
+ {
+ sqlite3_stmt *lPstmt;
+ StmtMap *stmtMap = getStatementMap(aDctx);
+
+ // get the prepared statement if exists
+ lPstmt = stmtMap->getStmt(aUUID);
+ if(lPstmt == NULL){
+ throwError("INVALID-PREPARED-STATEMENT",
+ getErrorMessage("INVALID-PREPARED-STATEMENT"));
+ }
+ sqlite3_clear_bindings(lPstmt);
+ }
+
+ String
+ SqliteFunction::getURI() const
+ {
+ return theModule->getURI();
+ }
+
+ void
+ SqliteFunction::throwError(
+ const char* aLocalName,
+ const char* aErrorMessage)
+ {
+ String errNS(SqliteModule::getModuleURI());
+ Item errQName = SqliteModule::getItemFactory()->createQName(
+ errNS, aLocalName);
+ throw USER_EXCEPTION(errQName, aErrorMessage);
+ }
+
+ void
+ SqliteFunction::checkForError(
+ int aErrNo,
+ const char* aLocalName,
+ sqlite3 *sql)
+ {
+ if (aErrNo != SQLITE_OK)
+ {
+ if (!aLocalName)
+ {
+ throwError("INTERNAL-SQLITE-PROBLEM", sqlite3_errmsg(sql));
+ }
+ else
+ {
+ throwError(aLocalName, sqlite3_errmsg(sql));
+ }
+ }
+ }
+
+ zorba::Item
+ SqliteFunction::getOneItem(const Arguments_t& aArgs, int aIndex)
+ {
+ Item lItem;
+ Iterator_t args_iter = aArgs[aIndex]->getIterator();
+ args_iter->open();
+ args_iter->next(lItem);
+ args_iter->close();
+
+ return lItem;
+ }
+
+ int
+ SqliteFunction::strToInt(std::string str){
+ int iInt;
+ sscanf(str.c_str(), "%d", &iInt);
+ return iInt;
+ }
+
+ double
+ SqliteFunction::strToDouble(std::string str){
+ double dDbl;
+ sscanf(str.c_str(), "%lf", &dDbl);
+ return dDbl;
+ }
+
+ const char *
+ SqliteFunction::getErrorMessage(std::string error){
+ if(error == "CANT-OPEN-DB")
+ {
+ return "Database file does not exist or it is not possible to open it";
+ }
+ else if(error == "INVALID-SQLITE-OBJECT")
+ {
+ return "Connection ID passed is not valid";
+ }
+ else if(error == "INVALID-SQL-STATEMENT")
+ {
+ return "Statement passed is not a valid SQL statement";
+ }
+ else if(error == "INVALID-PREPARED-STATEMENT")
+ {
+ return "Prepared statement passed is not valid";
+ }
+ else if(error == "INVALID-PLACEHOLDER-POSITION")
+ {
+ return "Parameter position passed is not valid";
+ }
+ else if(error == "INVALID-VALUE")
+ {
+ return "Parameter passed is not a valid number";
+ }
+ else if(error == "UNKNOWN-OPTION")
+ {
+ return "Parameter passed is not a valid value";
+ }
+#ifndef SQLITE_WITH_FILE_ACCESS
+ else if(error == "COMPILED-WITHOUT-DISK-ACCESS")
+ {
+ return "Only in-memory databases are allowed (Module built without filesystem access)";
+ }
+#endif /* not SQLITE_WITH_FILE_ACCESS */
+#ifndef ZORBA_SQLITE_HAVE_METADATA
+ else if(error == "UNAVAILABLE-METADATA")
+ {
+ return "Metadata not found (SQLite built without SQLITE_ENABLE_COLUMN_METADATA)";
+ }
+#endif /* not ZORBA_SQLITE_HAVE_METADATA */
+ else if(error == "INTERNAL-SQLITE-PROBLEM")
+ {
+ return "Internal error ocurred";
+ }
+ return "";
+ }
+
+ /********************
+ * Sqlite Options *
+ ********************/
+
+ SqliteOptions::SqliteOptions()
+ : theOpenReadOnly(false),
+ theOpenCreate(true),
+ theOpenNoMutex(false),
+ theOpenSharedCache(false) {}
+
+ void
+ SqliteOptions::setValues(sqlite3* aSqlite)
+ {
+ // TODO: check if it is possible to get those values from the sqlite3 pointer
+ }
+
+ void
+ SqliteOptions::setValues(Item& aOptions)
+ {
+ Item lItemJSONKey;
+
+ Iterator_t lIterKeys = aOptions.getObjectKeys();
+ lIterKeys->open();
+ while (lIterKeys->next(lItemJSONKey))
+ {
+ Item lOptionValue;
+ lOptionValue = aOptions.getObjectValue(lItemJSONKey.getStringValue());
+
+ if (lItemJSONKey.getStringValue() == "open-read-only")
+ {
+ theOpenReadOnly = lOptionValue.getBooleanValue() == true;
+ }
+ else if (lItemJSONKey.getStringValue() == "open-create")
+ {
+ theOpenCreate = lOptionValue.getBooleanValue();
+ }
+ else if (lItemJSONKey.getStringValue() == "open-no-mutex")
+ {
+ theOpenNoMutex = lOptionValue.getBooleanValue();
+ }
+ else if(lItemJSONKey.getStringValue() == "open-shared-cache")
+ {
+ theOpenSharedCache = lOptionValue.getBooleanValue();
+ } else
+ // Not sure if I should stop here in case that any option
+ // are not in the list
+ SqliteFunction::throwError("UNKNOWN-OPTION",
+ (std::string(SqliteFunction::getErrorMessage("UNKNOWN-OPTION")) + " - " +
+ lItemJSONKey.getStringValue().str()).c_str());
+ }
+ lIterKeys->close();
+ }
+
+ int
+ SqliteOptions::getOptionsAsInt(){
+ int opts = 0;
+ if(theOpenCreate)
+ opts |= SQLITE_OPEN_CREATE;
+ if(theOpenReadOnly)
+ opts |= SQLITE_OPEN_READONLY;
+ else
+ opts |= SQLITE_OPEN_READWRITE;
+ if(theOpenNoMutex)
+ opts |= SQLITE_OPEN_NOMUTEX;
+ if(theOpenSharedCache)
+ opts |= SQLITE_OPEN_SHAREDCACHE;
+ return opts;
+ }
+
+ std::string
+ SqliteOptions::getOptionsAsString(){
+ std::string res;
+ bool somethingthere = false;
+ if(theOpenCreate)
+ {
+ res += "SQLITE_OPEN_CREATE";
+ somethingthere = true;
+ }
+ if(theOpenReadOnly)
+ {
+ if(somethingthere)
+ {
+ res += " | ";
+ }
+ res += "SQLITE_OPEN_READONLY";
+ somethingthere = true;
+ }
+ else
+ {
+ if(somethingthere)
+ {
+ res += " | ";
+ }
+ res += "SQLITE_OPEN_READWRITE";
+ somethingthere = true;
+ }
+ if(theOpenNoMutex)
+ {
+ if(somethingthere)
+ {
+ res += " | ";
+ }
+ res += "SQLITE_OPEN_NOMUTEX";
+ somethingthere = true;
+ }
+ if(theOpenSharedCache)
+ {
+ if(somethingthere)
+ {
+ res += " | ";
+ }
+ res += "SQLITE_OPEN_SHAREDCACHE";
+ }
+ return res;
+ }
+
+/*******************************************************************************
+ * JSONItemSequence::JSONIterator *
+ ******************************************************************************/
+ void JSONItemSequence::JSONIterator::open(){
+ zorba::Item lColumnName;
+ char* lColumnNameChar;
+ // Get data and create the column names
+ if(theStmt != NULL){
+ theRc = sqlite3_step(theStmt);
+ SqliteFunction::checkForError((theRc==SQLITE_ROW || theRc==SQLITE_DONE)?0:-1, 0,
+ sqlite3_db_handle(theStmt));
+ if(theRc == SQLITE_DONE)
+ isUpdateResult = true;
+ theFactory = Zorba::getInstance(0)->getItemFactory();
+
+ theColumnCount = sqlite3_column_count(theStmt);
+ if(theColumnCount > 0)
+ {
+ for(int i=0; i<theColumnCount; i++)
+ {
+ const char* lpChar = sqlite3_column_name(theStmt, i);
+ int lLen = strlen(lpChar);
+ lColumnNameChar = new char[lLen+1];
+ memcpy(lColumnNameChar, lpChar, lLen);
+ lColumnNameChar[lLen] = '\0';
+ lColumnName = theFactory->createString(lColumnNameChar);
+ theColumnNamesZString.push_back(lColumnName);
+ delete lColumnNameChar;
+ }
+ }
+ }
+ }
+
+ bool JSONItemSequence::JSONIterator::next(zorba::Item& aItem){
+ int aType, aSize;
+ zorba::Item aValue;
+ std::vector<std::pair<zorba::Item, zorba::Item> > elements;
+ const char *aBlobPtr;
+
+ if(theRc == SQLITE_ROW){
+ // get the resulting data from the statement
+ // in a key = value fashion
+ for(int i=0; i<theColumnCount; i++){
+ aType = sqlite3_column_type(theStmt, i);
+ switch(aType){
+ case SQLITE_NULL:
+ aValue = theFactory->createJSONNull();
+ break;
+ case SQLITE_INTEGER:
+ aValue = theFactory->createInt(sqlite3_column_int(theStmt, i));
+ break;
+ case SQLITE_FLOAT:
+ aValue = theFactory->createDouble(sqlite3_column_double(theStmt, i));
+ break;
+ case SQLITE_BLOB:
+ aSize = sqlite3_column_bytes(theStmt, i);
+ aBlobPtr = (const char *)sqlite3_column_blob(theStmt, i);
+ aValue = theFactory->createBase64Binary(aBlobPtr, aSize, true);
+ break;
+ default:
+ std::string str = std::string((const char *)sqlite3_column_text(theStmt, i));
+ aValue = theFactory->createString(
+ zorba::String(str)
+ );
+ }
+ elements.push_back(std::pair<zorba::Item, zorba::Item>(theColumnNamesZString.at(i), aValue));
+ }
+ aItem = theFactory->createJSONObject(elements);
+ elements.clear();
+ // Get more data if available
+ theRc = sqlite3_step(theStmt);
+ return true;
+ } else if(isUpdateResult && theRc == SQLITE_DONE){
+ // we have a prepared statement that represents a UPDATE and it's already executed
+ aValue = theFactory->createInt(sqlite3_changes(sqlite3_db_handle(theStmt)));
+ elements.push_back(std::pair<zorba::Item, zorba::Item>(SqliteModule::getGlobalKey(SqliteModule::AFFECTED_ROWS), aValue));
+ aItem = theFactory->createJSONObject(elements);
+ elements.clear();
+ // be sure it won't be back in here
+ theRc = SQLITE_ERROR;
+ return true;
+ } else
+ // There is no data to return anymore
+ return false;
+ }
+
+ void JSONItemSequence::JSONIterator::close(){
+ // Set the Rc to "no more data" and clear the variables
+ theRc = SQLITE_ERROR;
+ if(theColumnCount > 0)
+ {
+ theColumnNamesZString.clear();
+ }
+ theColumnCount = 0;
+ if(theStmt != NULL)
+ sqlite3_reset(theStmt);
+ }
+
+/*******************************************************************************
+ * JSONMetadataItemSequence::JSONMetadataIterator *
+ ******************************************************************************/
+#ifdef ZORBA_SQLITE_HAVE_METADATA
+ void JSONMetadataItemSequence::JSONMetadataIterator::open(){
+ // Get data and create the column names
+ if(theStmt != NULL){
+ theRc = sqlite3_step(theStmt);
+ SqliteFunction::checkForError((theRc==SQLITE_ROW || theRc==SQLITE_DONE)?0:-1, 0,
+ sqlite3_db_handle(theStmt));
+ theFactory = Zorba::getInstance(0)->getItemFactory();
+
+ theColumnCount = sqlite3_column_count(theStmt);
+ if(theColumnCount > 0)
+ {
+ theActualColumn = 0;
+ theRc = SQLITE_ROW;
+ } else
+ theRc = SQLITE_ERROR;
+ } else
+ theRc = SQLITE_ERROR;
+ }
+
+ bool JSONMetadataItemSequence::JSONMetadataIterator::next(zorba::Item& aItem){
+ //zorba::Item aKey;
+ zorba::Item aValue;
+ std::vector<std::pair<zorba::Item, zorba::Item> > elements;
+ sqlite3 *lDbHandle;
+ const char *lDbName;
+ const char *lTableName;
+ const char *lDataType;
+ const char *lCollSequence;
+ const char *lOriginName;
+ int lNotNull, lPrimaryKey, lAutoinc, lRc;
+
+ if(theRc == SQLITE_ROW){
+ // Get the metadata for 'theActualColumn' column
+ // in a key = value fashion
+ lDbHandle = sqlite3_db_handle(theStmt);
+ lDbName = sqlite3_column_database_name(theStmt, theActualColumn);
+ lTableName = sqlite3_column_table_name(theStmt, theActualColumn);
+ lOriginName = sqlite3_column_origin_name(theStmt, theActualColumn);
+ lRc = sqlite3_table_column_metadata(lDbHandle,
+ lDbName,
+ lTableName,
+ lOriginName,
+ &lDataType,
+ &lCollSequence,
+ &lNotNull,
+ &lPrimaryKey,
+ &lAutoinc);
+ if(lRc != 0)
+ SqliteFunction::throwError(0, sqlite3_errmsg(lDbHandle));
+ aValue = theFactory->createString(lOriginName);
+ elements.push_back(std::pair<zorba::Item, zorba::Item>(SqliteModule::getGlobalKey(SqliteModule::NAME), aValue));
+ aValue = theFactory->createString(lDbName);
+ elements.push_back(std::pair<zorba::Item, zorba::Item>(SqliteModule::getGlobalKey(SqliteModule::DATABASE), aValue));
+ aValue = theFactory->createString(lTableName);
+ elements.push_back(std::pair<zorba::Item, zorba::Item>(SqliteModule::getGlobalKey(SqliteModule::TABLE), aValue));
+ aValue = theFactory->createString(lDataType);
+ elements.push_back(std::pair<zorba::Item, zorba::Item>(SqliteModule::getGlobalKey(SqliteModule::TYPE), aValue));
+ aValue = theFactory->createString(lCollSequence);
+ elements.push_back(std::pair<zorba::Item, zorba::Item>(SqliteModule::getGlobalKey(SqliteModule::COLLATION), aValue));
+ aValue = theFactory->createBoolean((lNotNull==0)?false:true);
+ elements.push_back(std::pair<zorba::Item, zorba::Item>(SqliteModule::getGlobalKey(SqliteModule::NULLABLE), aValue));
+ aValue = theFactory->createBoolean((lPrimaryKey==0)?false:true);
+ elements.push_back(std::pair<zorba::Item, zorba::Item>(SqliteModule::getGlobalKey(SqliteModule::PRIMARY_KEY), aValue));
+ aValue = theFactory->createBoolean((lAutoinc==0)?false:true);
+ elements.push_back(std::pair<zorba::Item, zorba::Item>(SqliteModule::getGlobalKey(SqliteModule::AUTOINC), aValue));
+ aItem = theFactory->createJSONObject(elements);
+ elements.clear();
+ // Get more data if available
+ theActualColumn++;
+ if(theActualColumn >= theColumnCount)
+ theRc = SQLITE_ERROR;
+ else
+ theRc = SQLITE_ROW;
+ return true;
+ } else
+ // There is no data to return anymore
+ return false;
+ }
+
+ void JSONMetadataItemSequence::JSONMetadataIterator::close(){
+ // Set the Rc to "no more data" and clear the variables
+ theRc = SQLITE_ERROR;
+ theColumnCount = 0;
+ if(theStmt != NULL)
+ sqlite3_reset(theStmt);
+ }
+#endif
+
+/*******************************************************************************
+ ******************************************************************************/
+ zorba::ItemSequence_t
+ ConnectFunction::evaluate(
+ const Arguments_t& aArgs,
+ const zorba::StaticContext* aSctx,
+ const zorba::DynamicContext* aDctx) const
+ {
+ sqlite3 *lSqldb = NULL;
+ int lRc;
+ ConnMap* lConnMap = getConnectionMap(aDctx);
+ Item lItemName = getOneItem(aArgs, 0);
+ Item lItemOpts;
+ std::string lStrUUID;
+ std::string lDbName;
+ SqliteOptions lOptions;
+
+ if(aArgs.size() == 2){
+ // add code to include options
+ lItemOpts = getOneItem(aArgs, 1);
+ lOptions.setValues(lItemOpts);
+ }
+
+ // Connect to the specified location with the specified options
+ lDbName = lItemName.getStringValue().str();
+ if(lDbName == "")
+ lDbName = std::string(":memory:");
+
+#ifndef SQLITE_WITH_FILE_ACCESS
+ if (lDbName != ":memory:") {
+ throwError("COMPILED-WITHOUT-DISK-ACCESS",
+ getErrorMessage("COMPILED-WITHOUT-DISK-ACCESS"));
+ }
+#endif /* not SQLITE_WITH_FILE_ACCESS */
+ lRc = sqlite3_open_v2(lDbName.c_str(), &lSqldb, lOptions.getOptionsAsInt(), NULL);
+ // Store the UUID for this connection and return it
+ lStrUUID = createUUID();
+ lConnMap->storeConn(lStrUUID, lSqldb);
+ if(lRc == SQLITE_CANTOPEN)
+ throwError("CANT-OPEN-DB", getErrorMessage("CANT-OPEN-DB"));
+ else
+ checkForError(lRc, 0, lSqldb);
+
+ return ItemSequence_t(new SingletonItemSequence(SqliteModule::getItemFactory()->createAnyURI(lStrUUID)));
+ }
+
+/*******************************************************************************
+ ******************************************************************************/
+ zorba::ItemSequence_t
+ IsConnectedFunction::evaluate(
+ const Arguments_t& aArgs,
+ const zorba::StaticContext* aSctx,
+ const zorba::DynamicContext* aDctx) const
+ {
+ sqlite3 *lSqldb;
+ ConnMap* lConnMap = getConnectionMap(aDctx);
+ Item lItemRes;
+ Item lItemUUID = getOneItem(aArgs, 0);
+
+ // Look for the UUID into the Connection Map
+ // if it is in there means that you have it connected
+ lSqldb = lConnMap->getConn(lItemUUID.getStringValue().str());
+ if(lSqldb == NULL){
+ lItemRes = SqliteModule::getItemFactory()->createBoolean(false);
+ } else {
+ lItemRes = SqliteModule::getItemFactory()->createBoolean(true);
+ }
+
+ return ItemSequence_t(new SingletonItemSequence(lItemRes));
+ }
+
+/*******************************************************************************
+ ******************************************************************************/
+ zorba::ItemSequence_t
+ CommitFunction::evaluate(
+ const Arguments_t& aArgs,
+ const zorba::StaticContext* aSctx,
+ const zorba::DynamicContext* aDctx) const
+ {
+ sqlite3 *lDb;
+ Item lItemUUID = getOneItem(aArgs, 0);
+ ConnMap* lConnMap = getConnectionMap(aDctx);
+
+ lDb = lConnMap->getConn(lItemUUID.getStringValue().str());
+ if(lDb == NULL)
+ throwError("INVALID-SQLITE-OBJECT", getErrorMessage("INVALID-SQLITE-OBJECT"));
+
+ return ItemSequence_t(new SingletonItemSequence(lItemUUID));
+ }
+
+/*******************************************************************************
+ ******************************************************************************/
+ zorba::ItemSequence_t
+ RollbackFunction::evaluate(
+ const Arguments_t& aArgs,
+ const zorba::StaticContext* aSctx,
+ const zorba::DynamicContext* aDctx) const
+ {
+ sqlite3 *lDb;
+ Item lItemUUID = getOneItem(aArgs, 0);
+ ConnMap* lConnMap = getConnectionMap(aDctx);
+
+ lDb = lConnMap->getConn(lItemUUID.getStringValue().str());
+ if(lDb == NULL)
+ throwError("INVALID-SQLITE-OBJECT", getErrorMessage("INVALID-SQLITE-OBJECT"));
+
+ return ItemSequence_t(new SingletonItemSequence(lItemUUID));
+ }
+
+/*******************************************************************************
+ ******************************************************************************/
+ zorba::ItemSequence_t
+ ExecuteQueryFunction::evaluate(
+ const Arguments_t& aArgs,
+ const zorba::StaticContext* aSctx,
+ const zorba::DynamicContext* aDctx) const
+ {
+ sqlite3_stmt *lPstmt;
+ Item lItemUUID = getOneItem(aArgs, 0);
+ Item lItemQry = getOneItem(aArgs, 1);
+ StmtMap *stmtMap = getStatementMap(aDctx);
+ std::string lStrUUID;
+
+ // Create the prepared statement with the UUID and Query passed
+ lPstmt = createPreparedStatement(aDctx, lItemUUID.getStringValue().str(),
+ lItemQry.getStringValue().str());
+ lStrUUID = createUUID();
+ stmtMap->storeStmt(lStrUUID, lPstmt);
+
+ // Once we got the SQL Query executed just pass it to the JSON Sequence
+ // so it will return what we need to the user
+ std::unique_ptr<JSONItemSequence> lSeq(new JSONItemSequence(lPstmt));
+ return ItemSequence_t(lSeq.release());
+ }
+
+/*******************************************************************************
+ ******************************************************************************/
+ zorba::ItemSequence_t
+ ExecuteUpdateFunction::evaluate(
+ const Arguments_t& aArgs,
+ const zorba::StaticContext* aSctx,
+ const zorba::DynamicContext* aDctx) const
+ {
+ sqlite3_stmt *lPstmt;
+ Item lItemUUID = getOneItem(aArgs, 0);
+ Item lItemQry = getOneItem(aArgs, 1);
+ Item lItemRes;
+ Item lItemJSONKey;
+ StmtMap *stmtMap = getStatementMap(aDctx);
+ std::string lStrUUID;
+
+ // Create the prepared statement with the UUID and Query passed
+ lPstmt = createPreparedStatement(aDctx, lItemUUID.getStringValue().str(),
+ lItemQry.getStringValue().str());
+ lStrUUID = createUUID();
+ stmtMap->storeStmt(lStrUUID, lPstmt);
+
+ // Once we got the SQL Query executed just pass it to the JSON Sequence
+ // after we get the result we convert it to a integer Item
+ std::unique_ptr<JSONItemSequence> lSeq(new JSONItemSequence(lPstmt));
+ Iterator_t lIter = lSeq->getIterator();
+ lIter->open();
+ lIter->next(lItemRes);
+ lIter->close();
+ Iterator_t lIterKeys = lItemRes.getObjectKeys();
+ lIterKeys->open();
+ lIterKeys->next(lItemJSONKey);
+ lIterKeys->close();
+ Item lItemValue = lItemRes.getObjectValue(lItemJSONKey.getStringValue());
+ return ItemSequence_t(new SingletonItemSequence(lItemValue));
+ }
+
+/*******************************************************************************
+ ******************************************************************************/
+ zorba::ItemSequence_t
+ MetadataFunction::evaluate(
+ const Arguments_t& aArgs,
+ const zorba::StaticContext* aSctx,
+ const zorba::DynamicContext* aDctx) const
+ {
+#ifdef ZORBA_SQLITE_HAVE_METADATA
+ sqlite3_stmt *lPstmt;
+ zorba::Item lItemPstmt = getOneItem(aArgs, 0);
+ zorba::Item lVecItem, lJSONKey, lJSONArray, lJSONRes;
+ StmtMap *lStmtMap = getStatementMap(aDctx);
+ std::vector<zorba::Item> lItems;
+ std::vector<std::pair<zorba::Item, zorba::Item> > lVectorRes;
+ ItemFactory* lFactory;
+ Iterator_t lIter;
+
+ lFactory = SqliteModule::getItemFactory();
+ // Get the prepared statement
+ lPstmt = lStmtMap->getStmt(lItemPstmt.getStringValue().str());
+ if(lPstmt == NULL){
+ // No valid prepared statement id passed
+ throwError("INVALID-PREPARED-STATEMENT",
+ getErrorMessage("INVALID-PREPARED-STATEMENT"));
+ }
+
+ // So now create a JSONMetadataItemSequence and let it
+ // get us what we need
+ std::unique_ptr<JSONMetadataItemSequence> lSeq(new JSONMetadataItemSequence(lPstmt));
+ lIter = lSeq->getIterator();
+ lIter->open();
+ while(lIter->next(lVecItem))
+ {
+ lItems.push_back(lVecItem);
+ }
+ lIter->close();
+ lJSONArray = lFactory->createJSONArray(lItems);
+ lJSONKey = lFactory->createString(std::string("columns"));
+ lVectorRes.push_back(std::pair<Item, Item>(lJSONKey, lJSONArray));
+ lJSONRes = lFactory->createJSONObject(lVectorRes);
+
+ return ItemSequence_t(new SingletonItemSequence(lJSONRes));
+#else
+ throwError("UNAVAILABLE-METADATA", getErrorMessage("UNAVAILABLE-METADATA"));
+#endif
+ }
+
+/*******************************************************************************
+ ******************************************************************************/
+ zorba::ItemSequence_t
+ PrepareStatementFunction::evaluate(
+ const Arguments_t& aArgs,
+ const zorba::StaticContext* aSctx,
+ const zorba::DynamicContext* aDctx) const
+ {
+ sqlite3_stmt *lPstmt;
+ Item lItemUUID = getOneItem(aArgs, 0);
+ Item lItemQry = getOneItem(aArgs, 1);
+ std::string lStrUUID;
+ StmtMap *stmtMap = getStatementMap(aDctx);
+
+ // Create the prepared statement
+ lPstmt = createPreparedStatement(aDctx, lItemUUID.getStringValue().str(),
+ lItemQry.getStringValue().str());
+
+ // Create a new UUID for the prepared statement
+ lStrUUID = SqliteFunction::createUUID();
+ stmtMap->storeStmt(lStrUUID, lPstmt);
+
+ return ItemSequence_t(new SingletonItemSequence(SqliteModule::getItemFactory()->createAnyURI(lStrUUID)));
+ }
+
+/*******************************************************************************
+ ******************************************************************************/
+ zorba::ItemSequence_t
+ SetValueFunction::evaluate(
+ const Arguments_t& aArgs,
+ const zorba::StaticContext* aSctx,
+ const zorba::DynamicContext* aDctx) const
+ {
+ Item lItemUUID = getOneItem(aArgs, 0);
+ Item lItemPos = getOneItem(aArgs, 1);
+ Item lItem = getOneItem(aArgs, 2);
+ int lPos;
+
+ lPos = strToInt(lItemPos.getStringValue().str());
+ switch(lItem.getTypeCode()){
+ case store::XS_BOOLEAN:
+ setValueToStatement(aDctx, lItemUUID.getStringValue().str(),
+ lPos, lItem.getBooleanValue());
+ break;
+ case store::XS_BYTE:
+ case store::XS_INT:
+ setValueToStatement(aDctx, lItemUUID.getStringValue().str(),
+ lPos, lItem.getIntValue());
+ break;
+ case store::XS_INTEGER:
+ setValueToStatement(aDctx, lItemUUID.getStringValue().str(),
+ lPos, strToInt(lItem.getStringValue().str()));
+ break;
+ case store::XS_FLOAT:
+ case store::XS_DOUBLE:
+ setValueToStatement(aDctx, lItemUUID.getStringValue().str(),
+ lPos, lItem.getDoubleValue());
+ break;
+ case store::XS_DECIMAL:
+ setValueToStatement(aDctx, lItemUUID.getStringValue().str(),
+ lPos, strToDouble(lItem.getStringValue().str()));
+ break;
+ case store::XS_STRING:
+ setValueToStatement(aDctx, lItemUUID.getStringValue().str(),
+ lPos, lItem.getStringValue().str());
+ break;
+ default:
+ throwError("INVALID-VALUE", getErrorMessage("INVALID-VALUE"));
+ }
+ return ItemSequence_t(new EmptySequence());
+ }
+
+/*******************************************************************************
+ ******************************************************************************/
+ zorba::ItemSequence_t
+ SetBooleanFunction::evaluate(
+ const Arguments_t& aArgs,
+ const zorba::StaticContext* aSctx,
+ const zorba::DynamicContext* aDctx) const
+ {
+ Item lItemUUID = getOneItem(aArgs, 0);
+ Item lItemPos = getOneItem(aArgs, 1);
+ Item lItemBool = getOneItem(aArgs, 2);
+
+ setValueToStatement(aDctx, lItemUUID.getStringValue().str(),
+ strToInt(lItemPos.getStringValue().str()), lItemBool.getBooleanValue());
+ return ItemSequence_t(new EmptySequence());
+ }
+
+/*******************************************************************************
+ ******************************************************************************/
+ zorba::ItemSequence_t
+ SetNumericFunction::evaluate(
+ const Arguments_t& aArgs,
+ const zorba::StaticContext* aSctx,
+ const zorba::DynamicContext* aDctx) const
+ {
+ Item lItemUUID = getOneItem(aArgs, 0);
+ Item lItemPos = getOneItem(aArgs, 1);
+ Item lItemNumeric = getOneItem(aArgs, 2);
+ int lPos = strToInt(lItemPos.getStringValue().str());
+
+ switch(lItemNumeric.getTypeCode()){
+ case store::XS_BYTE:
+ case store::XS_INT:
+ setValueToStatement(aDctx, lItemUUID.getStringValue().str(),
+ lPos, lItemNumeric.getIntValue());
+ break;
+ case store::XS_INTEGER:
+ setValueToStatement(aDctx, lItemUUID.getStringValue().str(),
+ lPos, strToInt(lItemNumeric.getStringValue().str()));
+ break;
+ case store::XS_FLOAT:
+ case store::XS_DOUBLE:
+ setValueToStatement(aDctx, lItemUUID.getStringValue().str(),
+ lPos, lItemNumeric.getDoubleValue());
+ break;
+ case store::XS_DECIMAL:
+ setValueToStatement(aDctx, lItemUUID.getStringValue().str(),
+ lPos, strToDouble(lItemNumeric.getStringValue().str()));
+ break;
+ default:
+ throwError("INVALID-VALUE", getErrorMessage("INVALID-VALUE"));
+ }
+ return ItemSequence_t(new EmptySequence());
+ }
+
+/*******************************************************************************
+ ******************************************************************************/
+ zorba::ItemSequence_t
+ SetStringFunction::evaluate(
+ const Arguments_t& aArgs,
+ const zorba::StaticContext* aSctx,
+ const zorba::DynamicContext* aDctx) const
+ {
+ Item lItemUUID = getOneItem(aArgs, 0);
+ Item lItemPos = getOneItem(aArgs, 1);
+ Item lItemString = getOneItem(aArgs, 2);
+
+ setValueToStatement(aDctx, lItemUUID.getStringValue().str(),
+ strToInt(lItemPos.getStringValue().str()), lItemString.getStringValue().str());
+ return ItemSequence_t(new EmptySequence());
+ }
+
+/*******************************************************************************
+ ******************************************************************************/
+ zorba::ItemSequence_t
+ SetNullFunction::evaluate(
+ const Arguments_t& aArgs,
+ const zorba::StaticContext* aSctx,
+ const zorba::DynamicContext* aDctx) const
+ {
+ Item lItemUUID = getOneItem(aArgs, 0);
+ Item lItemPos = getOneItem(aArgs, 1);
+
+ setValueToStatement(aDctx, lItemUUID.getStringValue().str(),
+ strToInt(lItemPos.getStringValue().str()));
+ return ItemSequence_t(new EmptySequence());
+ }
+
+/*******************************************************************************
+ ******************************************************************************/
+ zorba::ItemSequence_t
+ ClearParamsFunction::evaluate(
+ const Arguments_t& aArgs,
+ const zorba::StaticContext* aSctx,
+ const zorba::DynamicContext* aDctx) const
+ {
+ Item lItemUUID = getOneItem(aArgs, 0);
+
+ clearValues(aDctx, lItemUUID.getStringValue().str());
+ return ItemSequence_t(new EmptySequence());
+ }
+
+/*******************************************************************************
+ ******************************************************************************/
+ zorba::ItemSequence_t
+ ClosePreparedFunction::evaluate(
+ const Arguments_t& aArgs,
+ const zorba::StaticContext* aSctx,
+ const zorba::DynamicContext* aDctx) const
+ {
+ sqlite3_stmt *lPstmt;
+ Item lItemUUID = getOneItem(aArgs, 0);
+ StmtMap* stmtMap;
+
+ // get the prepared statement
+ stmtMap = getStatementMap(aDctx);
+ lPstmt = stmtMap->getStmt(lItemUUID.getStringValue().str());
+ if(lPstmt == NULL)
+ throwError("INVALID-PREPARED-STATEMENT",
+ getErrorMessage("INVALID-PREPARED-STATEMENT"));
+
+ // Once we got the prepared statement just get rid of it
+ stmtMap->deleteStmt(lItemUUID.getStringValue().str());
+ return ItemSequence_t(new EmptySequence());
+ }
+
+/*******************************************************************************
+ ******************************************************************************/
+ zorba::ItemSequence_t
+ ExecuteQueryPreparedFunction::evaluate(
+ const Arguments_t& aArgs,
+ const zorba::StaticContext* aSctx,
+ const zorba::DynamicContext* aDctx) const
+ {
+ sqlite3_stmt *lPstmt;
+ StmtMap *stmtMap = getStatementMap(aDctx);
+ Item lItemUUID = getOneItem(aArgs, 0);
+
+ // Get the prepared statement
+ lPstmt = stmtMap->getStmt(lItemUUID.getStringValue().str());
+ if(lPstmt == NULL)
+ throwError("INVALID-PREPARED-STATEMENT",
+ getErrorMessage("INVALID-PREPARED-STATEMENT"));
+
+ // And let the JSONItemSequence execute it
+ std::unique_ptr<JSONItemSequence> lSeq(new JSONItemSequence(lPstmt));
+ return ItemSequence_t(lSeq.release());
+ }
+
+/*******************************************************************************
+ ******************************************************************************/
+ zorba::ItemSequence_t
+ ExecuteUpdatePreparedFunction::evaluate(
+ const Arguments_t& aArgs,
+ const zorba::StaticContext* aSctx,
+ const zorba::DynamicContext* aDctx) const
+ {
+ sqlite3_stmt *lPstmt;
+ StmtMap *stmtMap = getStatementMap(aDctx);
+ Item lItemUUID = getOneItem(aArgs, 0);
+ Item lItemRes, lItemJSONKey;
+
+ // Get the prepared statement
+ lPstmt = stmtMap->getStmt(lItemUUID.getStringValue().str());
+ if(lPstmt == NULL)
+ throwError("INVALID-PREPARED-STATEMENT",
+ getErrorMessage("INVALID-PREPARED-STATEMENT"));
+
+ // And let the JSONItemSequence execute it
+ std::unique_ptr<JSONItemSequence> lSeq(new JSONItemSequence(lPstmt));
+ Iterator_t lIter = lSeq->getIterator();
+ lIter->open();
+ lIter->next(lItemRes);
+ lIter->close();
+ Iterator_t lIterKeys = lItemRes.getObjectKeys();
+ lIterKeys->open();
+ lIterKeys->next(lItemJSONKey);
+ lIterKeys->close();
+ Item lItemValue = lItemRes.getObjectValue(lItemJSONKey.getStringValue());
+ return ItemSequence_t(new SingletonItemSequence(lItemValue));
+ }
+
+} /* namespace zorba */ } /* namespace archive*/
+
+#ifdef WIN32
+# define DLL_EXPORT __declspec(dllexport)
+#else
+# define DLL_EXPORT __attribute__ ((visibility("default")))
+#endif
+
+extern "C" DLL_EXPORT zorba::ExternalModule* createModule() {
+ return new zorba::sqlite::SqliteModule();
+}
=== added file 'src/sqlite_module.xq.src/sqlite_module.h'
--- src/sqlite_module.xq.src/sqlite_module.h 1970-01-01 00:00:00 +0000
+++ src/sqlite_module.xq.src/sqlite_module.h 2013-09-11 04:36:11 +0000
@@ -0,0 +1,624 @@
+/*
+ * Copyright 2012 The FLWOR Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <map>
+#include <set>
+
+#include <zorba/zorba.h>
+#include <zorba/item_factory.h>
+#include <zorba/external_module.h>
+#include <zorba/function.h>
+#include <vector>
+#include <sqlite3.h>
+
+namespace zorba { namespace sqlite {
+
+/*******************************************************************************
+ ******************************************************************************/
+ class StmtMap : public ExternalFunctionParameter
+ {
+ private:
+ typedef std::map<std::string, sqlite3_stmt *> StmtMap_t;
+ StmtMap_t* stmtMap;
+
+ public:
+ StmtMap();
+ virtual ~StmtMap();
+ bool
+ storeStmt(const std::string&, sqlite3_stmt *sql);
+ sqlite3_stmt*
+ getStmt(const std::string&);
+ bool
+ deleteStmt(const std::string&);
+ virtual void
+ destroy() throw();
+ void deleteAllForConn(sqlite3* c);
+ };
+
+ class ConnMap : public ExternalFunctionParameter
+ {
+ private:
+ typedef std::map<std::string, sqlite3 *> ConnMap_t;
+ ConnMap_t* connMap;
+ StmtMap* sMap;
+
+ public:
+ ConnMap(StmtMap* sMap);
+ virtual ~ConnMap();
+ bool
+ storeConn(const std::string&, sqlite3 *sql);
+ sqlite3*
+ getConn(const std::string&);
+ bool
+ deleteConn(const std::string&);
+ virtual void
+ destroy() throw();
+ };
+
+ class SqliteModule : public ExternalModule {
+ protected:
+ class ltstr
+ {
+ public:
+ bool operator()(const String& s1, const String& s2) const
+ {
+ return s1.compare(s2) < 0;
+ }
+ };
+
+ typedef std::map<String, ExternalFunction*, ltstr> FuncMap_t;
+ FuncMap_t theFunctions;
+
+ static zorba::Item globalNameKey;
+ static zorba::Item globalDatabaseKey;
+ static zorba::Item globalTableKey;
+ static zorba::Item globalTypeKey;
+ static zorba::Item globalCollationKey;
+ static zorba::Item globalNullableKey;
+ static zorba::Item globalPrimaryKey;
+ static zorba::Item globalAutoincKey;
+ static zorba::Item globalAffectedRowsKey;
+
+ public:
+
+ enum GLOBAL_KEYS { NAME, DATABASE, TABLE, TYPE, COLLATION, NULLABLE, PRIMARY_KEY, AUTOINC, AFFECTED_ROWS };
+
+ SqliteModule();
+
+ virtual ~SqliteModule();
+
+ virtual zorba::String
+ getURI() const { return getModuleURI(); }
+
+ virtual zorba::ExternalFunction*
+ getExternalFunction(const String& localName);
+
+ virtual void destroy();
+
+ static ItemFactory*
+ getItemFactory()
+ {
+ return Zorba::getInstance(0)->getItemFactory();
+ }
+
+ static zorba::String
+ getModuleURI() { return "http://zorba.io/modules/sqlite";; }
+
+ static zorba::Item&
+ getGlobalKey(GLOBAL_KEYS g);
+
+ };
+
+
+/*******************************************************************************
+ ******************************************************************************/
+ class JSONItemSequence : public ItemSequence
+ {
+ public:
+ class JSONIterator : public Iterator
+ {
+ protected:
+ sqlite3_stmt* theStmt;
+ std::vector<zorba::Item> theColumnNamesZString;
+ int theColumnCount;
+ int theRc;
+ bool isUpdateResult;
+ zorba::ItemFactory* theFactory;
+
+ public:
+ JSONIterator(sqlite3_stmt* aPrepStmt):
+ theStmt(aPrepStmt),
+ theRc(0),isUpdateResult(false) {}
+
+ virtual ~JSONIterator() {
+ }
+
+ void
+ open();
+
+ bool
+ next(zorba::Item& aItem);
+
+ void
+ close();
+
+ bool
+ isOpen() const { return theRc == SQLITE_ROW; }
+ };
+
+ protected:
+ sqlite3_stmt* thePrepStmt;
+
+ public:
+ JSONItemSequence(sqlite3_stmt* aPrepStmt)
+ : thePrepStmt(aPrepStmt)
+ {}
+
+ virtual ~JSONItemSequence() {}
+
+ zorba::Iterator_t
+ getIterator() { return new JSONIterator(thePrepStmt); }
+ };
+
+/*******************************************************************************
+ ******************************************************************************/
+#ifdef ZORBA_SQLITE_HAVE_METADATA
+ class JSONMetadataItemSequence : public ItemSequence
+ {
+ public:
+ class JSONMetadataIterator : public Iterator
+ {
+ protected:
+ sqlite3_stmt* theStmt;
+ int theColumnCount;
+ int theRc;
+ int theActualColumn;
+ zorba::ItemFactory* theFactory;
+
+ public:
+ JSONMetadataIterator(sqlite3_stmt* aPrepStmt):
+ theStmt(aPrepStmt),theColumnCount(0),
+ theRc(0), theActualColumn(0) {}
+
+ virtual ~JSONMetadataIterator() {
+ }
+
+ void
+ open();
+
+ bool
+ next(zorba::Item& aItem);
+
+ void
+ close();
+
+ bool
+ isOpen() const { return theRc == SQLITE_ROW; }
+ };
+
+ protected:
+ sqlite3_stmt* thePrepStmt;
+
+ public:
+ JSONMetadataItemSequence(sqlite3_stmt* aPrepStmt)
+ : thePrepStmt(aPrepStmt)
+ {}
+
+ virtual ~JSONMetadataItemSequence() {}
+
+ zorba::Iterator_t
+ getIterator() { return new JSONMetadataIterator(thePrepStmt); }
+ };
+#endif
+
+/*******************************************************************************
+ ******************************************************************************/
+ class SqliteOptions {
+ protected:
+ bool theOpenReadOnly;
+ bool theOpenCreate;
+ bool theOpenNoMutex;
+ bool theOpenSharedCache;
+
+ public:
+
+ SqliteOptions();
+
+ bool
+ getOpenReadOnly() { return theOpenReadOnly; }
+
+ bool
+ getOpenCreate() { return theOpenCreate; }
+
+ bool
+ getOpenNoMutex() { return theOpenNoMutex; }
+
+ bool
+ getOpenSharedCache() { return theOpenSharedCache; }
+
+ void
+ setValues(Item&);
+
+ void
+ setValues(struct sqlite3* aSqlite);
+
+ int
+ getOptionsAsInt();
+
+ std::string
+ getOptionsAsString();
+
+ protected:
+ static std::string
+ getAttributeValue(
+ const Item& aNode,
+ const String& aAttrName = "value");
+ };
+
+/*******************************************************************************
+ ******************************************************************************/
+ class SqliteFunction : public ContextualExternalFunction {
+ protected:
+ const SqliteModule* theModule;
+
+ public:
+ SqliteFunction(const SqliteModule* module);
+ virtual ~SqliteFunction();
+
+ static zorba::Item
+ getOneItem(const Arguments_t& aArgs, int aIndex);
+
+ static ConnMap*
+ getConnectionMap(const zorba::DynamicContext* aDctx);
+
+ static StmtMap*
+ getStatementMap(const zorba::DynamicContext* aDctx);
+
+ static std::string
+ createUUID();
+
+ static sqlite3_stmt*
+ createPreparedStatement(const zorba::DynamicContext* aDctx,
+ std::string aUUID,
+ std::string aQry);
+
+ static void
+ setValueToStatement(const zorba::DynamicContext* aDctx,
+ std::string aUUID,
+ int aPos,
+ bool aVal);
+
+ static void
+ setValueToStatement(const zorba::DynamicContext* aDctx,
+ std::string aUUID,
+ int aPos,
+ int aVal);
+
+ static void
+ setValueToStatement(const zorba::DynamicContext* aDctx,
+ std::string aUUID,
+ int aPos,
+ double aVal);
+
+ static void
+ setValueToStatement(const zorba::DynamicContext* aDctx,
+ std::string aUUID,
+ int aPos,
+ std::string aVal);
+
+ static void
+ setValueToStatement(const zorba::DynamicContext* aDctx,
+ std::string aUUID,
+ int aPos);
+
+ static void
+ clearValues(const zorba::DynamicContext* aDctx,
+ std::string aUUID);
+
+ virtual String
+ getURI() const;
+
+ static void
+ throwError(const char*, const char*);
+
+ static void
+ checkForError(int aErrNo, const char* aLocalName, sqlite3 *sql);
+
+ static int
+ strToInt(std::string str);
+
+ static double
+ strToDouble(std::string strcat);
+
+ static const char *
+ getErrorMessage(std::string error);
+
+ };
+
+ class ConnectFunction : public SqliteFunction {
+ public:
+ ConnectFunction(const SqliteModule* aModule) : SqliteFunction(aModule) {}
+
+ virtual ~ConnectFunction() {}
+
+ virtual zorba::String
+ getLocalName() const { return "connect"; }
+
+ virtual zorba::ItemSequence_t
+ evaluate(const Arguments_t&,
+ const zorba::StaticContext*,
+ const zorba::DynamicContext*) const;
+
+ };
+
+ class IsConnectedFunction : public SqliteFunction {
+ public:
+ IsConnectedFunction(const SqliteModule* aModule) : SqliteFunction(aModule) {}
+
+ virtual ~IsConnectedFunction() {}
+
+ virtual zorba::String
+ getLocalName() const { return "is-connected"; }
+
+ virtual zorba::ItemSequence_t
+ evaluate(const Arguments_t&,
+ const zorba::StaticContext*,
+ const zorba::DynamicContext*) const;
+
+ };
+
+ class CommitFunction : public SqliteFunction {
+ public:
+ CommitFunction(const SqliteModule* aModule) : SqliteFunction(aModule) {}
+
+ virtual ~CommitFunction() {}
+
+ virtual zorba::String
+ getLocalName() const { return "commit"; }
+
+ virtual zorba::ItemSequence_t
+ evaluate(const Arguments_t&,
+ const zorba::StaticContext*,
+ const zorba::DynamicContext*) const;
+
+ };
+
+ class RollbackFunction : public SqliteFunction {
+ public:
+ RollbackFunction(const SqliteModule* aModule) : SqliteFunction(aModule) {}
+
+ virtual ~RollbackFunction() {}
+
+ virtual zorba::String
+ getLocalName() const { return "rollback"; }
+
+ virtual zorba::ItemSequence_t
+ evaluate(const Arguments_t&,
+ const zorba::StaticContext*,
+ const zorba::DynamicContext*) const;
+
+ };
+
+ class ExecuteQueryFunction : public SqliteFunction {
+ public:
+ ExecuteQueryFunction(const SqliteModule* aModule) : SqliteFunction(aModule) {}
+
+ virtual ~ExecuteQueryFunction() {}
+
+ virtual zorba::String
+ getLocalName() const { return "execute-query"; }
+
+ virtual zorba::ItemSequence_t
+ evaluate(const Arguments_t&,
+ const zorba::StaticContext*,
+ const zorba::DynamicContext*) const;
+
+ };
+
+ class ExecuteUpdateFunction : public SqliteFunction {
+ public:
+ ExecuteUpdateFunction(const SqliteModule* aModule) : SqliteFunction(aModule) {}
+
+ virtual ~ExecuteUpdateFunction() {}
+
+ virtual zorba::String
+ getLocalName() const { return "execute-update"; }
+
+ virtual zorba::ItemSequence_t
+ evaluate(const Arguments_t&,
+ const zorba::StaticContext*,
+ const zorba::DynamicContext*) const;
+
+ };
+
+ class MetadataFunction : public SqliteFunction {
+ public:
+ MetadataFunction(const SqliteModule* aModule) : SqliteFunction(aModule) {}
+
+ virtual ~MetadataFunction() {}
+
+ virtual zorba::String
+ getLocalName() const { return "metadata"; }
+
+ virtual zorba::ItemSequence_t
+ evaluate(const Arguments_t&,
+ const zorba::StaticContext*,
+ const zorba::DynamicContext*) const;
+
+ };
+
+ class PrepareStatementFunction : public SqliteFunction {
+ public:
+ PrepareStatementFunction(const SqliteModule* aModule) : SqliteFunction(aModule) {}
+
+ virtual ~PrepareStatementFunction() {}
+
+ virtual zorba::String
+ getLocalName() const { return "prepare-statement"; }
+
+ virtual zorba::ItemSequence_t
+ evaluate(const Arguments_t&,
+ const zorba::StaticContext*,
+ const zorba::DynamicContext*) const;
+
+ };
+
+ class SetValueFunction : public SqliteFunction {
+ public:
+ SetValueFunction(const SqliteModule* aModule) : SqliteFunction(aModule) {}
+
+ virtual ~SetValueFunction() {}
+
+ virtual zorba::String
+ getLocalName() const { return "set-value"; }
+
+ virtual zorba::ItemSequence_t
+ evaluate(const Arguments_t&,
+ const zorba::StaticContext*,
+ const zorba::DynamicContext*) const;
+
+ };
+
+ class SetBooleanFunction : public SqliteFunction {
+ public:
+ SetBooleanFunction(const SqliteModule* aModule) : SqliteFunction(aModule) {}
+
+ virtual ~SetBooleanFunction() {}
+
+ virtual zorba::String
+ getLocalName() const { return "set-boolean"; }
+
+ virtual zorba::ItemSequence_t
+ evaluate(const Arguments_t&,
+ const zorba::StaticContext*,
+ const zorba::DynamicContext*) const;
+
+ };
+
+ class SetNumericFunction : public SqliteFunction {
+ public:
+ SetNumericFunction(const SqliteModule* aModule) : SqliteFunction(aModule) {}
+
+ virtual ~SetNumericFunction() {}
+
+ virtual zorba::String
+ getLocalName() const { return "set-numeric"; }
+
+ virtual zorba::ItemSequence_t
+ evaluate(const Arguments_t&,
+ const zorba::StaticContext*,
+ const zorba::DynamicContext*) const;
+
+ };
+
+ class SetStringFunction : public SqliteFunction {
+ public:
+ SetStringFunction(const SqliteModule* aModule) : SqliteFunction(aModule) {}
+
+ virtual ~SetStringFunction() {}
+
+ virtual zorba::String
+ getLocalName() const { return "set-string"; }
+
+ virtual zorba::ItemSequence_t
+ evaluate(const Arguments_t&,
+ const zorba::StaticContext*,
+ const zorba::DynamicContext*) const;
+
+ };
+
+ class SetNullFunction : public SqliteFunction {
+ public:
+ SetNullFunction(const SqliteModule* aModule) : SqliteFunction(aModule) {}
+
+ virtual ~SetNullFunction() {}
+
+ virtual zorba::String
+ getLocalName() const { return "set-null"; }
+
+ virtual zorba::ItemSequence_t
+ evaluate(const Arguments_t&,
+ const zorba::StaticContext*,
+ const zorba::DynamicContext*) const;
+
+ };
+
+ class ClearParamsFunction : public SqliteFunction {
+ public:
+ ClearParamsFunction(const SqliteModule* aModule) : SqliteFunction(aModule) {}
+
+ virtual ~ClearParamsFunction() {}
+
+ virtual zorba::String
+ getLocalName() const { return "clear-params"; }
+
+ virtual zorba::ItemSequence_t
+ evaluate(const Arguments_t&,
+ const zorba::StaticContext*,
+ const zorba::DynamicContext*) const;
+
+ };
+
+ class ClosePreparedFunction : public SqliteFunction {
+ public:
+ ClosePreparedFunction(const SqliteModule* aModule) : SqliteFunction(aModule) {}
+
+ virtual ~ClosePreparedFunction() {}
+
+ virtual zorba::String
+ getLocalName() const { return "close-prepared"; }
+
+ virtual zorba::ItemSequence_t
+ evaluate(const Arguments_t&,
+ const zorba::StaticContext*,
+ const zorba::DynamicContext*) const;
+
+ };
+
+ class ExecuteQueryPreparedFunction : public SqliteFunction {
+ public:
+ ExecuteQueryPreparedFunction(const SqliteModule* aModule) : SqliteFunction(aModule) {}
+
+ virtual ~ExecuteQueryPreparedFunction() {}
+
+ virtual zorba::String
+ getLocalName() const { return "execute-query-prepared"; }
+
+ virtual zorba::ItemSequence_t
+ evaluate(const Arguments_t&,
+ const zorba::StaticContext*,
+ const zorba::DynamicContext*) const;
+
+ };
+
+ class ExecuteUpdatePreparedFunction : public SqliteFunction {
+ public:
+ ExecuteUpdatePreparedFunction(const SqliteModule* aModule) : SqliteFunction(aModule) {}
+
+ virtual ~ExecuteUpdatePreparedFunction() {}
+
+ virtual zorba::String
+ getLocalName() const { return "execute-update-prepared"; }
+
+ virtual zorba::ItemSequence_t
+ evaluate(const Arguments_t&,
+ const zorba::StaticContext*,
+ const zorba::DynamicContext*) const;
+
+ };
+
+} /* namespace sqlite */ } /* namespace zorba */
+
=== added directory 'test'
=== renamed directory 'test' => 'test.moved'
=== added directory 'test/ExpQueryResults'
=== added file 'test/ExpQueryResults/test0.xml.res'
--- test/ExpQueryResults/test0.xml.res 1970-01-01 00:00:00 +0000
+++ test/ExpQueryResults/test0.xml.res 2013-09-11 04:36:11 +0000
@@ -0,0 +1,1 @@
+{ "id" : 1, "name" : "apple", "calories" : 80 }{ "id" : 2, "name" : "orange", "calories" : 60 }{ "id" : 3, "name" : "fried egg", "calories" : 92 }{ "id" : 4, "name" : "cholate milk regular", "calories" : 210 }true
\ No newline at end of file
=== added file 'test/ExpQueryResults/test1.xml.res'
--- test/ExpQueryResults/test1.xml.res 1970-01-01 00:00:00 +0000
+++ test/ExpQueryResults/test1.xml.res 2013-09-11 04:36:11 +0000
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="UTF-8"?>
+1
\ No newline at end of file
=== added file 'test/ExpQueryResults/test10.xml.res'
--- test/ExpQueryResults/test10.xml.res 1970-01-01 00:00:00 +0000
+++ test/ExpQueryResults/test10.xml.res 2013-09-11 04:36:11 +0000
@@ -0,0 +1,1 @@
+{ "Affected Rows" : 1 }
\ No newline at end of file
=== added file 'test/ExpQueryResults/test18.xml.res'
--- test/ExpQueryResults/test18.xml.res 1970-01-01 00:00:00 +0000
+++ test/ExpQueryResults/test18.xml.res 2013-09-11 04:36:11 +0000
@@ -0,0 +1,1 @@
+{ "id" : 1, "name" : "one", "calories" : "100" }
\ No newline at end of file
=== added file 'test/ExpQueryResults/test2.xml.res'
--- test/ExpQueryResults/test2.xml.res 1970-01-01 00:00:00 +0000
+++ test/ExpQueryResults/test2.xml.res 2013-09-11 04:36:11 +0000
@@ -0,0 +1,1 @@
+{ "id" : 2, "name" : "orange", "calories" : 60 }{ "id" : 1, "name" : "apple", "calories" : 80 }{ "id" : 3, "name" : "fried egg", "calories" : 92 }{ "id" : 4, "name" : "cholate milk regular", "calories" : 210 }
\ No newline at end of file
=== added file 'test/ExpQueryResults/test3.xml.res'
--- test/ExpQueryResults/test3.xml.res 1970-01-01 00:00:00 +0000
+++ test/ExpQueryResults/test3.xml.res 2013-09-11 04:36:11 +0000
@@ -0,0 +1,1 @@
+{ "name" : "id", "database" : "main", "table" : "smalltable", "type" : "integer", "collation" : "BINARY", "nullable" : false, "primary key" : true, "autoincrement" : false }{ "name" : "name", "database" : "main", "table" : "smalltable", "type" : "varchar", "collation" : "BINARY", "nullable" : true, "primary key" : false, "autoincrement" : false }{ "name" : "calories", "database" : "main", "table" : "smalltable", "type" : "integer", "collation" : "BINARY", "nullable" : true, "primary key" : false, "autoincrement" : false }
\ No newline at end of file
=== added file 'test/ExpQueryResults/test4.xml.res'
--- test/ExpQueryResults/test4.xml.res 1970-01-01 00:00:00 +0000
+++ test/ExpQueryResults/test4.xml.res 2013-09-11 04:36:11 +0000
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="UTF-8"?>
+main:smalltable:id = integer; main:smalltable:name = varchar; main:smalltable:calories = integer; { "id" : 1, "name" : "apple", "calories" : 80 }{ "id" : 2, "name" : "orange", "calories" : 60 }{ "id" : 3, "name" : "fried egg", "calories" : 92 }{ "id" : 4, "name" : "cholate milk regular", "calories" : 210 }
\ No newline at end of file
=== added file 'test/ExpQueryResults/test5.xml.res'
--- test/ExpQueryResults/test5.xml.res 1970-01-01 00:00:00 +0000
+++ test/ExpQueryResults/test5.xml.res 2013-09-11 04:36:11 +0000
@@ -0,0 +1,1 @@
+{ "id" : 4, "name" : "cholate milk regular", "calories" : 210 }
\ No newline at end of file
=== added file 'test/ExpQueryResults/test6.xml.res'
--- test/ExpQueryResults/test6.xml.res 1970-01-01 00:00:00 +0000
+++ test/ExpQueryResults/test6.xml.res 2013-09-11 04:36:11 +0000
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="UTF-8"?>
+true
=== added file 'test/ExpQueryResults/test7.xml.res'
--- test/ExpQueryResults/test7.xml.res 1970-01-01 00:00:00 +0000
+++ test/ExpQueryResults/test7.xml.res 2013-09-11 04:36:11 +0000
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<food><id>1</id><name>apple</name><calories>80</calories></food><food><id>2</id><name>orange</name><calories>60</calories></food><food><id>3</id><name>fried egg</name><calories>92</calories></food><food><id>4</id><name>cholate milk regular</name><calories>210</calories></food>
\ No newline at end of file
=== added file 'test/ExpQueryResults/test8.xml.res'
--- test/ExpQueryResults/test8.xml.res 1970-01-01 00:00:00 +0000
+++ test/ExpQueryResults/test8.xml.res 2013-09-11 04:36:11 +0000
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="UTF-8"?>
+true{ "Affected Rows" : 0 }{ "Affected Rows" : 1 }{ "Affected Rows" : 1 }{ "Affected Rows" : 1 }{ "id" : 1, "name" : "Luis", "salary" : 100 }{ "id" : 2, "name" : "Juan", "salary" : 200 }{ "id" : 3, "name" : "Rodolfo", "salary" : 300 }
\ No newline at end of file
=== added file 'test/ExpQueryResults/test9.xml.res'
--- test/ExpQueryResults/test9.xml.res 1970-01-01 00:00:00 +0000
+++ test/ExpQueryResults/test9.xml.res 2013-09-11 04:36:11 +0000
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="UTF-8"?>
+1 1
\ No newline at end of file
=== added directory 'test/Queries'
=== added file 'test/Queries/small2.db'
Binary files test/Queries/small2.db 1970-01-01 00:00:00 +0000 and test/Queries/small2.db 2013-09-11 04:36:11 +0000 differ
=== added file 'test/Queries/test0.xq'
--- test/Queries/test0.xq 1970-01-01 00:00:00 +0000
+++ test/Queries/test0.xq 2013-09-11 04:36:11 +0000
@@ -0,0 +1,10 @@
+import module namespace s = "http://zorba.io/modules/sqlite";;
+import module namespace f = "http://expath.org/ns/file";;
+
+let $path := f:path-to-native(resolve-uri("./"))
+let $db := s:connect(concat($path, "small2.db"))
+return {
+ variable $isconn := s:is-connected($db);
+ variable $result := s:execute-query($db, "select * from smalltable");
+ ($result, $isconn)
+}
=== added file 'test/Queries/test1.xq'
--- test/Queries/test1.xq 1970-01-01 00:00:00 +0000
+++ test/Queries/test1.xq 2013-09-11 04:36:11 +0000
@@ -0,0 +1,9 @@
+import module namespace s = "http://zorba.io/modules/sqlite";;
+
+let $db := s:connect("")
+
+return {
+ variable $result0 := s:execute-update($db, "CREATE TABLE smalltable (id INTEGER primary key, name TEXT not null, calories TEXT)");
+ variable $result1 := s:execute-update($db, "INSERT INTO smalltable (name, calories) VALUES ('cholate milk regular',210)");
+ $result1
+}
=== added file 'test/Queries/test10.xq'
--- test/Queries/test10.xq 1970-01-01 00:00:00 +0000
+++ test/Queries/test10.xq 2013-09-11 04:36:11 +0000
@@ -0,0 +1,10 @@
+import module namespace s = "http://zorba.io/modules/sqlite";;
+
+let $db := s:connect("", { "open-read-only" : false(), "open-create" : false() })
+
+return {
+ variable $inst := s:execute-update($db, "CREATE TABLE smalltable (id INTEGER primary key asc, name TEXT not null, calories TEXT)");
+ variable $prep-stmt := s:prepare-statement($db, "INSERT INTO smalltable (name, calories) VALUES ('one', '100')");
+ variable $res := s:execute-update-prepared($prep-stmt);
+ {"Affected Rows" : $res}
+}
=== added file 'test/Queries/test11.spec'
--- test/Queries/test11.spec 1970-01-01 00:00:00 +0000
+++ test/Queries/test11.spec 2013-09-11 04:36:11 +0000
@@ -0,0 +1,1 @@
+Error: http://zorba.io/modules/sqlite:INVALID-SQL-STATEMENT
=== added file 'test/Queries/test11.xq'
--- test/Queries/test11.xq 1970-01-01 00:00:00 +0000
+++ test/Queries/test11.xq 2013-09-11 04:36:11 +0000
@@ -0,0 +1,8 @@
+import module namespace s = "http://zorba.io/modules/sqlite";;
+
+let $db := s:connect("")
+
+return {
+ variable $results := s:execute-query($db, "SELECT id, name, calories FROM smalltable");
+ $results
+}
=== added file 'test/Queries/test12.spec'
--- test/Queries/test12.spec 1970-01-01 00:00:00 +0000
+++ test/Queries/test12.spec 2013-09-11 04:36:11 +0000
@@ -0,0 +1,1 @@
+Error: http://zorba.io/modules/sqlite:CANT-OPEN-DB
=== added file 'test/Queries/test12.xq'
--- test/Queries/test12.xq 1970-01-01 00:00:00 +0000
+++ test/Queries/test12.xq 2013-09-11 04:36:11 +0000
@@ -0,0 +1,8 @@
+import module namespace s = "http://zorba.io/modules/sqlite";;
+
+let $db := s:connect("non-existent-file.db", {"open-read-only" : false(), "open-create" : false()})
+
+return {
+ variable $results := s:execute-query($db, "SELECT id, name, calories FROM smalltable");
+ $results
+}
=== added file 'test/Queries/test13.spec'
--- test/Queries/test13.spec 1970-01-01 00:00:00 +0000
+++ test/Queries/test13.spec 2013-09-11 04:36:11 +0000
@@ -0,0 +1,1 @@
+Error: http://zorba.io/modules/sqlite:INVALID-SQLITE-OBJECT
=== added file 'test/Queries/test13.xq'
--- test/Queries/test13.xq 1970-01-01 00:00:00 +0000
+++ test/Queries/test13.xq 2013-09-11 04:36:11 +0000
@@ -0,0 +1,9 @@
+import module namespace s = "http://zorba.io/modules/sqlite";;
+
+let $db := s:connect("")
+
+return {
+ variable $prep-stmnt1 := s:prepare-statement($db, "CREATE TABLE smalltable (id INTEGER primary key, name TEXT not null, calories INTEGER not null)");
+ variable $prep-stmnt2 := s:prepare-statement($prep-stmnt1, "INSERT INTO smalltable (name, calories) VALUES ('carrot', 80)");
+ $prep-stmnt2
+}
=== added file 'test/Queries/test14.spec'
--- test/Queries/test14.spec 1970-01-01 00:00:00 +0000
+++ test/Queries/test14.spec 2013-09-11 04:36:11 +0000
@@ -0,0 +1,1 @@
+Error: http://zorba.io/modules/sqlite:INVALID-PREPARED-STATEMENT
=== added file 'test/Queries/test14.xq'
--- test/Queries/test14.xq 1970-01-01 00:00:00 +0000
+++ test/Queries/test14.xq 2013-09-11 04:36:11 +0000
@@ -0,0 +1,9 @@
+import module namespace s = "http://zorba.io/modules/sqlite";;
+
+let $db := s:connect("")
+
+return {
+ variable $prep-stmnt1 := s:prepare-statement($db, "CREATE TABLE smalltable (id INTEGER primary key, name TEXT not null, calories INTEGER not null)");
+ variable $result := s:execute-update-prepared($db);
+ {"Affected Rows" : $result}
+}
=== added file 'test/Queries/test15.spec'
--- test/Queries/test15.spec 1970-01-01 00:00:00 +0000
+++ test/Queries/test15.spec 2013-09-11 04:36:11 +0000
@@ -0,0 +1,1 @@
+Error: http://zorba.io/modules/sqlite:INVALID-PLACEHOLDER-POSITION
=== added file 'test/Queries/test15.xq'
--- test/Queries/test15.xq 1970-01-01 00:00:00 +0000
+++ test/Queries/test15.xq 2013-09-11 04:36:11 +0000
@@ -0,0 +1,9 @@
+import module namespace s = "http://zorba.io/modules/sqlite";;
+
+let $db := s:connect("")
+
+return {
+ variable $prep-stmnt1 := s:prepare-statement($db, "CREATE TABLE smalltable (id INTEGER primary key, name TEXT not null, calories INTEGER not null)");
+ s:set-numeric($prep-stmnt1, 1, 0);
+ $prep-stmnt1
+}
=== added file 'test/Queries/test16.spec'
--- test/Queries/test16.spec 1970-01-01 00:00:00 +0000
+++ test/Queries/test16.spec 2013-09-11 04:36:11 +0000
@@ -0,0 +1,1 @@
+Error: http://zorba.io/modules/sqlite:INVALID-VALUE
=== added file 'test/Queries/test16.xq'
--- test/Queries/test16.xq 1970-01-01 00:00:00 +0000
+++ test/Queries/test16.xq 2013-09-11 04:36:11 +0000
@@ -0,0 +1,11 @@
+import module namespace s = "http://zorba.io/modules/sqlite";;
+
+let $db := s:connect("")
+
+return {
+ variable $prep-stmnt1 := s:prepare-statement($db, "CREATE TABLE smalltable (id INTEGER primary key, name TEXT not null, calories INTEGER not null)");
+ variable $res1 := s:execute-update-prepared($prep-stmnt1);
+ variable $prep-stmnt2 := s:prepare-statement($db, "INSERT INTO smalltable (name, calories) VALUES ('carrot', ?)");
+ variable $not := s:set-numeric($prep-stmnt2, 1, "string value");
+ $prep-stmnt1
+}
=== added file 'test/Queries/test17.spec'
--- test/Queries/test17.spec 1970-01-01 00:00:00 +0000
+++ test/Queries/test17.spec 2013-09-11 04:36:11 +0000
@@ -0,0 +1,1 @@
+Error: http://zorba.io/modules/sqlite:UNKNOWN-OPTION
=== added file 'test/Queries/test17.xq'
--- test/Queries/test17.xq 1970-01-01 00:00:00 +0000
+++ test/Queries/test17.xq 2013-09-11 04:36:11 +0000
@@ -0,0 +1,8 @@
+import module namespace s = "http://zorba.io/modules/sqlite";;
+
+let $db := s:connect("non-existent-file.db", {"non-existent-option" : true()})
+
+return {
+ variable $results := s:execute-query($db, "SELECT id, name, calories FROM smalltable");
+ $results
+}
=== added file 'test/Queries/test18.xq'
--- test/Queries/test18.xq 1970-01-01 00:00:00 +0000
+++ test/Queries/test18.xq 2013-09-11 04:36:11 +0000
@@ -0,0 +1,18 @@
+import module namespace s = "http://zorba.io/modules/sqlite";;
+
+let $db := s:connect("")
+
+return {
+ variable $p-stmt1 := s:prepare-statement($db, "CREATE TABLE smalltable (id INTEGER primary key asc, name TEXT not null, calories TEXT)");
+ variable $inst := s:execute-update-prepared($p-stmt1);
+ variable $p-stmt2 := s:prepare-statement($db, "INSERT INTO smalltable (name, calories) VALUES (?, ?)");
+ s:clear-params($p-stmt2);
+ s:set-string($p-stmt2, 1, 'one');
+ s:set-string($p-stmt2, 2, '100');
+ variable $upd1 := s:execute-update-prepared($p-stmt2);
+ variable $p-stmt3 := s:prepare-statement($db, 'SELECT * FROM smalltable');
+ variable $res := s:execute-query-prepared($p-stmt3);
+ s:close-prepared($p-stmt1);
+ s:close-prepared($p-stmt2);
+ $res
+}
=== added file 'test/Queries/test2.xq'
--- test/Queries/test2.xq 1970-01-01 00:00:00 +0000
+++ test/Queries/test2.xq 2013-09-11 04:36:11 +0000
@@ -0,0 +1,13 @@
+import module namespace s = "http://zorba.io/modules/sqlite";;
+import module namespace f = "http://expath.org/ns/file";;
+
+let $path := f:path-to-native(resolve-uri("./"))
+let $db := s:connect(concat($path, "small2.db"))
+
+return {
+ variable $result := s:execute-query($db, "SELECT * FROM smalltable");
+ for $e in $result
+ let $cal := $e("calories")
+ order by $cal
+ return $e
+}
=== added file 'test/Queries/test3.spec'
--- test/Queries/test3.spec 1970-01-01 00:00:00 +0000
+++ test/Queries/test3.spec 2013-09-11 04:36:11 +0000
@@ -0,0 +1,1 @@
+Error: http://zorba.io/modules/sqlite:UNAVAILABLE-METADATA
=== added file 'test/Queries/test3.xq'
--- test/Queries/test3.xq 1970-01-01 00:00:00 +0000
+++ test/Queries/test3.xq 2013-09-11 04:36:11 +0000
@@ -0,0 +1,12 @@
+import module namespace s = "http://zorba.io/modules/sqlite";;
+import module namespace f = "http://expath.org/ns/file";;
+
+let $path := f:path-to-native(resolve-uri("./"))
+let $db := s:connect(concat($path, "small2.db"))
+
+return {
+ variable $prep-statement := s:prepare-statement($db, "SELECT * FROM smalltable");
+ variable $meta := s:metadata($prep-statement);
+ for $i in 1 to jn:size($meta("columns"))
+ return $meta("columns")($i)
+}
=== added file 'test/Queries/test4.spec'
--- test/Queries/test4.spec 1970-01-01 00:00:00 +0000
+++ test/Queries/test4.spec 2013-09-11 04:36:11 +0000
@@ -0,0 +1,1 @@
+Error: http://zorba.io/modules/sqlite:UNAVAILABLE-METADATA
=== added file 'test/Queries/test4.xq'
--- test/Queries/test4.xq 1970-01-01 00:00:00 +0000
+++ test/Queries/test4.xq 2013-09-11 04:36:11 +0000
@@ -0,0 +1,18 @@
+import module namespace s = "http://zorba.io/modules/sqlite";;
+import module namespace f = "http://expath.org/ns/file";;
+
+let $path := f:path-to-native(resolve-uri("./"))
+let $db := s:connect(concat($path, "small2.db"))
+
+return {
+ variable $prep-statement := s:prepare-statement($db, "SELECT * FROM smalltable");
+ variable $meta := s:metadata($prep-statement);
+ variable $result := s:execute-query-prepared($prep-statement);
+ variable $cols := $meta("columns");
+
+ (for $i in 1 to jn:size($cols)
+ return concat($cols($i)("database"), ":", $cols($i)("table"), ":", $cols($i)("name"), " = ", $cols($i)("type"), "; ")
+ ,
+ for $e in $result
+ return $e)
+}
=== added file 'test/Queries/test5.spec'
--- test/Queries/test5.spec 1970-01-01 00:00:00 +0000
+++ test/Queries/test5.spec 2013-09-11 04:36:11 +0000
@@ -0,0 +1,1 @@
+Error: http://zorba.io/modules/sqlite:UNAVAILABLE-METADATA
=== added file 'test/Queries/test5.xq'
--- test/Queries/test5.xq 1970-01-01 00:00:00 +0000
+++ test/Queries/test5.xq 2013-09-11 04:36:11 +0000
@@ -0,0 +1,15 @@
+import module namespace s = "http://zorba.io/modules/sqlite";;
+import module namespace f = "http://expath.org/ns/file";;
+
+let $path := f:path-to-native(resolve-uri("./"))
+let $db := s:connect(concat($path, "small2.db"))
+
+return {
+ variable $prep-statement := s:prepare-statement($db, "SELECT * FROM smalltable WHERE calories > ?");
+ variable $meta := s:metadata($prep-statement);
+ s:set-value($prep-statement, 1, 100);
+ variable $result := s:execute-query-prepared($prep-statement);
+
+ for $e in $result
+ return $e
+}
=== added file 'test/Queries/test6.xq'
--- test/Queries/test6.xq 1970-01-01 00:00:00 +0000
+++ test/Queries/test6.xq 2013-09-11 04:36:11 +0000
@@ -0,0 +1,10 @@
+import module namespace s = "http://zorba.io/modules/sqlite";;
+
+let $db := s:connect("small2.db")
+
+return {
+ variable $comm := s:commit($db);
+ variable $roll := s:rollback($db);
+
+ $comm = $roll
+}
=== added file 'test/Queries/test7.xq'
--- test/Queries/test7.xq 1970-01-01 00:00:00 +0000
+++ test/Queries/test7.xq 2013-09-11 04:36:11 +0000
@@ -0,0 +1,14 @@
+import module namespace s = "http://zorba.io/modules/sqlite";;
+import module namespace f = "http://expath.org/ns/file";;
+
+let $path := f:path-to-native(resolve-uri("./"))
+let $db := s:connect(concat($path, "small2.db"))
+
+return {
+ variable $results := s:execute-query($db, "SELECT id, name, calories FROM smalltable");
+ for $e in $results
+ let $id := $e("id")
+ let $name := $e("name")
+ let $calories := $e("calories")
+ return <food><id>{$id}</id><name>{$name}</name><calories>{$calories}</calories></food>
+}
=== added file 'test/Queries/test8.xq'
--- test/Queries/test8.xq 1970-01-01 00:00:00 +0000
+++ test/Queries/test8.xq 2013-09-11 04:36:11 +0000
@@ -0,0 +1,14 @@
+import module namespace s = "http://zorba.io/modules/sqlite";;
+
+let $db := s:connect("")
+
+return {
+ variable $isconn := s:is-connected($db);
+ variable $result1 := s:execute-update($db, "CREATE TABLE maintable (id INTEGER primary key asc, name TEXT not null, salary REAL)");
+ variable $result2 := s:execute-update($db, "INSERT INTO maintable (name, salary) values('Luis', 100.0)");
+ variable $result3 := s:execute-update($db, "INSERT INTO maintable (name, salary) values('Juan', 200.0)");
+ variable $result4 := s:execute-update($db, "INSERT INTO maintable (name, salary) values('Rodolfo', 300.0)");
+ variable $result5 := s:execute-query($db, "SELECT id, name, salary FROM maintable");
+
+ ($isconn, {"Affected Rows" : $result1}, {"Affected Rows" : $result2}, {"Affected Rows" : $result3}, {"Affected Rows" : $result4}, $result5)
+}
=== added file 'test/Queries/test9.xq'
--- test/Queries/test9.xq 1970-01-01 00:00:00 +0000
+++ test/Queries/test9.xq 2013-09-11 04:36:11 +0000
@@ -0,0 +1,21 @@
+import module namespace s =
+ "http://zorba.io/modules/sqlite";;
+
+let $xml :=
+<root>
+ <food><name>carrot</name><calories>80</calories></food>
+ <food><name>tomato</name><calories>45</calories></food>
+</root>
+let $db := s:connect("")
+let $inst := s:execute-update($db, "CREATE TABLE smalltable (id INTEGER primary key asc, name TEXT not null, calories TEXT)")
+let $prep-stmt := s:prepare-statement($db, "INSERT INTO smalltable (name, calories) VALUES (?, ?)")
+
+for $e in $xml//food
+let $name := $e//name
+let $calories := $e//calories
+return {
+ s:clear-params($prep-stmt);
+ s:set-string($prep-stmt, 1, $name);
+ s:set-string($prep-stmt, 2, $calories);
+ s:execute-update-prepared($prep-stmt)
+}