├── .travis.yml ├── CMakeLists.txt ├── HISTORY ├── Makefile ├── README ├── cmake ├── FindLua.cmake ├── FindSQLite3.cmake ├── dist.cmake └── lua.cmake ├── dist.info ├── doc ├── lsqlite3.html ├── lsqlite3.pod └── pod2html.pl ├── examples ├── aggregate.lua ├── function.lua ├── order.lua ├── simple.lua ├── smart.lua ├── statement.lua └── tracing.lua ├── lsqlite3.c ├── lsqlite3.def ├── lunit.lua ├── test.lua └── tests-sqlite3.lua /.travis.yml: -------------------------------------------------------------------------------- 1 | # 2 | # LuaDist Travis-CI Hook 3 | # 4 | 5 | # We assume C build environments 6 | language: C 7 | 8 | # Try using multiple Lua Implementations 9 | env: 10 | - TOOL="gcc" # Use native compiler (GCC usually) 11 | - TOOL="clang" # Use clang 12 | - TOOL="i686-w64-mingw32" # 32bit MinGW 13 | - TOOL="x86_64-w64-mingw32" # 64bit MinGW 14 | - TOOL="arm-linux-gnueabihf" # ARM hard-float (hf), linux 15 | 16 | # Crosscompile builds may fail 17 | matrix: 18 | allow_failures: 19 | - env: TOOL="i686-w64-mingw32" 20 | - env: TOOL="x86_64-w64-mingw32" 21 | - env: TOOL="arm-linux-gnueabihf" 22 | 23 | # Install dependencies 24 | install: 25 | - git clone git://github.com/LuaDist/Tools.git ~/_tools 26 | - ~/_tools/travis/travis install 27 | 28 | # Bootstap 29 | before_script: 30 | - ~/_tools/travis/travis bootstrap 31 | 32 | # Build the module 33 | script: 34 | - ~/_tools/travis/travis build 35 | 36 | # Execute additional tests or commands 37 | after_script: 38 | - ~/_tools/travis/travis test 39 | 40 | # Only watch the master branch 41 | branches: 42 | only: 43 | - master 44 | 45 | # Notify the LuaDist Dev group if needed 46 | notifications: 47 | recipients: 48 | - luadist-dev@googlegroups.com 49 | email: 50 | on_success: change 51 | on_failure: always 52 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2007-2012 LuaDist. 2 | # Created by Peter Kapec 3 | # Redistribution and use of this file is allowed according to the terms of the MIT license. 4 | # For details see the COPYRIGHT file distributed with LuaDist. 5 | # Please note that the package source code is licensed under its own license. 6 | 7 | project ( lsqlite3 C ) 8 | cmake_minimum_required ( VERSION 2.8 ) 9 | include ( cmake/dist.cmake ) 10 | include ( lua ) 11 | 12 | # Find SQLite3 13 | find_package ( SQLite3 REQUIRED ) 14 | include_directories ( ${SQLITE3_INCLUDE_DIRS} ) 15 | 16 | # Create lsqlite module 17 | install_lua_module ( lsqlite3 lsqlite3.c lsqlite3.def LINK ${SQLITE3_LIBRARIES} ) 18 | install_data ( HISTORY README ) 19 | install_doc( doc/ ) 20 | install_test ( lunit.lua test.lua tests-sqlite3.lua ) 21 | install_example ( examples/ ) 22 | -------------------------------------------------------------------------------- /HISTORY: -------------------------------------------------------------------------------- 1 | 2007-August-15 e 2 | 3 | Version "0.6-devel" 4 | 5 | Since the "0.5-devel" release of this Lua library... 6 | 7 | Tested with SQLite 3.4.2 8 | 9 | Added some documentation. 10 | 11 | Thanks to Thomas Lauer... 12 | 13 | Moved line 525 ("luaL_checktype(L, 2, LUA_TTABLE);") 14 | below the declarations to eliminate non-gcc compiler errors. 15 | 16 | Added create-collation, and associated test case. 17 | 18 | -=- 19 | 20 | 2006-October-02 e 21 | 22 | Since the "0.1-devel" release of this Lua library... 23 | - updated for Lua 5.1 24 | - provide automatic re-preparation of queries after schema changes 25 | - made prepared statements with bindings work with for-loops 26 | - added some compatibility names 27 | - added many test cases, and ported Mike Roth's tests and examples 28 | 29 | -=- 30 | 31 | Below is a header comment from the 2004 "0.1" version of the library... 32 | 33 | /************************************************************************ 34 | $Id: lsqlite3.c,v 1.3 2004/09/05 17:50:32 tngd Exp $ 35 | 36 | To consider: 37 | ------------ 38 | 39 | EXPERIMENTAL APIs 40 | 41 | * sqlite3_progress_handler (implemented) 42 | * sqlite3_commit_hook 43 | 44 | TODO? 45 | 46 | * sqlite3_create_collation 47 | 48 | Changes: 49 | 04-09-2004 50 | ---------- 51 | * changed second return value of db:compile to be the rest of the 52 | sql statement that was not processed instead of the number of 53 | characters of sql not processed (situation in case of success). 54 | * progress callback register function parameter order changed. 55 | number of opcodes is given before the callback now. 56 | 57 | 29-08-2004 e 58 | ------------ 59 | * added version() (now supported in sqlite 3.0.5) 60 | * added db:errmsg db:errcode db:total_changes 61 | * rename vm:get_column to vm:get_value 62 | * merge in Tiago's v1.11 change in dbvm_tostring 63 | 64 | 23-06-2004 e 65 | ------------ 66 | * heavily revised for SQLite3 C API 67 | * row values now returned as native type (not always text) 68 | * added db:nrows (named rows) 69 | * added vm:bind_blob 70 | * added vm:get_column 71 | * removed encode_binary decode_binary (no longer needed or supported) 72 | * removed version encoding error_string (unsupported in v 3.0.1 -- soon?) 73 | 74 | 09-04-2004 75 | ---------- 76 | * renamed db:rows to db:urows 77 | * renamed db:prows to db:rows 78 | 79 | * added vm:get_unames() 80 | * added vm:get_utypes() 81 | * added vm:get_uvalues() 82 | 83 | 08-04-2004 84 | ---------- 85 | * changed db:encoding() and db:version() to use sqlite_libencoding() and 86 | sqlite_libversion() 87 | 88 | * added vm:columns() 89 | * added vm:get_named_types() 90 | * added vm:get_named_values() 91 | 92 | * added db:prows - like db:rows but returns a table with the column values 93 | instead of returning multiple columns seperatly on each iteration 94 | 95 | * added compatibility functions idata,iname,itype,data,type 96 | 97 | * added luaopen_sqlite_module. allow the library to be loaded without 98 | setting a global variable. does the same as luaopen_sqlite, but does not 99 | set the global name "sqlite". 100 | 101 | * vm:bind now also returns an error string in case of error 102 | 103 | 31-03-2004 - 01-04-2004 104 | ----------------------- 105 | * changed most of the internals. now using references (luaL_ref) in 106 | most of the places 107 | 108 | * make the virtual machine interface seperate from the database 109 | handle. db:compile now returns a vm handle 110 | 111 | * added db:rows [for ... in db:rows(...) do ... end] 112 | 113 | * added db:close_vm 114 | 115 | * added sqlite.encode_binary and sqlite.decode_binary 116 | 117 | * attempt to do a strict checking on the return type of the user 118 | defined functions returned values 119 | 120 | 18-01-2004 121 | ---------- 122 | * add check on sql function callback to ensure there is enough stack 123 | space to pass column values as parameters 124 | 125 | 03-12-2003 126 | ---------- 127 | * callback functions now have to return boolean values to abort or 128 | continue operation instead of a zero or non-zero value 129 | 130 | 06-12-2003 131 | ---------- 132 | * make version member of sqlite table a function instead of a string 133 | ************************************************************************/ 134 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | # makefile for lsqlite3 library for Lua 2 | 3 | ifneq "$(shell pkg-config --version)" "" 4 | # automagic setup (OS X fink, Linux apt-get, ..) 5 | # 6 | LUAINC= $(shell pkg-config --cflags lua) 7 | LUALIB= $(shell pkg-config --libs lua) 8 | LUAEXE= lua 9 | # Now, we actually want to _not_ push in stuff to the distro Lua CMOD directory, 10 | # way better to play within /usr/local/lib/lua/5.1/ 11 | #LUACMOD= $(shell pkg-config --variable=INSTALL_CMOD lua) 12 | LUACMOD= /usr/local/lib/lua/5.1/ 13 | # 14 | SQLITE3INC= $(shell pkg-config --cflags sqlite3) 15 | SQLITE3LIB= $(shell pkg-config --libs sqlite3) 16 | else 17 | # manual setup (change these to reflect your Lua installation) 18 | # 19 | BASE= /usr/local 20 | LUAINC= -I$(BASE)/include 21 | LUAEXE= $(BASE)/bin/lua.exe 22 | # LUALIB= -L$(BASE)/lib -llua51 23 | # LUACMOD= $(BASE)/lib/lua/5.1/ 24 | # Windows' LUA_CDIR and LUALIB are both the same as the Lua executable's directory... 25 | LUALIB= -L$(BASE)/bin -llua51 26 | LUACMOD= $(BASE)/bin 27 | # 28 | SQLITE3INC= -I$(BASE)/include 29 | SQLITE3LIB= -L$(BASE)/bin -lsqlite3 30 | # 31 | POD2HTML= perl -x -S doc/pod2html.pl 32 | endif 33 | 34 | TMP=./tmp 35 | DISTDIR=./archive 36 | 37 | # OS detection 38 | # 39 | SHFLAGS=-shared 40 | UNAME= $(shell uname) 41 | ifeq "$(UNAME)" "Linux" 42 | _SO=so 43 | SHFLAGS= -fPIC 44 | endif 45 | ifneq "" "$(findstring BSD,$(UNAME))" 46 | _SO=so 47 | endif 48 | ifeq "$(UNAME)" "Darwin" 49 | _SO=bundle 50 | SHFLAGS= -bundle 51 | endif 52 | ifneq "" "$(findstring msys,$(OSTYPE))" # 'msys' 53 | _SO=dll 54 | endif 55 | 56 | ifndef _SO 57 | $(error $(UNAME)) 58 | $(error Unknown OS) 59 | endif 60 | 61 | # no need to change anything below here - HAH! 62 | CFLAGS= $(INCS) $(DEFS) $(WARN) -O2 $(SHFLAGS) 63 | WARN= -Wall #-ansi -pedantic -Wall 64 | INCS= $(LUAINC) $(SQLITE3INC) 65 | LIBS= $(LUALIB) $(SQLITE3LIB) 66 | 67 | MYNAME= sqlite3 68 | MYLIB= l$(MYNAME) 69 | 70 | VER=$(shell svnversion -c . | sed 's/.*://') 71 | TARFILE = $(DISTDIR)/$(MYLIB)-$(VER).tar.gz 72 | 73 | OBJS= $(MYLIB).o 74 | T= $(MYLIB).$(_SO) 75 | 76 | all: $T 77 | 78 | test: $T 79 | $(LUAEXE) test.lua 80 | $(LUAEXE) tests-sqlite3.lua 81 | 82 | $T: $(OBJS) 83 | $(CC) $(SHFLAGS) -o $@ $(OBJS) $(LIBS) 84 | 85 | install: 86 | cp $T $(LUACMOD) 87 | 88 | clean: 89 | rm -f $(OBJS) $T core core.* a.out test.db 90 | 91 | html: 92 | $(POD2HTML) --title="LuaSQLite 3" --infile=doc/lsqlite3.pod --outfile=doc/lsqlite3.html 93 | 94 | dist: html 95 | echo 'Exporting...' 96 | mkdir -p $(TMP) 97 | mkdir -p $(DISTDIR) 98 | svn export -r HEAD . $(TMP)/$(MYLIB)-$(VER) 99 | mkdir -p $(TMP)/$(MYLIB)-$(VER)/doc 100 | cp -p doc/lsqlite3.html $(TMP)/$(MYLIB)-$(VER)/doc 101 | echo 'Compressing...' 102 | tar -zcf $(TARFILE) -C $(TMP) $(MYLIB)-$(VER) 103 | rm -fr $(TMP)/$(MYLIB)-$(VER) 104 | echo 'Done.' 105 | 106 | .PHONY: all test clean dist install 107 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | 2 | LuaSQLite 3 provides a means to manipulate SQLite3 3 | databases directly from lua using Lua 5. 4 | 5 | To use this library you need SQLite3 library. 6 | You can get it from http://www.sqlite.org/ 7 | 8 | Lua 5 is available from http://www.lua.org/ 9 | -------------------------------------------------------------------------------- /cmake/FindLua.cmake: -------------------------------------------------------------------------------- 1 | # Locate Lua library 2 | # This module defines 3 | # LUA_EXECUTABLE, if found 4 | # LUA_FOUND, if false, do not try to link to Lua 5 | # LUA_LIBRARIES 6 | # LUA_INCLUDE_DIR, where to find lua.h 7 | # LUA_VERSION_STRING, the version of Lua found (since CMake 2.8.8) 8 | # 9 | # Note that the expected include convention is 10 | # #include "lua.h" 11 | # and not 12 | # #include 13 | # This is because, the lua location is not standardized and may exist 14 | # in locations other than lua/ 15 | 16 | #============================================================================= 17 | # Copyright 2007-2009 Kitware, Inc. 18 | # Modified to support Lua 5.2 by LuaDist 2012 19 | # 20 | # Distributed under the OSI-approved BSD License (the "License"); 21 | # see accompanying file Copyright.txt for details. 22 | # 23 | # This software is distributed WITHOUT ANY WARRANTY; without even the 24 | # implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 25 | # See the License for more information. 26 | #============================================================================= 27 | # (To distribute this file outside of CMake, substitute the full 28 | # License text for the above reference.) 29 | # 30 | # The required version of Lua can be specified using the 31 | # standard syntax, e.g. FIND_PACKAGE(Lua 5.1) 32 | # Otherwise the module will search for any available Lua implementation 33 | 34 | # Always search for non-versioned lua first (recommended) 35 | SET(_POSSIBLE_LUA_INCLUDE include include/lua) 36 | SET(_POSSIBLE_LUA_EXECUTABLE lua) 37 | SET(_POSSIBLE_LUA_LIBRARY lua) 38 | 39 | # Determine possible naming suffixes (there is no standard for this) 40 | IF(Lua_FIND_VERSION_MAJOR AND Lua_FIND_VERSION_MINOR) 41 | SET(_POSSIBLE_SUFFIXES "${Lua_FIND_VERSION_MAJOR}${Lua_FIND_VERSION_MINOR}" "${Lua_FIND_VERSION_MAJOR}.${Lua_FIND_VERSION_MINOR}" "-${Lua_FIND_VERSION_MAJOR}.${Lua_FIND_VERSION_MINOR}") 42 | ELSE(Lua_FIND_VERSION_MAJOR AND Lua_FIND_VERSION_MINOR) 43 | SET(_POSSIBLE_SUFFIXES "52" "5.2" "-5.2" "51" "5.1" "-5.1") 44 | ENDIF(Lua_FIND_VERSION_MAJOR AND Lua_FIND_VERSION_MINOR) 45 | 46 | # Set up possible search names and locations 47 | FOREACH(_SUFFIX ${_POSSIBLE_SUFFIXES}) 48 | LIST(APPEND _POSSIBLE_LUA_INCLUDE "include/lua${_SUFFIX}") 49 | LIST(APPEND _POSSIBLE_LUA_EXECUTABLE "lua${_SUFFIX}") 50 | LIST(APPEND _POSSIBLE_LUA_LIBRARY "lua${_SUFFIX}") 51 | ENDFOREACH(_SUFFIX) 52 | 53 | # Find the lua executable 54 | FIND_PROGRAM(LUA_EXECUTABLE 55 | NAMES ${_POSSIBLE_LUA_EXECUTABLE} 56 | ) 57 | 58 | # Find the lua header 59 | FIND_PATH(LUA_INCLUDE_DIR lua.h 60 | HINTS 61 | $ENV{LUA_DIR} 62 | PATH_SUFFIXES ${_POSSIBLE_LUA_INCLUDE} 63 | PATHS 64 | ~/Library/Frameworks 65 | /Library/Frameworks 66 | /usr/local 67 | /usr 68 | /sw # Fink 69 | /opt/local # DarwinPorts 70 | /opt/csw # Blastwave 71 | /opt 72 | ) 73 | 74 | # Find the lua library 75 | FIND_LIBRARY(LUA_LIBRARY 76 | NAMES ${_POSSIBLE_LUA_LIBRARY} 77 | HINTS 78 | $ENV{LUA_DIR} 79 | PATH_SUFFIXES lib64 lib 80 | PATHS 81 | ~/Library/Frameworks 82 | /Library/Frameworks 83 | /usr/local 84 | /usr 85 | /sw 86 | /opt/local 87 | /opt/csw 88 | /opt 89 | ) 90 | 91 | IF(LUA_LIBRARY) 92 | # include the math library for Unix 93 | IF(UNIX AND NOT APPLE) 94 | FIND_LIBRARY(LUA_MATH_LIBRARY m) 95 | SET( LUA_LIBRARIES "${LUA_LIBRARY};${LUA_MATH_LIBRARY}" CACHE STRING "Lua Libraries") 96 | # For Windows and Mac, don't need to explicitly include the math library 97 | ELSE(UNIX AND NOT APPLE) 98 | SET( LUA_LIBRARIES "${LUA_LIBRARY}" CACHE STRING "Lua Libraries") 99 | ENDIF(UNIX AND NOT APPLE) 100 | ENDIF(LUA_LIBRARY) 101 | 102 | # Determine Lua version 103 | IF(LUA_INCLUDE_DIR AND EXISTS "${LUA_INCLUDE_DIR}/lua.h") 104 | FILE(STRINGS "${LUA_INCLUDE_DIR}/lua.h" lua_version_str REGEX "^#define[ \t]+LUA_RELEASE[ \t]+\"Lua .+\"") 105 | 106 | STRING(REGEX REPLACE "^#define[ \t]+LUA_RELEASE[ \t]+\"Lua ([^\"]+)\".*" "\\1" LUA_VERSION_STRING "${lua_version_str}") 107 | UNSET(lua_version_str) 108 | ENDIF() 109 | 110 | INCLUDE(FindPackageHandleStandardArgs) 111 | # handle the QUIETLY and REQUIRED arguments and set LUA_FOUND to TRUE if 112 | # all listed variables are TRUE 113 | FIND_PACKAGE_HANDLE_STANDARD_ARGS(Lua 114 | REQUIRED_VARS LUA_LIBRARIES LUA_INCLUDE_DIR 115 | VERSION_VAR LUA_VERSION_STRING) 116 | 117 | MARK_AS_ADVANCED(LUA_INCLUDE_DIR LUA_LIBRARIES LUA_LIBRARY LUA_MATH_LIBRARY LUA_EXECUTABLE) 118 | 119 | -------------------------------------------------------------------------------- /cmake/FindSQLite3.cmake: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2007-2009 LuaDist. 2 | # Created by Peter Kapec 3 | # Redistribution and use of this file is allowed according to the terms of the MIT license. 4 | # For details see the COPYRIGHT file distributed with LuaDist. 5 | # Note: 6 | # Searching headers and libraries is very simple and is NOT as powerful as scripts 7 | # distributed with CMake, because LuaDist defines directories to search for. 8 | # Everyone is encouraged to contact the author with improvements. Maybe this file 9 | # becomes part of CMake distribution sometimes. 10 | 11 | # - Find sqlite3 12 | # Find the native SQLITE3 headers and libraries. 13 | # 14 | # SQLITE3_INCLUDE_DIRS - where to find sqlite3.h, etc. 15 | # SQLITE3_LIBRARIES - List of libraries when using sqlite. 16 | # SQLITE3_FOUND - True if sqlite found. 17 | 18 | # Look for the header file. 19 | FIND_PATH(SQLITE3_INCLUDE_DIR NAMES sqlite3.h) 20 | 21 | # Look for the library. 22 | FIND_LIBRARY(SQLITE3_LIBRARY NAMES sqlite3 libsqlite3 sqlite libsqlite) 23 | 24 | # Handle the QUIETLY and REQUIRED arguments and set SQLITE3_FOUND to TRUE if all listed variables are TRUE. 25 | INCLUDE(FindPackageHandleStandardArgs) 26 | FIND_PACKAGE_HANDLE_STANDARD_ARGS(SQLITE3 DEFAULT_MSG SQLITE3_LIBRARY SQLITE3_INCLUDE_DIR) 27 | 28 | # Copy the results to the output variables. 29 | IF(SQLITE3_FOUND) 30 | SET(SQLITE3_LIBRARIES ${SQLITE3_LIBRARY}) 31 | SET(SQLITE3_INCLUDE_DIRS ${SQLITE3_INCLUDE_DIR}) 32 | ELSE(SQLITE3_FOUND) 33 | SET(SQLITE3_LIBRARIES) 34 | SET(SQLITE3_INCLUDE_DIRS) 35 | ENDIF(SQLITE3_FOUND) 36 | 37 | MARK_AS_ADVANCED(SQLITE3_INCLUDE_DIRS SQLITE3_LIBRARIES) 38 | -------------------------------------------------------------------------------- /cmake/dist.cmake: -------------------------------------------------------------------------------- 1 | # LuaDist CMake utility library. 2 | # Provides sane project defaults and macros common to LuaDist CMake builds. 3 | # 4 | # Copyright (C) 2007-2012 LuaDist. 5 | # by David Manura, Peter Drahoš 6 | # Redistribution and use of this file is allowed according to the terms of the MIT license. 7 | # For details see the COPYRIGHT file distributed with LuaDist. 8 | # Please note that the package source code is licensed under its own license. 9 | 10 | ## Extract information from dist.info 11 | if ( NOT EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/dist.info ) 12 | message ( FATAL_ERROR 13 | "Missing dist.info file (${CMAKE_CURRENT_SOURCE_DIR}/dist.info)." ) 14 | endif () 15 | file ( READ ${CMAKE_CURRENT_SOURCE_DIR}/dist.info DIST_INFO ) 16 | if ( "${DIST_INFO}" STREQUAL "" ) 17 | message ( FATAL_ERROR "Failed to load dist.info." ) 18 | endif () 19 | # Reads field `name` from dist.info string `DIST_INFO` into variable `var`. 20 | macro ( _parse_dist_field name var ) 21 | string ( REGEX REPLACE ".*${name}[ \t]?=[ \t]?[\"']([^\"']+)[\"'].*" "\\1" 22 | ${var} "${DIST_INFO}" ) 23 | if ( ${var} STREQUAL DIST_INFO ) 24 | message ( FATAL_ERROR "Failed to extract \"${var}\" from dist.info" ) 25 | endif () 26 | endmacro () 27 | # 28 | _parse_dist_field ( name DIST_NAME ) 29 | _parse_dist_field ( version DIST_VERSION ) 30 | _parse_dist_field ( license DIST_LICENSE ) 31 | _parse_dist_field ( author DIST_AUTHOR ) 32 | _parse_dist_field ( maintainer DIST_MAINTAINER ) 33 | _parse_dist_field ( url DIST_URL ) 34 | _parse_dist_field ( desc DIST_DESC ) 35 | message ( "DIST_NAME: ${DIST_NAME}") 36 | message ( "DIST_VERSION: ${DIST_VERSION}") 37 | message ( "DIST_LICENSE: ${DIST_LICENSE}") 38 | message ( "DIST_AUTHOR: ${DIST_AUTHOR}") 39 | message ( "DIST_MAINTAINER: ${DIST_MAINTAINER}") 40 | message ( "DIST_URL: ${DIST_URL}") 41 | message ( "DIST_DESC: ${DIST_DESC}") 42 | string ( REGEX REPLACE ".*depends[ \t]?=[ \t]?[\"']([^\"']+)[\"'].*" "\\1" 43 | DIST_DEPENDS ${DIST_INFO} ) 44 | if ( DIST_DEPENDS STREQUAL DIST_INFO ) 45 | set ( DIST_DEPENDS "" ) 46 | endif () 47 | message ( "DIST_DEPENDS: ${DIST_DEPENDS}") 48 | ## 2DO: Parse DIST_DEPENDS and try to install Dependencies with automatically using externalproject_add 49 | 50 | 51 | ## INSTALL DEFAULTS (Relative to CMAKE_INSTALL_PREFIX) 52 | # Primary paths 53 | set ( INSTALL_BIN bin CACHE PATH "Where to install binaries to." ) 54 | set ( INSTALL_LIB lib CACHE PATH "Where to install libraries to." ) 55 | set ( INSTALL_INC include CACHE PATH "Where to install headers to." ) 56 | set ( INSTALL_ETC etc CACHE PATH "Where to store configuration files" ) 57 | set ( INSTALL_SHARE share CACHE PATH "Directory for shared data." ) 58 | 59 | # Secondary paths 60 | option ( INSTALL_VERSION 61 | "Install runtime libraries and executables with version information." OFF) 62 | set ( INSTALL_DATA ${INSTALL_SHARE}/${DIST_NAME} CACHE PATH 63 | "Directory the package can store documentation, tests or other data in.") 64 | set ( INSTALL_DOC ${INSTALL_DATA}/doc CACHE PATH 65 | "Recommended directory to install documentation into.") 66 | set ( INSTALL_EXAMPLE ${INSTALL_DATA}/example CACHE PATH 67 | "Recommended directory to install examples into.") 68 | set ( INSTALL_TEST ${INSTALL_DATA}/test CACHE PATH 69 | "Recommended directory to install tests into.") 70 | set ( INSTALL_FOO ${INSTALL_DATA}/etc CACHE PATH 71 | "Where to install additional files") 72 | 73 | # Tweaks and other defaults 74 | # Setting CMAKE to use loose block and search for find modules in source directory 75 | set ( CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS true ) 76 | set ( CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake" ${CMAKE_MODULE_PATH} ) 77 | option ( BUILD_SHARED_LIBS "Build shared libraries" ON ) 78 | 79 | # In MSVC, prevent warnings that can occur when using standard libraries. 80 | if ( MSVC ) 81 | add_definitions ( -D_CRT_SECURE_NO_WARNINGS ) 82 | endif () 83 | 84 | # RPath and relative linking 85 | option ( USE_RPATH "Use relative linking." ON) 86 | if ( USE_RPATH ) 87 | string ( REGEX REPLACE "[^!/]+" ".." UP_DIR ${INSTALL_BIN} ) 88 | set ( CMAKE_SKIP_BUILD_RPATH FALSE CACHE STRING "" FORCE ) 89 | set ( CMAKE_BUILD_WITH_INSTALL_RPATH FALSE CACHE STRING "" FORCE ) 90 | set ( CMAKE_INSTALL_RPATH $ORIGIN/${UP_DIR}/${INSTALL_LIB} 91 | CACHE STRING "" FORCE ) 92 | set ( CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE CACHE STRING "" FORCE ) 93 | set ( CMAKE_INSTALL_NAME_DIR @executable_path/${UP_DIR}/${INSTALL_LIB} 94 | CACHE STRING "" FORCE ) 95 | endif () 96 | 97 | ## MACROS 98 | # Parser macro 99 | macro ( parse_arguments prefix arg_names option_names) 100 | set ( DEFAULT_ARGS ) 101 | foreach ( arg_name ${arg_names} ) 102 | set ( ${prefix}_${arg_name} ) 103 | endforeach () 104 | foreach ( option ${option_names} ) 105 | set ( ${prefix}_${option} FALSE ) 106 | endforeach () 107 | 108 | set ( current_arg_name DEFAULT_ARGS ) 109 | set ( current_arg_list ) 110 | foreach ( arg ${ARGN} ) 111 | set ( larg_names ${arg_names} ) 112 | list ( FIND larg_names "${arg}" is_arg_name ) 113 | if ( is_arg_name GREATER -1 ) 114 | set ( ${prefix}_${current_arg_name} ${current_arg_list} ) 115 | set ( current_arg_name ${arg} ) 116 | set ( current_arg_list ) 117 | else () 118 | set ( loption_names ${option_names} ) 119 | list ( FIND loption_names "${arg}" is_option ) 120 | if ( is_option GREATER -1 ) 121 | set ( ${prefix}_${arg} TRUE ) 122 | else () 123 | set ( current_arg_list ${current_arg_list} ${arg} ) 124 | endif () 125 | endif () 126 | endforeach () 127 | set ( ${prefix}_${current_arg_name} ${current_arg_list} ) 128 | endmacro () 129 | 130 | 131 | # install_executable ( executable_targets ) 132 | # Installs any executables generated using "add_executable". 133 | # USE: install_executable ( lua ) 134 | # NOTE: subdirectories are NOT supported 135 | set ( CPACK_COMPONENT_RUNTIME_DISPLAY_NAME "${DIST_NAME} Runtime" ) 136 | set ( CPACK_COMPONENT_RUNTIME_DESCRIPTION 137 | "Executables and runtime libraries. Installed into ${INSTALL_BIN}." ) 138 | macro ( install_executable ) 139 | foreach ( _file ${ARGN} ) 140 | if ( INSTALL_VERSION ) 141 | set_target_properties ( ${_file} PROPERTIES VERSION ${DIST_VERSION} 142 | SOVERSION ${DIST_VERSION} ) 143 | endif () 144 | install ( TARGETS ${_file} RUNTIME DESTINATION ${INSTALL_BIN} 145 | COMPONENT Runtime ) 146 | endforeach() 147 | endmacro () 148 | 149 | # install_library ( library_targets ) 150 | # Installs any libraries generated using "add_library" into apropriate places. 151 | # USE: install_library ( libexpat ) 152 | # NOTE: subdirectories are NOT supported 153 | set ( CPACK_COMPONENT_LIBRARY_DISPLAY_NAME "${DIST_NAME} Development Libraries" ) 154 | set ( CPACK_COMPONENT_LIBRARY_DESCRIPTION 155 | "Static and import libraries needed for development. Installed into ${INSTALL_LIB} or ${INSTALL_BIN}." ) 156 | macro ( install_library ) 157 | foreach ( _file ${ARGN} ) 158 | if ( INSTALL_VERSION ) 159 | set_target_properties ( ${_file} PROPERTIES VERSION ${DIST_VERSION} 160 | SOVERSION ${DIST_VERSION} ) 161 | endif () 162 | install ( TARGETS ${_file} 163 | RUNTIME DESTINATION ${INSTALL_BIN} COMPONENT Runtime 164 | LIBRARY DESTINATION ${INSTALL_LIB} COMPONENT Runtime 165 | ARCHIVE DESTINATION ${INSTALL_LIB} COMPONENT Library ) 166 | endforeach() 167 | endmacro () 168 | 169 | # helper function for various install_* functions, for PATTERN/REGEX args. 170 | macro ( _complete_install_args ) 171 | if ( NOT("${_ARG_PATTERN}" STREQUAL "") ) 172 | set ( _ARG_PATTERN PATTERN ${_ARG_PATTERN} ) 173 | endif () 174 | if ( NOT("${_ARG_REGEX}" STREQUAL "") ) 175 | set ( _ARG_REGEX REGEX ${_ARG_REGEX} ) 176 | endif () 177 | endmacro () 178 | 179 | # install_header ( files/directories [INTO destination] ) 180 | # Install a directories or files into header destination. 181 | # USE: install_header ( lua.h luaconf.h ) or install_header ( GL ) 182 | # USE: install_header ( mylib.h INTO mylib ) 183 | # For directories, supports optional PATTERN/REGEX arguments like install(). 184 | set ( CPACK_COMPONENT_HEADER_DISPLAY_NAME "${DIST_NAME} Development Headers" ) 185 | set ( CPACK_COMPONENT_HEADER_DESCRIPTION 186 | "Headers needed for development. Installed into ${INSTALL_INC}." ) 187 | macro ( install_header ) 188 | parse_arguments ( _ARG "INTO;PATTERN;REGEX" "" ${ARGN} ) 189 | _complete_install_args() 190 | foreach ( _file ${_ARG_DEFAULT_ARGS} ) 191 | if ( IS_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/${_file}" ) 192 | install ( DIRECTORY ${_file} DESTINATION ${INSTALL_INC}/${_ARG_INTO} 193 | COMPONENT Header ${_ARG_PATTERN} ${_ARG_REGEX} ) 194 | else () 195 | install ( FILES ${_file} DESTINATION ${INSTALL_INC}/${_ARG_INTO} 196 | COMPONENT Header ) 197 | endif () 198 | endforeach() 199 | endmacro () 200 | 201 | # install_data ( files/directories [INTO destination] ) 202 | # This installs additional data files or directories. 203 | # USE: install_data ( extra data.dat ) 204 | # USE: install_data ( image1.png image2.png INTO images ) 205 | # For directories, supports optional PATTERN/REGEX arguments like install(). 206 | set ( CPACK_COMPONENT_DATA_DISPLAY_NAME "${DIST_NAME} Data" ) 207 | set ( CPACK_COMPONENT_DATA_DESCRIPTION 208 | "Application data. Installed into ${INSTALL_DATA}." ) 209 | macro ( install_data ) 210 | parse_arguments ( _ARG "INTO;PATTERN;REGEX" "" ${ARGN} ) 211 | _complete_install_args() 212 | foreach ( _file ${_ARG_DEFAULT_ARGS} ) 213 | if ( IS_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/${_file}" ) 214 | install ( DIRECTORY ${_file} 215 | DESTINATION ${INSTALL_DATA}/${_ARG_INTO} 216 | COMPONENT Data ${_ARG_PATTERN} ${_ARG_REGEX} ) 217 | else () 218 | install ( FILES ${_file} DESTINATION ${INSTALL_DATA}/${_ARG_INTO} 219 | COMPONENT Data ) 220 | endif () 221 | endforeach() 222 | endmacro () 223 | 224 | # INSTALL_DOC ( files/directories [INTO destination] ) 225 | # This installs documentation content 226 | # USE: install_doc ( doc/ doc.pdf ) 227 | # USE: install_doc ( index.html INTO html ) 228 | # For directories, supports optional PATTERN/REGEX arguments like install(). 229 | set ( CPACK_COMPONENT_DOCUMENTATION_DISPLAY_NAME "${DIST_NAME} Documentation" ) 230 | set ( CPACK_COMPONENT_DOCUMENTATION_DESCRIPTION 231 | "Application documentation. Installed into ${INSTALL_DOC}." ) 232 | macro ( install_doc ) 233 | parse_arguments ( _ARG "INTO;PATTERN;REGEX" "" ${ARGN} ) 234 | _complete_install_args() 235 | foreach ( _file ${_ARG_DEFAULT_ARGS} ) 236 | if ( IS_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/${_file}" ) 237 | install ( DIRECTORY ${_file} DESTINATION ${INSTALL_DOC}/${_ARG_INTO} 238 | COMPONENT Documentation ${_ARG_PATTERN} ${_ARG_REGEX} ) 239 | else () 240 | install ( FILES ${_file} DESTINATION ${INSTALL_DOC}/${_ARG_INTO} 241 | COMPONENT Documentation ) 242 | endif () 243 | endforeach() 244 | endmacro () 245 | 246 | # install_example ( files/directories [INTO destination] ) 247 | # This installs additional examples 248 | # USE: install_example ( examples/ exampleA ) 249 | # USE: install_example ( super_example super_data INTO super) 250 | # For directories, supports optional PATTERN/REGEX argument like install(). 251 | set ( CPACK_COMPONENT_EXAMPLE_DISPLAY_NAME "${DIST_NAME} Examples" ) 252 | set ( CPACK_COMPONENT_EXAMPLE_DESCRIPTION 253 | "Examples and their associated data. Installed into ${INSTALL_EXAMPLE}." ) 254 | macro ( install_example ) 255 | parse_arguments ( _ARG "INTO;PATTERN;REGEX" "" ${ARGN} ) 256 | _complete_install_args() 257 | foreach ( _file ${_ARG_DEFAULT_ARGS} ) 258 | if ( IS_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/${_file}" ) 259 | install ( DIRECTORY ${_file} DESTINATION ${INSTALL_EXAMPLE}/${_ARG_INTO} 260 | COMPONENT Example ${_ARG_PATTERN} ${_ARG_REGEX} ) 261 | else () 262 | install ( FILES ${_file} DESTINATION ${INSTALL_EXAMPLE}/${_ARG_INTO} 263 | COMPONENT Example ) 264 | endif () 265 | endforeach() 266 | endmacro () 267 | 268 | # install_test ( files/directories [INTO destination] ) 269 | # This installs tests and test files, DOES NOT EXECUTE TESTS 270 | # USE: install_test ( my_test data.sql ) 271 | # USE: install_test ( feature_x_test INTO x ) 272 | # For directories, supports optional PATTERN/REGEX argument like install(). 273 | set ( CPACK_COMPONENT_TEST_DISPLAY_NAME "${DIST_NAME} Tests" ) 274 | set ( CPACK_COMPONENT_TEST_DESCRIPTION 275 | "Tests and associated data. Installed into ${INSTALL_TEST}." ) 276 | macro ( install_test ) 277 | parse_arguments ( _ARG "INTO;PATTERN;REGEX" "" ${ARGN} ) 278 | _complete_install_args() 279 | foreach ( _file ${_ARG_DEFAULT_ARGS} ) 280 | if ( IS_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/${_file}" ) 281 | install ( DIRECTORY ${_file} DESTINATION ${INSTALL_TEST}/${_ARG_INTO} 282 | COMPONENT Test ${_ARG_PATTERN} ${_ARG_REGEX} ) 283 | else () 284 | install ( FILES ${_file} DESTINATION ${INSTALL_TEST}/${_ARG_INTO} 285 | COMPONENT Test ) 286 | endif () 287 | endforeach() 288 | endmacro () 289 | 290 | # install_foo ( files/directories [INTO destination] ) 291 | # This installs optional or otherwise unneeded content 292 | # USE: install_foo ( etc/ example.doc ) 293 | # USE: install_foo ( icon.png logo.png INTO icons) 294 | # For directories, supports optional PATTERN/REGEX argument like install(). 295 | set ( CPACK_COMPONENT_OTHER_DISPLAY_NAME "${DIST_NAME} Unspecified Content" ) 296 | set ( CPACK_COMPONENT_OTHER_DESCRIPTION 297 | "Other unspecified content. Installed into ${INSTALL_FOO}." ) 298 | macro ( install_foo ) 299 | parse_arguments ( _ARG "INTO;PATTERN;REGEX" "" ${ARGN} ) 300 | _complete_install_args() 301 | foreach ( _file ${_ARG_DEFAULT_ARGS} ) 302 | if ( IS_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/${_file}" ) 303 | install ( DIRECTORY ${_file} DESTINATION ${INSTALL_FOO}/${_ARG_INTO} 304 | COMPONENT Other ${_ARG_PATTERN} ${_ARG_REGEX} ) 305 | else () 306 | install ( FILES ${_file} DESTINATION ${INSTALL_FOO}/${_ARG_INTO} 307 | COMPONENT Other ) 308 | endif () 309 | endforeach() 310 | endmacro () 311 | 312 | ## CTest defaults 313 | 314 | ## CPack defaults 315 | set ( CPACK_GENERATOR "ZIP" ) 316 | set ( CPACK_STRIP_FILES TRUE ) 317 | set ( CPACK_PACKAGE_NAME "${DIST_NAME}" ) 318 | set ( CPACK_PACKAGE_VERSION "${DIST_VERSION}") 319 | set ( CPACK_PACKAGE_VENDOR "LuaDist" ) 320 | set ( CPACK_COMPONENTS_ALL Runtime Library Header Data Documentation Example Other ) 321 | include ( CPack ) 322 | -------------------------------------------------------------------------------- /cmake/lua.cmake: -------------------------------------------------------------------------------- 1 | # LuaDist CMake utility library for Lua. 2 | # 3 | # Copyright (C) 2007-2012 LuaDist. 4 | # by David Manura, Peter Drahos 5 | # Redistribution and use of this file is allowed according to the terms of the MIT license. 6 | # For details see the COPYRIGHT file distributed with LuaDist. 7 | # Please note that the package source code is licensed under its own license. 8 | 9 | set ( INSTALL_LMOD ${INSTALL_LIB}/lua 10 | CACHE PATH "Directory to install Lua modules." ) 11 | set ( INSTALL_CMOD ${INSTALL_LIB}/lua 12 | CACHE PATH "Directory to install Lua binary modules." ) 13 | 14 | option ( SKIP_LUA_WRAPPER 15 | "Do not build and install Lua executable wrappers." OFF) 16 | 17 | # List of (Lua module name, file path) pairs. 18 | # Used internally by add_lua_test. Built by add_lua_module. 19 | set ( _lua_modules ) 20 | 21 | # utility function: appends path `path` to path `basepath`, properly 22 | # handling cases when `path` may be relative or absolute. 23 | macro ( _append_path basepath path result ) 24 | if ( IS_ABSOLUTE "${path}" ) 25 | set ( ${result} "${path}" ) 26 | else () 27 | set ( ${result} "${basepath}/${path}" ) 28 | endif () 29 | endmacro () 30 | 31 | # install_lua_executable ( target source ) 32 | # Automatically generate a binary if srlua package is available 33 | # The application or its source will be placed into /bin 34 | # If the application source did not have .lua suffix then it will be added 35 | # USE: lua_executable ( sputnik src/sputnik.lua ) 36 | macro ( install_lua_executable _name _source ) 37 | get_filename_component ( _source_name ${_source} NAME_WE ) 38 | # Find srlua and glue 39 | find_program( SRLUA_EXECUTABLE NAMES srlua ) 40 | find_program( GLUE_EXECUTABLE NAMES glue ) 41 | # Executable output 42 | set ( _exe ${CMAKE_CURRENT_BINARY_DIR}/${_name}${CMAKE_EXECUTABLE_SUFFIX} ) 43 | if ( NOT SKIP_LUA_WRAPPER AND SRLUA_EXECUTABLE AND GLUE_EXECUTABLE ) 44 | # Generate binary gluing the lua code to srlua, this is a robuust approach for most systems 45 | add_custom_command( 46 | OUTPUT ${_exe} 47 | COMMAND ${GLUE_EXECUTABLE} 48 | ARGS ${SRLUA_EXECUTABLE} ${_source} ${_exe} 49 | DEPENDS ${_source} 50 | WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} 51 | VERBATIM 52 | ) 53 | # Make sure we have a target associated with the binary 54 | add_custom_target(${_name} ALL 55 | DEPENDS ${_exe} 56 | ) 57 | # Install with run permissions 58 | install ( PROGRAMS ${_exe} DESTINATION ${INSTALL_BIN} COMPONENT Runtime) 59 | # Also install source as optional resurce 60 | install ( FILES ${_source} DESTINATION ${INSTALL_FOO} COMPONENT Other ) 61 | else() 62 | # Install into bin as is but without the lua suffix, we assume the executable uses UNIX shebang/hash-bang magic 63 | install ( PROGRAMS ${_source} DESTINATION ${INSTALL_BIN} 64 | RENAME ${_source_name} 65 | COMPONENT Runtime 66 | ) 67 | endif() 68 | endmacro () 69 | 70 | macro ( _lua_module_helper is_install _name ) 71 | parse_arguments ( _MODULE "LINK;ALL_IN_ONE" "" ${ARGN} ) 72 | # _target is CMake-compatible target name for module (e.g. socket_core). 73 | # _module is relative path of target (e.g. socket/core), 74 | # without extension (e.g. .lua/.so/.dll). 75 | # _MODULE_SRC is list of module source files (e.g. .lua and .c files). 76 | # _MODULE_NAMES is list of module names (e.g. socket.core). 77 | if ( _MODULE_ALL_IN_ONE ) 78 | string ( REGEX REPLACE "\\..*" "" _target "${_name}" ) 79 | string ( REGEX REPLACE "\\..*" "" _module "${_name}" ) 80 | set ( _target "${_target}_all_in_one") 81 | set ( _MODULE_SRC ${_MODULE_ALL_IN_ONE} ) 82 | set ( _MODULE_NAMES ${_name} ${_MODULE_DEFAULT_ARGS} ) 83 | else () 84 | string ( REPLACE "." "_" _target "${_name}" ) 85 | string ( REPLACE "." "/" _module "${_name}" ) 86 | set ( _MODULE_SRC ${_MODULE_DEFAULT_ARGS} ) 87 | set ( _MODULE_NAMES ${_name} ) 88 | endif () 89 | if ( NOT _MODULE_SRC ) 90 | message ( FATAL_ERROR "no module sources specified" ) 91 | endif () 92 | list ( GET _MODULE_SRC 0 _first_source ) 93 | 94 | get_filename_component ( _ext ${_first_source} EXT ) 95 | if ( _ext STREQUAL ".lua" ) # Lua source module 96 | list ( LENGTH _MODULE_SRC _len ) 97 | if ( _len GREATER 1 ) 98 | message ( FATAL_ERROR "more than one source file specified" ) 99 | endif () 100 | 101 | set ( _module "${_module}.lua" ) 102 | 103 | get_filename_component ( _module_dir ${_module} PATH ) 104 | get_filename_component ( _module_filename ${_module} NAME ) 105 | _append_path ( "${CMAKE_CURRENT_SOURCE_DIR}" "${_first_source}" _module_path ) 106 | list ( APPEND _lua_modules "${_name}" "${_module_path}" ) 107 | 108 | if ( ${is_install} ) 109 | install ( FILES ${_first_source} DESTINATION ${INSTALL_LMOD}/${_module_dir} 110 | RENAME ${_module_filename} 111 | COMPONENT Runtime 112 | ) 113 | endif () 114 | else () # Lua C binary module 115 | enable_language ( C ) 116 | find_package ( Lua REQUIRED ) 117 | include_directories ( ${LUA_INCLUDE_DIR} ) 118 | 119 | set ( _module "${_module}${CMAKE_SHARED_MODULE_SUFFIX}" ) 120 | 121 | get_filename_component ( _module_dir ${_module} PATH ) 122 | get_filename_component ( _module_filenamebase ${_module} NAME_WE ) 123 | foreach ( _thisname ${_MODULE_NAMES} ) 124 | list ( APPEND _lua_modules "${_thisname}" 125 | "${CMAKE_CURRENT_BINARY_DIR}/\${CMAKE_CFG_INTDIR}/${_module}" ) 126 | endforeach () 127 | 128 | add_library( ${_target} MODULE ${_MODULE_SRC}) 129 | target_link_libraries ( ${_target} ${LUA_LIBRARY} ${_MODULE_LINK} ) 130 | set_target_properties ( ${_target} PROPERTIES LIBRARY_OUTPUT_DIRECTORY 131 | "${_module_dir}" PREFIX "" OUTPUT_NAME "${_module_filenamebase}" ) 132 | if ( ${is_install} ) 133 | install ( TARGETS ${_target} DESTINATION ${INSTALL_CMOD}/${_module_dir} COMPONENT Runtime) 134 | endif () 135 | endif () 136 | endmacro () 137 | 138 | # add_lua_module 139 | # Builds a Lua source module into a destination locatable by Lua 140 | # require syntax. 141 | # Binary modules are also supported where this function takes sources and 142 | # libraries to compile separated by LINK keyword. 143 | # USE: add_lua_module ( socket.http src/http.lua ) 144 | # USE2: add_lua_module ( mime.core src/mime.c ) 145 | # USE3: add_lua_module ( socket.core ${SRC_SOCKET} LINK ${LIB_SOCKET} ) 146 | # USE4: add_lua_module ( ssl.context ssl.core ALL_IN_ONE src/context.c src/ssl.c ) 147 | # This form builds an "all-in-one" module (e.g. ssl.so or ssl.dll containing 148 | # both modules ssl.context and ssl.core). The CMake target name will be 149 | # ssl_all_in_one. 150 | # Also sets variable _module_path (relative path where module typically 151 | # would be installed). 152 | macro ( add_lua_module ) 153 | _lua_module_helper ( 0 ${ARGN} ) 154 | endmacro () 155 | 156 | 157 | # install_lua_module 158 | # This is the same as `add_lua_module` but also installs the module. 159 | # USE: install_lua_module ( socket.http src/http.lua ) 160 | # USE2: install_lua_module ( mime.core src/mime.c ) 161 | # USE3: install_lua_module ( socket.core ${SRC_SOCKET} LINK ${LIB_SOCKET} ) 162 | macro ( install_lua_module ) 163 | _lua_module_helper ( 1 ${ARGN} ) 164 | endmacro () 165 | 166 | # Builds string representing Lua table mapping Lua modules names to file 167 | # paths. Used internally. 168 | macro ( _make_module_table _outvar ) 169 | set ( ${_outvar} ) 170 | list ( LENGTH _lua_modules _n ) 171 | if ( ${_n} GREATER 0 ) # avoids cmake complaint 172 | foreach ( _i RANGE 1 ${_n} 2 ) 173 | list ( GET _lua_modules ${_i} _path ) 174 | math ( EXPR _ii ${_i}-1 ) 175 | list ( GET _lua_modules ${_ii} _name ) 176 | set ( ${_outvar} "${_table} ['${_name}'] = '${_path}'\;\n") 177 | endforeach () 178 | endif () 179 | set ( ${_outvar} 180 | "local modules = { 181 | ${_table}}" ) 182 | endmacro () 183 | 184 | # add_lua_test ( _testfile [ WORKING_DIRECTORY _working_dir ] ) 185 | # Runs Lua script `_testfile` under CTest tester. 186 | # Optional named argument `WORKING_DIRECTORY` is current working directory to 187 | # run test under (defaults to ${CMAKE_CURRENT_BINARY_DIR}). 188 | # Both paths, if relative, are relative to ${CMAKE_CURRENT_SOURCE_DIR}. 189 | # Any modules previously defined with install_lua_module are automatically 190 | # preloaded (via package.preload) prior to running the test script. 191 | # Under LuaDist, set test=true in config.lua to enable testing. 192 | # USE: add_lua_test ( test/test1.lua [args...] [WORKING_DIRECTORY dir]) 193 | macro ( add_lua_test _testfile ) 194 | if ( NOT SKIP_TESTING ) 195 | parse_arguments ( _ARG "WORKING_DIRECTORY" "" ${ARGN} ) 196 | include ( CTest ) 197 | find_program ( LUA NAMES lua lua.bat ) 198 | get_filename_component ( TESTFILEABS ${_testfile} ABSOLUTE ) 199 | get_filename_component ( TESTFILENAME ${_testfile} NAME ) 200 | get_filename_component ( TESTFILEBASE ${_testfile} NAME_WE ) 201 | 202 | # Write wrapper script. 203 | # Note: One simple way to allow the script to find modules is 204 | # to just put them in package.preload. 205 | set ( TESTWRAPPER ${CMAKE_CURRENT_BINARY_DIR}/${TESTFILENAME} ) 206 | _make_module_table ( _table ) 207 | set ( TESTWRAPPERSOURCE 208 | "local CMAKE_CFG_INTDIR = ... or '.' 209 | ${_table} 210 | local function preload_modules(modules) 211 | for name, path in pairs(modules) do 212 | if path:match'%.lua' then 213 | package.preload[name] = assert(loadfile(path)) 214 | else 215 | local name = name:gsub('.*%-', '') -- remove any hyphen prefix 216 | local symbol = 'luaopen_' .. name:gsub('%.', '_') 217 | --improve: generalize to support all-in-one loader? 218 | local path = path:gsub('%$%{CMAKE_CFG_INTDIR%}', CMAKE_CFG_INTDIR) 219 | package.preload[name] = assert(package.loadlib(path, symbol)) 220 | end 221 | end 222 | end 223 | preload_modules(modules) 224 | arg[0] = '${TESTFILEABS}' 225 | table.remove(arg, 1) 226 | return assert(loadfile '${TESTFILEABS}')(unpack(arg)) 227 | " ) 228 | if ( _ARG_WORKING_DIRECTORY ) 229 | get_filename_component ( 230 | TESTCURRENTDIRABS ${_ARG_WORKING_DIRECTORY} ABSOLUTE ) 231 | # note: CMake 2.6 (unlike 2.8) lacks WORKING_DIRECTORY parameter. 232 | set ( _pre ${CMAKE_COMMAND} -E chdir "${TESTCURRENTDIRABS}" ) 233 | endif () 234 | file ( WRITE ${TESTWRAPPER} ${TESTWRAPPERSOURCE}) 235 | add_test ( NAME ${TESTFILEBASE} COMMAND ${_pre} ${LUA} 236 | ${TESTWRAPPER} "${CMAKE_CFG_INTDIR}" 237 | ${_ARG_DEFAULT_ARGS} ) 238 | endif () 239 | # see also http://gdcm.svn.sourceforge.net/viewvc/gdcm/Sandbox/CMakeModules/UsePythonTest.cmake 240 | # Note: ${CMAKE_CFG_INTDIR} is a command-line argument to allow proper 241 | # expansion by the native build tool. 242 | endmacro () 243 | 244 | 245 | # Converts Lua source file `_source` to binary string embedded in C source 246 | # file `_target`. Optionally compiles Lua source to byte code (not available 247 | # under LuaJIT2, which doesn't have a bytecode loader). Additionally, Lua 248 | # versions of bin2c [1] and luac [2] may be passed respectively as additional 249 | # arguments. 250 | # 251 | # [1] http://lua-users.org/wiki/BinToCee 252 | # [2] http://lua-users.org/wiki/LuaCompilerInLua 253 | function ( add_lua_bin2c _target _source ) 254 | find_program ( LUA NAMES lua lua.bat ) 255 | execute_process ( COMMAND ${LUA} -e "string.dump(function()end)" 256 | RESULT_VARIABLE _LUA_DUMP_RESULT ERROR_QUIET ) 257 | if ( NOT ${_LUA_DUMP_RESULT} ) 258 | SET ( HAVE_LUA_DUMP true ) 259 | endif () 260 | message ( "-- string.dump=${HAVE_LUA_DUMP}" ) 261 | 262 | if ( ARGV2 ) 263 | get_filename_component ( BIN2C ${ARGV2} ABSOLUTE ) 264 | set ( BIN2C ${LUA} ${BIN2C} ) 265 | else () 266 | find_program ( BIN2C NAMES bin2c bin2c.bat ) 267 | endif () 268 | if ( HAVE_LUA_DUMP ) 269 | if ( ARGV3 ) 270 | get_filename_component ( LUAC ${ARGV3} ABSOLUTE ) 271 | set ( LUAC ${LUA} ${LUAC} ) 272 | else () 273 | find_program ( LUAC NAMES luac luac.bat ) 274 | endif () 275 | endif ( HAVE_LUA_DUMP ) 276 | message ( "-- bin2c=${BIN2C}" ) 277 | message ( "-- luac=${LUAC}" ) 278 | 279 | get_filename_component ( SOURCEABS ${_source} ABSOLUTE ) 280 | if ( HAVE_LUA_DUMP ) 281 | get_filename_component ( SOURCEBASE ${_source} NAME_WE ) 282 | add_custom_command ( 283 | OUTPUT ${_target} DEPENDS ${_source} 284 | COMMAND ${LUAC} -o ${CMAKE_CURRENT_BINARY_DIR}/${SOURCEBASE}.lo 285 | ${SOURCEABS} 286 | COMMAND ${BIN2C} ${CMAKE_CURRENT_BINARY_DIR}/${SOURCEBASE}.lo 287 | ">${_target}" ) 288 | else () 289 | add_custom_command ( 290 | OUTPUT ${_target} DEPENDS ${SOURCEABS} 291 | COMMAND ${BIN2C} ${_source} ">${_target}" ) 292 | endif () 293 | endfunction() 294 | -------------------------------------------------------------------------------- /dist.info: -------------------------------------------------------------------------------- 1 | --- This dist file is part of LuaDist project 2 | 3 | name = "lsqlite3" 4 | version = "0.6devel" 5 | 6 | desc = "LuaSQLite 3 is a thin wrapper around the public domain SQLite3 database engine." 7 | author = "Tiago Dionizio, Doug Currie" 8 | license = "MIT" 9 | url = "http://luaforge.net/projects/luasqlite/" 10 | maintainer = "Peter Kapec" 11 | 12 | depends = { 13 | "lua ~> 5.1", 14 | "libsqlite3 >=3.5" 15 | } 16 | -------------------------------------------------------------------------------- /doc/lsqlite3.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | LuaSQLite 3 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 108 | 109 | 110 |
111 |

112 |


113 |

NAME

114 |

LuaSQLite 3 - a Lua 5.1 wrapper for the SQLite3 library

115 |

116 |


117 |

OVERVIEW

118 |

LuaSQLite 3 is a thin wrapper around the public domain SQLite3 119 | database engine.

120 |

The lsqlite3 module supports the creation and manipulation of 121 | SQLite3 databases. After a require('lsqlite3') the exported 122 | functions are called with prefix sqlite3. However, most sqlite3 123 | functions are called via an object-oriented interface to either 124 | database or SQL statement objects; see below for details.

125 |

This documentation does not attempt to describe how SQLite3 itself 126 | works, it just describes the Lua binding and the available functions. 127 | For more information about the SQL features supported by SQLite3 and 128 | details about the syntax of SQL statements and queries, please see the 129 | SQLite3 documentation http://www.sqlite.org/. Using some of the 130 | advanced features (how to use callbacks, for instance) will require 131 | some familiarity with the SQLite3 API.

132 |

133 |


134 |

DOWNLOAD

135 |

LuaSQLite 3 source code can be downloaded from its 136 | LuaForge (http://luaforge.net/projects/luasqlite/) page.

137 |

You will also need to build or obtain an SQLite3 loadable library 138 | (DLL or .so). See http://www.sqlite.org/ for obtaining SQLite3 139 | source code or downloading a binary SQLite3 library.

140 |

141 |


142 |

INSTALLATION

143 |

A Makefile is provided; it assumes an SQLite3 library is already 144 | installed.

145 |

146 |


147 |

EXAMPLES

148 |

The distribution contains an examples directory. The unit tests 149 | also show some example use.

150 |

151 |


152 |

VERIFICATION TESTS

153 |

The distribution contains some units tests using Michael Roth's 154 | lunit (which is also included). Some of the tests were also derived 155 | from Michael's lua-sqlite3 module, and more unit tests added by 156 | Doug Currie.

157 |

The distribution also contains some functional tests by Tiago.

158 |

This version of lsqlite3 was tested with SQLite 3.4.2.

159 |

160 |


161 |

REFERENCE

162 |

163 |


164 |

SQLite3 functions

165 |

166 |

sqlite3.complete

167 |
168 |         sqlite3.complete(sql)
169 |

Returns true if the string sql comprises one or more complete SQL 170 | statements and false otherwise.

171 |

172 |

sqlite3.open

173 |
174 |         sqlite3.open(filename)
175 |

Opens (or creates if it does not exist) an SQLite database with name 176 | filename and returns its handle as userdata (the returned object 177 | should be used for all further method calls in connection with this 178 | specific database, see Database methods). Example:

179 |
180 |         myDB=sqlite3.open('MyDatabase.sqlite3')  -- open
181 |         -- do some database calls...
182 |         myDB:close()  -- close
183 |

In case of an error, the function returns nil, an error code and an 184 | error message.

185 |

186 |

sqlite3.open_memory

187 |
188 |         sqlite3.open_memory()
189 |

Opens an SQLite database in memory and returns its handle as 190 | userdata. In case of an error, the function returns nil, an error code 191 | and an error message. (In-memory databases are volatile as they are 192 | never stored on disk.)

193 |

194 |

sqlite3.temp_directory

195 |
196 |         sqlite3.temp_directory([temp])
197 |

Sets or queries the directory used by SQLite for temporary files. If 198 | string temp is a directory name or nil, the temporary directory is 199 | set accordingly and the old value is returned. If temp is missing, 200 | the function simply returns the current temporary directory.

201 |

202 |

sqlite3.version

203 |
204 |         sqlite3.version()
205 |

Returns a string with SQLite version information, in the form 'x.y[.z]'.

206 |

207 |


208 |

Database methods

209 |

After opening a database with sqlite3.open() or 210 | sqlite3.open_memory() 211 | the returned database object should be used for all further method calls 212 | in connection with that database. An open database object supports the 213 | following methods.

214 |

215 |

db:busy_handler

216 |
217 |         db:busy_handler([func[,udata]])
218 |

Sets or removes a busy handler for a database. func is either a Lua 219 | function that implements the busy handler or nil to remove a previously 220 | set handler. This function returns nothing.

221 |

The handler function is called with two parameters: udata and the 222 | number of (re-)tries for a pending transaction. It should return nil, 223 | false or 0 if the transaction is to be aborted. All other values will 224 | result in another attempt to perform the transaction. (See the SQLite 225 | documentation for important hints about writing busy handlers.)

226 |

227 |

db:busy_timeout

228 |
229 |         db:busy_timeout(t)
230 |

Sets a busy handler that waits for t milliseconds if a transaction 231 | cannot proceed. Calling this function will remove any busy handler set 232 | by db:busy_handler(); calling it with an argument 233 | less than or equal to 0 will turn off all busy handlers.

234 |

235 |

db:changes

236 |
237 |         db:changes()
238 |

This function returns the number of database rows that were changed (or 239 | inserted or deleted) by the most recent SQL statement. Only changes that 240 | are directly specified by INSERT, UPDATE, or DELETE statements are 241 | counted. Auxiliary changes caused by triggers are not counted. Use 242 | db:total_changes() to find the total number of 243 | changes.

244 |

245 |

db:close

246 |
247 |         db:close()
248 |

Closes a database. All SQL statements prepared using 249 | db:prepare() should 250 | have been finalized before this function is called. The function returns 251 | sqlite3.OK on success or else a numerical error code (see the list of 252 | Numerical error and result codes).

253 |

254 |

db:close_vm

255 |
256 |         db:close_vm(temponly)
257 |

Finalizes all statements that have not been explicitly finalized. If 258 | temponly is true, only internal, temporary statements are finalized. 259 | This function returns nothing.

260 |

261 |

db:create_aggregate

262 |
263 |         db:create_aggregate(name,nargs,step,final)
264 |

This function creates an aggregate callback function. Aggregates perform 265 | an operation over all rows in a query. name is a string with the name 266 | of the aggregate function as given in an SQL statement; nargs is the 267 | number of arguments this call will provide. step is the actual Lua 268 | function that gets called once for every row; it should accept a function 269 | context (see Methods for callback contexts) plus the same number of 270 | parameters as given in nargs. final is a function that is called 271 | once after all rows have been processed; it receives one argument, the 272 | function context.

273 |

The function context can be used inside the two callback functions to 274 | communicate with SQLite3. Here is a simple example:

275 |
276 |         db:exec[=[
277 |           CREATE TABLE numbers(num1,num2);
278 |           INSERT INTO numbers VALUES(1,11);
279 |           INSERT INTO numbers VALUES(2,22);
280 |           INSERT INTO numbers VALUES(3,33);
281 |         ]=]
282 |         local num_sum=0
283 |         local function oneRow(context,num)  -- add one column in all rows
284 |           num_sum=num_sum+num
285 |         end
286 |         local function afterLast(context)   -- return sum after last row has been processed
287 |           context:result_number(num_sum)
288 |           num_sum=0
289 |         end
290 |         db:create_aggregate("do_the_sums",1,oneRow,afterLast)
291 |         for sum in db:urows('SELECT do_the_sums(num1) FROM numbers') do print("Sum of col 1:",sum) end
292 |         for sum in db:urows('SELECT do_the_sums(num2) FROM numbers') do print("Sum of col 2:",sum) end
293 |

This prints:

294 |
295 |         Sum of col 1:   6
296 |         Sum of col 2:   66
297 |

298 |

db:create_collation

299 |
300 |         db:create_collation(name,func)
301 |

This creates a collation callback. A collation callback is used to 302 | establish a collation order, mostly for string comparisons and sorting 303 | purposes. name is a string with the name of the collation to be created; 304 | func is a function that accepts two string arguments, compares them 305 | and returns 0 if both strings are identical, -1 if the first argument is 306 | lower in the collation order than the second and 1 if the first argument 307 | is higher in the collation order than the second. A simple example:

308 |
309 |         local function collate(s1,s2)
310 |           s1=s1:lower()
311 |           s2=s2:lower()
312 |           if s1==s2 then return 0
313 |           elseif s1<s2 then return -1
314 |           else return 1 end
315 |         end
316 |         db:exec[=[
317 |           CREATE TABLE test(id INTEGER PRIMARY KEY,content COLLATE CINSENS);
318 |           INSERT INTO test VALUES(NULL,'hello world');
319 |           INSERT INTO test VALUES(NULL,'Buenos dias');
320 |           INSERT INTO test VALUES(NULL,'HELLO WORLD');
321 |         ]=]
322 |         db:create_collation('CINSENS',collate)
323 |         for row in db:nrows('SELECT * FROM test') do print(row.id,row.content) end
324 |

325 |

db:create_function

326 |
327 |         db:create_function(name,nargs,func)
328 |

This function creates a callback function. Callback function are called 329 | by SQLite3 once for every row in a query. name is a string with the 330 | name of the callback function as given in an SQL statement; nargs is 331 | the number of arguments this call will provide. func is the actual Lua 332 | function that gets called once for every row; it should accept a 333 | function context (see Methods for callback contexts) plus the same 334 | number of parameters as given in nargs. Here is an example:

335 |
336 |         db:exec'CREATE TABLE test(col1,col2,col3)'
337 |         db:exec'INSERT INTO test VALUES(1,2,4)'
338 |         db:exec'INSERT INTO test VALUES(2,4,9)'
339 |         db:exec'INSERT INTO test VALUES(3,6,16)'
340 |         db:create_function('sum_cols',3,function(ctx,a,b,c)
341 |           ctx:result_number(a+b+c)
342 |         end))
343 |         for col1,col2,col3,sum in db:urows('SELECT *,sum_cols(col1,col2,col3) FROM test') do
344 |           util.printf('%2i+%2i+%2i=%2i\n',col1,col2,col3,sum)
345 |         end
346 |

347 |

db:errcode

348 |
349 |         db:errcode()
350 |         db:error_code()
351 |

Returns the numerical result code (or extended result code) for the most 352 | recent failed call associated with database db. See 353 | Numerical error and result codes for details.

354 |

355 |

db:errmsg

356 |
357 |         db:errmsg()
358 |         db:error_message()
359 |

Returns a string that contains an error message for the most recent 360 | failed call associated with database db.

361 |

362 |

db:exec

363 |
364 |         db:exec(sql[,func[,udata]])
365 |         db:execute(sql[,func[,udata]])
366 |

Compiles and executes the SQL statement(s) given in string sql. The 367 | statements are simply executed one after the other and not stored. The 368 | function returns sqlite3.OK on success or else a numerical error code 369 | (see Numerical error and result codes).

370 |

If one or more of the SQL statements are queries, then the callback 371 | function specified in func is invoked once for each row of the query 372 | result (if func is nil, no callback is invoked). The callback receives 373 | four arguments: udata (the third parameter of the db:exec() call), 374 | the number of columns in the row, a table with the column values and 375 | another table with the column names. The callback function should return 376 | 0. If the callback returns a non-zero value then the query is aborted, 377 | all subsequent SQL statements are skipped and db:exec() returns 378 | sqlite3.ABORT. Here is a simple example:

379 |
380 |         sql=[=[
381 |           CREATE TABLE numbers(num1,num2,str);
382 |           INSERT INTO numbers VALUES(1,11,"ABC");
383 |           INSERT INTO numbers VALUES(2,22,"DEF");
384 |           INSERT INTO numbers VALUES(3,33,"UVW");
385 |           INSERT INTO numbers VALUES(4,44,"XYZ");
386 |           SELECT * FROM numbers;
387 |         ]=]
388 |         function showrow(udata,cols,values,names)
389 |           assert(udata=='test_udata')
390 |           print('exec:')
391 |           for i=1,cols do print('',names[i],values[i]) end
392 |           return 0
393 |         end
394 |         db:exec(sql,showrow,'test_udata')
395 |

396 |

db:interrupt

397 |
398 |         db:interrupt()
399 |

This function causes any pending database operation to abort and return 400 | at the next opportunity. This function returns nothing.

401 |

402 |

db:isopen

403 |
404 |         db:isopen()
405 |

Returns true if database db is open, false otherwise.

406 |

407 |

db:last_insert_rowid

408 |
409 |         db:last_insert_rowid()
410 |

This function returns the rowid of the most recent INSERT into the 411 | database. If no inserts have ever occurred, 0 is returned. (Each row in 412 | an SQLite table has a unique 64-bit signed integer key called the 413 | 'rowid'. This id is always available as an undeclared column named 414 | ROWID, OID, or _ROWID_. If the table has a column of type INTEGER 415 | PRIMARY KEY then that column is another alias for the rowid.)

416 |

If an INSERT occurs within a trigger, then the rowid of the inserted row 417 | is returned as long as the trigger is running. Once the trigger 418 | terminates, the value returned reverts to the last value inserted before 419 | the trigger fired.

420 |

421 |

db:nrows

422 |
423 |         db:nrows(sql)
424 |

Creates an iterator that returns the successive rows selected by the SQL 425 | statement given in string sql. Each call to the iterator returns a 426 | table in which the named fields correspond to the columns in the database. 427 | Here is an example:

428 |
429 |         db:exec[=[
430 |           CREATE TABLE numbers(num1,num2);
431 |           INSERT INTO numbers VALUES(1,11);
432 |           INSERT INTO numbers VALUES(2,22);
433 |           INSERT INTO numbers VALUES(3,33);
434 |         ]=]
435 |         for a in db:nrows('SELECT * FROM numbers') do table.print(a) end
436 |

This script prints:

437 |
438 |         num2: 11
439 |         num1: 1
440 |         num2: 22
441 |         num1: 2
442 |         num2: 33
443 |         num1: 3
444 |

445 |

db:prepare

446 |
447 |         db:prepare(sql)
448 |

This function compiles the SQL statement in string sql into an internal 449 | representation and returns this as userdata. The returned object should 450 | be used for all further method calls in connection with this specific 451 | SQL statement (see Methods for prepared statements).

452 |

453 |

db:progress_handler

454 |
455 |         db:progress_handler(n,func,udata)
456 |

This function installs a callback function func that is invoked 457 | periodically during long-running calls to db:exec() 458 | or stmt:step(). The 459 | progress callback is invoked once for every n internal operations, 460 | where n is the first argument to this function. udata is passed to 461 | the progress callback function each time it is invoked. If a call to 462 | db:exec() or stmt:step() results in fewer than n operations 463 | being executed, then the progress callback is never invoked. Only a 464 | single progress callback function may be registered for each opened 465 | database and a call to this function will overwrite any previously set 466 | callback function. To remove the progress callback altogether, pass nil 467 | as the second argument.

468 |

If the progress callback returns a result other than 0, then the current 469 | query is immediately terminated, any database changes are rolled back 470 | and the containing db:exec() or stmt:step() call returns 471 | sqlite3.INTERRUPT. This feature can be used to cancel long-running 472 | queries.

473 |

474 |

db:rows

475 |
476 |         db:rows(sql)
477 |

Creates an iterator that returns the successive rows selected by the SQL 478 | statement given in string sql. Each call to the iterator returns a table 479 | in which the numerical indices 1 to n correspond to the selected columns 480 | 1 to n in the database. Here is an example:

481 |
482 |         db:exec[=[
483 |           CREATE TABLE numbers(num1,num2);
484 |           INSERT INTO numbers VALUES(1,11);
485 |           INSERT INTO numbers VALUES(2,22);
486 |           INSERT INTO numbers VALUES(3,33);
487 |         ]=]
488 |         for a in db:rows('SELECT * FROM numbers') do table.print(a) end
489 |

This script prints:

490 |
491 |         1: 1
492 |         2: 11
493 |         1: 2
494 |         2: 22
495 |         1: 3
496 |         2: 33
497 |

498 |

db:total_changes

499 |
500 |         db:total_changes()
501 |

This function returns the number of database rows that have been 502 | modified by INSERT, UPDATE or DELETE statements since the database was 503 | opened. This includes UPDATE, INSERT and DELETE statements executed as 504 | part of trigger programs. All changes are counted as soon as the 505 | statement that produces them is completed by calling either 506 | stmt:reset() or stmt:finalize().

507 |

508 |

db:trace

509 |
510 |         db:trace(func,udata)
511 |

This function installs a trace callback handler. func is a Lua 512 | function that is called by SQLite3 just before the evaluation of an SQL 513 | statement. This callback receives two arguments: the first is the 514 | udata argument used when the callback was installed; the second is a 515 | string with the SQL statement about to be executed.

516 |

517 |

db:urows

518 |
519 |         db:urows(sql)
520 |

Creates an iterator that returns the successive rows selected by the SQL 521 | statement given in string sql. Each call to the iterator returns the 522 | values that correspond to the columns in the currently selected row. 523 | Here is an example:

524 |
525 |         db:exec[=[
526 |           CREATE TABLE numbers(num1,num2);
527 |           INSERT INTO numbers VALUES(1,11);
528 |           INSERT INTO numbers VALUES(2,22);
529 |           INSERT INTO numbers VALUES(3,33);
530 |         ]=]
531 |         for num1,num2 in db:urows('SELECT * FROM numbers') do print(num1,num2) end
532 |

This script prints:

533 |
534 |         1       11
535 |         2       22
536 |         3       33
537 |

538 |


539 |

Methods for prepared statements

540 |

After creating a prepared statement with db:prepare() 541 | the returned statement object should be used for all further calls in 542 | connection with that statement. Statement objects support the following 543 | methods.

544 |

545 |

stmt:bind

546 |
547 |         stmt:bind(n[,value])
548 |

Binds value to statement parameter n. If the type of value is string 549 | or number, it is bound as text or double, respectively. If value is a 550 | boolean or nil or missing, any previous binding is removed. The function 551 | returns sqlite3.OK on success or else a numerical error code (see 552 | Numerical error and result codes).

553 |

554 |

stmt:bind_blob

555 |
556 |         stmt:bind_blob(n,blob)
557 |

Binds string blob (which can be a binary string) as a blob to 558 | statement parameter n. The function returns sqlite3.OK on success 559 | or else a numerical error code (see Numerical error and result codes).

560 |

561 |

stmt:bind_names

562 |
563 |         stmt:bind_names(nametable)
564 |

Binds the values in nametable to statement parameters. If the 565 | statement parameters are named (i.e., of the form ``:AAA'' or ``$AAA'') 566 | then this function looks for appropriately named fields in nametable; 567 | if the statement parameters are 568 | not named, it looks for numerical fields 1 to the number of statement 569 | parameters. The function returns sqlite3.OK on success or else a 570 | numerical error code (see Numerical error and result codes).

571 |

572 |

stmt:bind_parameter_count

573 |
574 |         stmt:bind_parameter_count()
575 |

Returns the largest statement parameter index in prepared statement 576 | stmt. When the statement parameters are of the forms ``:AAA'' or ``?'', 577 | then they are assigned sequentially increasing numbers beginning with 578 | one, so the value returned is the number of parameters. However if the 579 | same statement parameter name is used multiple times, each occurrence 580 | is given the same number, so the value returned is the number of unique 581 | statement parameter names.

582 |

If statement parameters of the form ``?NNN'' are used (where NNN is an 583 | integer) then there might be gaps in the numbering and the value 584 | returned by this interface is the index of the statement parameter with 585 | the largest index value.

586 |

587 |

stmt:bind_parameter_name

588 |
589 |         stmt:bind_parameter_name(n)
590 |

Returns the name of the n-th parameter in prepared statement stmt. 591 | Statement parameters of the form ``:AAA'' or ``@AAA'' or ``$VVV'' have a name 592 | which is the string ``:AAA'' or ``@AAA'' or ``$VVV''. In other words, the 593 | initial ``:'' or ``$'' or ``@'' is included as part of the name. Parameters 594 | of the form ``?'' or ``?NNN'' have no name. The first bound parameter has 595 | an index of 1. 596 | If the value n is out of range or if the n-th parameter is 597 | nameless, then nil is returned. The function returns sqlite3.OK on 598 | success or else a numerical error code (see 599 | Numerical error and result codes)

600 |

601 |

stmt:bind_values

602 |
603 |         stmt:bind_values(value1,value2,...,valueN)
604 |

Binds the given values to statement parameters. The function returns 605 | sqlite3.OK on success or else a numerical error code (see 606 | Numerical error and result codes).

607 |

608 |

stmt:columns

609 |
610 |         stmt:columns()
611 |

Returns the number of columns in the result set returned by statement 612 | stmt or 0 if the statement does not return data (for example an UPDATE).

613 |

614 |

stmt:finalize

615 |
616 |         stmt:finalize()
617 |

This function frees prepared statement stmt. If the statement was 618 | executed successfully, or not executed at all, then sqlite3.OK is 619 | returned. If execution of the statement failed then an error code is 620 | returned.

621 |

622 |

stmt:get_name

623 |
624 |         stmt:get_name(n)
625 |

Returns the name of column n in the result set of statement stmt. (The 626 | left-most column is number 0.)

627 |

628 |

stmt:get_named_types

629 |
630 |         stmt:get_named_types()
631 |

Returns a table with the names and types of all columns in the result 632 | set of statement stmt.

633 |

634 |

stmt:get_named_values

635 |
636 |         stmt:get_named_values()
637 |

This function returns a table with names and values of all columns in 638 | the current result row of a query.

639 |

640 |

stmt:get_names

641 |
642 |         stmt:get_names()
643 |

This function returns an array with the names of all columns in the 644 | result set returned by statement stmt.

645 |

646 |

stmt:get_type

647 |
648 |         stmt:get_type(n)
649 |

Returns the type of column n in the result set of statement stmt. (The 650 | left-most column is number 0.)

651 |

652 |

stmt:get_types

653 |
654 |         stmt:get_types()
655 |

This function returns an array with the types of all columns in the 656 | result set returned by statement stmt.

657 |

658 |

stmt:get_unames

659 |
660 |         stmt:get_unames()
661 |

This function returns a list with the names of all columns in the result 662 | set returned by statement stmt.

663 |

664 |

stmt:get_utypes

665 |
666 |         stmt:get_utypes()
667 |

This function returns a list with the types of all columns in the result 668 | set returned by statement stmt.

669 |

670 |

stmt:get_uvalues

671 |
672 |         stmt:get_uvalues()
673 |

This function returns a list with the values of all columns in the 674 | current result row of a query.

675 |

676 |

stmt:get_value

677 |
678 |         stmt:get_value(n)
679 |

Returns the value of column n in the result set of statement stmt. (The 680 | left-most column is number 0.)

681 |

682 |

stmt:get_values

683 |
684 |         stmt:get_values()
685 |

This function returns an array with the values of all columns in the 686 | result set returned by statement stmt.

687 |

688 |

stmt:isopen

689 |
690 |         stmt:isopen()
691 |

Returns true if stmt has not yet been finalized, false otherwise.

692 |

693 |

stmt:nrows

694 |
695 |         stmt:nrows()
696 |

Returns an function that iterates over the names and values of the 697 | result set of statement stmt. Each iteration returns a table with the 698 | names and values for the current row. 699 | This is the prepared statement equivalent of db:nrows().

700 |

701 |

stmt:reset

702 |
703 |         stmt:reset()
704 |

This function resets SQL statement stmt, so that it is ready to be 705 | re-executed. Any statement variables that had values bound to them using 706 | the stmt:bind*() functions retain their values.

707 |

708 |

stmt:rows

709 |
710 |         stmt:rows()
711 |

Returns an function that iterates over the values of the result set of 712 | statement stmt. Each iteration returns an array with the values for the 713 | current row. 714 | This is the prepared statement equivalent of db:rows().

715 |

716 |

stmt:step

717 |
718 |         stmt:step()
719 |

This function must be called to evaluate the (next iteration of the) 720 | prepared statement stmt. It will return one of the following values:

721 | 754 |

755 |

stmt:urows

756 |
757 |         stmt:urows()
758 |

Returns an function that iterates over the values of the result set of 759 | statement stmt. Each iteration returns the values for the current row. 760 | This is the prepared statement equivalent of db:urows().

761 |

762 |


763 |

Methods for callback contexts

764 |

A callback context is available as a parameter inside the callback 765 | functions db:create_aggregate() and 766 | db:create_function(). It can be used 767 | to get further information about the state of a query.

768 |

769 |

context:aggregate_count

770 |
771 |         context:aggregate_count()
772 |

Returns the number of calls to the aggregate step function.

773 |

774 |

context:get_aggregate_data

775 |
776 |         context:get_aggregate_data()
777 |

Returns the user-definable data field for callback funtions.

778 |

779 |

context:set_aggregate_data

780 |
781 |         context:set_aggregate_data(udata)
782 |

Set the user-definable data field for callback funtions to udata.

783 |

784 |

context:result

785 |
786 |         context:result(res)
787 |

This function sets the result of a callback function to res. The type of 788 | the result depends on the type of res and is either a number or a string 789 | or nil. All other values will raise an error message.

790 |

791 |

context:result_null

792 |
793 |         context:result_null()
794 |

This function sets the result of a callback function to nil. It returns 795 | nothing.

796 |

797 |

context:result_number

798 |
799 |         context:result_number(number)
800 |         context:result_double(number)
801 |

This function sets the result of a callback function to the value 802 | number. It returns nothing.

803 |

804 |

context:result_int

805 |
806 |         context:result_int(number)
807 |

This function sets the result of a callback function to the integer 808 | value in number. It returns nothing.

809 |

810 |

context:result_text

811 |
812 |         context:result_text(str)
813 |

This function sets the result of a callback function to the string in 814 | str. It returns nothing.

815 |

816 |

context:result_blob

817 |
818 |         context:result_blob(blob)
819 |

This function sets the result of a callback function to the binary 820 | string in blob. It returns nothing.

821 |

822 |

context:result_error

823 |
824 |         context:result_error(err)
825 |

This function sets the result of a callback function to the error value 826 | in err. It returns nothing.

827 |

828 |

context:user_data

829 |
830 |         context:user_data()
831 |

Returns the userdata parameter given in the call to install the callback 832 | function (see db:create_aggregate() and 833 | db:create_function() for details).

834 |

835 |


836 |

Numerical error and result codes

837 |

The following constants are defined by module sqlite3:

838 |
839 |         OK: 0          ERROR: 1       INTERNAL: 2    PERM: 3        ABORT: 4
840 |         BUSY: 5        LOCKED: 6      NOMEM: 7       READONLY: 8    INTERRUPT: 9
841 |         IOERR: 10      CORRUPT: 11    NOTFOUND: 12   FULL: 13       CANTOPEN: 14
842 |         PROTOCOL: 15   EMPTY: 16      SCHEMA: 17     TOOBIG: 18     CONSTRAINT: 19
843 |         MISMATCH: 20   MISUSE: 21     NOLFS: 22      FORMAT: 24     RANGE: 25
844 |         NOTADB: 26     ROW: 100       DONE: 101
845 |

For details about their exact meaning please see the SQLite3 846 | documentation http://www.sqlite.org/.

847 |

848 |


849 |

VERSION

850 |

This is lsqlite3 subversion 6, also known as ``devel-0.6''.

851 |

852 |


853 |

CREDITS

854 |

lsqlite3 was developed by Tiago Dionizio and Doug Currie with 855 | contributions from Thomas Lauer and Michael Roth.

856 |

This documentation is based on the ``(very) preliminary'' documents 857 | for the Idle-SQLite3 database module. Thanks to Thomas Lauer for 858 | making it available.

859 |

860 |


861 |

LICENSE

862 |
863 |     /************************************************************************
864 |     * lsqlite3                                                              *
865 |     * Copyright (C) 2002-2007 Tiago Dionizio, Doug Currie                   *
866 |     * All rights reserved.                                                  *
867 |     * Author    : Tiago Dionizio <tiago.dionizio@ist.utl.pt>                *
868 |     * Author    : Doug Currie <doug.currie@alum.mit.edu>                    *
869 |     * Library   : lsqlite3 - a SQLite 3 database binding for Lua 5          *
870 |     *                                                                       *
871 |     * Permission is hereby granted, free of charge, to any person obtaining *
872 |     * a copy of this software and associated documentation files (the       *
873 |     * "Software"), to deal in the Software without restriction, including   *
874 |     * without limitation the rights to use, copy, modify, merge, publish,   *
875 |     * distribute, sublicense, and/or sell copies of the Software, and to    *
876 |     * permit persons to whom the Software is furnished to do so, subject to *
877 |     * the following conditions:                                             *
878 |     *                                                                       *
879 |     * The above copyright notice and this permission notice shall be        *
880 |     * included in all copies or substantial portions of the Software.       *
881 |     *                                                                       *
882 |     * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       *
883 |     * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    *
884 |     * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*
885 |     * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  *
886 |     * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  *
887 |     * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     *
888 |     * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                *
889 |     ************************************************************************/
890 | 891 | 892 | 893 | 894 | -------------------------------------------------------------------------------- /doc/lsqlite3.pod: -------------------------------------------------------------------------------- 1 | =pod 2 | 3 | =head1 NAME 4 | 5 | B - a Lua 5.1 wrapper for the SQLite3 library 6 | 7 | =head1 OVERVIEW 8 | 9 | B is a thin wrapper around the public domain SQLite3 10 | database engine. 11 | 12 | The C module supports the creation and manipulation of 13 | SQLite3 databases. After a C the exported 14 | functions are called with prefix C. However, most sqlite3 15 | functions are called via an object-oriented interface to either 16 | database or SQL statement objects; see below for details. 17 | 18 | This documentation does not attempt to describe how SQLite3 itself 19 | works, it just describes the Lua binding and the available functions. 20 | For more information about the SQL features supported by SQLite3 and 21 | details about the syntax of SQL statements and queries, please see the 22 | B L. Using some of the 23 | advanced features (how to use callbacks, for instance) will require 24 | some familiarity with the SQLite3 API. 25 | 26 | =head1 DOWNLOAD 27 | 28 | B source code can be downloaded from its 29 | LuaForge (L) page. 30 | 31 | You will also need to build or obtain an SQLite3 loadable library 32 | (DLL or .so). See L for obtaining SQLite3 33 | source code or downloading a binary SQLite3 library. 34 | 35 | =head1 INSTALLATION 36 | 37 | A I is provided; it assumes an SQLite3 library is already 38 | installed. 39 | 40 | =head1 EXAMPLES 41 | 42 | The distribution contains an I directory. The unit tests 43 | also show some example use. 44 | 45 | =head1 VERIFICATION TESTS 46 | 47 | The distribution contains some units tests using Michael Roth's 48 | C (which is also included). Some of the tests were also derived 49 | from Michael's B module, and more unit tests added by 50 | Doug Currie. 51 | 52 | The distribution also contains some functional tests by Tiago. 53 | 54 | This version of C was tested with SQLite 3.4.2. 55 | 56 | =head1 REFERENCE 57 | 58 | =head1 SQLite3 functions 59 | 60 | =head2 sqlite3.complete 61 | 62 | sqlite3.complete(sql) 63 | 64 | Returns true if the string C comprises one or more complete SQL 65 | statements and false otherwise. 66 | 67 | =head2 sqlite3.open 68 | 69 | sqlite3.open(filename) 70 | 71 | Opens (or creates if it does not exist) an SQLite database with name 72 | C and returns its handle as userdata (the returned object 73 | should be used for all further method calls in connection with this 74 | specific database, see L). Example: 75 | 76 | myDB=sqlite3.open('MyDatabase.sqlite3') -- open 77 | -- do some database calls... 78 | myDB:close() -- close 79 | 80 | In case of an error, the function returns nil, an error code and an 81 | error message. 82 | 83 | =head2 sqlite3.open_memory 84 | 85 | sqlite3.open_memory() 86 | 87 | Opens an SQLite database B and returns its handle as 88 | userdata. In case of an error, the function returns nil, an error code 89 | and an error message. (In-memory databases are volatile as they are 90 | never stored on disk.) 91 | 92 | =head2 sqlite3.temp_directory 93 | 94 | sqlite3.temp_directory([temp]) 95 | 96 | Sets or queries the directory used by SQLite for temporary files. If 97 | string C is a directory name or nil, the temporary directory is 98 | set accordingly and the old value is returned. If C is missing, 99 | the function simply returns the current temporary directory. 100 | 101 | =head2 sqlite3.version 102 | 103 | sqlite3.version() 104 | 105 | Returns a string with SQLite version information, in the form 'x.y[.z]'. 106 | 107 | =head1 Database methods 108 | 109 | After opening a database with L|/sqlite3.open> or 110 | L|/sqlite3.open_memory> 111 | the returned database object should be used for all further method calls 112 | in connection with that database. An open database object supports the 113 | following methods. 114 | 115 | =head2 db:busy_handler 116 | 117 | db:busy_handler([func[,udata]]) 118 | 119 | Sets or removes a busy handler for a database. C is either a Lua 120 | function that implements the busy handler or nil to remove a previously 121 | set handler. This function returns nothing. 122 | 123 | The handler function is called with two parameters: C and the 124 | number of (re-)tries for a pending transaction. It should return nil, 125 | false or 0 if the transaction is to be aborted. All other values will 126 | result in another attempt to perform the transaction. (See the SQLite 127 | documentation for important hints about writing busy handlers.) 128 | 129 | =head2 db:busy_timeout 130 | 131 | db:busy_timeout(t) 132 | 133 | Sets a busy handler that waits for C milliseconds if a transaction 134 | cannot proceed. Calling this function will remove any busy handler set 135 | by L|/db:busy_handler>; calling it with an argument 136 | less than or equal to 0 will turn off all busy handlers. 137 | 138 | =head2 db:changes 139 | 140 | db:changes() 141 | 142 | This function returns the number of database rows that were changed (or 143 | inserted or deleted) by the most recent SQL statement. Only changes that 144 | are directly specified by INSERT, UPDATE, or DELETE statements are 145 | counted. Auxiliary changes caused by triggers are not counted. Use 146 | L|/db:total_changes> to find the total number of 147 | changes. 148 | 149 | =head2 db:close 150 | 151 | db:close() 152 | 153 | Closes a database. All SQL statements prepared using 154 | L|/db:prepare> should 155 | have been finalized before this function is called. The function returns 156 | C on success or else a numerical error code (see the list of 157 | L). 158 | 159 | =head2 db:close_vm 160 | 161 | db:close_vm(temponly) 162 | 163 | Finalizes all statements that have not been explicitly finalized. If 164 | C is true, only internal, temporary statements are finalized. 165 | This function returns nothing. 166 | 167 | =head2 db:create_aggregate 168 | 169 | db:create_aggregate(name,nargs,step,final) 170 | 171 | This function creates an aggregate callback function. Aggregates perform 172 | an operation over all rows in a query. C is a string with the name 173 | of the aggregate function as given in an SQL statement; C is the 174 | number of arguments this call will provide. C is the actual Lua 175 | function that gets called once for every row; it should accept a function 176 | context (see L) plus the same number of 177 | parameters as given in C. C is a function that is called 178 | once after all rows have been processed; it receives one argument, the 179 | function context. 180 | 181 | The function context can be used inside the two callback functions to 182 | communicate with SQLite3. Here is a simple example: 183 | 184 | db:exec[=[ 185 | CREATE TABLE numbers(num1,num2); 186 | INSERT INTO numbers VALUES(1,11); 187 | INSERT INTO numbers VALUES(2,22); 188 | INSERT INTO numbers VALUES(3,33); 189 | ]=] 190 | local num_sum=0 191 | local function oneRow(context,num) -- add one column in all rows 192 | num_sum=num_sum+num 193 | end 194 | local function afterLast(context) -- return sum after last row has been processed 195 | context:result_number(num_sum) 196 | num_sum=0 197 | end 198 | db:create_aggregate("do_the_sums",1,oneRow,afterLast) 199 | for sum in db:urows('SELECT do_the_sums(num1) FROM numbers') do print("Sum of col 1:",sum) end 200 | for sum in db:urows('SELECT do_the_sums(num2) FROM numbers') do print("Sum of col 2:",sum) end 201 | 202 | This prints: 203 | 204 | Sum of col 1: 6 205 | Sum of col 2: 66 206 | 207 | =head2 db:create_collation 208 | 209 | db:create_collation(name,func) 210 | 211 | This creates a collation callback. A collation callback is used to 212 | establish a collation order, mostly for string comparisons and sorting 213 | purposes. C is a string with the name of the collation to be created; 214 | C is a function that accepts two string arguments, compares them 215 | and returns 0 if both strings are identical, -1 if the first argument is 216 | lower in the collation order than the second and 1 if the first argument 217 | is higher in the collation order than the second. A simple example: 218 | 219 | local function collate(s1,s2) 220 | s1=s1:lower() 221 | s2=s2:lower() 222 | if s1==s2 then return 0 223 | elseif s1 is a string with the 241 | name of the callback function as given in an SQL statement; C is 242 | the number of arguments this call will provide. C is the actual Lua 243 | function that gets called once for every row; it should accept a 244 | function context (see L) plus the same 245 | number of parameters as given in nargs. Here is an example: 246 | 247 | db:exec'CREATE TABLE test(col1,col2,col3)' 248 | db:exec'INSERT INTO test VALUES(1,2,4)' 249 | db:exec'INSERT INTO test VALUES(2,4,9)' 250 | db:exec'INSERT INTO test VALUES(3,6,16)' 251 | db:create_function('sum_cols',3,function(ctx,a,b,c) 252 | ctx:result_number(a+b+c) 253 | end)) 254 | for col1,col2,col3,sum in db:urows('SELECT *,sum_cols(col1,col2,col3) FROM test') do 255 | util.printf('%2i+%2i+%2i=%2i\n',col1,col2,col3,sum) 256 | end 257 | 258 | =head2 db:errcode 259 | 260 | db:errcode() 261 | db:error_code() 262 | 263 | Returns the numerical result code (or extended result code) for the most 264 | recent failed call associated with database db. See 265 | L for details. 266 | 267 | =head2 db:errmsg 268 | 269 | db:errmsg() 270 | db:error_message() 271 | 272 | Returns a string that contains an error message for the most recent 273 | failed call associated with database db. 274 | 275 | =head2 db:exec 276 | 277 | db:exec(sql[,func[,udata]]) 278 | db:execute(sql[,func[,udata]]) 279 | 280 | Compiles and executes the SQL statement(s) given in string C. The 281 | statements are simply executed one after the other and not stored. The 282 | function returns C on success or else a numerical error code 283 | (see L). 284 | 285 | If one or more of the SQL statements are queries, then the callback 286 | function specified in C is invoked once for each row of the query 287 | result (if C is nil, no callback is invoked). The callback receives 288 | four arguments: C (the third parameter of the C call), 289 | the number of columns in the row, a table with the column values and 290 | another table with the column names. The callback function should return 291 | 0. If the callback returns a non-zero value then the query is aborted, 292 | all subsequent SQL statements are skipped and C returns 293 | C. Here is a simple example: 294 | 295 | sql=[=[ 296 | CREATE TABLE numbers(num1,num2,str); 297 | INSERT INTO numbers VALUES(1,11,"ABC"); 298 | INSERT INTO numbers VALUES(2,22,"DEF"); 299 | INSERT INTO numbers VALUES(3,33,"UVW"); 300 | INSERT INTO numbers VALUES(4,44,"XYZ"); 301 | SELECT * FROM numbers; 302 | ]=] 303 | function showrow(udata,cols,values,names) 304 | assert(udata=='test_udata') 305 | print('exec:') 306 | for i=1,cols do print('',names[i],values[i]) end 307 | return 0 308 | end 309 | db:exec(sql,showrow,'test_udata') 310 | 311 | =head2 db:interrupt 312 | 313 | db:interrupt() 314 | 315 | This function causes any pending database operation to abort and return 316 | at the next opportunity. This function returns nothing. 317 | 318 | =head2 db:isopen 319 | 320 | db:isopen() 321 | 322 | Returns true if database db is open, false otherwise. 323 | 324 | =head2 db:last_insert_rowid 325 | 326 | db:last_insert_rowid() 327 | 328 | This function returns the rowid of the most recent INSERT into the 329 | database. If no inserts have ever occurred, 0 is returned. (Each row in 330 | an SQLite table has a unique 64-bit signed integer key called the 331 | 'rowid'. This id is always available as an undeclared column named 332 | ROWID, OID, or _ROWID_. If the table has a column of type INTEGER 333 | PRIMARY KEY then that column is another alias for the rowid.) 334 | 335 | If an INSERT occurs within a trigger, then the rowid of the inserted row 336 | is returned as long as the trigger is running. Once the trigger 337 | terminates, the value returned reverts to the last value inserted before 338 | the trigger fired. 339 | 340 | =head2 db:nrows 341 | 342 | db:nrows(sql) 343 | 344 | Creates an iterator that returns the successive rows selected by the SQL 345 | statement given in string C. Each call to the iterator returns a 346 | table in which the named fields correspond to the columns in the database. 347 | Here is an example: 348 | 349 | db:exec[=[ 350 | CREATE TABLE numbers(num1,num2); 351 | INSERT INTO numbers VALUES(1,11); 352 | INSERT INTO numbers VALUES(2,22); 353 | INSERT INTO numbers VALUES(3,33); 354 | ]=] 355 | for a in db:nrows('SELECT * FROM numbers') do table.print(a) end 356 | 357 | This script prints: 358 | 359 | num2: 11 360 | num1: 1 361 | num2: 22 362 | num1: 2 363 | num2: 33 364 | num1: 3 365 | 366 | =head2 db:prepare 367 | 368 | db:prepare(sql) 369 | 370 | This function compiles the SQL statement in string C into an internal 371 | representation and returns this as userdata. The returned object should 372 | be used for all further method calls in connection with this specific 373 | SQL statement (see L). 374 | 375 | =head2 db:progress_handler 376 | 377 | db:progress_handler(n,func,udata) 378 | 379 | This function installs a callback function C that is invoked 380 | periodically during long-running calls to L|/db:exec> 381 | or L|/stmt:step>. The 382 | progress callback is invoked once for every C internal operations, 383 | where C is the first argument to this function. C is passed to 384 | the progress callback function each time it is invoked. If a call to 385 | C or C results in fewer than C operations 386 | being executed, then the progress callback is never invoked. Only a 387 | single progress callback function may be registered for each opened 388 | database and a call to this function will overwrite any previously set 389 | callback function. To remove the progress callback altogether, pass nil 390 | as the second argument. 391 | 392 | If the progress callback returns a result other than 0, then the current 393 | query is immediately terminated, any database changes are rolled back 394 | and the containing C or C call returns 395 | C. This feature can be used to cancel long-running 396 | queries. 397 | 398 | =head2 db:rows 399 | 400 | db:rows(sql) 401 | 402 | Creates an iterator that returns the successive rows selected by the SQL 403 | statement given in string C. Each call to the iterator returns a table 404 | in which the numerical indices 1 to n correspond to the selected columns 405 | 1 to n in the database. Here is an example: 406 | 407 | db:exec[=[ 408 | CREATE TABLE numbers(num1,num2); 409 | INSERT INTO numbers VALUES(1,11); 410 | INSERT INTO numbers VALUES(2,22); 411 | INSERT INTO numbers VALUES(3,33); 412 | ]=] 413 | for a in db:rows('SELECT * FROM numbers') do table.print(a) end 414 | 415 | This script prints: 416 | 417 | 1: 1 418 | 2: 11 419 | 1: 2 420 | 2: 22 421 | 1: 3 422 | 2: 33 423 | 424 | =head2 db:total_changes 425 | 426 | db:total_changes() 427 | 428 | This function returns the number of database rows that have been 429 | modified by INSERT, UPDATE or DELETE statements since the database was 430 | opened. This includes UPDATE, INSERT and DELETE statements executed as 431 | part of trigger programs. All changes are counted as soon as the 432 | statement that produces them is completed by calling either 433 | L|/stmt:reset> or L|/stmt:finalize>. 434 | 435 | =head2 db:trace 436 | 437 | db:trace(func,udata) 438 | 439 | This function installs a trace callback handler. C is a Lua 440 | function that is called by SQLite3 just before the evaluation of an SQL 441 | statement. This callback receives two arguments: the first is the 442 | C argument used when the callback was installed; the second is a 443 | string with the SQL statement about to be executed. 444 | 445 | =head2 db:urows 446 | 447 | db:urows(sql) 448 | 449 | Creates an iterator that returns the successive rows selected by the SQL 450 | statement given in string C. Each call to the iterator returns the 451 | values that correspond to the columns in the currently selected row. 452 | Here is an example: 453 | 454 | db:exec[=[ 455 | CREATE TABLE numbers(num1,num2); 456 | INSERT INTO numbers VALUES(1,11); 457 | INSERT INTO numbers VALUES(2,22); 458 | INSERT INTO numbers VALUES(3,33); 459 | ]=] 460 | for num1,num2 in db:urows('SELECT * FROM numbers') do print(num1,num2) end 461 | 462 | This script prints: 463 | 464 | 1 11 465 | 2 22 466 | 3 33 467 | 468 | =head1 Methods for prepared statements 469 | 470 | After creating a prepared statement with L|/db:prepare> 471 | the returned statement object should be used for all further calls in 472 | connection with that statement. Statement objects support the following 473 | methods. 474 | 475 | =head2 stmt:bind 476 | 477 | stmt:bind(n[,value]) 478 | 479 | Binds value to statement parameter C. If the type of value is string 480 | or number, it is bound as text or double, respectively. If C is a 481 | boolean or nil or missing, any previous binding is removed. The function 482 | returns C on success or else a numerical error code (see 483 | L). 484 | 485 | =head2 stmt:bind_blob 486 | 487 | stmt:bind_blob(n,blob) 488 | 489 | Binds string C (which can be a binary string) as a blob to 490 | statement parameter C. The function returns C on success 491 | or else a numerical error code (see L). 492 | 493 | =head2 stmt:bind_names 494 | 495 | stmt:bind_names(nametable) 496 | 497 | Binds the values in C to statement parameters. If the 498 | statement parameters are named (i.e., of the form ":AAA" or "$AAA") 499 | then this function looks for appropriately named fields in C; 500 | if the statement parameters are 501 | not named, it looks for numerical fields 1 to the number of statement 502 | parameters. The function returns C on success or else a 503 | numerical error code (see L). 504 | 505 | =head2 stmt:bind_parameter_count 506 | 507 | stmt:bind_parameter_count() 508 | 509 | Returns the largest statement parameter index in prepared statement 510 | C. When the statement parameters are of the forms ":AAA" or "?", 511 | then they are assigned sequentially increasing numbers beginning with 512 | one, so the value returned is the number of parameters. However if the 513 | same statement parameter name is used multiple times, each occurrence 514 | is given the same number, so the value returned is the number of unique 515 | statement parameter names. 516 | 517 | If statement parameters of the form "?NNN" are used (where NNN is an 518 | integer) then there might be gaps in the numbering and the value 519 | returned by this interface is the index of the statement parameter with 520 | the largest index value. 521 | 522 | =head2 stmt:bind_parameter_name 523 | 524 | stmt:bind_parameter_name(n) 525 | 526 | Returns the name of the C-th parameter in prepared statement C. 527 | Statement parameters of the form ":AAA" or "@AAA" or "$VVV" have a name 528 | which is the string ":AAA" or "@AAA" or "$VVV". In other words, the 529 | initial ":" or "$" or "@" is included as part of the name. Parameters 530 | of the form "?" or "?NNN" have no name. The first bound parameter has 531 | an index of 1. 532 | If the value C is out of range or if the C-th parameter is 533 | nameless, then nil is returned. The function returns C on 534 | success or else a numerical error code (see 535 | L) 536 | 537 | =head2 stmt:bind_values 538 | 539 | stmt:bind_values(value1,value2,...,valueN) 540 | 541 | Binds the given values to statement parameters. The function returns 542 | C on success or else a numerical error code (see 543 | L). 544 | 545 | =head2 stmt:columns 546 | 547 | stmt:columns() 548 | 549 | Returns the number of columns in the result set returned by statement 550 | stmt or 0 if the statement does not return data (for example an UPDATE). 551 | 552 | =head2 stmt:finalize 553 | 554 | stmt:finalize() 555 | 556 | This function frees prepared statement stmt. If the statement was 557 | executed successfully, or not executed at all, then C is 558 | returned. If execution of the statement failed then an error code is 559 | returned. 560 | 561 | =head2 stmt:get_name 562 | 563 | stmt:get_name(n) 564 | 565 | Returns the name of column C in the result set of statement stmt. (The 566 | left-most column is number 0.) 567 | 568 | =head2 stmt:get_named_types 569 | 570 | stmt:get_named_types() 571 | 572 | Returns a table with the names and types of all columns in the result 573 | set of statement stmt. 574 | 575 | =head2 stmt:get_named_values 576 | 577 | stmt:get_named_values() 578 | 579 | This function returns a table with names and values of all columns in 580 | the current result row of a query. 581 | 582 | =head2 stmt:get_names 583 | 584 | stmt:get_names() 585 | 586 | This function returns an array with the names of all columns in the 587 | result set returned by statement stmt. 588 | 589 | =head2 stmt:get_type 590 | 591 | stmt:get_type(n) 592 | 593 | Returns the type of column C in the result set of statement stmt. (The 594 | left-most column is number 0.) 595 | 596 | =head2 stmt:get_types 597 | 598 | stmt:get_types() 599 | 600 | This function returns an array with the types of all columns in the 601 | result set returned by statement stmt. 602 | 603 | =head2 stmt:get_unames 604 | 605 | stmt:get_unames() 606 | 607 | This function returns a list with the names of all columns in the result 608 | set returned by statement stmt. 609 | 610 | =head2 stmt:get_utypes 611 | 612 | stmt:get_utypes() 613 | 614 | This function returns a list with the types of all columns in the result 615 | set returned by statement stmt. 616 | 617 | =head2 stmt:get_uvalues 618 | 619 | stmt:get_uvalues() 620 | 621 | This function returns a list with the values of all columns in the 622 | current result row of a query. 623 | 624 | =head2 stmt:get_value 625 | 626 | stmt:get_value(n) 627 | 628 | Returns the value of column C in the result set of statement stmt. (The 629 | left-most column is number 0.) 630 | 631 | =head2 stmt:get_values 632 | 633 | stmt:get_values() 634 | 635 | This function returns an array with the values of all columns in the 636 | result set returned by statement stmt. 637 | 638 | =head2 stmt:isopen 639 | 640 | stmt:isopen() 641 | 642 | Returns true if stmt has not yet been finalized, false otherwise. 643 | 644 | =head2 stmt:nrows 645 | 646 | stmt:nrows() 647 | 648 | Returns an function that iterates over the names and values of the 649 | result set of statement C. Each iteration returns a table with the 650 | names and values for the current row. 651 | This is the prepared statement equivalent of L|/db:nrows>. 652 | 653 | =head2 stmt:reset 654 | 655 | stmt:reset() 656 | 657 | This function resets SQL statement C, so that it is ready to be 658 | re-executed. Any statement variables that had values bound to them using 659 | the C functions retain their values. 660 | 661 | =head2 stmt:rows 662 | 663 | stmt:rows() 664 | 665 | Returns an function that iterates over the values of the result set of 666 | statement stmt. Each iteration returns an array with the values for the 667 | current row. 668 | This is the prepared statement equivalent of L|/db:rows>. 669 | 670 | =head2 stmt:step 671 | 672 | stmt:step() 673 | 674 | This function must be called to evaluate the (next iteration of the) 675 | prepared statement stmt. It will return one of the following values: 676 | 677 | =over 4 678 | 679 | =item * 680 | 681 | C: the engine was unable to acquire the locks needed. If the 682 | statement is a COMMIT or occurs outside of an explicit transaction, then 683 | you can retry the statement. If the statement is not a COMMIT and occurs 684 | within a explicit transaction then you should rollback the transaction 685 | before continuing. 686 | 687 | =item * 688 | 689 | C: the statement has finished executing successfully. 690 | L|/stmt:step> should not be called again on this statement 691 | without first calling L|/stmt:reset> to reset the virtual 692 | machine back to the initial state. 693 | 694 | =item * 695 | 696 | C: this is returned each time a new row of data is ready for 697 | processing by the caller. The values may be accessed using the column 698 | access functions. L|/stmt:step> can be called again to 699 | retrieve the next row of data. 700 | 701 | =item * 702 | 703 | C: a run-time error (such as a constraint violation) has 704 | occurred. L|/stmt:step> should not be called again. More 705 | information may be found by calling L|/db:errmsg>. A more 706 | specific error 707 | code (can be obtained by calling L|/stmt:reset>. 708 | 709 | =item * 710 | 711 | C: the function was called inappropriately, perhaps 712 | because the statement has already been finalized or a previous call to 713 | L|/stmt:step> has returned C or 714 | C. 715 | 716 | =back 717 | 718 | =head2 stmt:urows 719 | 720 | stmt:urows() 721 | 722 | Returns an function that iterates over the values of the result set of 723 | statement stmt. Each iteration returns the values for the current row. 724 | This is the prepared statement equivalent of L|/db:urows>. 725 | 726 | =head1 Methods for callback contexts 727 | 728 | A callback context is available as a parameter inside the callback 729 | functions L|/db:create_aggregate> and 730 | L|/db:create_function>. It can be used 731 | to get further information about the state of a query. 732 | 733 | =head2 context:aggregate_count 734 | 735 | context:aggregate_count() 736 | 737 | Returns the number of calls to the aggregate step function. 738 | 739 | =head2 context:get_aggregate_data 740 | 741 | context:get_aggregate_data() 742 | 743 | Returns the user-definable data field for callback funtions. 744 | 745 | =head2 context:set_aggregate_data 746 | 747 | context:set_aggregate_data(udata) 748 | 749 | Set the user-definable data field for callback funtions to C. 750 | 751 | =head2 context:result 752 | 753 | context:result(res) 754 | 755 | This function sets the result of a callback function to res. The type of 756 | the result depends on the type of res and is either a number or a string 757 | or nil. All other values will raise an error message. 758 | 759 | =head2 context:result_null 760 | 761 | context:result_null() 762 | 763 | This function sets the result of a callback function to nil. It returns 764 | nothing. 765 | 766 | =head2 context:result_number 767 | 768 | context:result_number(number) 769 | context:result_double(number) 770 | 771 | This function sets the result of a callback function to the value 772 | C. It returns nothing. 773 | 774 | =head2 context:result_int 775 | 776 | context:result_int(number) 777 | 778 | This function sets the result of a callback function to the integer 779 | value in C. It returns nothing. 780 | 781 | =head2 context:result_text 782 | 783 | context:result_text(str) 784 | 785 | This function sets the result of a callback function to the string in 786 | C. It returns nothing. 787 | 788 | =head2 context:result_blob 789 | 790 | context:result_blob(blob) 791 | 792 | This function sets the result of a callback function to the binary 793 | string in C. It returns nothing. 794 | 795 | =head2 context:result_error 796 | 797 | context:result_error(err) 798 | 799 | This function sets the result of a callback function to the error value 800 | in C. It returns nothing. 801 | 802 | =head2 context:user_data 803 | 804 | context:user_data() 805 | 806 | Returns the userdata parameter given in the call to install the callback 807 | function (see L|/db:create_aggregate> and 808 | L|/db:create_function> for details). 809 | 810 | =head1 Numerical error and result codes 811 | 812 | The following constants are defined by module sqlite3: 813 | 814 | OK: 0 ERROR: 1 INTERNAL: 2 PERM: 3 ABORT: 4 815 | BUSY: 5 LOCKED: 6 NOMEM: 7 READONLY: 8 INTERRUPT: 9 816 | IOERR: 10 CORRUPT: 11 NOTFOUND: 12 FULL: 13 CANTOPEN: 14 817 | PROTOCOL: 15 EMPTY: 16 SCHEMA: 17 TOOBIG: 18 CONSTRAINT: 19 818 | MISMATCH: 20 MISUSE: 21 NOLFS: 22 FORMAT: 24 RANGE: 25 819 | NOTADB: 26 ROW: 100 DONE: 101 820 | 821 | For details about their exact meaning please see the B L. 823 | 824 | =head1 VERSION 825 | 826 | This is C subversion 6, also known as "devel-0.6". 827 | 828 | =head1 CREDITS 829 | 830 | C was developed by Tiago Dionizio and Doug Currie with 831 | contributions from Thomas Lauer and Michael Roth. 832 | 833 | This documentation is based on the "(very) preliminary" documents 834 | for the Idle-SQLite3 database module. Thanks to Thomas Lauer for 835 | making it available. 836 | 837 | =head1 LICENSE 838 | 839 | /************************************************************************ 840 | * lsqlite3 * 841 | * Copyright (C) 2002-2007 Tiago Dionizio, Doug Currie * 842 | * All rights reserved. * 843 | * Author : Tiago Dionizio * 844 | * Author : Doug Currie * 845 | * Library : lsqlite3 - a SQLite 3 database binding for Lua 5 * 846 | * * 847 | * Permission is hereby granted, free of charge, to any person obtaining * 848 | * a copy of this software and associated documentation files (the * 849 | * "Software"), to deal in the Software without restriction, including * 850 | * without limitation the rights to use, copy, modify, merge, publish, * 851 | * distribute, sublicense, and/or sell copies of the Software, and to * 852 | * permit persons to whom the Software is furnished to do so, subject to * 853 | * the following conditions: * 854 | * * 855 | * The above copyright notice and this permission notice shall be * 856 | * included in all copies or substantial portions of the Software. * 857 | * * 858 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * 859 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * 860 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.* 861 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * 862 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * 863 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * 864 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * 865 | ************************************************************************/ 866 | 867 | -------------------------------------------------------------------------------- /doc/pod2html.pl: -------------------------------------------------------------------------------- 1 | #!perl 2 | 3 | use Pod::Html; 4 | 5 | pod2html @ARGV; 6 | 7 | __END__ 8 | -------------------------------------------------------------------------------- /examples/aggregate.lua: -------------------------------------------------------------------------------- 1 | 2 | require("lsqlite3") 3 | 4 | local db = sqlite3.open_memory() 5 | 6 | assert( db:exec "CREATE TABLE test (col1, col2)" ) 7 | assert( db:exec "INSERT INTO test VALUES (1, 2)" ) 8 | assert( db:exec "INSERT INTO test VALUES (2, 4)" ) 9 | assert( db:exec "INSERT INTO test VALUES (3, 6)" ) 10 | assert( db:exec "INSERT INTO test VALUES (4, 8)" ) 11 | assert( db:exec "INSERT INTO test VALUES (5, 10)" ) 12 | 13 | do 14 | 15 | local square_error_sum = 0 16 | 17 | local function step(ctx, a, b) 18 | local error = a - b 19 | local square_error = error * error 20 | square_error_sum = square_error_sum + square_error 21 | end 22 | 23 | local function final(ctx) 24 | ctx:result_number( square_error_sum / ctx:aggregate_count() ) 25 | end 26 | 27 | assert( db:create_aggregate("my_stats", 2, step, final) ) 28 | 29 | end 30 | 31 | --for a,b in db:urows("SELECT col1, col2 FROM test") 32 | --do print("a b: ", a, b) end 33 | 34 | for my_stats in db:urows("SELECT my_stats(col1, col2) FROM test") 35 | do print("my_stats:", my_stats) end 36 | -------------------------------------------------------------------------------- /examples/function.lua: -------------------------------------------------------------------------------- 1 | 2 | require("lsqlite3") 3 | 4 | 5 | local db = sqlite3.open_memory() 6 | 7 | assert( db:exec "CREATE TABLE test (col1, col2)" ) 8 | assert( db:exec "INSERT INTO test VALUES (1, 2)" ) 9 | assert( db:exec "INSERT INTO test VALUES (2, 4)" ) 10 | assert( db:exec "INSERT INTO test VALUES (3, 6)" ) 11 | assert( db:exec "INSERT INTO test VALUES (4, 8)" ) 12 | assert( db:exec "INSERT INTO test VALUES (5, 10)" ) 13 | 14 | assert( db:create_function("my_sum", 2, function(ctx, a, b) 15 | ctx:result_number( a + b ) 16 | end)) 17 | 18 | 19 | for col1, col2, sum in db:urows("SELECT *, my_sum(col1, col2) FROM test") do 20 | print(col1, col2, sum) 21 | end 22 | -------------------------------------------------------------------------------- /examples/order.lua: -------------------------------------------------------------------------------- 1 | 2 | require("lsqlite3") 3 | 4 | local db = assert( sqlite3:open_memory() ) 5 | 6 | assert( db:exec[[ 7 | 8 | CREATE TABLE customer ( 9 | id INTEGER PRIMARY KEY, 10 | name VARCHAR(40) 11 | ); 12 | 13 | CREATE TABLE invoice ( 14 | id INTEGER PRIMARY KEY, 15 | customer INTEGER NOT NULL, 16 | title VARCHAR(80) NOT NULL, 17 | article1 VARCHAR(40) NOT NULL, 18 | price1 REAL NOT NULL, 19 | article2 VARCHAR(40), 20 | price2 REAL 21 | ); 22 | 23 | CREATE TABLE invoice_overflow ( 24 | id INTEGER PRIMARY KEY, 25 | invoice INTEGER NOT NULL, 26 | article VARCHAR(40) NOT NULL, 27 | price REAL NOT NULL 28 | ); 29 | 30 | INSERT INTO customer VALUES( 31 | 1, "Michael" ); 32 | 33 | INSERT INTO invoice VALUES( 34 | 1, 1, "Computer parts", "harddisc", 89.90, "floppy", 9.99 ); 35 | 36 | INSERT INTO customer VALUES( 37 | 2, "John" ); 38 | 39 | INSERT INTO invoice VALUES( 40 | 2, 2, "Somme food", "apples", 2.79, "pears", 5.99 ); 41 | 42 | INSERT INTO invoice_overflow VALUES( 43 | NULL, 2, "grapes", 6.34 ); 44 | 45 | INSERT INTO invoice_overflow VALUES( 46 | NULL, 2, "strawberries", 4.12 ); 47 | 48 | INSERT INTO invoice_overflow VALUES( 49 | NULL, 2, "tomatoes", 6.17 ); 50 | 51 | INSERT INTO invoice VALUES( 52 | 3, 2, "A new car", "Cybercar XL-1000", 65000.00, NULL, NULL ); 53 | 54 | ]] ) 55 | 56 | 57 | local function customer_name(id) 58 | local stmt = db:prepare("SELECT name FROM customer WHERE id = ?") 59 | stmt:bind_values(id) 60 | stmt:step() 61 | local r = stmt:get_uvalues() 62 | stmt:finalize() 63 | return r 64 | end 65 | 66 | 67 | local function all_invoices() 68 | return db:nrows("SELECT id, customer, title FROM invoice") 69 | end 70 | 71 | 72 | local function all_articles(invoice) 73 | 74 | local function iterator() 75 | local stmt, row 76 | 77 | -- Get the articles that are contained in the invoice table itself. 78 | stmt = db:prepare("SELECT article1, price1, article2, price2 FROM invoice WHERE id = ?") 79 | stmt:bind_values(invoice) 80 | stmt:step() 81 | row = stmt:get_named_values() 82 | 83 | -- Every Invoice has at least one article. 84 | coroutine.yield(row.article1, row.price1) 85 | 86 | -- Maybe the Invoice has a second article? 87 | if row.article2 then 88 | 89 | -- Yes, there is a second article, so return it. 90 | coroutine.yield(row.article2, row.price2) 91 | 92 | -- When there was an second article, maybe there are even 93 | -- more articles in the overflow table? We will see... 94 | 95 | stmt = db:prepare("SELECT article, price FROM invoice_overflow WHERE invoice = ? ORDER BY id") 96 | stmt:bind_values(invoice) 97 | 98 | for row in stmt:nrows() do 99 | coroutine.yield(row.article, row.price) 100 | end 101 | end 102 | end 103 | 104 | return coroutine.wrap(iterator) 105 | end 106 | 107 | 108 | for invoice in all_invoices() do 109 | local id = invoice.id 110 | local name = customer_name(invoice.customer) 111 | local title = invoice.title 112 | 113 | print() 114 | print("Invoice #"..id..", "..name..": '"..title.."'") 115 | print("----------------------------------------") 116 | 117 | for article, price in all_articles(id) do 118 | print( string.format("%20s %8.2f", article, price) ) 119 | end 120 | 121 | print() 122 | end 123 | -------------------------------------------------------------------------------- /examples/simple.lua: -------------------------------------------------------------------------------- 1 | 2 | require("lsqlite3") 3 | 4 | local db = sqlite3.open_memory() 5 | 6 | db:exec[[ 7 | CREATE TABLE test (id INTEGER PRIMARY KEY, content); 8 | 9 | INSERT INTO test VALUES (NULL, 'Hello World'); 10 | INSERT INTO test VALUES (NULL, 'Hello Lua'); 11 | INSERT INTO test VALUES (NULL, 'Hello Sqlite3') 12 | ]] 13 | 14 | for row in db:nrows("SELECT * FROM test") do 15 | print(row.id, row.content) 16 | end 17 | -------------------------------------------------------------------------------- /examples/smart.lua: -------------------------------------------------------------------------------- 1 | 2 | require("lsqlite3") 3 | 4 | local db = sqlite3.open_memory() 5 | 6 | db:exec[[ CREATE TABLE test (id INTEGER PRIMARY KEY, content) ]] 7 | 8 | local stmt = db:prepare[[ INSERT INTO test VALUES (:key, :value) ]] 9 | 10 | stmt:bind_names{ key = 1, value = "Hello World" } 11 | stmt:step() 12 | stmt:reset() 13 | stmt:bind_names{ key = 2, value = "Hello Lua" } 14 | stmt:step() 15 | stmt:reset() 16 | stmt:bind_names{ key = 3, value = "Hello Sqlite3" } 17 | stmt:step() 18 | stmt:finalize() 19 | 20 | for row in db:nrows("SELECT * FROM test") do 21 | print(row.id, row.content) 22 | end 23 | -------------------------------------------------------------------------------- /examples/statement.lua: -------------------------------------------------------------------------------- 1 | 2 | require("lsqlite3") 3 | 4 | local db = sqlite3.open_memory() 5 | 6 | db:exec[[ 7 | CREATE TABLE test ( 8 | id INTEGER PRIMARY KEY, 9 | content VARCHAR 10 | ); 11 | ]] 12 | 13 | local insert_stmt = assert( db:prepare("INSERT INTO test VALUES (NULL, ?)") ) 14 | 15 | local function insert(data) 16 | insert_stmt:bind_values(data) 17 | insert_stmt:step() 18 | insert_stmt:reset() 19 | end 20 | 21 | local select_stmt = assert( db:prepare("SELECT * FROM test") ) 22 | 23 | local function select() 24 | for row in select_stmt:nrows() do 25 | print(row.id, row.content) 26 | end 27 | end 28 | 29 | insert("Hello World") 30 | print("First:") 31 | select() 32 | 33 | insert("Hello Lua") 34 | print("Second:") 35 | select() 36 | 37 | insert("Hello Sqlite3") 38 | print("Third:") 39 | select() 40 | -------------------------------------------------------------------------------- /examples/tracing.lua: -------------------------------------------------------------------------------- 1 | 2 | require("lsqlite3") 3 | 4 | local db = sqlite3.open_memory() 5 | 6 | db:trace( function(ud, sql) 7 | print("Sqlite Trace:", sql) 8 | end ) 9 | 10 | db:exec[[ 11 | CREATE TABLE test ( id INTEGER PRIMARY KEY, content VARCHAR ); 12 | 13 | INSERT INTO test VALUES (NULL, 'Hello World'); 14 | INSERT INTO test VALUES (NULL, 'Hello Lua'); 15 | INSERT INTO test VALUES (NULL, 'Hello Sqlite3'); 16 | ]] 17 | 18 | for row in db:rows("SELECT * FROM test") do 19 | -- NOP 20 | end 21 | -------------------------------------------------------------------------------- /lsqlite3.def: -------------------------------------------------------------------------------- 1 | EXPORTS 2 | luaopen_lsqlite3 3 | -------------------------------------------------------------------------------- /lunit.lua: -------------------------------------------------------------------------------- 1 | 2 | --[[-------------------------------------------------------------------------- 3 | 4 | This file is part of lunit 0.4pre (alpha). 5 | 6 | For Details about lunit look at: http://www.nessie.de/mroth/lunit/ 7 | 8 | Author: Michael Roth 9 | 10 | Copyright (c) 2004 Michael Roth 11 | 12 | Permission is hereby granted, free of charge, to any person 13 | obtaining a copy of this software and associated documentation 14 | files (the "Software"), to deal in the Software without restriction, 15 | including without limitation the rights to use, copy, modify, merge, 16 | publish, distribute, sublicense, and/or sell copies of the Software, 17 | and to permit persons to whom the Software is furnished to do so, 18 | subject to the following conditions: 19 | 20 | The above copyright notice and this permission notice shall be 21 | included in all copies or substantial portions of the Software. 22 | 23 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 24 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 25 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 26 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 27 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 28 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 29 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 30 | 31 | --]]-------------------------------------------------------------------------- 32 | 33 | 34 | 35 | 36 | ----------------------- 37 | -- Intialize package -- 38 | ----------------------- 39 | 40 | local P = { } 41 | lunit = P 42 | 43 | -- Import 44 | local type = type 45 | local print = print 46 | local ipairs = ipairs 47 | local pairs = pairs 48 | local string = string 49 | local table = table 50 | local pcall = pcall 51 | local xpcall = xpcall 52 | local traceback = debug.traceback 53 | local error = error 54 | local setmetatable = setmetatable 55 | local rawset = rawset 56 | local orig_assert = assert 57 | local getfenv = getfenv 58 | local setfenv = setfenv 59 | local tostring = tostring 60 | 61 | 62 | -- Start package scope 63 | setfenv(1, P) 64 | 65 | 66 | 67 | 68 | -------------------------------- 69 | -- Private data and functions -- 70 | -------------------------------- 71 | 72 | local run_testcase 73 | local do_assert, check_msg 74 | local stats = { } 75 | local testcases = { } 76 | local stats_inc, tc_mt 77 | 78 | 79 | 80 | 81 | -------------------------- 82 | -- Type check functions -- 83 | -------------------------- 84 | 85 | function is_nil(x) 86 | return type(x) == "nil" 87 | end 88 | 89 | function is_boolean(x) 90 | return type(x) == "boolean" 91 | end 92 | 93 | function is_number(x) 94 | return type(x) == "number" 95 | end 96 | 97 | function is_string(x) 98 | return type(x) == "string" 99 | end 100 | 101 | function is_table(x) 102 | return type(x) == "table" 103 | end 104 | 105 | function is_function(x) 106 | return type(x) == "function" 107 | end 108 | 109 | function is_thread(x) 110 | return type(x) == "thread" 111 | end 112 | 113 | function is_userdata(x) 114 | return type(x) == "userdata" 115 | end 116 | 117 | 118 | 119 | 120 | ---------------------- 121 | -- Assert functions -- 122 | ---------------------- 123 | 124 | function assert(assertion, msg) 125 | stats_inc("assertions") 126 | check_msg("assert", msg) 127 | do_assert(not not assertion, "assertion failed (was: "..tostring(assertion)..")", msg) -- (convert assertion to bool) 128 | return assertion 129 | end 130 | 131 | 132 | function assert_fail(msg) 133 | stats_inc("assertions") 134 | check_msg("assert_fail", msg) 135 | do_assert(false, "failure", msg) 136 | end 137 | 138 | 139 | function assert_true(actual, msg) 140 | stats_inc("assertions") 141 | check_msg("assert_true", msg) 142 | do_assert(is_boolean(actual), "true expected but was a "..type(actual), msg) 143 | do_assert(actual == true, "true expected but was false", msg) 144 | return actual 145 | end 146 | 147 | 148 | function assert_false(actual, msg) 149 | stats_inc("assertions") 150 | check_msg("assert_false", msg) 151 | do_assert(is_boolean(actual), "false expected but was a "..type(actual), msg) 152 | do_assert(actual == false, "false expected but was true", msg) 153 | return actual 154 | end 155 | 156 | 157 | function assert_equal(expected, actual, msg) 158 | stats_inc("assertions") 159 | check_msg("assert_equal", msg) 160 | do_assert(expected == actual, "expected '"..tostring(expected).."' but was '"..tostring(actual).."'", msg) 161 | return actual 162 | end 163 | 164 | 165 | function assert_not_equal(unexpected, actual, msg) 166 | stats_inc("assertions") 167 | check_msg("assert_not_equal", msg) 168 | do_assert(unexpected ~= actual, "'"..tostring(expected).."' not expected but was one", msg) 169 | return actual 170 | end 171 | 172 | 173 | function assert_match(pattern, actual, msg) 174 | stats_inc("assertions") 175 | check_msg("assert_match", msg) 176 | do_assert(is_string(pattern), "assert_match expects the pattern as a string") 177 | do_assert(is_string(actual), "expected a string to match pattern '"..pattern.."' but was a '"..type(actual).."'", msg) 178 | do_assert(not not string.find(actual, pattern), "expected '"..actual.."' to match pattern '"..pattern.."' but doesn't", msg) 179 | return actual 180 | end 181 | 182 | 183 | function assert_not_match(pattern, actual, msg) 184 | stats_inc("assertions") 185 | check_msg("assert_not_match", msg) 186 | do_assert(is_string(actual), "expected a string to not match pattern '"..pattern.."' but was a '"..type(actual).."'", msg) 187 | do_assert(string.find(actual, pattern) == nil, "expected '"..actual.."' to not match pattern '"..pattern.."' but it does", msg) 188 | return actual 189 | end 190 | 191 | 192 | function assert_nil(actual, msg) 193 | stats_inc("assertions") 194 | check_msg("assert_nil", msg) 195 | do_assert(is_nil(actual), "nil expected but was a "..type(actual), msg) 196 | return actual 197 | end 198 | 199 | 200 | function assert_not_nil(actual, msg) 201 | stats_inc("assertions") 202 | check_msg("assert_not_nil", msg) 203 | do_assert(not is_nil(actual), "nil not expected but was one", msg) 204 | return actual 205 | end 206 | 207 | 208 | function assert_boolean(actual, msg) 209 | stats_inc("assertions") 210 | check_msg("assert_boolean", msg) 211 | do_assert(is_boolean(actual), "boolean expected but was a "..type(actual), msg) 212 | return actual 213 | end 214 | 215 | 216 | function assert_not_boolean(actual, msg) 217 | stats_inc("assertions") 218 | check_msg("assert_not_boolean", msg) 219 | do_assert(not is_boolean(actual), "boolean not expected but was one", msg) 220 | return actual 221 | end 222 | 223 | 224 | function assert_number(actual, msg) 225 | stats_inc("assertions") 226 | check_msg("assert_number", msg) 227 | do_assert(is_number(actual), "number expected but was a "..type(actual), msg) 228 | return actual 229 | end 230 | 231 | 232 | function assert_not_number(actual, msg) 233 | stats_inc("assertions") 234 | check_msg("assert_not_number", msg) 235 | do_assert(not is_number(actual), "number not expected but was one", msg) 236 | return actual 237 | end 238 | 239 | 240 | function assert_string(actual, msg) 241 | stats_inc("assertions") 242 | check_msg("assert_string", msg) 243 | do_assert(is_string(actual), "string expected but was a "..type(actual), msg) 244 | return actual 245 | end 246 | 247 | 248 | function assert_not_string(actual, msg) 249 | stats_inc("assertions") 250 | check_msg("assert_not_string", msg) 251 | do_assert(not is_string(actual), "string not expected but was one", msg) 252 | return actual 253 | end 254 | 255 | 256 | function assert_table(actual, msg) 257 | stats_inc("assertions") 258 | check_msg("assert_table", msg) 259 | do_assert(is_table(actual), "table expected but was a "..type(actual), msg) 260 | return actual 261 | end 262 | 263 | 264 | function assert_not_table(actual, msg) 265 | stats_inc("assertions") 266 | check_msg("assert_not_table", msg) 267 | do_assert(not is_table(actual), "table not expected but was one", msg) 268 | return actual 269 | end 270 | 271 | 272 | function assert_function(actual, msg) 273 | stats_inc("assertions") 274 | check_msg("assert_function", msg) 275 | do_assert(is_function(actual), "function expected but was a "..type(actual), msg) 276 | return actual 277 | end 278 | 279 | 280 | function assert_not_function(actual, msg) 281 | stats_inc("assertions") 282 | check_msg("assert_not_function", msg) 283 | do_assert(not is_function(actual), "function not expected but was one", msg) 284 | return actual 285 | end 286 | 287 | 288 | function assert_thread(actual, msg) 289 | stats_inc("assertions") 290 | check_msg("assert_thread", msg) 291 | do_assert(is_thread(actual), "thread expected but was a "..type(actual), msg) 292 | return actual 293 | end 294 | 295 | 296 | function assert_not_thread(actual, msg) 297 | stats_inc("assertions") 298 | check_msg("assert_not_thread", msg) 299 | do_assert(not is_thread(actual), "thread not expected but was one", msg) 300 | return actual 301 | end 302 | 303 | 304 | function assert_userdata(actual, msg) 305 | stats_inc("assertions") 306 | check_msg("assert_userdata", msg) 307 | do_assert(is_userdata(actual), "userdata expected but was a "..type(actual), msg) 308 | return actual 309 | end 310 | 311 | 312 | function assert_not_userdata(actual, msg) 313 | stats_inc("assertions") 314 | check_msg("assert_not_userdata", msg) 315 | do_assert(not is_userdata(actual), "userdata not expected but was one", msg) 316 | return actual 317 | end 318 | 319 | 320 | function assert_error(msg, func) 321 | stats_inc("assertions") 322 | if is_nil(func) then func, msg = msg, nil end 323 | check_msg("assert_error", msg) 324 | do_assert(is_function(func), "assert_error expects a function as the last argument but it was a "..type(func)) 325 | local ok, errmsg = pcall(func) 326 | do_assert(ok == false, "error expected but no error occurred", msg) 327 | end 328 | 329 | 330 | function assert_pass(msg, func) 331 | stats_inc("assertions") 332 | if is_nil(func) then func, msg = msg, nil end 333 | check_msg("assert_pass", msg) 334 | do_assert(is_function(func), "assert_pass expects a function as the last argument but it was a "..type(func)) 335 | local ok, errmsg = pcall(func) 336 | if not ok then do_assert(ok == true, "no error expected but error was: "..errmsg, msg) end 337 | end 338 | 339 | 340 | 341 | 342 | ----------------------------------------------------------- 343 | -- Assert implementation that assumes it was called from -- 344 | -- lunit code which was called directly from user code. -- 345 | ----------------------------------------------------------- 346 | 347 | function do_assert(assertion, base_msg, user_msg) 348 | orig_assert(is_boolean(assertion)) 349 | orig_assert(is_string(base_msg)) 350 | orig_assert(is_string(user_msg) or is_nil(user_msg)) 351 | if not assertion then 352 | if user_msg then 353 | error(base_msg..": "..user_msg, 3) 354 | else 355 | error(base_msg.."!", 3) 356 | end 357 | end 358 | end 359 | 360 | ------------------------------------------- 361 | -- Checks the msg argument in assert_xxx -- 362 | ------------------------------------------- 363 | 364 | function check_msg(name, msg) 365 | orig_assert(is_string(name)) 366 | if not (is_nil(msg) or is_string(msg)) then 367 | error("lunit."..name.."() expects the optional message as a string but it was a "..type(msg).."!" ,3) 368 | end 369 | end 370 | 371 | 372 | 373 | 374 | ------------------------------------- 375 | -- Creates a new TestCase 'Object' -- 376 | ------------------------------------- 377 | 378 | function TestCase(name) 379 | do_assert(is_string(name), "lunit.TestCase() needs a string as an argument") 380 | local tc = { 381 | __lunit_name = name; 382 | __lunit_setup = nil; 383 | __lunit_tests = { }; 384 | __lunit_teardown = nil; 385 | } 386 | setmetatable(tc, tc_mt) 387 | table.insert(testcases, tc) 388 | return tc 389 | end 390 | 391 | tc_mt = { 392 | __newindex = function(tc, key, value) 393 | rawset(tc, key, value) 394 | if is_string(key) and is_function(value) then 395 | local name = string.lower(key) 396 | if string.find(name, "^test") or string.find(name, "test$") then 397 | table.insert(tc.__lunit_tests, key) 398 | elseif name == "setup" then 399 | tc.__lunit_setup = value 400 | elseif name == "teardown" then 401 | tc.__lunit_teardown = value 402 | end 403 | end 404 | end 405 | } 406 | 407 | 408 | 409 | ----------------------------------------- 410 | -- Wrap Functions in a TestCase object -- 411 | ----------------------------------------- 412 | 413 | function wrap(name, ...) 414 | if is_function(name) then 415 | table.insert({...}, 1, name) 416 | name = "Anonymous Testcase" 417 | end 418 | 419 | local tc = TestCase(name) 420 | for index, test in ipairs({...}) do 421 | tc["Test #"..index] = test 422 | end 423 | return tc 424 | end 425 | 426 | 427 | 428 | 429 | 430 | 431 | ---------------------------------- 432 | -- Runs the complete Test Suite -- 433 | ---------------------------------- 434 | 435 | function run() 436 | 437 | --------------------------- 438 | -- Initialize statistics -- 439 | --------------------------- 440 | 441 | stats.testcases = 0 -- Total number of Test Cases 442 | stats.tests = 0 -- Total number of all Tests in all Test Cases 443 | stats.run = 0 -- Number of Tests run 444 | stats.notrun = 0 -- Number of Tests not run 445 | stats.failed = 0 -- Number of Tests failed 446 | stats.warnings = 0 -- Number of Warnings (teardown) 447 | stats.errors = 0 -- Number of Errors (setup) 448 | stats.passed = 0 -- Number of Test passed 449 | stats.assertions = 0 -- Number of all assertions made in all Test in all Test Cases 450 | 451 | -------------------------------- 452 | -- Count Test Cases and Tests -- 453 | -------------------------------- 454 | 455 | stats.testcases = table.getn(testcases) 456 | 457 | for _, tc in ipairs(testcases) do 458 | stats_inc("tests" , table.getn(tc.__lunit_tests)) 459 | end 460 | 461 | ------------------ 462 | -- Print Header -- 463 | ------------------ 464 | 465 | print() 466 | print("#### Test Suite with "..stats.tests.." Tests in "..stats.testcases.." Test Cases loaded.") 467 | 468 | ------------------------ 469 | -- Run all Test Cases -- 470 | ------------------------ 471 | 472 | for _, tc in ipairs(testcases) do 473 | run_testcase(tc) 474 | end 475 | 476 | ------------------ 477 | -- Print Footer -- 478 | ------------------ 479 | 480 | print() 481 | print("#### Test Suite finished.") 482 | 483 | local msg_assertions = stats.assertions.." Assertions checked. " 484 | local msg_passed = stats.passed == stats.tests and "All Tests passed" or stats.passed.." Tests passed" 485 | local msg_failed = stats.failed > 0 and ", "..stats.failed.." failed" or "" 486 | local msg_run = stats.notrun > 0 and ", "..stats.notrun.." not run" or "" 487 | local msg_warn = stats.warnings > 0 and ", "..stats.warnings.." warnings" or "" 488 | 489 | print() 490 | print(msg_assertions..msg_passed..msg_failed..msg_run..msg_warn.."!") 491 | 492 | ----------------- 493 | -- Return code -- 494 | ----------------- 495 | 496 | if stats.passed == stats.tests then 497 | return 0 498 | else 499 | return 1 500 | end 501 | end 502 | 503 | 504 | 505 | 506 | ----------------------------- 507 | -- Runs a single Test Case -- 508 | ----------------------------- 509 | 510 | function run_testcase(tc) 511 | 512 | orig_assert(is_table(tc)) 513 | orig_assert(is_table(tc.__lunit_tests)) 514 | orig_assert(is_string(tc.__lunit_name)) 515 | orig_assert(is_nil(tc.__lunit_setup) or is_function(tc.__lunit_setup)) 516 | orig_assert(is_nil(tc.__lunit_teardown) or is_function(tc.__lunit_teardown)) 517 | 518 | ---------------------------------- 519 | -- Protected call to a function -- 520 | ---------------------------------- 521 | 522 | local function call(errprefix, func) 523 | orig_assert(is_string(errprefix)) 524 | orig_assert(is_function(func)) 525 | local ok, errmsg = xpcall(function() func(tc) end, traceback) 526 | if not ok then 527 | print() 528 | print(errprefix..": "..errmsg) 529 | end 530 | return ok 531 | end 532 | 533 | ------------------------------------ 534 | -- Calls setup() on the Test Case -- 535 | ------------------------------------ 536 | 537 | local function setup(testname) 538 | if tc.__lunit_setup then 539 | return call("ERROR: "..testname..": setup() failed", tc.__lunit_setup) 540 | else 541 | return true 542 | end 543 | end 544 | 545 | ------------------------------------------ 546 | -- Calls a single Test on the Test Case -- 547 | ------------------------------------------ 548 | 549 | local function run(testname) 550 | orig_assert(is_string(testname)) 551 | orig_assert(is_function(tc[testname])) 552 | local ok = call("FAIL: "..testname, tc[testname]) 553 | if not ok then 554 | stats_inc("failed") 555 | else 556 | stats_inc("passed") 557 | end 558 | return ok 559 | end 560 | 561 | --------------------------------------- 562 | -- Calls teardown() on the Test Case -- 563 | --------------------------------------- 564 | 565 | local function teardown(testname) 566 | if tc.__lunit_teardown then 567 | if not call("WARNING: "..testname..": teardown() failed", tc.__lunit_teardown) then 568 | stats_inc("warnings") 569 | end 570 | end 571 | end 572 | 573 | --------------------------------- 574 | -- Run all Tests on a TestCase -- 575 | --------------------------------- 576 | 577 | print() 578 | print("#### Running '"..tc.__lunit_name.."' ("..table.getn(tc.__lunit_tests).." Tests)...") 579 | 580 | for _, testname in ipairs(tc.__lunit_tests) do 581 | if setup(testname) then 582 | run(testname) 583 | stats_inc("run") 584 | teardown(testname) 585 | else 586 | print("WARN: Skipping '"..testname.."'...") 587 | stats_inc("notrun") 588 | end 589 | end 590 | 591 | end 592 | 593 | 594 | 595 | 596 | --------------------- 597 | -- Import function -- 598 | --------------------- 599 | 600 | function import(name) 601 | 602 | do_assert(is_string(name), "lunit.import() expects a single string as argument") 603 | 604 | local user_env = getfenv(2) 605 | 606 | -------------------------------------------------- 607 | -- Installs a specific function in the user env -- 608 | -------------------------------------------------- 609 | 610 | local function install(funcname) 611 | user_env[funcname] = P[funcname] 612 | end 613 | 614 | 615 | ---------------------------------------------------------- 616 | -- Install functions matching a pattern in the user env -- 617 | ---------------------------------------------------------- 618 | 619 | local function install_pattern(pattern) 620 | for funcname, _ in pairs(P) do 621 | if string.find(funcname, pattern) then 622 | install(funcname) 623 | end 624 | end 625 | end 626 | 627 | ------------------------------------------------------------ 628 | -- Installs assert() and all assert_xxx() in the user env -- 629 | ------------------------------------------------------------ 630 | 631 | local function install_asserts() 632 | install_pattern("^assert.*") 633 | end 634 | 635 | ------------------------------------------- 636 | -- Installs all is_xxx() in the user env -- 637 | ------------------------------------------- 638 | 639 | local function install_tests() 640 | install_pattern("^is_.+") 641 | end 642 | 643 | if name == "asserts" or name == "assertions" then 644 | install_asserts() 645 | elseif name == "tests" or name == "checks" then 646 | install_tests() 647 | elseif name == "all" then 648 | install_asserts() 649 | install_tests() 650 | install("TestCase") 651 | elseif string.find(name, "^assert.*") and P[name] then 652 | install(name) 653 | elseif string.find(name, "^is_.+") and P[name] then 654 | install(name) 655 | elseif name == "TestCase" then 656 | install("TestCase") 657 | else 658 | error("luniit.import(): invalid function '"..name.."' to import", 2) 659 | end 660 | end 661 | 662 | 663 | 664 | 665 | -------------------------------------------------- 666 | -- Installs a private environment on the caller -- 667 | -------------------------------------------------- 668 | 669 | function setprivfenv() 670 | local new_env = { } 671 | local new_env_mt = { __index = getfenv(2) } 672 | setmetatable(new_env, new_env_mt) 673 | setfenv(2, new_env) 674 | end 675 | 676 | 677 | 678 | 679 | -------------------------------------------------- 680 | -- Increments a counter in the statistics table -- 681 | -------------------------------------------------- 682 | 683 | function stats_inc(varname, value) 684 | orig_assert(is_table(stats)) 685 | orig_assert(is_string(varname)) 686 | orig_assert(is_nil(value) or is_number(value)) 687 | if not stats[varname] then return end 688 | stats[varname] = stats[varname] + (value or 1) 689 | end 690 | 691 | 692 | 693 | 694 | -------------------------------------------------------------------------------- /test.lua: -------------------------------------------------------------------------------- 1 | require("lsqlite3") 2 | 3 | local width = 78 4 | local function line(pref, suff) 5 | pref = pref or '' 6 | suff = suff or '' 7 | local len = width - 2 - string.len(pref) - string.len(suff) 8 | print(pref .. string.rep('-', len) .. suff) 9 | end 10 | 11 | local db, vm 12 | local assert_, assert = assert, function (test) 13 | if (not test) then 14 | error(db:errmsg(), 2) 15 | end 16 | end 17 | 18 | line(sqlite3.version()) 19 | 20 | os.remove('test.db') 21 | db = sqlite3.open('test.db') 22 | 23 | line(nil, 'db:exec') 24 | db:exec('CREATE TABLE t(a, b)') 25 | 26 | line(nil, 'prepare') 27 | vm = db:prepare('insert into t values(?, :bork)') 28 | assert(vm, db:errmsg()) 29 | assert(vm:bind_parameter_count() == 2) 30 | assert(vm:bind_values(2, 4) == sqlite3.OK) 31 | assert(vm:step() == sqlite3.DONE) 32 | assert(vm:reset() == sqlite3.OK) 33 | assert(vm:bind_names{ 'pork', bork = 'nono' } == sqlite3.OK) 34 | assert(vm:step() == sqlite3.DONE) 35 | assert(vm:reset() == sqlite3.OK) 36 | assert(vm:bind_names{ bork = 'sisi' } == sqlite3.OK) 37 | assert(vm:step() == sqlite3.DONE) 38 | assert(vm:reset() == sqlite3.OK) 39 | assert(vm:bind_names{ 1 } == sqlite3.OK) 40 | assert(vm:step() == sqlite3.DONE) 41 | assert(vm:finalize() == sqlite3.OK) 42 | 43 | line("select * from t", 'db:exec') 44 | 45 | assert(db:exec('select * from t', function (ud, ncols, values, names) 46 | --table.setn(values, 2) 47 | print(unpack(values)) 48 | return sqlite3.OK 49 | end) == sqlite3.OK) 50 | 51 | line("select * from t", 'db:prepare') 52 | 53 | vm = db:prepare('select * from t') 54 | assert(vm, db:errmsg()) 55 | print(vm:get_unames()) 56 | while (vm:step() == sqlite3.ROW) do 57 | print(vm:get_uvalues()) 58 | end 59 | assert(vm:finalize() == sqlite3.OK) 60 | 61 | 62 | 63 | line('udf', 'scalar') 64 | 65 | local function do_query(sql) 66 | local r 67 | local vm = db:prepare(sql) 68 | assert(vm, db:errmsg()) 69 | print('====================================') 70 | print(vm:get_unames()) 71 | print('------------------------------------') 72 | r = vm:step() 73 | while (r == sqlite3.ROW) do 74 | print(vm:get_uvalues()) 75 | r = vm:step() 76 | end 77 | assert(r == sqlite3.DONE) 78 | assert(vm:finalize() == sqlite3.OK) 79 | print('====================================') 80 | end 81 | 82 | local function udf1_scalar(ctx, v) 83 | local ud = ctx:user_data() 84 | ud.r = (ud.r or '') .. tostring(v) 85 | ctx:result_text(ud.r) 86 | end 87 | 88 | db:create_function('udf1', 1, udf1_scalar, { }) 89 | do_query('select udf1(a) from t') 90 | 91 | 92 | line('udf', 'aggregate') 93 | 94 | local function udf2_aggregate(ctx, ...) 95 | local ud = ctx:get_aggregate_data() 96 | if (not ud) then 97 | ud = {} 98 | ctx:set_aggregate_data(ud) 99 | end 100 | ud.r = (ud.r or 0) + 2 101 | end 102 | 103 | local function udf2_aggregate_finalize(ctx, v) 104 | local ud = ctx:get_aggregate_data() 105 | ctx:result_number(ud and ud.r or 0) 106 | end 107 | 108 | db:create_aggregate('udf2', 1, udf2_aggregate, udf2_aggregate_finalize, { }) 109 | do_query('select udf2(a) from t') 110 | 111 | if (true) then 112 | line(nil, '100 insert exec') 113 | db:exec('delete from t') 114 | local t = os.time() 115 | for i = 1, 100 do 116 | db:exec('insert into t values('..i..', '..(i * 2 * -1^i)..')') 117 | end 118 | print('elapsed: '..(os.time() - t)) 119 | do_query('select count(*) from t') 120 | 121 | line(nil, '100000 insert exec T') 122 | db:exec('delete from t') 123 | local t = os.time() 124 | db:exec('begin') 125 | for i = 1, 100000 do 126 | db:exec('insert into t values('..i..', '..(i * 2 * -1^i)..')') 127 | end 128 | db:exec('commit') 129 | print('elapsed: '..(os.time() - t)) 130 | do_query('select count(*) from t') 131 | 132 | line(nil, '100000 insert prepare/bind T') 133 | db:exec('delete from t') 134 | local t = os.time() 135 | local vm = db:prepare('insert into t values(?, ?)') 136 | db:exec('begin') 137 | for i = 1, 100000 do 138 | vm:bind_values(i, i * 2 * -1^i) 139 | vm:step() 140 | vm:reset() 141 | end 142 | vm:finalize() 143 | db:exec('commit') 144 | print('elapsed: '..(os.time() - t)) 145 | do_query('select count(*) from t') 146 | 147 | end 148 | 149 | line(nil, "db:close") 150 | 151 | assert(db:close() == sqlite3.OK) 152 | 153 | line(sqlite3.version()) 154 | -------------------------------------------------------------------------------- /tests-sqlite3.lua: -------------------------------------------------------------------------------- 1 | 2 | --[[-------------------------------------------------------------------------- 3 | 4 | Author: Michael Roth 5 | 6 | Copyright (c) 2004, 2005 Michael Roth 7 | 8 | Permission is hereby granted, free of charge, to any person 9 | obtaining a copy of this software and associated documentation 10 | files (the "Software"), to deal in the Software without restriction, 11 | including without limitation the rights to use, copy, modify, merge, 12 | publish, distribute, sublicense, and/or sell copies of the Software, 13 | and to permit persons to whom the Software is furnished to do so, 14 | subject to the following conditions: 15 | 16 | The above copyright notice and this permission notice shall be 17 | included in all copies or substantial portions of the Software. 18 | 19 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 20 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 21 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 22 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 23 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 24 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 25 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 26 | 27 | --]]-------------------------------------------------------------------------- 28 | 29 | 30 | require "lsqlite3" 31 | 32 | require "lunit" 33 | 34 | lunit.setprivfenv() 35 | lunit.import "assertions" 36 | lunit.import "checks" 37 | 38 | 39 | 40 | 41 | 42 | 43 | ------------------------------- 44 | -- Basic open and close test -- 45 | ------------------------------- 46 | 47 | lunit.wrap("open_memory", function() 48 | local db = assert_userdata( sqlite3.open_memory() ) 49 | assert( db:close() ) 50 | end) 51 | 52 | lunit.wrap("open", function() 53 | local filename = "/tmp/__lua-sqlite3-20040906135849." .. os.time() 54 | local db = assert_userdata( sqlite3.open(filename) ) 55 | assert( db:close() ) 56 | os.remove(filename) 57 | end) 58 | 59 | 60 | 61 | ------------------------------------- 62 | -- Presence of db member functions -- 63 | ------------------------------------- 64 | 65 | local db_funcs = lunit.TestCase("Database Member Functions") 66 | 67 | function db_funcs:setup() 68 | self.db = assert( sqlite3.open_memory() ) 69 | end 70 | 71 | function db_funcs:teardown() 72 | assert( self.db:close() ) 73 | end 74 | 75 | function db_funcs:test() 76 | local db = self.db 77 | assert_function( db.close ) 78 | assert_function( db.exec ) 79 | --e assert_function( db.irows ) 80 | assert_function( db.rows ) 81 | --e assert_function( db.cols ) 82 | --e assert_function( db.first_irow ) 83 | --e assert_function( db.first_row ) 84 | --e assert_function( db.first_cols ) 85 | assert_function( db.prepare ) 86 | assert_function( db.interrupt ) 87 | assert_function( db.last_insert_rowid ) 88 | assert_function( db.changes ) 89 | assert_function( db.total_changes ) 90 | end 91 | 92 | 93 | 94 | --------------------------------------- 95 | -- Presence of stmt member functions -- 96 | --------------------------------------- 97 | 98 | local stmt_funcs = lunit.TestCase("Statement Member Functions") 99 | 100 | function stmt_funcs:setup() 101 | self.db = assert( sqlite3.open_memory() ) 102 | self.stmt = assert( self.db:prepare("CREATE TABLE test (id, content)") ) 103 | end 104 | 105 | function stmt_funcs:teardown() 106 | --e- assert( self.stmt:close() ) 107 | assert( self.stmt:finalize() ) --e+ 108 | assert( self.db:close() ) 109 | end 110 | 111 | function stmt_funcs:test() 112 | local stmt = self.stmt 113 | --e assert_function( stmt.close ) 114 | assert_function( stmt.reset ) 115 | --e assert_function( stmt.exec ) 116 | assert_function( stmt.bind ) 117 | --e assert_function( stmt.irows ) 118 | --e assert_function( stmt.rows ) 119 | --e assert_function( stmt.cols ) 120 | --e assert_function( stmt.first_irow ) 121 | --e assert_function( stmt.first_row ) 122 | --e assert_function( stmt.first_cols ) 123 | --e assert_function( stmt.column_names ) 124 | --e assert_function( stmt.column_decltypes ) 125 | --e assert_function( stmt.column_count ) 126 | --e + 127 | assert_function( stmt.isopen ) 128 | assert_function( stmt.step ) 129 | assert_function( stmt.reset ) 130 | assert_function( stmt.finalize ) 131 | assert_function( stmt.columns ) 132 | assert_function( stmt.bind ) 133 | assert_function( stmt.bind_values ) 134 | assert_function( stmt.bind_names ) 135 | assert_function( stmt.bind_blob ) 136 | assert_function( stmt.bind_parameter_count ) 137 | assert_function( stmt.bind_parameter_name ) 138 | assert_function( stmt.get_value ) 139 | assert_function( stmt.get_values ) 140 | assert_function( stmt.get_name ) 141 | assert_function( stmt.get_names ) 142 | assert_function( stmt.get_type ) 143 | assert_function( stmt.get_types ) 144 | assert_function( stmt.get_uvalues ) 145 | assert_function( stmt.get_unames ) 146 | assert_function( stmt.get_utypes ) 147 | assert_function( stmt.get_named_values ) 148 | assert_function( stmt.get_named_types ) 149 | assert_function( stmt.idata ) 150 | assert_function( stmt.inames ) 151 | assert_function( stmt.itypes ) 152 | assert_function( stmt.data ) 153 | assert_function( stmt.type ) 154 | --e + 155 | end 156 | 157 | 158 | 159 | ------------------ 160 | -- Tests basics -- 161 | ------------------ 162 | 163 | local basics = lunit.TestCase("Basics") 164 | 165 | function basics:setup() 166 | self.db = assert_userdata( sqlite3.open_memory() ) 167 | end 168 | 169 | function basics:teardown() 170 | assert_number( self.db:close() ) 171 | end 172 | 173 | function basics:create_table() 174 | assert_number( self.db:exec("CREATE TABLE test (id, name)") ) 175 | end 176 | 177 | function basics:drop_table() 178 | assert_number( self.db:exec("DROP TABLE test") ) 179 | end 180 | 181 | function basics:insert(id, name) 182 | assert_number( self.db:exec("INSERT INTO test VALUES ("..id..", '"..name.."')") ) 183 | end 184 | 185 | function basics:update(id, name) 186 | assert_number( self.db:exec("UPDATE test SET name = '"..name.."' WHERE id = "..id) ) 187 | end 188 | 189 | function basics:test_create_drop() 190 | self:create_table() 191 | self:drop_table() 192 | end 193 | 194 | function basics:test_multi_create_drop() 195 | self:create_table() 196 | self:drop_table() 197 | self:create_table() 198 | self:drop_table() 199 | end 200 | 201 | function basics:test_insert() 202 | self:create_table() 203 | self:insert(1, "Hello World") 204 | self:insert(2, "Hello Lua") 205 | self:insert(3, "Hello sqlite3") 206 | end 207 | 208 | function basics:test_update() 209 | self:create_table() 210 | self:insert(1, "Hello Home") 211 | self:insert(2, "Hello Lua") 212 | self:update(1, "Hello World") 213 | end 214 | 215 | 216 | --------------------------------- 217 | -- Statement Column Info Tests -- 218 | --------------------------------- 219 | 220 | lunit.wrap("Column Info Test", function() 221 | local db = assert_userdata( sqlite3.open_memory() ) 222 | assert_number( db:exec("CREATE TABLE test (id INTEGER, name TEXT)") ) 223 | local stmt = assert_userdata( db:prepare("SELECT * FROM test") ) 224 | 225 | assert_equal(2, stmt:columns(), "Wrong number of columns." ) 226 | 227 | local names = assert_table( stmt:get_names() ) 228 | assert_equal(2, #(names), "Wrong number of names.") 229 | assert_equal("id", names[1] ) 230 | assert_equal("name", names[2] ) 231 | 232 | local types = assert_table( stmt:get_types() ) 233 | assert_equal(2, #(types), "Wrong number of declaration types.") 234 | assert_equal("INTEGER", types[1] ) 235 | assert_equal("TEXT", types[2] ) 236 | 237 | assert_equal( sqlite3.OK, stmt:finalize() ) 238 | assert_equal( sqlite3.OK, db:close() ) 239 | end) 240 | 241 | 242 | 243 | --------------------- 244 | -- Statement Tests -- 245 | --------------------- 246 | 247 | st = lunit.TestCase("Statement Tests") 248 | 249 | function st:setup() 250 | self.db = assert( sqlite3.open_memory() ) 251 | assert_equal( sqlite3.OK, self.db:exec("CREATE TABLE test (id, name)") ) 252 | assert_equal( sqlite3.OK, self.db:exec("INSERT INTO test VALUES (1, 'Hello World')") ) 253 | assert_equal( sqlite3.OK, self.db:exec("INSERT INTO test VALUES (2, 'Hello Lua')") ) 254 | assert_equal( sqlite3.OK, self.db:exec("INSERT INTO test VALUES (3, 'Hello sqlite3')") ) 255 | end 256 | 257 | function st:teardown() 258 | assert_equal( sqlite3.OK, self.db:close() ) 259 | end 260 | 261 | function st:check_content(expected) 262 | local stmt = assert( self.db:prepare("SELECT * FROM test ORDER BY id") ) 263 | local i = 0 264 | for row in stmt:rows() do 265 | i = i + 1 266 | assert( i <= #(expected), "Too many rows." ) 267 | assert_equal(2, #(row), "Two result column expected.") 268 | assert_equal(i, row[1], "Wrong 'id'.") 269 | assert_equal(expected[i], row[2], "Wrong 'name'.") 270 | end 271 | assert_equal( #(expected), i, "Too few rows." ) 272 | assert_number( stmt:finalize() ) 273 | end 274 | 275 | function st:test_setup() 276 | assert_pass(function() self:check_content{ "Hello World", "Hello Lua", "Hello sqlite3" } end) 277 | assert_error(function() self:check_content{ "Hello World", "Hello Lua" } end) 278 | assert_error(function() self:check_content{ "Hello World", "Hello Lua", "Hello sqlite3", "To much" } end) 279 | assert_error(function() self:check_content{ "Hello World", "Hello Lua", "Wrong" } end) 280 | assert_error(function() self:check_content{ "Hello World", "Wrong", "Hello sqlite3" } end) 281 | assert_error(function() self:check_content{ "Wrong", "Hello Lua", "Hello sqlite3" } end) 282 | end 283 | 284 | function st:test_questionmark_args() 285 | local stmt = assert_userdata( self.db:prepare("INSERT INTO test VALUES (?, ?)") ) 286 | assert_number( stmt:bind_values(0, "Test") ) 287 | assert_error(function() stmt:bind_values("To few") end) 288 | assert_error(function() stmt:bind_values(0, "Test", "To many") end) 289 | end 290 | 291 | function st:test_questionmark() 292 | local stmt = assert_userdata( self.db:prepare("INSERT INTO test VALUES (?, ?)") ) 293 | assert_number( stmt:bind_values(4, "Good morning") ) 294 | assert_number( stmt:step() ) 295 | assert_number( stmt:reset() ) 296 | self:check_content{ "Hello World", "Hello Lua", "Hello sqlite3", "Good morning" } 297 | assert_number( stmt:bind_values(5, "Foo Bar") ) 298 | assert_number( stmt:step() ) 299 | assert_number( stmt:reset() ) 300 | self:check_content{ "Hello World", "Hello Lua", "Hello sqlite3", "Good morning", "Foo Bar" } 301 | assert_number( stmt:finalize() ) 302 | end 303 | 304 | --[===[ 305 | function st:test_questionmark_multi() 306 | local stmt = assert_userdata( self.db:prepare([[ 307 | INSERT INTO test VALUES (?, ?); INSERT INTO test VALUES (?, ?) ]])) 308 | assert( stmt:bind_values(5, "Foo Bar", 4, "Good morning") ) 309 | assert_number( stmt:step() ) 310 | assert_number( stmt:reset() ) 311 | self:check_content{ "Hello World", "Hello Lua", "Hello sqlite3", "Good morning", "Foo Bar" } 312 | assert_number( stmt:finalize() ) 313 | end 314 | ]===] 315 | 316 | function st:test_identifiers() 317 | local stmt = assert_userdata( self.db:prepare("INSERT INTO test VALUES (:id, :name)") ) 318 | assert_number( stmt:bind_values(4, "Good morning") ) 319 | assert_number( stmt:step() ) 320 | assert_number( stmt:reset() ) 321 | self:check_content{ "Hello World", "Hello Lua", "Hello sqlite3", "Good morning" } 322 | assert_number( stmt:bind_values(5, "Foo Bar") ) 323 | assert_number( stmt:step() ) 324 | assert_number( stmt:reset() ) 325 | self:check_content{ "Hello World", "Hello Lua", "Hello sqlite3", "Good morning", "Foo Bar" } 326 | assert_number( stmt:finalize() ) 327 | end 328 | 329 | --[===[ 330 | function st:test_identifiers_multi() 331 | local stmt = assert_table( self.db:prepare([[ 332 | INSERT INTO test VALUES (:id1, :name1); INSERT INTO test VALUES (:id2, :name2) ]])) 333 | assert( stmt:bind_values(5, "Foo Bar", 4, "Good morning") ) 334 | assert( stmt:exec() ) 335 | self:check_content{ "Hello World", "Hello Lua", "Hello sqlite3", "Good morning", "Foo Bar" } 336 | end 337 | ]===] 338 | 339 | function st:test_identifiers_names() 340 | --local stmt = assert_userdata( self.db:prepare({"name", "id"}, "INSERT INTO test VALUES (:id, $name)") ) 341 | local stmt = assert_userdata( self.db:prepare("INSERT INTO test VALUES (:id, $name)") ) 342 | assert_number( stmt:bind_names({name="Good morning", id=4}) ) 343 | assert_number( stmt:step() ) 344 | assert_number( stmt:reset() ) 345 | self:check_content{ "Hello World", "Hello Lua", "Hello sqlite3", "Good morning" } 346 | assert_number( stmt:bind_names({name="Foo Bar", id=5}) ) 347 | assert_number( stmt:step() ) 348 | assert_number( stmt:reset() ) 349 | self:check_content{ "Hello World", "Hello Lua", "Hello sqlite3", "Good morning", "Foo Bar" } 350 | assert_number( stmt:finalize() ) 351 | end 352 | 353 | --[===[ 354 | function st:test_identifiers_multi_names() 355 | local stmt = assert_table( self.db:prepare( {"name", "id1", "id2"},[[ 356 | INSERT INTO test VALUES (:id1, $name); INSERT INTO test VALUES ($id2, :name) ]])) 357 | assert( stmt:bind_values("Hoho", 4, 5) ) 358 | assert( stmt:exec() ) 359 | self:check_content{ "Hello World", "Hello Lua", "Hello sqlite3", "Hoho", "Hoho" } 360 | end 361 | ]===] 362 | 363 | function st:test_colon_identifiers_names() 364 | local stmt = assert_userdata( self.db:prepare("INSERT INTO test VALUES (:id, :name)") ) 365 | assert_number( stmt:bind_names({name="Good morning", id=4}) ) 366 | assert_number( stmt:step() ) 367 | assert_number( stmt:reset() ) 368 | self:check_content{ "Hello World", "Hello Lua", "Hello sqlite3", "Good morning" } 369 | assert_number( stmt:bind_names({name="Foo Bar", id=5}) ) 370 | assert_number( stmt:step() ) 371 | assert_number( stmt:reset() ) 372 | self:check_content{ "Hello World", "Hello Lua", "Hello sqlite3", "Good morning", "Foo Bar" } 373 | assert_number( stmt:finalize() ) 374 | end 375 | 376 | --[===[ 377 | function st:test_colon_identifiers_multi_names() 378 | local stmt = assert_table( self.db:prepare( {":name", ":id1", ":id2"},[[ 379 | INSERT INTO test VALUES (:id1, $name); INSERT INTO test VALUES ($id2, :name) ]])) 380 | assert( stmt:bind_values("Hoho", 4, 5) ) 381 | assert( stmt:exec() ) 382 | self:check_content{ "Hello World", "Hello Lua", "Hello sqlite3", "Hoho", "Hoho" } 383 | end 384 | 385 | 386 | function st:test_dollar_identifiers_names() 387 | local stmt = assert_table( self.db:prepare({"$name", "$id"}, "INSERT INTO test VALUES (:id, $name)") ) 388 | assert_table( stmt:bind_values("Good morning", 4) ) 389 | assert_table( stmt:exec() ) 390 | self:check_content{ "Hello World", "Hello Lua", "Hello sqlite3", "Good morning" } 391 | assert_table( stmt:bind_values("Foo Bar", 5) ) 392 | assert_table( stmt:exec() ) 393 | self:check_content{ "Hello World", "Hello Lua", "Hello sqlite3", "Good morning", "Foo Bar" } 394 | end 395 | 396 | function st:test_dollar_identifiers_multi_names() 397 | local stmt = assert_table( self.db:prepare( {"$name", "$id1", "$id2"},[[ 398 | INSERT INTO test VALUES (:id1, $name); INSERT INTO test VALUES ($id2, :name) ]])) 399 | assert( stmt:bind_values("Hoho", 4, 5) ) 400 | assert( stmt:exec() ) 401 | self:check_content{ "Hello World", "Hello Lua", "Hello sqlite3", "Hoho", "Hoho" } 402 | end 403 | ]===] 404 | 405 | function st:test_bind_by_names() 406 | local stmt = assert_userdata( self.db:prepare("INSERT INTO test VALUES (:id, :name)") ) 407 | local args = { } 408 | args.id = 5 409 | args.name = "Hello girls" 410 | assert( stmt:bind_names(args) ) 411 | assert_number( stmt:step() ) 412 | assert_number( stmt:reset() ) 413 | args.id = 4 414 | args.name = "Hello boys" 415 | assert( stmt:bind_names(args) ) 416 | assert_number( stmt:step() ) 417 | assert_number( stmt:reset() ) 418 | self:check_content{ "Hello World", "Hello Lua", "Hello sqlite3", "Hello boys", "Hello girls" } 419 | assert_number( stmt:finalize() ) 420 | end 421 | 422 | 423 | 424 | -------------------------------- 425 | -- Tests binding of arguments -- 426 | -------------------------------- 427 | 428 | b = lunit.TestCase("Binding Tests") 429 | 430 | function b:setup() 431 | self.db = assert( sqlite3.open_memory() ) 432 | assert_number( self.db:exec("CREATE TABLE test (id, name, u, v, w, x, y, z)") ) 433 | end 434 | 435 | function b:teardown() 436 | assert_number( self.db:close() ) 437 | end 438 | 439 | function b:test_auto_parameter_names() 440 | local stmt = assert_userdata( self.db:prepare("INSERT INTO test VALUES(:a, $b, :a2, :b2, $a, :b, $a3, $b3)") ) 441 | local parameters = assert_number( stmt:bind_parameter_count() ) 442 | assert_equal( 8, parameters ) 443 | assert_equal( ":a", stmt:bind_parameter_name(1) ) 444 | assert_equal( "$b", stmt:bind_parameter_name(2) ) 445 | assert_equal( ":a2", stmt:bind_parameter_name(3) ) 446 | assert_equal( ":b2", stmt:bind_parameter_name(4) ) 447 | assert_equal( "$a", stmt:bind_parameter_name(5) ) 448 | assert_equal( ":b", stmt:bind_parameter_name(6) ) 449 | assert_equal( "$a3", stmt:bind_parameter_name(7) ) 450 | assert_equal( "$b3", stmt:bind_parameter_name(8) ) 451 | end 452 | 453 | function b:test_auto_parameter_names() 454 | local stmt = assert_userdata( self.db:prepare("INSERT INTO test VALUES($a, $b, $a2, $b2, $a, $b, $a3, $b3)") ) 455 | local parameters = assert_number( stmt:bind_parameter_count() ) 456 | assert_equal( 6, parameters ) 457 | assert_equal( "$a", stmt:bind_parameter_name(1) ) 458 | assert_equal( "$b", stmt:bind_parameter_name(2) ) 459 | assert_equal( "$a2", stmt:bind_parameter_name(3) ) 460 | assert_equal( "$b2", stmt:bind_parameter_name(4) ) 461 | assert_equal( "$a3", stmt:bind_parameter_name(5) ) 462 | assert_equal( "$b3", stmt:bind_parameter_name(6) ) 463 | end 464 | 465 | function b:test_no_parameter_names_1() 466 | local stmt = assert_userdata( self.db:prepare([[ SELECT * FROM test ]])) 467 | local parameters = assert_number( stmt:bind_parameter_count() ) 468 | assert_equal( 0, (parameters) ) 469 | end 470 | 471 | function b:test_no_parameter_names_2() 472 | local stmt = assert_userdata( self.db:prepare([[ INSERT INTO test VALUES(?, ?, ?, ?, ?, ?, ?, ?) ]])) 473 | local parameters = assert_number( stmt:bind_parameter_count() ) 474 | assert_equal( 8, (parameters) ) 475 | assert_nil( stmt:bind_parameter_name(1) ) 476 | end 477 | 478 | 479 | 480 | 481 | 482 | 483 | 484 | -------------------------------------------- 485 | -- Tests loop break and statement reusage -- 486 | -------------------------------------------- 487 | 488 | 489 | 490 | ---------------------------- 491 | -- Test for bugs reported -- 492 | ---------------------------- 493 | 494 | bug = lunit.TestCase("Bug-Report Tests") 495 | 496 | function bug:setup() 497 | self.db = assert( sqlite3.open_memory() ) 498 | end 499 | 500 | function bug:teardown() 501 | assert_number( self.db:close() ) 502 | end 503 | 504 | --[===[ 505 | function bug:test_1() 506 | self.db:exec("CREATE TABLE test (id INTEGER PRIMARY KEY, value TEXT)") 507 | 508 | local query = assert_userdata( self.db:prepare("SELECT id FROM test WHERE value=?") ) 509 | 510 | assert_table ( query:bind_values("1") ) 511 | assert_nil ( query:first_cols() ) 512 | assert_table ( query:bind_values("2") ) 513 | assert_nil ( query:first_cols() ) 514 | end 515 | ]===] 516 | 517 | function bug:test_nils() -- appeared in lua-5.1 (holes in arrays) 518 | local function check(arg1, arg2, arg3, arg4, arg5) 519 | assert_equal(1, arg1) 520 | assert_equal(2, arg2) 521 | assert_nil(arg3) 522 | assert_equal(4, arg4) 523 | assert_nil(arg5) 524 | end 525 | 526 | self.db:create_function("test_nils", 5, function(arg1, arg2, arg3, arg4, arg5) 527 | check(arg1, arg2, arg3, arg4, arg5) 528 | end, {}) 529 | 530 | assert_number( self.db:exec([[ SELECT test_nils(1, 2, NULL, 4, NULL) ]]) ) 531 | 532 | for arg1, arg2, arg3, arg4, arg5 in self.db:urows([[ SELECT 1, 2, NULL, 4, NULL ]]) 533 | do check(arg1, arg2, arg3, arg4, arg5) 534 | end 535 | 536 | for row in self.db:rows([[ SELECT 1, 2, NULL, 4, NULL ]]) 537 | do assert_table( row ) 538 | check(row[1], row[2], row[3], row[4], row[5]) 539 | end 540 | end 541 | 542 | ---------------------------- 543 | -- Test for collation fun -- 544 | ---------------------------- 545 | 546 | colla = lunit.TestCase("Collation Tests") 547 | 548 | function colla:setup() 549 | local function collate(s1,s2) 550 | -- if p then print("collation callback: ",s1,s2) end 551 | s1=s1:lower() 552 | s2=s2:lower() 553 | if s1==s2 then return 0 554 | elseif s1