diff --git a/binding.gyp b/binding.gyp index b056fb6b..5c2459b1 100644 --- a/binding.gyp +++ b/binding.gyp @@ -1,3 +1,7 @@ +# === +# This is the main GYP file, which builds better-sqlite3 with SQLite3 itself. +# === + { 'includes': ['deps/common.gypi'], 'targets': [ diff --git a/deps/common.gypi b/deps/common.gypi index 5bd141b9..63f36af2 100644 --- a/deps/common.gypi +++ b/deps/common.gypi @@ -1,3 +1,8 @@ +# === +# This configuration defines the differences between Release and Debug builds. +# Some miscellaneous Windows settings are also defined here. +# === + { 'target_defaults': { 'default_configuration': 'Release', diff --git a/deps/defines.gypi b/deps/defines.gypi new file mode 100644 index 00000000..4e588772 --- /dev/null +++ b/deps/defines.gypi @@ -0,0 +1,34 @@ +# THIS FILE IS AUTOMATICALLY GENERATED (DO NOT EDIT) + +{ + 'target_defaults': { + 'defines': [ + 'SQLITE_THREADSAFE=0', + 'SQLITE_DEFAULT_MEMSTATUS=0', + 'SQLITE_LIKE_DOESNT_MATCH_BLOBS', + 'SQLITE_OMIT_DEPRECATED', + 'SQLITE_OMIT_TRACE', + 'SQLITE_OMIT_COMPLETE', + 'SQLITE_OMIT_GET_TABLE', + 'SQLITE_OMIT_DESERIALIZE', + 'SQLITE_OMIT_TCL_VARIABLE', + 'SQLITE_OMIT_AUTHORIZATION', + 'SQLITE_OMIT_PROGRESS_CALLBACK', + 'SQLITE_DEFAULT_CACHE_SIZE=-16000', + 'SQLITE_DEFAULT_FOREIGN_KEYS=1', + 'SQLITE_DEFAULT_WAL_SYNCHRONOUS=1', + 'SQLITE_MAX_ATTACHED=125', + 'SQLITE_MAX_LENGTH=2147483647', + 'SQLITE_MAX_SQL_LENGTH=1073741824', + 'SQLITE_USE_URI=1', + 'SQLITE_ENABLE_COLUMN_METADATA', + 'SQLITE_ENABLE_UPDATE_DELETE_LIMIT', + 'SQLITE_ENABLE_FTS4', + 'SQLITE_ENABLE_FTS5', + 'SQLITE_ENABLE_JSON1', + 'SQLITE_ENABLE_RTREE', + 'SQLITE_INTROSPECTION_PRAGMAS', + 'SQLITE_SOUNDEX', + ], + }, +} diff --git a/deps/download.sh b/deps/download.sh index 15d5a62d..a8bd6ab4 100755 --- a/deps/download.sh +++ b/deps/download.sh @@ -1,16 +1,72 @@ #!/usr/bin/env sh +# === +# This script defines and generates the bundled SQLite3 unit (sqlite3.c). +# +# The following steps are taken: +# 1. populate the shell environment with the defined compile-time options. +# 2. download and extract the SQLite3 source code into a temporary directory. +# 3. run "sh configure" and "make sqlite3.c" within the source directory. +# 4. bundle the generated amalgamation into a tar.gz file (sqlite3.tar.gz). +# 5. export the defined compile-time options to a gyp file (defines.gypi). +# 6. update the docs (../docs/compilation.md) with details of this distribution. +# +# When a user builds better-sqlite3, the following steps are taken: +# 1. node-gyp loads the previously exported compile-time options (defines.gypi). +# 2. the extract.js script unpacks the bundled amalgamation (sqlite3.tar.gz). +# 3. node-gyp compiles the extracted sqlite3.c along with better_sqlite3.cpp. +# 3. node-gyp links the two resulting binaries to generate better_sqlite3.node. +# === + VERSION="3250100" YEAR="2018" -echo "downloading source..." -DEPS="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )" +# TODO: SQLITE_ENABLE_STAT4 (test ANALYZE with stat4 enabled) +# TODO: SQLITE_ENABLE_GEOPOLY (determine if the emitted warnings are safe or not) + +DEFINES=" +SQLITE_THREADSAFE=0 +SQLITE_DEFAULT_MEMSTATUS=0 +SQLITE_LIKE_DOESNT_MATCH_BLOBS +SQLITE_OMIT_DEPRECATED +SQLITE_OMIT_TRACE +SQLITE_OMIT_COMPLETE +SQLITE_OMIT_GET_TABLE +SQLITE_OMIT_DESERIALIZE +SQLITE_OMIT_TCL_VARIABLE +SQLITE_OMIT_AUTHORIZATION +SQLITE_OMIT_PROGRESS_CALLBACK +SQLITE_DEFAULT_CACHE_SIZE=-16000 +SQLITE_DEFAULT_FOREIGN_KEYS=1 +SQLITE_DEFAULT_WAL_SYNCHRONOUS=1 +SQLITE_MAX_ATTACHED=125 +SQLITE_MAX_LENGTH=2147483647 +SQLITE_MAX_SQL_LENGTH=1073741824 +SQLITE_USE_URI=1 +SQLITE_ENABLE_COLUMN_METADATA +SQLITE_ENABLE_UPDATE_DELETE_LIMIT +SQLITE_ENABLE_FTS4 +SQLITE_ENABLE_FTS5 +SQLITE_ENABLE_JSON1 +SQLITE_ENABLE_RTREE +SQLITE_INTROSPECTION_PRAGMAS +SQLITE_SOUNDEX +" + +# ========== START SCRIPT ========== # + +echo "setting up environment..." +DEPS="$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)" TEMP="$DEPS/temp" rm -rf "$TEMP" mkdir -p "$TEMP" -curl -#f "https://www.sqlite.org/$YEAR/sqlite-src-$VERSION.zip" > "$TEMP/temp.zip" || exit 1 +export CFLAGS=`echo $(echo "$DEFINES" | sed -e "/^\s*$/d" -e "s/^/-D/")` + +echo "downloading source..." +curl -#f "https://www.sqlite.org/$YEAR/sqlite-src-$VERSION.zip" > "$TEMP/source.zip" || exit 1 + echo "extracting source..." -unzip "$TEMP/temp.zip" -d "$TEMP" > /dev/null || exit 1 +unzip "$TEMP/source.zip" -d "$TEMP" > /dev/null || exit 1 cd "$TEMP/sqlite-src-$VERSION" echo "configuring amalgamation..." @@ -22,11 +78,23 @@ make sqlite3.c > /dev/null || exit 1 echo "generating tarball..." tar czf "$DEPS/sqlite3.tar.gz" sqlite3.c sqlite3.h sqlite3ext.h || exit 1 -echo "cleaning up..." -cd - > /dev/null -rm -rf "$TEMP" +echo "updating gyp configs..." +GYP="$DEPS/defines.gypi" +printf "# THIS FILE IS AUTOMATICALLY GENERATED (DO NOT EDIT)\n\n{\n 'target_defaults': {\n 'defines': [\n" > "$GYP" +printf "$DEFINES" | sed -e "/^\s*$/d" -e "s/\(.*\)/ '\1',/" >> "$GYP" +printf " ],\n },\n}\n" >> "$GYP" + +echo "updating docs..." +DOCS="$DEPS/../docs/compilation.md" MAJOR=`expr "${VERSION:0:1}" + 0` MINOR=`expr "${VERSION:1:2}" + 0` PATCH=`expr "${VERSION:3:2}" + 0` -sed -Ei "" -e "s/version [0-9]+\.[0-9]+\.[0-9]+/version $MAJOR.$MINOR.$PATCH/g" "$DEPS/../docs/compilation.md" +sed -Ei "" -e "s/version [0-9]+\.[0-9]+\.[0-9]+/version $MAJOR.$MINOR.$PATCH/g" "$DOCS" +sed -i "" -e "/^- SQLITE_/,\$d" "$DOCS" +printf "$DEFINES" | sed -e "/^\s*$/d" -e "s/^/- /" >> "$DOCS" + +echo "cleaning up..." +cd - > /dev/null +rm -rf "$TEMP" + echo "done!" diff --git a/deps/extract.js b/deps/extract.js index c791544b..3a0990d4 100644 --- a/deps/extract.js +++ b/deps/extract.js @@ -2,10 +2,15 @@ const path = require('path'); const tar = require('tar'); -const source = path.join(__dirname, process.argv[2]); -const dest = process.argv[3]; +const source = path.join(__dirname, 'sqlite3.tar.gz'); +const dest = process.argv[2]; process.on('unhandledRejection', (err) => { throw err; }); +/* + This extracts the bundled sqlite3.tar.gz file and places the resulting files + into the directory specified by <$2>. + */ + tar.extract({ file: source, cwd: dest, onwarn: process.emitWarning }) .then(() => process.exit(0)); diff --git a/deps/sqlite3.gyp b/deps/sqlite3.gyp index 7ba59a4f..1edcdd2d 100755 --- a/deps/sqlite3.gyp +++ b/deps/sqlite3.gyp @@ -1,5 +1,11 @@ +# === +# This configuration defines options specific to compiling SQLite3 itself. +# Compile-time options are loaded by the auto-generated file "defines.gypi". +# Before SQLite3 is compiled, it gets extracted from "sqlite3.tar.gz". +# === + { - 'includes': ['common.gypi'], + 'includes': ['common.gypi', 'defines.gypi'], 'target_defaults': { 'configurations': { 'Debug': { @@ -33,13 +39,13 @@ 'hard_dependency': 1, 'actions': [{ 'action_name': 'unpack_sqlite_dep', - 'inputs': ['./sqlite3.tar.gz'], + 'inputs': ['sqlite3.tar.gz'], 'outputs': [ '<(SHARED_INTERMEDIATE_DIR)/sqlite3/sqlite3.c', '<(SHARED_INTERMEDIATE_DIR)/sqlite3/sqlite3.h', '<(SHARED_INTERMEDIATE_DIR)/sqlite3/sqlite3ext.h', ], - 'action': ['node', './extract.js', '<@(_inputs)', '<(SHARED_INTERMEDIATE_DIR)/sqlite3'], + 'action': ['node', 'extract.js', '<(SHARED_INTERMEDIATE_DIR)/sqlite3'], }], }, { @@ -63,39 +69,6 @@ '-Wno-sign-compare', ], }, - 'defines': [ - # NOTE: when these change, so must /docs/compilation.md - 'SQLITE_THREADSAFE=0', - 'SQLITE_DEFAULT_MEMSTATUS=0', - 'SQLITE_LIKE_DOESNT_MATCH_BLOBS', - 'SQLITE_OMIT_DEPRECATED', - 'SQLITE_OMIT_TRACE', - 'SQLITE_OMIT_COMPLETE', - 'SQLITE_OMIT_GET_TABLE', - 'SQLITE_OMIT_DESERIALIZE', - 'SQLITE_OMIT_TCL_VARIABLE', - 'SQLITE_OMIT_AUTHORIZATION', - 'SQLITE_OMIT_PROGRESS_CALLBACK', - 'SQLITE_DEFAULT_CACHE_SIZE=-16000', - 'SQLITE_DEFAULT_FOREIGN_KEYS=1', - 'SQLITE_DEFAULT_WAL_SYNCHRONOUS=1', - 'SQLITE_MAX_ATTACHED=125', - 'SQLITE_MAX_LENGTH=2147483647', - 'SQLITE_MAX_SQL_LENGTH=1073741824', - 'SQLITE_USE_URI=1', - 'SQLITE_ENABLE_COLUMN_METADATA', - # TODO: test ANALYZE with stat4 enabled - # 'SQLITE_ENABLE_STAT4', - 'SQLITE_ENABLE_UPDATE_DELETE_LIMIT', - 'SQLITE_ENABLE_FTS4', - 'SQLITE_ENABLE_FTS5', - 'SQLITE_ENABLE_JSON1', - 'SQLITE_ENABLE_RTREE', - # TODO: determine if the emitted warnings are safe or not - # 'SQLITE_ENABLE_GEOPOLY', - 'SQLITE_INTROSPECTION_PRAGMAS', - 'SQLITE_SOUNDEX', - ], }, ], } diff --git a/deps/sqlite3.tar.gz b/deps/sqlite3.tar.gz index 038d753e..0cd5b459 100644 Binary files a/deps/sqlite3.tar.gz and b/deps/sqlite3.tar.gz differ diff --git a/deps/test_extension.c b/deps/test_extension.c index a6fa5c92..982446cf 100644 --- a/deps/test_extension.c +++ b/deps/test_extension.c @@ -1,6 +1,10 @@ #include SQLITE_EXTENSION_INIT1 +/* + This SQLite3 extension is used only for testing purposes (npm test). + */ + static void TestExtensionFunction(sqlite3_context* pCtx, int nVal, sqlite3_value** _) { sqlite3_result_double(pCtx, (double)nVal); }