Add initial version of dijkstra backend cloudron image

This commit is contained in:
2020-10-12 11:27:15 +02:00
commit 4f5db9ab26
4209 changed files with 448228 additions and 0 deletions

33
node_modules/sqlite3/.dockerignore generated vendored Normal file
View File

@@ -0,0 +1,33 @@
#.dockerignore
*~
Dockerfile
.git/
#.gitignore
*.dylib
*.so
*.o
*.lo
*.Makefile
*.target.gyp.mk
lib/binding
build
out
Release
Debug
node_modules
.deps
Makefile.gyp
gyp-mac-tool
.dirstamp
npm-debug.log
test/support/big.db
test/tmp
test/nw/app.nw
.DS_Store
.idea
.dtps
local.env
.mason
.eslintrc.js
setup.sh

282
node_modules/sqlite3/CHANGELOG.md generated vendored Normal file
View File

@@ -0,0 +1,282 @@
# Changelog
## 4.1.1
- Electron v6.1 and v7 support [#1237](https://github.com/mapbox/node-sqlite3/pull/1237)
- Electron v7.1 support [#1254](https://github.com/mapbox/node-sqlite3/pull/1254)
- SQLite3 update to 3.30.1 [#1238](https://github.com/mapbox/node-sqlite3/pull/1238)
- Overwrite 'msbuild_toolset' only if 'toolset' is defined [#1242](https://github.com/mapbox/node-sqlite3/pull/1242)
- Upgrade CI to node-gyp 6.x for Windows Electron v5 & v6 builds [#1245](https://github.com/mapbox/node-sqlite3/pull/1245)
- Node v13 support [#1247](https://github.com/mapbox/node-sqlite3/pull/1247)
- Use minimum supported node version for Electron 7 [#1255](https://github.com/mapbox/node-sqlite3/pull/1255)
## 4.1.0
- Electron v6 support [#1195](https://github.com/mapbox/node-sqlite3/pull/1195)
- Electron v4.1 and v4.2 support [#1180](https://github.com/mapbox/node-sqlite3/pull/1180)
- Custom file header with `--sqlite_magic` [#1144](https://github.com/mapbox/node-sqlite3/pull/1144)
- https everywhere [#1177](https://github.com/mapbox/node-sqlite3/pull/1177)
## 4.0.9
- Use trusty as the base for prebuilts [#1167](https://github.com/mapbox/node-sqlite3/pull/1167)
## 4.0.8
- Rerelease of 4.0.7 but removed excess .vscode files [0df90c7](https://github.com/mapbox/node-sqlite3/commit/0df90c7811331169ad5f8fbad396422e72757af3)
## 4.0.7
- Node v12 support
- Electron v5 support
- Fix backup API tests
- HAVE_USLEEP=1 for all platforms
- docker suport
## 4.0.6
- Release of 4.0.5 (again due CI)
## 4.0.5
- **SECURITY:** Upgrade SQLite to 3.26.0 [#1088](https://github.com/mapbox/node-sqlite3/pull/1088)
- add constants for file open (shared databases) [#1078](https://github.com/mapbox/node-sqlite3/pull/1078)
- Allow specifying the python to use [#1089](https://github.com/mapbox/node-sqlite3/pull/1089)
## 4.0.4
- Add NodeJS 11 support [#1072](https://github.com/mapbox/node-sqlite3/pull/1072)
- Add electron osx 3.0.0 support [#1071](https://github.com/mapbox/node-sqlite3/pull/1071)
## 4.0.3
- Increase electron/osx binary coverage [#1041](https://github.com/mapbox/node-sqlite3/pull/1041) (@kewde)
## 4.0.2
- Fixed HTTP proxy support by using `request` over `needle` in node-pre-gyp
## 4.0.1
- Node v10 support
- Upgrade to node-pre-gyp@0.10.1
- Upgrade to nan@2.10.0
- Upgrade to sqlite v3.24.0
- Stopped bundling node-pre-gyp
- Upgrade to mocha@5
- Now building electron binaries (@kewde)
- Add OPEN_FULLMUTEX constant
## 4.0.0
- Drop support for Node v0.10 and v.12
- Upgrade to node-pre-gyp@0.9.0
- Upgrade to nan@2.9.2
## 3.1.13
- Attempt to fix regression of #866
## 3.1.12
- Fixed to ensure the binaries do not rely on `GLIBC_2.14` and only `GLIBC_2.2.5`. This regressed in v3.1.11.
## 3.1.11
- Fixed building from source on alpine linux
## 3.1.10
- Removed `npm ls` from `prepublish` hook per mapbox/node-pre-gyp#291
- Upgraded node-pre-gyp to v0.6.37
- Removed accidentally committed large file
## 3.1.9
- Added support for node v8 and upgraded `nan`, `node-pre-gyp` deps.
## 3.1.8
- Added support for node v7 (pre-compiled binaries available)
## 3.1.7
- Upgrade sqlite to 3.15, enable FTS4, FTS5 (@wmertens)
- Upgrade to node-pre-gyp@0.6.31 and nan@2.4.0
## 3.1.6
- Starts bundling node-pre-gyp again to avoid #720
## 3.1.5
- [Added support for sqlite3_interrupt](https://github.com/mapbox/node-sqlite3/pull/518): this makes
it possible to interrupt a long-running query.
- [Fixes uv_ref race](https://github.com/mapbox/node-sqlite3/pull/705).
## 3.1.4
- Added support for node v6
## 3.1.3
- Upgrade to node-pre-gyp@0.6.26 with better support for Electron
## 3.1.2
- Only providing binaries for node v0.10x, v0.12.x, v4, and v5
- Upgrade to nan@2.2.x
- Upgrade to node-pre-gyp@0.6.24
## 3.1.1
- Support for node 5.x
- Upgraded SQLite to 3.9.1: https://www.sqlite.org/releaselog/3_9_1.html
- Enabled json1 extension by default
## 3.1.0
- Support for node 3.x and 4.x
- Stopped producing binaries for node-webkit and 32 bit linux
## 3.0.11
- Support for io.js 3.x (upgrade to Nan 2.x) @kkoopa
## 3.0.10
- Upgraded SQLite to 3.8.11.1: https://www.sqlite.org/releaselog/3_8_11_1.html
- Fixed binary compatibility regression with old centos/rhel glibc GLIBC_2.14 (re-introduced alpine linux (musl) build regression)
- Now providing binaries against Visual Studio 2015 (pass --toolset=v140) and use binaries from https://github.com/mapbox/node-cpp11
## 3.0.9
- Fixed build regression against alpine linux (musl)
- Upgraded node-pre-gyp@0.6.8
## 3.0.8
- Fixed build regression against FreeBSD
- Upgraded node-pre-gyp@0.6.7
## 3.0.7
- Fixed build regression against ARM and i386 linux
- Upgraded node-pre-gyp@0.6.6
- Added support for io.js 2.0.0
## 3.0.6
- Upgraded node-pre-gyp@0.6.5
- Upgraded nan@1.8.4
- Fixed binaries to work on older linux systems (circa GLIBC_2.2.5 like centos 6) @bnoordhuis
- Updated internal libsqlite3 from 3.8.7.1 -> 3.8.9 (https://www.sqlite.org/news.html)
## 3.0.5
- IO.js and Node v0.12.x support.
- Node-webkit v0.11.x support regressed in this release, sorry (https://github.com/mapbox/node-sqlite3/issues/404).
## 3.0.4
- Upgraded node-pre-gyp@0.6.1
## 3.0.3
- Upgraded to node-pre-gyp@0.6.0 which should fix crashes against node v0.11.14
- Now providing binaries against Visual Studio 2014 (pass --toolset=v140) and use binaries from https://github.com/mapbox/node-cpp11
## 3.0.2
- Republish for possibly busted npm package.
## 3.0.1
- Use ~ in node-pre-gyp semver for more flexible dep management.
## 3.0.0
Released September 20nd, 2014
- Backwards-incompatible change: node versions 0.8.x are no longer supported.
- Updated to node-pre-gyp@0.5.27
- Updated NAN to 1.3.0
- Updated internal libsqlite3 to v3.8.6
## 2.2.7
Released August 6th, 2014
- Removed usage of `npm ls` with `prepublish` target (which breaks node v0.8.x)
## 2.2.6
Released August 6th, 2014
- Fix bundled version of node-pre-gyp
## 2.2.5
Released August 5th, 2014
- Fix leak in complete() callback of Database.each() (#307)
- Started using `engineStrict` and improved `engines` declaration to make clear only >= 0.11.13 is supported for the 0.11.x series.
## 2.2.4
Released July 14th, 2014
- Now supporting node v0.11.x (specifically >=0.11.13)
- Fix db opening error with absolute path on windows
- Updated to node-pre-gyp@0.5.18
- updated internal libsqlite3 from 3.8.4.3 -> 3.8.5 (https://www.sqlite.org/news.html)
## 2.2.3
- Fixed regression in v2.2.2 for installing from binaries on windows.
## 2.2.2
- Fixed packaging problem whereby a `config.gypi` was unintentially packaged and could cause breakages for OS X builds.
## 2.2.1
- Now shipping with 64bit FreeBSD binaries against both node v0.10.x and node v0.8.x.
- Fixed solaris/smartos source compile by passing `-std=c99` when building internally bundled libsqlite3 (#201)
- Reduced size of npm package by ignoring tests and examples.
- Various fixes and improvements for building against node-webkit
- Upgraded to node-pre-gyp@0.5.x from node-pre-gyp@0.2.5
- Improved ability to build from source against `sqlcipher` by passing custom library name: `--sqlite_libname=sqlcipher`
- No changes to C++ Core / Existing binaries are exactly the same
## 2.2.0
Released Jan 13th, 2014
- updated internal libsqlite3 from 3.7.17 -> 3.8.2 (https://www.sqlite.org/news.html) which includes the next-generation query planner http://www.sqlite.org/queryplanner-ng.html
- improved binary deploy system using https://github.com/springmeyer/node-pre-gyp
- binary install now supports http proxies
- source compile now supports freebsd
- fixed support for node-webkit
## 2.1.19
Released October 31st, 2013
- Started respecting `process.env.npm_config_tmp` as location to download binaries
- Removed uneeded `progress` dependency
## 2.1.18
Released October 22nd, 2013
- `node-sqlite3` moved to mapbox github group
- Fixed reporting of node-gyp errors
- Fixed support for node v0.6.x
## 2.1.17
- Minor fixes to binary deployment
## 2.1.16
- Support for binary deployment
## 2.1.15
Released August 7th, 2013
- Minor readme additions and code optimizations

57
node_modules/sqlite3/CONTRIBUTING.md generated vendored Normal file
View File

@@ -0,0 +1,57 @@
# Contributing
General guidelines for contributing to node-sqlite3
## Install Help
If you've landed here due to a failed install of `node-sqlite3` then feel free to create a [new issue](https://github.com/mapbox/node-sqlite3/issues/new) to ask for help. The most likely problem is that we do not yet provide pre-built binaries for your particular platform and so the `node-sqlite3` install attempted a source compile but failed because you are missing the [dependencies for node-gyp](https://github.com/TooTallNate/node-gyp#installation). But please provide as much detail on your problem as possible and we'll try to help. Please include:
- terminal logs of failed install (preferably from running `npm install sqlite3 --loglevel=info`)
- `node-sqlite3` version you tried to install
- node version you are running
- operating system and architecture you are running, e.g. `Windows 7 64 bit`.
## Developing / Pre-release
Create a milestone for the next release on github. If all anticipated changes are back compatible then a `patch` release is in order. If minor API changes are needed then a `minor` release is in order. And a `major` bump is warranted if major API changes are needed.
Assign tickets and pull requests you are working to the milestone you created.
## Releasing
To release a new version:
**1)** Ensure tests are passing
Before considering a release all the tests need to be passing on appveyor and travis.
**2)** Bump commit
Bump the version in `package.json` like https://github.com/mapbox/node-sqlite3/commit/77d51d5785b047ff40f6a8225051488a0d96f7fd
What if you already committed the `package.json` bump and you have no changes to commit but want to publish binaries? In this case you can do:
```sh
git commit --allow-empty -m "[publish binary]"
```
**3)** Ensure binaries built
Check the travis and appveyor pages to ensure they are all green as an indication that the `[publish binary]` command worked.
If you need to republish binaries you can do this with the command below, however this should not be a common thing for you to do!
```sh
git commit --allow-empty -m "[republish binary]"
```
Note: NEVER republish binaries for an existing released version.
**7)** Officially release
An official release requires:
- Updating the CHANGELOG.md
- Create and push github tag like `git tag v3.1.1 -m "v3.1.1" && git push --tags`
- Ensure you have a clean checkout (no extra files in your check that are not known by git). You need to be careful, for instance, to avoid a large accidental file being packaged by npm. You can get a view of what npm will publish by running `make testpack`
- Fully rebuild and ensure install from binary works: `make clean && npm install --fallback-to-build=false`
- Then publish the module to npm repositories by running `npm publish`

76
node_modules/sqlite3/Dockerfile generated vendored Executable file
View File

@@ -0,0 +1,76 @@
#!/bin/echo docker build . -f
# -*- coding: utf-8 -*-
#{
# ISC License
# Copyright (c) 2004-2010 by Internet Systems Consortium, Inc. ("ISC")
# Copyright (c) 1995-2003 by Internet Software Consortium
# Permission to use, copy, modify, and /or distribute this software
# for any purpose with or without fee is hereby granted,
# provided that the above copyright notice
# and this permission notice appear in all copies.
# THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
# OF MERCHANTABILITY AND FITNESS.
# IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT,
# OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
# WHETHER IN AN ACTION OF CONTRACT,
# NEGLIGENCE OR OTHER TORTIOUS ACTION,
# ARISING OUT OF OR IN CONNECTION WITH THE USE
# OR PERFORMANCE OF THIS SOFTWARE.
#}
FROM ubuntu:latest
MAINTAINER Philippe Coval (p.coval@samsung.com)
ENV DEBIAN_FRONTEND noninteractive
ENV LC_ALL en_US.UTF-8
ENV LANG ${LC_ALL}
RUN echo "#log: Configuring locales" \
&& set -x \
&& apt-get update -y \
&& apt-get install -y locales \
&& echo "${LC_ALL} UTF-8" | tee /etc/locale.gen \
&& locale-gen ${LC_ALL} \
&& dpkg-reconfigure locales \
&& sync
ENV project node-sqlite3
RUN echo "#log: ${project}: Setup system" \
&& set -x \
&& apt-get update -y \
&& apt-get install -y \
curl \
sudo \
build-essential \
python \
&& apt-get clean \
&& NVM_VERSION="v0.33.8" \
&& NODE_VERSION="--lts=carbon" \
&& curl -o- https://raw.githubusercontent.com/creationix/nvm/${NVM_VERSION}/install.sh | bash \
&& which nvm || . ~/.bashrc \
&& nvm install ${NODE_VERSION} \
&& nvm use ${NODE_VERSION} \
&& sync
ADD . /usr/local/${project}/${project}
WORKDIR /usr/local/${project}/${project}
RUN echo "#log: ${project}: Preparing sources" \
&& set -x \
&& which npm || . ~/.bashrc \
&& npm install || cat npm-debug.log \
&& npm install \
&& npm install --unsafe-perm --build-from-source \
&& sync
WORKDIR /usr/local/${project}/${project}
RUN echo "#log: ${project}: Building sources" \
&& set -x \
&& which npm || . ~/.bashrc \
&& npm run pack \
&& npm pack \
&& find build/stage/ -type f \
&& sync

25
node_modules/sqlite3/LICENSE generated vendored Normal file
View File

@@ -0,0 +1,25 @@
Copyright (c) MapBox
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
- Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
- Neither the name "MapBox" nor the names of its contributors may be
used to endorse or promote products derived from this software without
specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

227
node_modules/sqlite3/README.md generated vendored Normal file
View File

@@ -0,0 +1,227 @@
Asynchronous, non-blocking [SQLite3](https://sqlite.org/) bindings for [Node.js](http://nodejs.org/).
[![NPM](https://nodei.co/npm/sqlite3.png?downloads=true&downloadRank=true)](https://nodei.co/npm/sqlite3/)
[![Build Status](https://travis-ci.org/mapbox/node-sqlite3.svg?branch=master)](https://travis-ci.org/mapbox/node-sqlite3)
[![Build status](https://ci.appveyor.com/api/projects/status/gvm7ul0hpmdawqom)](https://ci.appveyor.com/project/Mapbox/node-sqlite3)
[![Coverage Status](https://coveralls.io/repos/mapbox/node-sqlite3/badge.svg?branch=master&service=github)](https://coveralls.io/github/mapbox/node-sqlite3?branch=master)
[![Dependencies](https://david-dm.org/mapbox/node-sqlite3.svg)](https://david-dm.org/mapbox/node-sqlite3)
[![FOSSA Status](https://app.fossa.io/api/projects/git%2Bhttps%3A%2F%2Fgithub.com%2Fmapbox%2Fnode-sqlite3.svg?type=shield)](https://app.fossa.io/projects/git%2Bhttps%3A%2F%2Fgithub.com%2Fmapbox%2Fnode-sqlite3?ref=badge_shield)
## Supported platforms
The `sqlite3` module works with Node.js v4.x, v6.x, v8.x, v10.x, v11.x and v12.x.
Binaries for most Node versions and platforms are provided by default via [node-pre-gyp](https://github.com/mapbox/node-pre-gyp).
The `sqlite3` module also works with [node-webkit](https://github.com/rogerwang/node-webkit) if node-webkit contains a supported version of Node.js engine. [(See below.)](#building-for-node-webkit)
SQLite's [SQLCipher extension](https://github.com/sqlcipher/sqlcipher) is also supported. [(See below.)](#building-for-sqlcipher)
# Usage
**Note:** the module must be [installed](#installing) before use.
``` js
var sqlite3 = require('sqlite3').verbose();
var db = new sqlite3.Database(':memory:');
db.serialize(function() {
db.run("CREATE TABLE lorem (info TEXT)");
var stmt = db.prepare("INSERT INTO lorem VALUES (?)");
for (var i = 0; i < 10; i++) {
stmt.run("Ipsum " + i);
}
stmt.finalize();
db.each("SELECT rowid AS id, info FROM lorem", function(err, row) {
console.log(row.id + ": " + row.info);
});
});
db.close();
```
# Features
- Straightforward query and parameter binding interface
- Full Buffer/Blob support
- Extensive [debugging support](https://github.com/mapbox/node-sqlite3/wiki/Debugging)
- [Query serialization](https://github.com/mapbox/node-sqlite3/wiki/Control-Flow) API
- [Extension support](https://github.com/mapbox/node-sqlite3/wiki/Extensions)
- Big test suite
- Written in modern C++ and tested for memory leaks
- Bundles Sqlite3 3.26.0 as a fallback if the installing system doesn't include SQLite
# API
See the [API documentation](https://github.com/mapbox/node-sqlite3/wiki) in the wiki.
# Installing
You can use [`npm`](https://github.com/isaacs/npm) to download and install:
* The latest `sqlite3` package: `npm install sqlite3`
* GitHub's `master` branch: `npm install https://github.com/mapbox/node-sqlite3/tarball/master`
The module uses [node-pre-gyp](https://github.com/mapbox/node-pre-gyp) to download a pre-compiled binary for your platform, if it exists. Otherwise, it uses `node-gyp` to build the extension.
It is also possible to make your own build of `sqlite3` from its source instead of its npm package ([see below](#building-from-the-source)).
It is possible to use the installed package in [node-webkit](https://github.com/rogerwang/node-webkit) instead of the vanilla Node.js. See [Building for node-webkit](#building-for-node-webkit) for details.
## Source install
To skip searching for pre-compiled binaries, and force a build from source, use
npm install --build-from-source
The sqlite3 module depends only on libsqlite3. However, by default, an internal/bundled copy of sqlite will be built and statically linked, so an externally installed sqlite3 is not required.
If you wish to install against an external sqlite then you need to pass the `--sqlite` argument to `npm` wrapper:
npm install --build-from-source --sqlite=/usr/local
If building against an external sqlite3 make sure to have the development headers available. Mac OS X ships with these by default. If you don't have them installed, install the `-dev` package with your package manager, e.g. `apt-get install libsqlite3-dev` for Debian/Ubuntu. Make sure that you have at least `libsqlite3` >= 3.6.
Note, if building against homebrew-installed sqlite on OS X you can do:
npm install --build-from-source --sqlite=/usr/local/opt/sqlite/
By default the node-gyp install will use `python` as part of the installation. A
different python executable can be specified on the command line.
npm install --build-from-source --python=/usr/bin/python2
This uses the npm_config_python config, so values in .npmrc will be honoured:
python=/usr/bin/python2
## Custom file header (magic)
The default sqlite file header is "SQLite format 3".
You can specify a different magic, though this will make standard tools and libraries unable to work with your files.
npm install --build-from-source --sqlite_magic="MyCustomMagic15"
Note that the magic *must* be exactly 15 characters long (16 bytes including null terminator).
## Building for node-webkit
Because of ABI differences, `sqlite3` must be built in a custom to be used with [node-webkit](https://github.com/rogerwang/node-webkit).
To build node-sqlite3 for node-webkit:
1. Install [`nw-gyp`](https://github.com/rogerwang/nw-gyp) globally: `npm install nw-gyp -g` *(unless already installed)*
2. Build the module with the custom flags of `--runtime`, `--target_arch`, and `--target`:
```sh
NODE_WEBKIT_VERSION="0.8.6" # see latest version at https://github.com/rogerwang/node-webkit#downloads
npm install sqlite3 --build-from-source --runtime=node-webkit --target_arch=ia32 --target=$(NODE_WEBKIT_VERSION)
```
This command internally calls out to [`node-pre-gyp`](https://github.com/mapbox/node-pre-gyp) which itself calls out to [`nw-gyp`](https://github.com/rogerwang/nw-gyp) when the `--runtime=node-webkit` option is passed.
You can also run this command from within a `node-sqlite3` checkout:
```sh
npm install --build-from-source --runtime=node-webkit --target_arch=ia32 --target=$(NODE_WEBKIT_VERSION)
```
Remember the following:
* You must provide the right `--target_arch` flag. `ia32` is needed to target 32bit node-webkit builds, while `x64` will target 64bit node-webkit builds (if available for your platform).
* After the `sqlite3` package is built for node-webkit it cannot run in the vanilla Node.js (and vice versa).
* For example, `npm test` of the node-webkit's package would fail.
Visit the “[Using Node modules](https://github.com/rogerwang/node-webkit/wiki/Using-Node-modules)” article in the node-webkit's wiki for more details.
## Building for sqlcipher
For instructions for building sqlcipher see
[Building SQLCipher for node.js](https://coolaj86.com/articles/building-sqlcipher-for-node-js-on-raspberry-pi-2/)
To run node-sqlite3 against sqlcipher you need to compile from source by passing build options like:
npm install sqlite3 --build-from-source --sqlite_libname=sqlcipher --sqlite=/usr/
node -e 'require("sqlite3")'
If your sqlcipher is installed in a custom location (if you compiled and installed it yourself),
you'll also need to to set some environment variables:
### On OS X with Homebrew
Set the location where `brew` installed it:
export LDFLAGS="-L`brew --prefix`/opt/sqlcipher/lib"
export CPPFLAGS="-I`brew --prefix`/opt/sqlcipher/include"
npm install sqlite3 --build-from-source --sqlite_libname=sqlcipher --sqlite=`brew --prefix`
node -e 'require("sqlite3")'
### On most Linuxes (including Raspberry Pi)
Set the location where `make` installed it:
export LDFLAGS="-L/usr/local/lib"
export CPPFLAGS="-I/usr/local/include -I/usr/local/include/sqlcipher"
export CXXFLAGS="$CPPFLAGS"
npm install sqlite3 --build-from-source --sqlite_libname=sqlcipher --sqlite=/usr/local --verbose
node -e 'require("sqlite3")'
### Custom builds and Electron
Running sqlite3 through [electron-rebuild](https://github.com/electron/electron-rebuild) does not preserve the sqlcipher extension, so some additional flags are needed to make this build Electron compatible. Your `npm install sqlite3 --build-from-source` command needs these additional flags (be sure to replace the target version with the current Electron version you are working with):
--runtime=electron --target=1.7.6 --dist-url=https://atom.io/download/electron
In the case of MacOS with Homebrew, the command should look like the following:
npm install sqlite3 --build-from-source --sqlite_libname=sqlcipher --sqlite=`brew --prefix` --runtime=electron --target=1.7.6 --dist-url=https://atom.io/download/electron
# Testing
[mocha](https://github.com/visionmedia/mocha) is required to run unit tests.
In sqlite3's directory (where its `package.json` resides) run the following:
npm install mocha
npm test
# Contributors
* [Konstantin Käfer](https://github.com/kkaefer)
* [Dane Springmeyer](https://github.com/springmeyer)
* [Will White](https://github.com/willwhite)
* [Orlando Vazquez](https://github.com/orlandov)
* [Artem Kustikov](https://github.com/artiz)
* [Eric Fredricksen](https://github.com/grumdrig)
* [John Wright](https://github.com/mrjjwright)
* [Ryan Dahl](https://github.com/ry)
* [Tom MacWright](https://github.com/tmcw)
* [Carter Thaxton](https://github.com/carter-thaxton)
* [Audrius Kažukauskas](https://github.com/audriusk)
* [Johannes Schauer](https://github.com/pyneo)
* [Mithgol](https://github.com/Mithgol)
# Acknowledgments
Thanks to [Orlando Vazquez](https://github.com/orlandov),
[Eric Fredricksen](https://github.com/grumdrig) and
[Ryan Dahl](https://github.com/ry) for their SQLite bindings for node, and to mraleph on Freenode's #v8 for answering questions.
Development of this module is sponsored by [MapBox](https://mapbox.org/).
# License
`node-sqlite3` is [BSD licensed](https://github.com/mapbox/node-sqlite3/raw/master/LICENSE).
[![FOSSA Status](https://app.fossa.io/api/projects/git%2Bhttps%3A%2F%2Fgithub.com%2Fmapbox%2Fnode-sqlite3.svg?type=large)](https://app.fossa.io/projects/git%2Bhttps%3A%2F%2Fgithub.com%2Fmapbox%2Fnode-sqlite3?ref=badge_large)

53
node_modules/sqlite3/binding.gyp generated vendored Normal file
View File

@@ -0,0 +1,53 @@
{
"includes": [ "deps/common-sqlite.gypi" ],
"variables": {
"sqlite%":"internal",
"sqlite_libname%":"sqlite3"
},
"targets": [
{
"target_name": "<(module_name)",
"include_dirs": ["<!(node -e \"require('nan')\")"],
"conditions": [
["sqlite != 'internal'", {
"include_dirs": [ "<(sqlite)/include" ],
"libraries": [
"-l<(sqlite_libname)"
],
"conditions": [ [ "OS=='linux'", {"libraries+":["-Wl,-rpath=<@(sqlite)/lib"]} ] ],
"conditions": [ [ "OS!='win'", {"libraries+":["-L<@(sqlite)/lib"]} ] ],
'msvs_settings': {
'VCLinkerTool': {
'AdditionalLibraryDirectories': [
'<(sqlite)/lib'
],
},
}
},
{
"dependencies": [
"deps/sqlite3.gyp:sqlite3"
]
}
]
],
"sources": [
"src/backup.cc",
"src/database.cc",
"src/node_sqlite3.cc",
"src/statement.cc"
]
},
{
"target_name": "action_after_build",
"type": "none",
"dependencies": [ "<(module_name)" ],
"copies": [
{
"files": [ "<(PRODUCT_DIR)/<(module_name).node" ],
"destination": "<(module_path)"
}
]
}
]
}

60
node_modules/sqlite3/deps/common-sqlite.gypi generated vendored Normal file
View File

@@ -0,0 +1,60 @@
{
'variables': {
'sqlite_version%':'3300100',
"toolset%":'',
},
'target_defaults': {
'default_configuration': 'Release',
'conditions': [
[ 'toolset!=""', {
'msbuild_toolset':'<(toolset)'
}]
],
'configurations': {
'Debug': {
'defines!': [
'NDEBUG'
],
'cflags_cc!': [
'-O3',
'-Os',
'-DNDEBUG'
],
'xcode_settings': {
'OTHER_CPLUSPLUSFLAGS!': [
'-O3',
'-Os',
'-DDEBUG'
],
'GCC_OPTIMIZATION_LEVEL': '0',
'GCC_GENERATE_DEBUGGING_SYMBOLS': 'YES'
},
'msvs_settings': {
'VCCLCompilerTool': {
'ExceptionHandling': 1, # /EHsc
}
}
},
'Release': {
'defines': [
'NDEBUG'
],
'xcode_settings': {
'OTHER_CPLUSPLUSFLAGS!': [
'-Os',
'-O2'
],
'GCC_OPTIMIZATION_LEVEL': '3',
'GCC_GENERATE_DEBUGGING_SYMBOLS': 'NO',
'DEAD_CODE_STRIPPING': 'YES',
'GCC_INLINES_ARE_PRIVATE_EXTERN': 'YES'
},
'msvs_settings': {
'VCCLCompilerTool': {
'ExceptionHandling': 1, # /EHsc
}
}
}
}
}
}

9
node_modules/sqlite3/deps/extract.py generated vendored Normal file
View File

@@ -0,0 +1,9 @@
import sys
import tarfile
import os
tarball = os.path.abspath(sys.argv[1])
dirname = os.path.abspath(sys.argv[2])
tfile = tarfile.open(tarball,'r:gz');
tfile.extractall(dirname)
sys.exit(0)

Binary file not shown.

119
node_modules/sqlite3/deps/sqlite3.gyp generated vendored Executable file
View File

@@ -0,0 +1,119 @@
{
'includes': [ 'common-sqlite.gypi' ],
'variables': {
'sqlite_magic%': '',
},
'target_defaults': {
'default_configuration': 'Release',
'cflags':[
'-std=c99'
],
'configurations': {
'Debug': {
'defines': [ 'DEBUG', '_DEBUG' ],
'msvs_settings': {
'VCCLCompilerTool': {
'RuntimeLibrary': 1, # static debug
},
},
},
'Release': {
'defines': [ 'NDEBUG' ],
'msvs_settings': {
'VCCLCompilerTool': {
'RuntimeLibrary': 0, # static release
},
},
}
},
'msvs_settings': {
'VCCLCompilerTool': {
},
'VCLibrarianTool': {
},
'VCLinkerTool': {
'GenerateDebugInformation': 'true',
},
},
'conditions': [
['OS == "win"', {
'defines': [
'WIN32'
],
}]
],
},
'targets': [
{
'target_name': 'action_before_build',
'type': 'none',
'hard_dependency': 1,
'actions': [
{
'action_name': 'unpack_sqlite_dep',
'inputs': [
'./sqlite-autoconf-<@(sqlite_version).tar.gz'
],
'outputs': [
'<(SHARED_INTERMEDIATE_DIR)/sqlite-autoconf-<@(sqlite_version)/sqlite3.c'
],
'action': ['<!(node -p "process.env.npm_config_python || \\"python\\"")','./extract.py','./sqlite-autoconf-<@(sqlite_version).tar.gz','<(SHARED_INTERMEDIATE_DIR)']
}
],
'direct_dependent_settings': {
'include_dirs': [
'<(SHARED_INTERMEDIATE_DIR)/sqlite-autoconf-<@(sqlite_version)/',
]
},
},
{
'target_name': 'sqlite3',
'type': 'static_library',
'include_dirs': [ '<(SHARED_INTERMEDIATE_DIR)/sqlite-autoconf-<@(sqlite_version)/' ],
'dependencies': [
'action_before_build'
],
'sources': [
'<(SHARED_INTERMEDIATE_DIR)/sqlite-autoconf-<@(sqlite_version)/sqlite3.c'
],
'direct_dependent_settings': {
'include_dirs': [ '<(SHARED_INTERMEDIATE_DIR)/sqlite-autoconf-<@(sqlite_version)/' ],
'defines': [
'SQLITE_THREADSAFE=1',
'HAVE_USLEEP=1',
'SQLITE_ENABLE_FTS3',
'SQLITE_ENABLE_FTS4',
'SQLITE_ENABLE_FTS5',
'SQLITE_ENABLE_JSON1',
'SQLITE_ENABLE_RTREE'
],
},
'cflags_cc': [
'-Wno-unused-value'
],
'defines': [
'_REENTRANT=1',
'SQLITE_THREADSAFE=1',
'HAVE_USLEEP=1',
'SQLITE_ENABLE_FTS3',
'SQLITE_ENABLE_FTS4',
'SQLITE_ENABLE_FTS5',
'SQLITE_ENABLE_JSON1',
'SQLITE_ENABLE_RTREE'
],
'export_dependent_settings': [
'action_before_build',
],
'conditions': [
["sqlite_magic != ''", {
'defines': [
'SQLITE_FILE_HEADER="<(sqlite_magic)"'
]
}]
],
}
]
}

Binary file not shown.

1
node_modules/sqlite3/lib/index.js generated vendored Normal file
View File

@@ -0,0 +1 @@
module.exports = require('./sqlite3');

207
node_modules/sqlite3/lib/sqlite3.js generated vendored Normal file
View File

@@ -0,0 +1,207 @@
var binary = require('node-pre-gyp');
var path = require('path');
var binding_path = binary.find(path.resolve(path.join(__dirname,'../package.json')));
var binding = require(binding_path);
var sqlite3 = module.exports = exports = binding;
var EventEmitter = require('events').EventEmitter;
function normalizeMethod (fn) {
return function (sql) {
var errBack;
var args = Array.prototype.slice.call(arguments, 1);
if (typeof args[args.length - 1] === 'function') {
var callback = args[args.length - 1];
errBack = function(err) {
if (err) {
callback(err);
}
};
}
var statement = new Statement(this, sql, errBack);
return fn.call(this, statement, args);
};
}
function inherits(target, source) {
for (var k in source.prototype)
target.prototype[k] = source.prototype[k];
}
sqlite3.cached = {
Database: function(file, a, b) {
if (file === '' || file === ':memory:') {
// Don't cache special databases.
return new Database(file, a, b);
}
var db;
file = path.resolve(file);
function cb() { callback.call(db, null); }
if (!sqlite3.cached.objects[file]) {
db = sqlite3.cached.objects[file] = new Database(file, a, b);
}
else {
// Make sure the callback is called.
db = sqlite3.cached.objects[file];
var callback = (typeof a === 'number') ? b : a;
if (typeof callback === 'function') {
if (db.open) process.nextTick(cb);
else db.once('open', cb);
}
}
return db;
},
objects: {}
};
var Database = sqlite3.Database;
var Statement = sqlite3.Statement;
var Backup = sqlite3.Backup;
inherits(Database, EventEmitter);
inherits(Statement, EventEmitter);
inherits(Backup, EventEmitter);
// Database#prepare(sql, [bind1, bind2, ...], [callback])
Database.prototype.prepare = normalizeMethod(function(statement, params) {
return params.length
? statement.bind.apply(statement, params)
: statement;
});
// Database#run(sql, [bind1, bind2, ...], [callback])
Database.prototype.run = normalizeMethod(function(statement, params) {
statement.run.apply(statement, params).finalize();
return this;
});
// Database#get(sql, [bind1, bind2, ...], [callback])
Database.prototype.get = normalizeMethod(function(statement, params) {
statement.get.apply(statement, params).finalize();
return this;
});
// Database#all(sql, [bind1, bind2, ...], [callback])
Database.prototype.all = normalizeMethod(function(statement, params) {
statement.all.apply(statement, params).finalize();
return this;
});
// Database#each(sql, [bind1, bind2, ...], [callback], [complete])
Database.prototype.each = normalizeMethod(function(statement, params) {
statement.each.apply(statement, params).finalize();
return this;
});
Database.prototype.map = normalizeMethod(function(statement, params) {
statement.map.apply(statement, params).finalize();
return this;
});
// Database#backup(filename, [callback])
// Database#backup(filename, destName, sourceName, filenameIsDest, [callback])
Database.prototype.backup = function() {
var backup;
if (arguments.length <= 2) {
// By default, we write the main database out to the main database of the named file.
// This is the most likely use of the backup api.
backup = new Backup(this, arguments[0], 'main', 'main', true, arguments[1]);
} else {
// Otherwise, give the user full control over the sqlite3_backup_init arguments.
backup = new Backup(this, arguments[0], arguments[1], arguments[2], arguments[3], arguments[4]);
}
// Per the sqlite docs, exclude the following errors as non-fatal by default.
backup.retryErrors = [sqlite3.BUSY, sqlite3.LOCKED];
return backup;
};
Statement.prototype.map = function() {
var params = Array.prototype.slice.call(arguments);
var callback = params.pop();
params.push(function(err, rows) {
if (err) return callback(err);
var result = {};
if (rows.length) {
var keys = Object.keys(rows[0]), key = keys[0];
if (keys.length > 2) {
// Value is an object
for (var i = 0; i < rows.length; i++) {
result[rows[i][key]] = rows[i];
}
} else {
var value = keys[1];
// Value is a plain value
for (i = 0; i < rows.length; i++) {
result[rows[i][key]] = rows[i][value];
}
}
}
callback(err, result);
});
return this.all.apply(this, params);
};
var isVerbose = false;
var supportedEvents = [ 'trace', 'profile', 'insert', 'update', 'delete' ];
Database.prototype.addListener = Database.prototype.on = function(type) {
var val = EventEmitter.prototype.addListener.apply(this, arguments);
if (supportedEvents.indexOf(type) >= 0) {
this.configure(type, true);
}
return val;
};
Database.prototype.removeListener = function(type) {
var val = EventEmitter.prototype.removeListener.apply(this, arguments);
if (supportedEvents.indexOf(type) >= 0 && !this._events[type]) {
this.configure(type, false);
}
return val;
};
Database.prototype.removeAllListeners = function(type) {
var val = EventEmitter.prototype.removeAllListeners.apply(this, arguments);
if (supportedEvents.indexOf(type) >= 0) {
this.configure(type, false);
}
return val;
};
// Save the stack trace over EIO callbacks.
sqlite3.verbose = function() {
if (!isVerbose) {
var trace = require('./trace');
[
'prepare',
'get',
'run',
'all',
'each',
'map',
'close',
'exec'
].forEach(function (name) {
trace.extendTrace(Database.prototype, name);
});
[
'bind',
'get',
'run',
'all',
'each',
'map',
'reset',
'finalize',
].forEach(function (name) {
trace.extendTrace(Statement.prototype, name);
});
isVerbose = true;
}
return this;
};

41
node_modules/sqlite3/lib/trace.js generated vendored Normal file
View File

@@ -0,0 +1,41 @@
// Inspired by https://github.com/tlrobinson/long-stack-traces
var util = require('util');
function extendTrace(object, property, pos) {
var old = object[property];
object[property] = function() {
var error = new Error();
var name = object.constructor.name + '#' + property + '(' +
Array.prototype.slice.call(arguments).map(function(el) {
return util.inspect(el, false, 0);
}).join(', ') + ')';
if (typeof pos === 'undefined') pos = -1;
if (pos < 0) pos += arguments.length;
var cb = arguments[pos];
if (typeof arguments[pos] === 'function') {
arguments[pos] = function replacement() {
try {
return cb.apply(this, arguments);
} catch (err) {
if (err && err.stack && !err.__augmented) {
err.stack = filter(err).join('\n');
err.stack += '\n--> in ' + name;
err.stack += '\n' + filter(error).slice(1).join('\n');
err.__augmented = true;
}
throw err;
}
};
}
return old.apply(this, arguments);
};
}
exports.extendTrace = extendTrace;
function filter(error) {
return error.stack.split('\n').filter(function(line) {
return line.indexOf(__filename) < 0;
});
}

142
node_modules/sqlite3/package.json generated vendored Normal file
View File

@@ -0,0 +1,142 @@
{
"_args": [
[
"sqlite3@4.1.1",
"/home/rui/code/personal/dijkstra-app/backend-dijkstra"
]
],
"_from": "sqlite3@4.1.1",
"_id": "sqlite3@4.1.1",
"_inBundle": false,
"_integrity": "sha512-CvT5XY+MWnn0HkbwVKJAyWEMfzpAPwnTiB3TobA5Mri44SrTovmmh499NPQP+gatkeOipqPlBLel7rn4E/PCQg==",
"_location": "/sqlite3",
"_phantomChildren": {},
"_requested": {
"type": "version",
"registry": true,
"raw": "sqlite3@4.1.1",
"name": "sqlite3",
"escapedName": "sqlite3",
"rawSpec": "4.1.1",
"saveSpec": null,
"fetchSpec": "4.1.1"
},
"_requiredBy": [
"/"
],
"_resolved": "https://registry.npmjs.org/sqlite3/-/sqlite3-4.1.1.tgz",
"_spec": "4.1.1",
"_where": "/home/rui/code/personal/dijkstra-app/backend-dijkstra",
"author": {
"name": "MapBox",
"url": "https://mapbox.com/"
},
"binary": {
"module_name": "node_sqlite3",
"module_path": "./lib/binding/{node_abi}-{platform}-{arch}",
"host": "https://mapbox-node-binary.s3.amazonaws.com",
"remote_path": "./{name}/v{version}/{toolset}/",
"package_name": "{node_abi}-{platform}-{arch}.tar.gz"
},
"bugs": {
"url": "https://github.com/mapbox/node-sqlite3/issues"
},
"contributors": [
{
"name": "Konstantin Käfer",
"email": "mail@kkaefer.com"
},
{
"name": "Dane Springmeyer",
"email": "dane@mapbox.com"
},
{
"name": "Will White",
"email": "will@mapbox.com"
},
{
"name": "Orlando Vazquez",
"email": "ovazquez@gmail.com"
},
{
"name": "Artem Kustikov",
"email": "kustikoff@gmail.com"
},
{
"name": "Eric Fredricksen",
"email": "efredricksen@gmail.com"
},
{
"name": "John Wright",
"email": "mrjjwright@gmail.com"
},
{
"name": "Ryan Dahl",
"email": "ry@tinyclouds.org"
},
{
"name": "Tom MacWright",
"email": "tom@mapbox.com"
},
{
"name": "Carter Thaxton",
"email": "carter.thaxton@gmail.com"
},
{
"name": "Audrius Kažukauskas",
"email": "audrius@neutrino.lt"
},
{
"name": "Johannes Schauer",
"email": "josch@pyneo.org"
},
{
"name": "Nathan Rajlich",
"email": "nathan@tootallnate.net"
},
{
"name": "AJ ONeal",
"email": "coolaj86@gmail.com"
},
{
"name": "Mithgol"
},
{
"name": "Ben Noordhuis",
"email": "ben@strongloop.com"
}
],
"dependencies": {
"nan": "^2.12.1",
"node-pre-gyp": "^0.11.0",
"request": "^2.87.0"
},
"description": "Asynchronous, non-blocking SQLite3 bindings",
"devDependencies": {
"@mapbox/cloudfriend": "^1.9.0",
"aws-sdk": "2.x",
"eslint": "3.5.0",
"mocha": "^5.2.0"
},
"homepage": "https://github.com/mapbox/node-sqlite3",
"keywords": [
"sql",
"sqlite",
"sqlite3",
"database"
],
"license": "BSD-3-Clause",
"main": "./lib/sqlite3",
"name": "sqlite3",
"repository": {
"type": "git",
"url": "git://github.com/mapbox/node-sqlite3.git"
},
"scripts": {
"install": "node-pre-gyp install --fallback-to-build",
"pack": "node-pre-gyp package",
"pretest": "node test/support/createdb.js",
"test": "mocha -R spec --timeout 480000"
},
"version": "4.1.1"
}

1
node_modules/sqlite3/sqlite3.js generated vendored Normal file
View File

@@ -0,0 +1 @@
module.exports = require('./lib/sqlite3');

78
node_modules/sqlite3/src/async.h generated vendored Normal file
View File

@@ -0,0 +1,78 @@
#ifndef NODE_SQLITE3_SRC_ASYNC_H
#define NODE_SQLITE3_SRC_ASYNC_H
#include "threading.h"
#include <node_version.h>
#if defined(NODE_SQLITE3_BOOST_THREADING)
#include <boost/thread/mutex.hpp>
#endif
// Generic uv_async handler.
template <class Item, class Parent> class Async {
typedef void (*Callback)(Parent* parent, Item* item);
protected:
uv_async_t watcher;
NODE_SQLITE3_MUTEX_t
std::vector<Item*> data;
Callback callback;
public:
Parent* parent;
public:
Async(Parent* parent_, Callback cb_)
: callback(cb_), parent(parent_) {
watcher.data = this;
NODE_SQLITE3_MUTEX_INIT
uv_async_init(uv_default_loop(), &watcher, reinterpret_cast<uv_async_cb>(listener));
}
static void listener(uv_async_t* handle, int status) {
Async* async = static_cast<Async*>(handle->data);
std::vector<Item*> rows;
NODE_SQLITE3_MUTEX_LOCK(&async->mutex)
rows.swap(async->data);
NODE_SQLITE3_MUTEX_UNLOCK(&async->mutex)
for (unsigned int i = 0, size = rows.size(); i < size; i++) {
async->callback(async->parent, rows[i]);
}
}
static void close(uv_handle_t* handle) {
assert(handle != NULL);
assert(handle->data != NULL);
Async* async = static_cast<Async*>(handle->data);
delete async;
}
void finish() {
// Need to call the listener again to ensure all items have been
// processed. Is this a bug in uv_async? Feels like uv_close
// should handle that.
listener(&watcher, 0);
uv_close((uv_handle_t*)&watcher, close);
}
void add(Item* item) {
NODE_SQLITE3_MUTEX_LOCK(&mutex);
data.push_back(item);
NODE_SQLITE3_MUTEX_UNLOCK(&mutex)
}
void send() {
uv_async_send(&watcher);
}
void send(Item* item) {
add(item);
send();
}
~Async() {
NODE_SQLITE3_MUTEX_DESTROY
}
};
#endif

416
node_modules/sqlite3/src/backup.cc generated vendored Normal file
View File

@@ -0,0 +1,416 @@
#include <string.h>
#include <node.h>
#include <node_buffer.h>
#include <node_version.h>
#include "macros.h"
#include "database.h"
#include "backup.h"
using namespace node_sqlite3;
Nan::Persistent<FunctionTemplate> Backup::constructor_template;
NAN_MODULE_INIT(Backup::Init) {
Nan::HandleScope scope;
Local<FunctionTemplate> t = Nan::New<FunctionTemplate>(New);
t->InstanceTemplate()->SetInternalFieldCount(1);
t->SetClassName(Nan::New("Backup").ToLocalChecked());
Nan::SetPrototypeMethod(t, "step", Step);
Nan::SetPrototypeMethod(t, "finish", Finish);
NODE_SET_GETTER(t, "idle", IdleGetter);
NODE_SET_GETTER(t, "completed", CompletedGetter);
NODE_SET_GETTER(t, "failed", FailedGetter);
NODE_SET_GETTER(t, "remaining", RemainingGetter);
NODE_SET_GETTER(t, "pageCount", PageCountGetter);
NODE_SET_SETTER(t, "retryErrors", RetryErrorGetter, RetryErrorSetter);
constructor_template.Reset(t);
Nan::Set(target, Nan::New("Backup").ToLocalChecked(),
Nan::GetFunction(t).ToLocalChecked());
}
void Backup::Process() {
if (finished && !queue.empty()) {
return CleanQueue();
}
while (inited && !locked && !queue.empty()) {
Call* call = queue.front();
queue.pop();
call->callback(call->baton);
delete call;
}
}
void Backup::Schedule(Work_Callback callback, Baton* baton) {
if (finished) {
queue.push(new Call(callback, baton));
CleanQueue();
}
else if (!inited || locked || !queue.empty()) {
queue.push(new Call(callback, baton));
}
else {
callback(baton);
}
}
template <class T> void Backup::Error(T* baton) {
Nan::HandleScope scope;
Backup* backup = baton->backup;
// Fail hard on logic errors.
assert(backup->status != 0);
EXCEPTION(backup->message, backup->status, exception);
Local<Function> cb = Nan::New(baton->callback);
if (!cb.IsEmpty() && cb->IsFunction()) {
Local<Value> argv[] = { exception };
TRY_CATCH_CALL(backup->handle(), cb, 1, argv);
}
else {
Local<Value> argv[] = { Nan::New("error").ToLocalChecked(), exception };
EMIT_EVENT(backup->handle(), 2, argv);
}
}
void Backup::CleanQueue() {
Nan::HandleScope scope;
if (inited && !queue.empty()) {
// This backup has already been initialized and is now finished.
// Fire error for all remaining items in the queue.
EXCEPTION("Backup is already finished", SQLITE_MISUSE, exception);
Local<Value> argv[] = { exception };
bool called = false;
// Clear out the queue so that this object can get GC'ed.
while (!queue.empty()) {
Call* call = queue.front();
queue.pop();
Local<Function> cb = Nan::New(call->baton->callback);
if (inited && !cb.IsEmpty() &&
cb->IsFunction()) {
TRY_CATCH_CALL(handle(), cb, 1, argv);
called = true;
}
// We don't call the actual callback, so we have to make sure that
// the baton gets destroyed.
delete call->baton;
delete call;
}
// When we couldn't call a callback function, emit an error on the
// Backup object.
if (!called) {
Local<Value> info[] = { Nan::New("error").ToLocalChecked(), exception };
EMIT_EVENT(handle(), 2, info);
}
}
else while (!queue.empty()) {
// Just delete all items in the queue; we already fired an event when
// initializing the backup failed.
Call* call = queue.front();
queue.pop();
// We don't call the actual callback, so we have to make sure that
// the baton gets destroyed.
delete call->baton;
delete call;
}
}
NAN_METHOD(Backup::New) {
if (!info.IsConstructCall()) {
return Nan::ThrowTypeError("Use the new operator to create new Backup objects");
}
int length = info.Length();
if (length <= 0 || !Database::HasInstance(info[0])) {
return Nan::ThrowTypeError("Database object expected");
}
else if (length <= 1 || !info[1]->IsString()) {
return Nan::ThrowTypeError("Filename expected");
}
else if (length <= 2 || !info[2]->IsString()) {
return Nan::ThrowTypeError("Source database name expected");
}
else if (length <= 3 || !info[3]->IsString()) {
return Nan::ThrowTypeError("Destination database name expected");
}
else if (length <= 4 || !info[4]->IsBoolean()) {
return Nan::ThrowTypeError("Direction flag expected");
}
else if (length > 5 && !info[5]->IsUndefined() && !info[5]->IsFunction()) {
return Nan::ThrowTypeError("Callback expected");
}
Database* db = Nan::ObjectWrap::Unwrap<Database>(info[0].As<Object>());
Local<String> filename = Local<String>::Cast(info[1]);
Local<String> sourceName = Local<String>::Cast(info[2]);
Local<String> destName = Local<String>::Cast(info[3]);
Local<Boolean> filenameIsDest = Local<Boolean>::Cast(info[4]);
Nan::ForceSet(info.This(), Nan::New("filename").ToLocalChecked(), filename, ReadOnly);
Nan::ForceSet(info.This(), Nan::New("sourceName").ToLocalChecked(), sourceName, ReadOnly);
Nan::ForceSet(info.This(), Nan::New("destName").ToLocalChecked(), destName, ReadOnly);
Nan::ForceSet(info.This(), Nan::New("filenameIsDest").ToLocalChecked(), filenameIsDest, ReadOnly);
Backup* backup = new Backup(db);
backup->Wrap(info.This());
InitializeBaton* baton = new InitializeBaton(db, Local<Function>::Cast(info[5]), backup);
baton->filename = std::string(*Nan::Utf8String(filename));
baton->sourceName = std::string(*Nan::Utf8String(sourceName));
baton->destName = std::string(*Nan::Utf8String(destName));
baton->filenameIsDest = Nan::To<bool>(filenameIsDest).FromJust();
db->Schedule(Work_BeginInitialize, baton);
info.GetReturnValue().Set(info.This());
}
void Backup::Work_BeginInitialize(Database::Baton* baton) {
assert(baton->db->open);
baton->db->pending++;
int status = uv_queue_work(uv_default_loop(),
&baton->request, Work_Initialize, (uv_after_work_cb)Work_AfterInitialize);
assert(status == 0);
}
void Backup::Work_Initialize(uv_work_t* req) {
BACKUP_INIT(InitializeBaton);
// In case stepping fails, we use a mutex to make sure we get the associated
// error message.
sqlite3_mutex* mtx = sqlite3_db_mutex(baton->db->_handle);
sqlite3_mutex_enter(mtx);
backup->status = sqlite3_open(baton->filename.c_str(), &backup->_otherDb);
if (backup->status == SQLITE_OK) {
backup->_handle = sqlite3_backup_init(
baton->filenameIsDest ? backup->_otherDb : backup->db->_handle,
baton->destName.c_str(),
baton->filenameIsDest ? backup->db->_handle : backup->_otherDb,
baton->sourceName.c_str());
}
backup->_destDb = baton->filenameIsDest ? backup->_otherDb : backup->db->_handle;
if (backup->status != SQLITE_OK) {
backup->message = std::string(sqlite3_errmsg(backup->_destDb));
sqlite3_close(backup->_otherDb);
backup->_otherDb = NULL;
backup->_destDb = NULL;
}
sqlite3_mutex_leave(mtx);
}
void Backup::Work_AfterInitialize(uv_work_t* req) {
Nan::HandleScope scope;
BACKUP_INIT(InitializeBaton);
if (backup->status != SQLITE_OK) {
Error(baton);
backup->FinishAll();
}
else {
backup->inited = true;
Local<Function> cb = Nan::New(baton->callback);
if (!cb.IsEmpty() && cb->IsFunction()) {
Local<Value> argv[] = { Nan::Null() };
TRY_CATCH_CALL(backup->handle(), cb, 1, argv);
}
}
BACKUP_END();
}
NAN_METHOD(Backup::Step) {
Backup* backup = Nan::ObjectWrap::Unwrap<Backup>(info.This());
REQUIRE_ARGUMENT_INTEGER(0, pages);
OPTIONAL_ARGUMENT_FUNCTION(1, callback);
StepBaton* baton = new StepBaton(backup, callback, pages);
backup->GetRetryErrors(baton->retryErrorsSet);
backup->Schedule(Work_BeginStep, baton);
info.GetReturnValue().Set(info.This());
}
void Backup::Work_BeginStep(Baton* baton) {
BACKUP_BEGIN(Step);
}
void Backup::Work_Step(uv_work_t* req) {
BACKUP_INIT(StepBaton);
if (backup->_handle) {
backup->status = sqlite3_backup_step(backup->_handle, baton->pages);
backup->remaining = sqlite3_backup_remaining(backup->_handle);
backup->pageCount = sqlite3_backup_pagecount(backup->_handle);
}
if (backup->status != SQLITE_OK) {
// Text of message is a little awkward to get, since the error is not associated
// with a db connection.
#if SQLITE_VERSION_NUMBER >= 3007015
// sqlite3_errstr is a relatively new method
backup->message = std::string(sqlite3_errstr(backup->status));
#else
backup->message = "Sqlite error";
#endif
if (baton->retryErrorsSet.size() > 0) {
if (baton->retryErrorsSet.find(backup->status) == baton->retryErrorsSet.end()) {
backup->FinishSqlite();
}
}
}
}
void Backup::Work_AfterStep(uv_work_t* req) {
Nan::HandleScope scope;
BACKUP_INIT(StepBaton);
if (backup->status == SQLITE_DONE) {
backup->completed = true;
} else if (!backup->_handle) {
backup->failed = true;
}
if (backup->status != SQLITE_OK && backup->status != SQLITE_DONE) {
Error(baton);
}
else {
// Fire callbacks.
Local<Function> cb = Nan::New(baton->callback);
if (!cb.IsEmpty() && cb->IsFunction()) {
Local<Value> argv[] = { Nan::Null(), Nan::New(backup->status == SQLITE_DONE) };
TRY_CATCH_CALL(backup->handle(), cb, 2, argv);
}
}
BACKUP_END();
}
NAN_METHOD(Backup::Finish) {
Backup* backup = Nan::ObjectWrap::Unwrap<Backup>(info.This());
OPTIONAL_ARGUMENT_FUNCTION(0, callback);
Baton* baton = new Baton(backup, callback);
backup->Schedule(Work_BeginFinish, baton);
info.GetReturnValue().Set(info.This());
}
void Backup::Work_BeginFinish(Baton* baton) {
BACKUP_BEGIN(Finish);
}
void Backup::Work_Finish(uv_work_t* req) {
BACKUP_INIT(Baton);
backup->FinishSqlite();
}
void Backup::Work_AfterFinish(uv_work_t* req) {
Nan::HandleScope scope;
BACKUP_INIT(Baton);
backup->FinishAll();
// Fire callback in case there was one.
Local<Function> cb = Nan::New(baton->callback);
if (!cb.IsEmpty() && cb->IsFunction()) {
TRY_CATCH_CALL(backup->handle(), cb, 0, NULL);
}
BACKUP_END();
}
void Backup::FinishAll() {
assert(!finished);
if (!completed && !failed) {
failed = true;
}
finished = true;
CleanQueue();
FinishSqlite();
db->Unref();
}
void Backup::FinishSqlite() {
if (_handle) {
sqlite3_backup_finish(_handle);
_handle = NULL;
}
if (_otherDb) {
sqlite3_close(_otherDb);
_otherDb = NULL;
}
_destDb = NULL;
}
NAN_GETTER(Backup::IdleGetter) {
Backup* backup = Nan::ObjectWrap::Unwrap<Backup>(info.This());
bool idle = backup->inited && !backup->locked && backup->queue.empty();
info.GetReturnValue().Set(idle);
}
NAN_GETTER(Backup::CompletedGetter) {
Backup* backup = Nan::ObjectWrap::Unwrap<Backup>(info.This());
info.GetReturnValue().Set(backup->completed);
}
NAN_GETTER(Backup::FailedGetter) {
Backup* backup = Nan::ObjectWrap::Unwrap<Backup>(info.This());
info.GetReturnValue().Set(backup->failed);
}
NAN_GETTER(Backup::RemainingGetter) {
Backup* backup = Nan::ObjectWrap::Unwrap<Backup>(info.This());
info.GetReturnValue().Set(backup->remaining);
}
NAN_GETTER(Backup::PageCountGetter) {
Backup* backup = Nan::ObjectWrap::Unwrap<Backup>(info.This());
info.GetReturnValue().Set(backup->pageCount);
}
NAN_GETTER(Backup::RetryErrorGetter) {
Backup* backup = Nan::ObjectWrap::Unwrap<Backup>(info.This());
info.GetReturnValue().Set(Nan::New(backup->retryErrors));
}
NAN_SETTER(Backup::RetryErrorSetter) {
Backup* backup = Nan::ObjectWrap::Unwrap<Backup>(info.This());
if (!value->IsArray()) {
return Nan::ThrowError("retryErrors must be an array");
}
Local<Array> array = Local<Array>::Cast(value);
backup->retryErrors.Reset(array);
}
void Backup::GetRetryErrors(std::set<int>& retryErrorsSet) {
retryErrorsSet.clear();
Local<Array> array = Nan::New(retryErrors);
int length = array->Length();
for (int i = 0; i < length; i++) {
Local<Value> code = Nan::Get(array, i).ToLocalChecked();
if (code->IsInt32()) {
retryErrorsSet.insert(Nan::To<int32_t>(code).FromJust());
}
}
}

223
node_modules/sqlite3/src/backup.h generated vendored Normal file
View File

@@ -0,0 +1,223 @@
#ifndef NODE_SQLITE3_SRC_BACKUP_H
#define NODE_SQLITE3_SRC_BACKUP_H
#include "database.h"
#include <string>
#include <queue>
#include <set>
#include <sqlite3.h>
#include <nan.h>
using namespace v8;
using namespace node;
namespace node_sqlite3 {
/**
*
* A class for managing an sqlite3_backup object. For consistency
* with other node-sqlite3 classes, it maintains an internal queue
* of calls.
*
* Intended usage from node:
*
* var db = new sqlite3.Database('live.db');
* var backup = db.backup('backup.db');
* ...
* // in event loop, move backup forward when we have time.
* if (backup.idle) { backup.step(NPAGES); }
* if (backup.completed) { ... success ... }
* if (backup.failed) { ... sadness ... }
* // do other work in event loop - fine to modify live.db
* ...
*
* Here is how sqlite's backup api is exposed:
*
* - `sqlite3_backup_init`: This is implemented as
* `db.backup(filename, [callback])` or
* `db.backup(filename, destDbName, sourceDbName, filenameIsDest, [callback])`.
* - `sqlite3_backup_step`: `backup.step(pages, [callback])`.
* - `sqlite3_backup_finish`: `backup.finish([callback])`.
* - `sqlite3_backup_remaining`: `backup.remaining`.
* - `sqlite3_backup_pagecount`: `backup.pageCount`.
*
* There are the following read-only properties:
*
* - `backup.completed` is set to `true` when the backup
* succeeeds.
* - `backup.failed` is set to `true` when the backup
* has a fatal error.
* - `backup.idle` is set to `true` when no operation
* is currently in progress or queued for the backup.
* - `backup.remaining` is an integer with the remaining
* number of pages after the last call to `backup.step`
* (-1 if `step` not yet called).
* - `backup.pageCount` is an integer with the total number
* of pages measured during the last call to `backup.step`
* (-1 if `step` not yet called).
*
* There is the following writable property:
*
* - `backup.retryErrors`: an array of sqlite3 error codes
* that are treated as non-fatal - meaning, if they occur,
* backup.failed is not set, and the backup may continue.
* By default, this is `[sqlite3.BUSY, sqlite3.LOCKED]`.
*
* The `db.backup(filename, [callback])` shorthand is sufficient
* for making a backup of a database opened by node-sqlite3. If
* using attached or temporary databases, or moving data in the
* opposite direction, the more complete (but daunting)
* `db.backup(filename, destDbName, sourceDbName, filenameIsDest, [callback])`
* signature is provided.
*
* A backup will finish automatically when it succeeds or a fatal
* error occurs, meaning it is not necessary to call `db.finish()`.
* By default, SQLITE_LOCKED and SQLITE_BUSY errors are not
* treated as failures, and the backup will continue if they
* occur. The set of errors that are tolerated can be controlled
* by setting `backup.retryErrors`. To disable automatic
* finishing and stick strictly to sqlite's raw api, set
* `backup.retryErrors` to `[]`. In that case, it is necessary
* to call `backup.finish()`.
*
* In the same way as node-sqlite3 databases and statements,
* backup methods can be called safely without callbacks, due
* to an internal call queue. So for example this naive code
* will correctly back up a db, if there are no errors:
*
* var backup = db.backup('backup.db');
* backup.step(-1);
* backup.finish();
*
*/
class Backup : public Nan::ObjectWrap {
public:
static Nan::Persistent<FunctionTemplate> constructor_template;
static NAN_MODULE_INIT(Init);
static NAN_METHOD(New);
struct Baton {
uv_work_t request;
Backup* backup;
Nan::Persistent<Function> callback;
Baton(Backup* backup_, Local<Function> cb_) : backup(backup_) {
backup->Ref();
request.data = this;
callback.Reset(cb_);
}
virtual ~Baton() {
backup->Unref();
callback.Reset();
}
};
struct InitializeBaton : Database::Baton {
Backup* backup;
std::string filename;
std::string sourceName;
std::string destName;
bool filenameIsDest;
InitializeBaton(Database* db_, Local<Function> cb_, Backup* backup_) :
Baton(db_, cb_), backup(backup_), filenameIsDest(true) {
backup->Ref();
}
virtual ~InitializeBaton() {
backup->Unref();
if (!db->IsOpen() && db->IsLocked()) {
// The database handle was closed before the backup could be opened.
backup->FinishAll();
}
}
};
struct StepBaton : Baton {
int pages;
std::set<int> retryErrorsSet;
StepBaton(Backup* backup_, Local<Function> cb_, int pages_) :
Baton(backup_, cb_), pages(pages_) {}
};
typedef void (*Work_Callback)(Baton* baton);
struct Call {
Call(Work_Callback cb_, Baton* baton_) : callback(cb_), baton(baton_) {};
Work_Callback callback;
Baton* baton;
};
Backup(Database* db_) : Nan::ObjectWrap(),
db(db_),
_handle(NULL),
_otherDb(NULL),
_destDb(NULL),
inited(false),
locked(true),
completed(false),
failed(false),
remaining(-1),
pageCount(-1),
finished(false) {
db->Ref();
}
~Backup() {
if (!finished) {
FinishAll();
}
retryErrors.Reset();
}
WORK_DEFINITION(Step);
WORK_DEFINITION(Finish);
static NAN_GETTER(IdleGetter);
static NAN_GETTER(CompletedGetter);
static NAN_GETTER(FailedGetter);
static NAN_GETTER(PageCountGetter);
static NAN_GETTER(RemainingGetter);
static NAN_GETTER(FatalErrorGetter);
static NAN_GETTER(RetryErrorGetter);
static NAN_SETTER(FatalErrorSetter);
static NAN_SETTER(RetryErrorSetter);
protected:
static void Work_BeginInitialize(Database::Baton* baton);
static void Work_Initialize(uv_work_t* req);
static void Work_AfterInitialize(uv_work_t* req);
void Schedule(Work_Callback callback, Baton* baton);
void Process();
void CleanQueue();
template <class T> static void Error(T* baton);
void FinishAll();
void FinishSqlite();
void GetRetryErrors(std::set<int>& retryErrorsSet);
Database* db;
sqlite3_backup* _handle;
sqlite3* _otherDb;
sqlite3* _destDb;
int status;
std::string message;
bool inited;
bool locked;
bool completed;
bool failed;
int remaining;
int pageCount;
bool finished;
std::queue<Call*> queue;
Nan::Persistent<Array> retryErrors;
};
}
#endif

692
node_modules/sqlite3/src/database.cc generated vendored Normal file
View File

@@ -0,0 +1,692 @@
#include <string.h>
#include "macros.h"
#include "database.h"
#include "statement.h"
using namespace node_sqlite3;
Nan::Persistent<FunctionTemplate> Database::constructor_template;
NAN_MODULE_INIT(Database::Init) {
Nan::HandleScope scope;
Local<FunctionTemplate> t = Nan::New<FunctionTemplate>(New);
t->InstanceTemplate()->SetInternalFieldCount(1);
t->SetClassName(Nan::New("Database").ToLocalChecked());
Nan::SetPrototypeMethod(t, "close", Close);
Nan::SetPrototypeMethod(t, "exec", Exec);
Nan::SetPrototypeMethod(t, "wait", Wait);
Nan::SetPrototypeMethod(t, "loadExtension", LoadExtension);
Nan::SetPrototypeMethod(t, "serialize", Serialize);
Nan::SetPrototypeMethod(t, "parallelize", Parallelize);
Nan::SetPrototypeMethod(t, "configure", Configure);
Nan::SetPrototypeMethod(t, "interrupt", Interrupt);
NODE_SET_GETTER(t, "open", OpenGetter);
constructor_template.Reset(t);
Nan::Set(target, Nan::New("Database").ToLocalChecked(),
Nan::GetFunction(t).ToLocalChecked());
}
void Database::Process() {
Nan::HandleScope scope;
if (!open && locked && !queue.empty()) {
EXCEPTION("Database handle is closed", SQLITE_MISUSE, exception);
Local<Value> argv[] = { exception };
bool called = false;
// Call all callbacks with the error object.
while (!queue.empty()) {
Call* call = queue.front();
Local<Function> cb = Nan::New(call->baton->callback);
if (!cb.IsEmpty() && cb->IsFunction()) {
TRY_CATCH_CALL(this->handle(), cb, 1, argv);
called = true;
}
queue.pop();
// We don't call the actual callback, so we have to make sure that
// the baton gets destroyed.
delete call->baton;
delete call;
}
// When we couldn't call a callback function, emit an error on the
// Database object.
if (!called) {
Local<Value> info[] = { Nan::New("error").ToLocalChecked(), exception };
EMIT_EVENT(handle(), 2, info);
}
return;
}
while (open && (!locked || pending == 0) && !queue.empty()) {
Call* call = queue.front();
if (call->exclusive && pending > 0) {
break;
}
queue.pop();
locked = call->exclusive;
call->callback(call->baton);
delete call;
if (locked) break;
}
}
void Database::Schedule(Work_Callback callback, Baton* baton, bool exclusive) {
Nan::HandleScope scope;
if (!open && locked) {
EXCEPTION("Database is closed", SQLITE_MISUSE, exception);
Local<Function> cb = Nan::New(baton->callback);
if (!cb.IsEmpty() && cb->IsFunction()) {
Local<Value> argv[] = { exception };
TRY_CATCH_CALL(handle(), cb, 1, argv);
}
else {
Local<Value> argv[] = { Nan::New("error").ToLocalChecked(), exception };
EMIT_EVENT(handle(), 2, argv);
}
return;
}
if (!open || ((locked || exclusive || serialize) && pending > 0)) {
queue.push(new Call(callback, baton, exclusive || serialize));
}
else {
locked = exclusive;
callback(baton);
}
}
NAN_METHOD(Database::New) {
if (!info.IsConstructCall()) {
return Nan::ThrowTypeError("Use the new operator to create new Database objects");
}
REQUIRE_ARGUMENT_STRING(0, filename);
int pos = 1;
int mode;
if (info.Length() >= pos && info[pos]->IsInt32()) {
mode = Nan::To<int>(info[pos++]).FromJust();
} else {
mode = SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_FULLMUTEX;
}
Local<Function> callback;
if (info.Length() >= pos && info[pos]->IsFunction()) {
callback = Local<Function>::Cast(info[pos++]);
}
Database* db = new Database();
db->Wrap(info.This());
Nan::ForceSet(info.This(), Nan::New("filename").ToLocalChecked(), info[0].As<String>(), ReadOnly);
Nan::ForceSet(info.This(), Nan::New("mode").ToLocalChecked(), Nan::New(mode), ReadOnly);
// Start opening the database.
OpenBaton* baton = new OpenBaton(db, callback, *filename, mode);
Work_BeginOpen(baton);
info.GetReturnValue().Set(info.This());
}
void Database::Work_BeginOpen(Baton* baton) {
int status = uv_queue_work(uv_default_loop(),
&baton->request, Work_Open, (uv_after_work_cb)Work_AfterOpen);
assert(status == 0);
}
void Database::Work_Open(uv_work_t* req) {
OpenBaton* baton = static_cast<OpenBaton*>(req->data);
Database* db = baton->db;
baton->status = sqlite3_open_v2(
baton->filename.c_str(),
&db->_handle,
baton->mode,
NULL
);
if (baton->status != SQLITE_OK) {
baton->message = std::string(sqlite3_errmsg(db->_handle));
sqlite3_close(db->_handle);
db->_handle = NULL;
}
else {
// Set default database handle values.
sqlite3_busy_timeout(db->_handle, 1000);
}
}
void Database::Work_AfterOpen(uv_work_t* req) {
Nan::HandleScope scope;
OpenBaton* baton = static_cast<OpenBaton*>(req->data);
Database* db = baton->db;
Local<Value> argv[1];
if (baton->status != SQLITE_OK) {
EXCEPTION(baton->message, baton->status, exception);
argv[0] = exception;
}
else {
db->open = true;
argv[0] = Nan::Null();
}
Local<Function> cb = Nan::New(baton->callback);
if (!cb.IsEmpty() && cb->IsFunction()) {
TRY_CATCH_CALL(db->handle(), cb, 1, argv);
}
else if (!db->open) {
Local<Value> info[] = { Nan::New("error").ToLocalChecked(), argv[0] };
EMIT_EVENT(db->handle(), 2, info);
}
if (db->open) {
Local<Value> info[] = { Nan::New("open").ToLocalChecked() };
EMIT_EVENT(db->handle(), 1, info);
db->Process();
}
delete baton;
}
NAN_GETTER(Database::OpenGetter) {
Database* db = Nan::ObjectWrap::Unwrap<Database>(info.This());
info.GetReturnValue().Set(db->open);
}
NAN_METHOD(Database::Close) {
Database* db = Nan::ObjectWrap::Unwrap<Database>(info.This());
OPTIONAL_ARGUMENT_FUNCTION(0, callback);
Baton* baton = new Baton(db, callback);
db->Schedule(Work_BeginClose, baton, true);
info.GetReturnValue().Set(info.This());
}
void Database::Work_BeginClose(Baton* baton) {
assert(baton->db->locked);
assert(baton->db->open);
assert(baton->db->_handle);
assert(baton->db->pending == 0);
baton->db->RemoveCallbacks();
baton->db->closing = true;
int status = uv_queue_work(uv_default_loop(),
&baton->request, Work_Close, (uv_after_work_cb)Work_AfterClose);
assert(status == 0);
}
void Database::Work_Close(uv_work_t* req) {
Baton* baton = static_cast<Baton*>(req->data);
Database* db = baton->db;
baton->status = sqlite3_close(db->_handle);
if (baton->status != SQLITE_OK) {
baton->message = std::string(sqlite3_errmsg(db->_handle));
}
else {
db->_handle = NULL;
}
}
void Database::Work_AfterClose(uv_work_t* req) {
Nan::HandleScope scope;
Baton* baton = static_cast<Baton*>(req->data);
Database* db = baton->db;
db->closing = false;
Local<Value> argv[1];
if (baton->status != SQLITE_OK) {
EXCEPTION(baton->message, baton->status, exception);
argv[0] = exception;
}
else {
db->open = false;
// Leave db->locked to indicate that this db object has reached
// the end of its life.
argv[0] = Nan::Null();
}
Local<Function> cb = Nan::New(baton->callback);
// Fire callbacks.
if (!cb.IsEmpty() && cb->IsFunction()) {
TRY_CATCH_CALL(db->handle(), cb, 1, argv);
}
else if (db->open) {
Local<Value> info[] = { Nan::New("error").ToLocalChecked(), argv[0] };
EMIT_EVENT(db->handle(), 2, info);
}
if (!db->open) {
Local<Value> info[] = { Nan::New("close").ToLocalChecked(), argv[0] };
EMIT_EVENT(db->handle(), 1, info);
db->Process();
}
delete baton;
}
NAN_METHOD(Database::Serialize) {
Database* db = Nan::ObjectWrap::Unwrap<Database>(info.This());
OPTIONAL_ARGUMENT_FUNCTION(0, callback);
bool before = db->serialize;
db->serialize = true;
if (!callback.IsEmpty() && callback->IsFunction()) {
TRY_CATCH_CALL(info.This(), callback, 0, NULL);
db->serialize = before;
}
db->Process();
info.GetReturnValue().Set(info.This());
}
NAN_METHOD(Database::Parallelize) {
Database* db = Nan::ObjectWrap::Unwrap<Database>(info.This());
OPTIONAL_ARGUMENT_FUNCTION(0, callback);
bool before = db->serialize;
db->serialize = false;
if (!callback.IsEmpty() && callback->IsFunction()) {
TRY_CATCH_CALL(info.This(), callback, 0, NULL);
db->serialize = before;
}
db->Process();
info.GetReturnValue().Set(info.This());
}
NAN_METHOD(Database::Configure) {
Database* db = Nan::ObjectWrap::Unwrap<Database>(info.This());
REQUIRE_ARGUMENTS(2);
if (Nan::Equals(info[0], Nan::New("trace").ToLocalChecked()).FromJust()) {
Local<Function> handle;
Baton* baton = new Baton(db, handle);
db->Schedule(RegisterTraceCallback, baton);
}
else if (Nan::Equals(info[0], Nan::New("profile").ToLocalChecked()).FromJust()) {
Local<Function> handle;
Baton* baton = new Baton(db, handle);
db->Schedule(RegisterProfileCallback, baton);
}
else if (Nan::Equals(info[0], Nan::New("busyTimeout").ToLocalChecked()).FromJust()) {
if (!info[1]->IsInt32()) {
return Nan::ThrowTypeError("Value must be an integer");
}
Local<Function> handle;
Baton* baton = new Baton(db, handle);
baton->status = Nan::To<int>(info[1]).FromJust();
db->Schedule(SetBusyTimeout, baton);
}
else {
return Nan::ThrowError(Exception::Error(String::Concat(
#if V8_MAJOR_VERSION > 6
info.GetIsolate(),
#endif
Nan::To<String>(info[0]).ToLocalChecked(),
Nan::New(" is not a valid configuration option").ToLocalChecked()
)));
}
db->Process();
info.GetReturnValue().Set(info.This());
}
NAN_METHOD(Database::Interrupt) {
Database* db = Nan::ObjectWrap::Unwrap<Database>(info.This());
if (!db->open) {
return Nan::ThrowError("Database is not open");
}
if (db->closing) {
return Nan::ThrowError("Database is closing");
}
sqlite3_interrupt(db->_handle);
info.GetReturnValue().Set(info.This());
}
void Database::SetBusyTimeout(Baton* baton) {
assert(baton->db->open);
assert(baton->db->_handle);
// Abuse the status field for passing the timeout.
sqlite3_busy_timeout(baton->db->_handle, baton->status);
delete baton;
}
void Database::RegisterTraceCallback(Baton* baton) {
assert(baton->db->open);
assert(baton->db->_handle);
Database* db = baton->db;
if (db->debug_trace == NULL) {
// Add it.
db->debug_trace = new AsyncTrace(db, TraceCallback);
sqlite3_trace(db->_handle, TraceCallback, db);
}
else {
// Remove it.
sqlite3_trace(db->_handle, NULL, NULL);
db->debug_trace->finish();
db->debug_trace = NULL;
}
delete baton;
}
void Database::TraceCallback(void* db, const char* sql) {
// Note: This function is called in the thread pool.
// Note: Some queries, such as "EXPLAIN" queries, are not sent through this.
static_cast<Database*>(db)->debug_trace->send(new std::string(sql));
}
void Database::TraceCallback(Database* db, std::string* sql) {
// Note: This function is called in the main V8 thread.
Nan::HandleScope scope;
Local<Value> argv[] = {
Nan::New("trace").ToLocalChecked(),
Nan::New(sql->c_str()).ToLocalChecked()
};
EMIT_EVENT(db->handle(), 2, argv);
delete sql;
}
void Database::RegisterProfileCallback(Baton* baton) {
assert(baton->db->open);
assert(baton->db->_handle);
Database* db = baton->db;
if (db->debug_profile == NULL) {
// Add it.
db->debug_profile = new AsyncProfile(db, ProfileCallback);
sqlite3_profile(db->_handle, ProfileCallback, db);
}
else {
// Remove it.
sqlite3_profile(db->_handle, NULL, NULL);
db->debug_profile->finish();
db->debug_profile = NULL;
}
delete baton;
}
void Database::ProfileCallback(void* db, const char* sql, sqlite3_uint64 nsecs) {
// Note: This function is called in the thread pool.
// Note: Some queries, such as "EXPLAIN" queries, are not sent through this.
ProfileInfo* info = new ProfileInfo();
info->sql = std::string(sql);
info->nsecs = nsecs;
static_cast<Database*>(db)->debug_profile->send(info);
}
void Database::ProfileCallback(Database *db, ProfileInfo* info) {
Nan::HandleScope scope;
Local<Value> argv[] = {
Nan::New("profile").ToLocalChecked(),
Nan::New(info->sql.c_str()).ToLocalChecked(),
Nan::New<Number>((double)info->nsecs / 1000000.0)
};
EMIT_EVENT(db->handle(), 3, argv);
delete info;
}
void Database::RegisterUpdateCallback(Baton* baton) {
assert(baton->db->open);
assert(baton->db->_handle);
Database* db = baton->db;
if (db->update_event == NULL) {
// Add it.
db->update_event = new AsyncUpdate(db, UpdateCallback);
sqlite3_update_hook(db->_handle, UpdateCallback, db);
}
else {
// Remove it.
sqlite3_update_hook(db->_handle, NULL, NULL);
db->update_event->finish();
db->update_event = NULL;
}
delete baton;
}
void Database::UpdateCallback(void* db, int type, const char* database,
const char* table, sqlite3_int64 rowid) {
// Note: This function is called in the thread pool.
// Note: Some queries, such as "EXPLAIN" queries, are not sent through this.
UpdateInfo* info = new UpdateInfo();
info->type = type;
info->database = std::string(database);
info->table = std::string(table);
info->rowid = rowid;
static_cast<Database*>(db)->update_event->send(info);
}
void Database::UpdateCallback(Database *db, UpdateInfo* info) {
Nan::HandleScope scope;
Local<Value> argv[] = {
Nan::New(sqlite_authorizer_string(info->type)).ToLocalChecked(),
Nan::New(info->database.c_str()).ToLocalChecked(),
Nan::New(info->table.c_str()).ToLocalChecked(),
Nan::New<Number>(info->rowid),
};
EMIT_EVENT(db->handle(), 4, argv);
delete info;
}
NAN_METHOD(Database::Exec) {
Database* db = Nan::ObjectWrap::Unwrap<Database>(info.This());
REQUIRE_ARGUMENT_STRING(0, sql);
OPTIONAL_ARGUMENT_FUNCTION(1, callback);
Baton* baton = new ExecBaton(db, callback, *sql);
db->Schedule(Work_BeginExec, baton, true);
info.GetReturnValue().Set(info.This());
}
void Database::Work_BeginExec(Baton* baton) {
assert(baton->db->locked);
assert(baton->db->open);
assert(baton->db->_handle);
assert(baton->db->pending == 0);
int status = uv_queue_work(uv_default_loop(),
&baton->request, Work_Exec, (uv_after_work_cb)Work_AfterExec);
assert(status == 0);
}
void Database::Work_Exec(uv_work_t* req) {
ExecBaton* baton = static_cast<ExecBaton*>(req->data);
char* message = NULL;
baton->status = sqlite3_exec(
baton->db->_handle,
baton->sql.c_str(),
NULL,
NULL,
&message
);
if (baton->status != SQLITE_OK && message != NULL) {
baton->message = std::string(message);
sqlite3_free(message);
}
}
void Database::Work_AfterExec(uv_work_t* req) {
Nan::HandleScope scope;
ExecBaton* baton = static_cast<ExecBaton*>(req->data);
Database* db = baton->db;
Local<Function> cb = Nan::New(baton->callback);
if (baton->status != SQLITE_OK) {
EXCEPTION(baton->message, baton->status, exception);
if (!cb.IsEmpty() && cb->IsFunction()) {
Local<Value> argv[] = { exception };
TRY_CATCH_CALL(db->handle(), cb, 1, argv);
}
else {
Local<Value> info[] = { Nan::New("error").ToLocalChecked(), exception };
EMIT_EVENT(db->handle(), 2, info);
}
}
else if (!cb.IsEmpty() && cb->IsFunction()) {
Local<Value> argv[] = { Nan::Null() };
TRY_CATCH_CALL(db->handle(), cb, 1, argv);
}
db->Process();
delete baton;
}
NAN_METHOD(Database::Wait) {
Database* db = Nan::ObjectWrap::Unwrap<Database>(info.This());
OPTIONAL_ARGUMENT_FUNCTION(0, callback);
Baton* baton = new Baton(db, callback);
db->Schedule(Work_Wait, baton, true);
info.GetReturnValue().Set(info.This());
}
void Database::Work_Wait(Baton* baton) {
Nan::HandleScope scope;
assert(baton->db->locked);
assert(baton->db->open);
assert(baton->db->_handle);
assert(baton->db->pending == 0);
Local<Function> cb = Nan::New(baton->callback);
if (!cb.IsEmpty() && cb->IsFunction()) {
Local<Value> argv[] = { Nan::Null() };
TRY_CATCH_CALL(baton->db->handle(), cb, 1, argv);
}
baton->db->Process();
delete baton;
}
NAN_METHOD(Database::LoadExtension) {
Database* db = Nan::ObjectWrap::Unwrap<Database>(info.This());
REQUIRE_ARGUMENT_STRING(0, filename);
OPTIONAL_ARGUMENT_FUNCTION(1, callback);
Baton* baton = new LoadExtensionBaton(db, callback, *filename);
db->Schedule(Work_BeginLoadExtension, baton, true);
info.GetReturnValue().Set(info.This());
}
void Database::Work_BeginLoadExtension(Baton* baton) {
assert(baton->db->locked);
assert(baton->db->open);
assert(baton->db->_handle);
assert(baton->db->pending == 0);
int status = uv_queue_work(uv_default_loop(),
&baton->request, Work_LoadExtension, reinterpret_cast<uv_after_work_cb>(Work_AfterLoadExtension));
assert(status == 0);
}
void Database::Work_LoadExtension(uv_work_t* req) {
LoadExtensionBaton* baton = static_cast<LoadExtensionBaton*>(req->data);
sqlite3_enable_load_extension(baton->db->_handle, 1);
char* message = NULL;
baton->status = sqlite3_load_extension(
baton->db->_handle,
baton->filename.c_str(),
0,
&message
);
sqlite3_enable_load_extension(baton->db->_handle, 0);
if (baton->status != SQLITE_OK && message != NULL) {
baton->message = std::string(message);
sqlite3_free(message);
}
}
void Database::Work_AfterLoadExtension(uv_work_t* req) {
Nan::HandleScope scope;
LoadExtensionBaton* baton = static_cast<LoadExtensionBaton*>(req->data);
Database* db = baton->db;
Local<Function> cb = Nan::New(baton->callback);
if (baton->status != SQLITE_OK) {
EXCEPTION(baton->message, baton->status, exception);
if (!cb.IsEmpty() && cb->IsFunction()) {
Local<Value> argv[] = { exception };
TRY_CATCH_CALL(db->handle(), cb, 1, argv);
}
else {
Local<Value> info[] = { Nan::New("error").ToLocalChecked(), exception };
EMIT_EVENT(db->handle(), 2, info);
}
}
else if (!cb.IsEmpty() && cb->IsFunction()) {
Local<Value> argv[] = { Nan::Null() };
TRY_CATCH_CALL(db->handle(), cb, 1, argv);
}
db->Process();
delete baton;
}
void Database::RemoveCallbacks() {
if (debug_trace) {
debug_trace->finish();
debug_trace = NULL;
}
if (debug_profile) {
debug_profile->finish();
debug_profile = NULL;
}
}

193
node_modules/sqlite3/src/database.h generated vendored Normal file
View File

@@ -0,0 +1,193 @@
#ifndef NODE_SQLITE3_SRC_DATABASE_H
#define NODE_SQLITE3_SRC_DATABASE_H
#include <string>
#include <queue>
#include <sqlite3.h>
#include <nan.h>
#include "async.h"
using namespace v8;
namespace node_sqlite3 {
class Database;
class Database : public Nan::ObjectWrap {
public:
static Nan::Persistent<FunctionTemplate> constructor_template;
static NAN_MODULE_INIT(Init);
static inline bool HasInstance(Local<Value> val) {
Nan::HandleScope scope;
if (!val->IsObject()) return false;
Local<Object> obj = val.As<Object>();
return Nan::New(constructor_template)->HasInstance(obj);
}
struct Baton {
uv_work_t request;
Database* db;
Nan::Persistent<Function> callback;
int status;
std::string message;
Baton(Database* db_, Local<Function> cb_) :
db(db_), status(SQLITE_OK) {
db->Ref();
request.data = this;
callback.Reset(cb_);
}
virtual ~Baton() {
db->Unref();
callback.Reset();
}
};
struct OpenBaton : Baton {
std::string filename;
int mode;
OpenBaton(Database* db_, Local<Function> cb_, const char* filename_, int mode_) :
Baton(db_, cb_), filename(filename_), mode(mode_) {}
};
struct ExecBaton : Baton {
std::string sql;
ExecBaton(Database* db_, Local<Function> cb_, const char* sql_) :
Baton(db_, cb_), sql(sql_) {}
};
struct LoadExtensionBaton : Baton {
std::string filename;
LoadExtensionBaton(Database* db_, Local<Function> cb_, const char* filename_) :
Baton(db_, cb_), filename(filename_) {}
};
typedef void (*Work_Callback)(Baton* baton);
struct Call {
Call(Work_Callback cb_, Baton* baton_, bool exclusive_ = false) :
callback(cb_), exclusive(exclusive_), baton(baton_) {};
Work_Callback callback;
bool exclusive;
Baton* baton;
};
struct ProfileInfo {
std::string sql;
sqlite3_int64 nsecs;
};
struct UpdateInfo {
int type;
std::string database;
std::string table;
sqlite3_int64 rowid;
};
bool IsOpen() { return open; }
bool IsLocked() { return locked; }
typedef Async<std::string, Database> AsyncTrace;
typedef Async<ProfileInfo, Database> AsyncProfile;
typedef Async<UpdateInfo, Database> AsyncUpdate;
friend class Statement;
friend class Backup;
protected:
Database() : Nan::ObjectWrap(),
_handle(NULL),
open(false),
closing(false),
locked(false),
pending(0),
serialize(false),
debug_trace(NULL),
debug_profile(NULL),
update_event(NULL) {
}
~Database() {
RemoveCallbacks();
sqlite3_close(_handle);
_handle = NULL;
open = false;
}
static NAN_METHOD(New);
static void Work_BeginOpen(Baton* baton);
static void Work_Open(uv_work_t* req);
static void Work_AfterOpen(uv_work_t* req);
static NAN_GETTER(OpenGetter);
void Schedule(Work_Callback callback, Baton* baton, bool exclusive = false);
void Process();
static NAN_METHOD(Exec);
static void Work_BeginExec(Baton* baton);
static void Work_Exec(uv_work_t* req);
static void Work_AfterExec(uv_work_t* req);
static NAN_METHOD(Wait);
static void Work_Wait(Baton* baton);
static NAN_METHOD(Close);
static void Work_BeginClose(Baton* baton);
static void Work_Close(uv_work_t* req);
static void Work_AfterClose(uv_work_t* req);
static NAN_METHOD(LoadExtension);
static void Work_BeginLoadExtension(Baton* baton);
static void Work_LoadExtension(uv_work_t* req);
static void Work_AfterLoadExtension(uv_work_t* req);
static NAN_METHOD(Serialize);
static NAN_METHOD(Parallelize);
static NAN_METHOD(Configure);
static NAN_METHOD(Interrupt);
static void SetBusyTimeout(Baton* baton);
static void RegisterTraceCallback(Baton* baton);
static void TraceCallback(void* db, const char* sql);
static void TraceCallback(Database* db, std::string* sql);
static void RegisterProfileCallback(Baton* baton);
static void ProfileCallback(void* db, const char* sql, sqlite3_uint64 nsecs);
static void ProfileCallback(Database* db, ProfileInfo* info);
static void RegisterUpdateCallback(Baton* baton);
static void UpdateCallback(void* db, int type, const char* database, const char* table, sqlite3_int64 rowid);
static void UpdateCallback(Database* db, UpdateInfo* info);
void RemoveCallbacks();
protected:
sqlite3* _handle;
bool open;
bool closing;
bool locked;
unsigned int pending;
bool serialize;
std::queue<Call*> queue;
AsyncTrace* debug_trace;
AsyncProfile* debug_profile;
AsyncUpdate* update_event;
};
}
#endif

6
node_modules/sqlite3/src/gcc-preinclude.h generated vendored Normal file
View File

@@ -0,0 +1,6 @@
// http://web.archive.org/web/20140401031018/http://rjpower9000.wordpress.com:80/2012/04/09/fun-with-shared-libraries-version-glibc_2-14-not-found/
#if defined(__linux__) && defined(__x86_64__)
__asm__(".symver memcpy,memcpy@GLIBC_2.2.5");
#endif

183
node_modules/sqlite3/src/macros.h generated vendored Normal file
View File

@@ -0,0 +1,183 @@
#ifndef NODE_SQLITE3_SRC_MACROS_H
#define NODE_SQLITE3_SRC_MACROS_H
const char* sqlite_code_string(int code);
const char* sqlite_authorizer_string(int type);
#define REQUIRE_ARGUMENTS(n) \
if (info.Length() < (n)) { \
return Nan::ThrowTypeError("Expected " #n "arguments"); \
}
#define REQUIRE_ARGUMENT_EXTERNAL(i, var) \
if (info.Length() <= (i) || !info[i]->IsExternal()) { \
return Nan::ThrowTypeError("Argument " #i " invalid"); \
} \
Local<External> var = Local<External>::Cast(info[i]);
#define REQUIRE_ARGUMENT_FUNCTION(i, var) \
if (info.Length() <= (i) || !info[i]->IsFunction()) { \
return Nan::ThrowTypeError("Argument " #i " must be a function"); \
} \
Local<Function> var = Local<Function>::Cast(info[i]);
#define REQUIRE_ARGUMENT_STRING(i, var) \
if (info.Length() <= (i) || !info[i]->IsString()) { \
return Nan::ThrowTypeError("Argument " #i " must be a string"); \
} \
Nan::Utf8String var(info[i]);
#define REQUIRE_ARGUMENT_INTEGER(i, var) \
if (info.Length() <= (i) || !info[i]->IsInt32()) { \
return Nan::ThrowTypeError("Argument " #i " must be an integer"); \
} \
int var(Nan::To<int32_t>(info[i]).FromJust());
#define OPTIONAL_ARGUMENT_FUNCTION(i, var) \
Local<Function> var; \
if (info.Length() > i && !info[i]->IsUndefined()) { \
if (!info[i]->IsFunction()) { \
return Nan::ThrowTypeError("Argument " #i " must be a function"); \
} \
var = Local<Function>::Cast(info[i]); \
}
#define OPTIONAL_ARGUMENT_INTEGER(i, var, default) \
int var; \
if (info.Length() <= (i)) { \
var = (default); \
} \
else if (info[i]->IsInt32()) { \
var = Nan::To<int32_t>(info[i]).FromJust(); \
} \
else { \
return Nan::ThrowTypeError("Argument " #i " must be an integer"); \
}
#define DEFINE_CONSTANT_INTEGER(target, constant, name) \
Nan::ForceSet(target, \
Nan::New(#name).ToLocalChecked(), \
Nan::New<Integer>(constant), \
static_cast<PropertyAttribute>(ReadOnly | DontDelete) \
);
#define DEFINE_CONSTANT_STRING(target, constant, name) \
Nan::ForceSet(target, \
Nan::New(#name).ToLocalChecked(), \
Nan::New(constant).ToLocalChecked(), \
static_cast<PropertyAttribute>(ReadOnly | DontDelete) \
);
#define NODE_SET_GETTER(target, name, function) \
Nan::SetAccessor((target)->InstanceTemplate(), \
Nan::New(name).ToLocalChecked(), (function));
#define NODE_SET_SETTER(target, name, getter, setter) \
Nan::SetAccessor((target)->InstanceTemplate(), \
Nan::New(name).ToLocalChecked(), getter, setter);
#define GET_STRING(source, name, property) \
Nan::Utf8String name(Nan::Get(source, \
Nan::New(prop).ToLocalChecked()).ToLocalChecked());
#define GET_INTEGER(source, name, prop) \
int name = Nan::To<int>(Nan::Get(source, \
Nan::New(property).ToLocalChecked()).ToLocalChecked()).FromJust();
#define EXCEPTION(msg, errno, name) \
Local<Value> name = Exception::Error(Nan::New( \
std::string(sqlite_code_string(errno)) + \
std::string(": ") + std::string(msg) \
).ToLocalChecked()); \
Local<Object> name ##_obj = name.As<Object>(); \
Nan::Set(name ##_obj, Nan::New("errno").ToLocalChecked(), Nan::New(errno));\
Nan::Set(name ##_obj, Nan::New("code").ToLocalChecked(), \
Nan::New(sqlite_code_string(errno)).ToLocalChecked());
#define EMIT_EVENT(obj, argc, argv) \
TRY_CATCH_CALL((obj), \
Nan::Get(obj, \
Nan::New("emit").ToLocalChecked()).ToLocalChecked().As<Function>(),\
argc, argv \
);
#define TRY_CATCH_CALL(context, callback, argc, argv) \
Nan::MakeCallback((context), (callback), (argc), (argv))
#define WORK_DEFINITION(name) \
static NAN_METHOD(name); \
static void Work_Begin##name(Baton* baton); \
static void Work_##name(uv_work_t* req); \
static void Work_After##name(uv_work_t* req);
#define STATEMENT_BEGIN(type) \
assert(baton); \
assert(baton->stmt); \
assert(!baton->stmt->locked); \
assert(!baton->stmt->finalized); \
assert(baton->stmt->prepared); \
baton->stmt->locked = true; \
baton->stmt->db->pending++; \
int status = uv_queue_work(uv_default_loop(), \
&baton->request, \
Work_##type, reinterpret_cast<uv_after_work_cb>(Work_After##type)); \
assert(status == 0);
#define STATEMENT_INIT(type) \
type* baton = static_cast<type*>(req->data); \
Statement* stmt = baton->stmt;
#define STATEMENT_END() \
assert(stmt->locked); \
assert(stmt->db->pending); \
stmt->locked = false; \
stmt->db->pending--; \
stmt->Process(); \
stmt->db->Process(); \
delete baton;
#define BACKUP_BEGIN(type) \
assert(baton); \
assert(baton->backup); \
assert(!baton->backup->locked); \
assert(!baton->backup->finished); \
assert(baton->backup->inited); \
baton->backup->locked = true; \
baton->backup->db->pending++; \
int status = uv_queue_work(uv_default_loop(), \
&baton->request, \
Work_##type, reinterpret_cast<uv_after_work_cb>(Work_After##type)); \
assert(status == 0);
#define BACKUP_INIT(type) \
type* baton = static_cast<type*>(req->data); \
Backup* backup = baton->backup;
#define BACKUP_END() \
assert(backup->locked); \
assert(backup->db->pending); \
backup->locked = false; \
backup->db->pending--; \
backup->Process(); \
backup->db->Process(); \
delete baton;
#define DELETE_FIELD(field) \
if (field != NULL) { \
switch ((field)->type) { \
case SQLITE_INTEGER: delete (Values::Integer*)(field); break; \
case SQLITE_FLOAT: delete (Values::Float*)(field); break; \
case SQLITE_TEXT: delete (Values::Text*)(field); break; \
case SQLITE_BLOB: delete (Values::Blob*)(field); break; \
case SQLITE_NULL: delete (Values::Null*)(field); break; \
} \
}
#endif

111
node_modules/sqlite3/src/node_sqlite3.cc generated vendored Normal file
View File

@@ -0,0 +1,111 @@
#include <stdint.h>
#include <sstream>
#include <cstring>
#include <string>
#include <sqlite3.h>
#include "macros.h"
#include "database.h"
#include "statement.h"
#include "backup.h"
using namespace node_sqlite3;
namespace {
NAN_MODULE_INIT(RegisterModule) {
Nan::HandleScope scope;
Database::Init(target);
Statement::Init(target);
Backup::Init(target);
DEFINE_CONSTANT_INTEGER(target, SQLITE_OPEN_READONLY, OPEN_READONLY);
DEFINE_CONSTANT_INTEGER(target, SQLITE_OPEN_READWRITE, OPEN_READWRITE);
DEFINE_CONSTANT_INTEGER(target, SQLITE_OPEN_CREATE, OPEN_CREATE);
DEFINE_CONSTANT_INTEGER(target, SQLITE_OPEN_FULLMUTEX, OPEN_FULLMUTEX);
DEFINE_CONSTANT_INTEGER(target, SQLITE_OPEN_URI, OPEN_URI);
DEFINE_CONSTANT_INTEGER(target, SQLITE_OPEN_SHAREDCACHE, OPEN_SHAREDCACHE);
DEFINE_CONSTANT_INTEGER(target, SQLITE_OPEN_PRIVATECACHE, OPEN_PRIVATECACHE);
DEFINE_CONSTANT_STRING(target, SQLITE_VERSION, VERSION);
#ifdef SQLITE_SOURCE_ID
DEFINE_CONSTANT_STRING(target, SQLITE_SOURCE_ID, SOURCE_ID);
#endif
DEFINE_CONSTANT_INTEGER(target, SQLITE_VERSION_NUMBER, VERSION_NUMBER);
DEFINE_CONSTANT_INTEGER(target, SQLITE_OK, OK);
DEFINE_CONSTANT_INTEGER(target, SQLITE_ERROR, ERROR);
DEFINE_CONSTANT_INTEGER(target, SQLITE_INTERNAL, INTERNAL);
DEFINE_CONSTANT_INTEGER(target, SQLITE_PERM, PERM);
DEFINE_CONSTANT_INTEGER(target, SQLITE_ABORT, ABORT);
DEFINE_CONSTANT_INTEGER(target, SQLITE_BUSY, BUSY);
DEFINE_CONSTANT_INTEGER(target, SQLITE_LOCKED, LOCKED);
DEFINE_CONSTANT_INTEGER(target, SQLITE_NOMEM, NOMEM);
DEFINE_CONSTANT_INTEGER(target, SQLITE_READONLY, READONLY);
DEFINE_CONSTANT_INTEGER(target, SQLITE_INTERRUPT, INTERRUPT);
DEFINE_CONSTANT_INTEGER(target, SQLITE_IOERR, IOERR);
DEFINE_CONSTANT_INTEGER(target, SQLITE_CORRUPT, CORRUPT);
DEFINE_CONSTANT_INTEGER(target, SQLITE_NOTFOUND, NOTFOUND);
DEFINE_CONSTANT_INTEGER(target, SQLITE_FULL, FULL);
DEFINE_CONSTANT_INTEGER(target, SQLITE_CANTOPEN, CANTOPEN);
DEFINE_CONSTANT_INTEGER(target, SQLITE_PROTOCOL, PROTOCOL);
DEFINE_CONSTANT_INTEGER(target, SQLITE_EMPTY, EMPTY);
DEFINE_CONSTANT_INTEGER(target, SQLITE_SCHEMA, SCHEMA);
DEFINE_CONSTANT_INTEGER(target, SQLITE_TOOBIG, TOOBIG);
DEFINE_CONSTANT_INTEGER(target, SQLITE_CONSTRAINT, CONSTRAINT);
DEFINE_CONSTANT_INTEGER(target, SQLITE_MISMATCH, MISMATCH);
DEFINE_CONSTANT_INTEGER(target, SQLITE_MISUSE, MISUSE);
DEFINE_CONSTANT_INTEGER(target, SQLITE_NOLFS, NOLFS);
DEFINE_CONSTANT_INTEGER(target, SQLITE_AUTH, AUTH);
DEFINE_CONSTANT_INTEGER(target, SQLITE_FORMAT, FORMAT);
DEFINE_CONSTANT_INTEGER(target, SQLITE_RANGE, RANGE);
DEFINE_CONSTANT_INTEGER(target, SQLITE_NOTADB, NOTADB);
}
}
const char* sqlite_code_string(int code) {
switch (code) {
case SQLITE_OK: return "SQLITE_OK";
case SQLITE_ERROR: return "SQLITE_ERROR";
case SQLITE_INTERNAL: return "SQLITE_INTERNAL";
case SQLITE_PERM: return "SQLITE_PERM";
case SQLITE_ABORT: return "SQLITE_ABORT";
case SQLITE_BUSY: return "SQLITE_BUSY";
case SQLITE_LOCKED: return "SQLITE_LOCKED";
case SQLITE_NOMEM: return "SQLITE_NOMEM";
case SQLITE_READONLY: return "SQLITE_READONLY";
case SQLITE_INTERRUPT: return "SQLITE_INTERRUPT";
case SQLITE_IOERR: return "SQLITE_IOERR";
case SQLITE_CORRUPT: return "SQLITE_CORRUPT";
case SQLITE_NOTFOUND: return "SQLITE_NOTFOUND";
case SQLITE_FULL: return "SQLITE_FULL";
case SQLITE_CANTOPEN: return "SQLITE_CANTOPEN";
case SQLITE_PROTOCOL: return "SQLITE_PROTOCOL";
case SQLITE_EMPTY: return "SQLITE_EMPTY";
case SQLITE_SCHEMA: return "SQLITE_SCHEMA";
case SQLITE_TOOBIG: return "SQLITE_TOOBIG";
case SQLITE_CONSTRAINT: return "SQLITE_CONSTRAINT";
case SQLITE_MISMATCH: return "SQLITE_MISMATCH";
case SQLITE_MISUSE: return "SQLITE_MISUSE";
case SQLITE_NOLFS: return "SQLITE_NOLFS";
case SQLITE_AUTH: return "SQLITE_AUTH";
case SQLITE_FORMAT: return "SQLITE_FORMAT";
case SQLITE_RANGE: return "SQLITE_RANGE";
case SQLITE_NOTADB: return "SQLITE_NOTADB";
case SQLITE_ROW: return "SQLITE_ROW";
case SQLITE_DONE: return "SQLITE_DONE";
default: return "UNKNOWN";
}
}
const char* sqlite_authorizer_string(int type) {
switch (type) {
case SQLITE_INSERT: return "insert";
case SQLITE_UPDATE: return "update";
case SQLITE_DELETE: return "delete";
default: return "";
}
}
NODE_MODULE(node_sqlite3, RegisterModule)

901
node_modules/sqlite3/src/statement.cc generated vendored Normal file
View File

@@ -0,0 +1,901 @@
#include <string.h>
#include <node.h>
#include <node_buffer.h>
#include <node_version.h>
#include "macros.h"
#include "database.h"
#include "statement.h"
using namespace node_sqlite3;
Nan::Persistent<FunctionTemplate> Statement::constructor_template;
NAN_MODULE_INIT(Statement::Init) {
Nan::HandleScope scope;
Local<FunctionTemplate> t = Nan::New<FunctionTemplate>(New);
t->InstanceTemplate()->SetInternalFieldCount(1);
t->SetClassName(Nan::New("Statement").ToLocalChecked());
Nan::SetPrototypeMethod(t, "bind", Bind);
Nan::SetPrototypeMethod(t, "get", Get);
Nan::SetPrototypeMethod(t, "run", Run);
Nan::SetPrototypeMethod(t, "all", All);
Nan::SetPrototypeMethod(t, "each", Each);
Nan::SetPrototypeMethod(t, "reset", Reset);
Nan::SetPrototypeMethod(t, "finalize", Finalize);
constructor_template.Reset(t);
Nan::Set(target, Nan::New("Statement").ToLocalChecked(),
Nan::GetFunction(t).ToLocalChecked());
}
void Statement::Process() {
if (finalized && !queue.empty()) {
return CleanQueue();
}
while (prepared && !locked && !queue.empty()) {
Call* call = queue.front();
queue.pop();
call->callback(call->baton);
delete call;
}
}
void Statement::Schedule(Work_Callback callback, Baton* baton) {
if (finalized) {
queue.push(new Call(callback, baton));
CleanQueue();
}
else if (!prepared || locked) {
queue.push(new Call(callback, baton));
}
else {
callback(baton);
}
}
template <class T> void Statement::Error(T* baton) {
Nan::HandleScope scope;
Statement* stmt = baton->stmt;
// Fail hard on logic errors.
assert(stmt->status != 0);
EXCEPTION(stmt->message, stmt->status, exception);
Local<Function> cb = Nan::New(baton->callback);
if (!cb.IsEmpty() && cb->IsFunction()) {
Local<Value> argv[] = { exception };
TRY_CATCH_CALL(stmt->handle(), cb, 1, argv);
}
else {
Local<Value> argv[] = { Nan::New("error").ToLocalChecked(), exception };
EMIT_EVENT(stmt->handle(), 2, argv);
}
}
// { Database db, String sql, Array params, Function callback }
NAN_METHOD(Statement::New) {
if (!info.IsConstructCall()) {
return Nan::ThrowTypeError("Use the new operator to create new Statement objects");
}
int length = info.Length();
if (length <= 0 || !Database::HasInstance(info[0])) {
return Nan::ThrowTypeError("Database object expected");
}
else if (length <= 1 || !info[1]->IsString()) {
return Nan::ThrowTypeError("SQL query expected");
}
else if (length > 2 && !info[2]->IsUndefined() && !info[2]->IsFunction()) {
return Nan::ThrowTypeError("Callback expected");
}
Database* db = Nan::ObjectWrap::Unwrap<Database>(info[0].As<Object>());
Local<String> sql = Local<String>::Cast(info[1]);
Nan::ForceSet(info.This(),Nan::New("sql").ToLocalChecked(), sql, ReadOnly);
Statement* stmt = new Statement(db);
stmt->Wrap(info.This());
PrepareBaton* baton = new PrepareBaton(db, Local<Function>::Cast(info[2]), stmt);
baton->sql = std::string(*Nan::Utf8String(sql));
db->Schedule(Work_BeginPrepare, baton);
info.GetReturnValue().Set(info.This());
}
void Statement::Work_BeginPrepare(Database::Baton* baton) {
assert(baton->db->open);
baton->db->pending++;
int status = uv_queue_work(uv_default_loop(),
&baton->request, Work_Prepare, (uv_after_work_cb)Work_AfterPrepare);
assert(status == 0);
}
void Statement::Work_Prepare(uv_work_t* req) {
STATEMENT_INIT(PrepareBaton);
// In case preparing fails, we use a mutex to make sure we get the associated
// error message.
sqlite3_mutex* mtx = sqlite3_db_mutex(baton->db->_handle);
sqlite3_mutex_enter(mtx);
stmt->status = sqlite3_prepare_v2(
baton->db->_handle,
baton->sql.c_str(),
baton->sql.size(),
&stmt->_handle,
NULL
);
if (stmt->status != SQLITE_OK) {
stmt->message = std::string(sqlite3_errmsg(baton->db->_handle));
stmt->_handle = NULL;
}
sqlite3_mutex_leave(mtx);
}
void Statement::Work_AfterPrepare(uv_work_t* req) {
Nan::HandleScope scope;
STATEMENT_INIT(PrepareBaton);
if (stmt->status != SQLITE_OK) {
Error(baton);
stmt->Finalize();
}
else {
stmt->prepared = true;
Local<Function> cb = Nan::New(baton->callback);
if (!cb.IsEmpty() && cb->IsFunction()) {
Local<Value> argv[] = { Nan::Null() };
TRY_CATCH_CALL(stmt->handle(), cb, 1, argv);
}
}
STATEMENT_END();
}
template <class T> Values::Field*
Statement::BindParameter(const Local<Value> source, T pos) {
if (source->IsString() || source->IsRegExp()) {
Nan::Utf8String val(source);
return new Values::Text(pos, val.length(), *val);
}
else if (source->IsInt32()) {
return new Values::Integer(pos, Nan::To<int32_t>(source).FromJust());
}
else if (source->IsNumber()) {
return new Values::Float(pos, Nan::To<double>(source).FromJust());
}
else if (source->IsBoolean()) {
return new Values::Integer(pos, Nan::To<bool>(source).FromJust() ? 1 : 0);
}
else if (source->IsNull()) {
return new Values::Null(pos);
}
else if (Buffer::HasInstance(source)) {
Local<Object> buffer = Nan::To<Object>(source).ToLocalChecked();
return new Values::Blob(pos, Buffer::Length(buffer), Buffer::Data(buffer));
}
else if (source->IsDate()) {
return new Values::Float(pos, Nan::To<double>(source).FromJust());
}
else {
return NULL;
}
}
template <class T> T* Statement::Bind(Nan::NAN_METHOD_ARGS_TYPE info, int start, int last) {
Nan::HandleScope scope;
if (last < 0) last = info.Length();
Local<Function> callback;
if (last > start && info[last - 1]->IsFunction()) {
callback = Local<Function>::Cast(info[last - 1]);
last--;
}
T* baton = new T(this, callback);
if (start < last) {
if (info[start]->IsArray()) {
Local<Array> array = Local<Array>::Cast(info[start]);
int length = array->Length();
// Note: bind parameters start with 1.
for (int i = 0, pos = 1; i < length; i++, pos++) {
baton->parameters.push_back(BindParameter(Nan::Get(array, i).ToLocalChecked(), pos));
}
}
else if (!info[start]->IsObject() || info[start]->IsRegExp() || info[start]->IsDate() || Buffer::HasInstance(info[start])) {
// Parameters directly in array.
// Note: bind parameters start with 1.
for (int i = start, pos = 1; i < last; i++, pos++) {
baton->parameters.push_back(BindParameter(info[i], pos));
}
}
else if (info[start]->IsObject()) {
Local<Object> object = Local<Object>::Cast(info[start]);
Local<Array> array = Nan::GetPropertyNames(object).ToLocalChecked();
int length = array->Length();
for (int i = 0; i < length; i++) {
Local<Value> name = Nan::Get(array, i).ToLocalChecked();
if (name->IsInt32()) {
baton->parameters.push_back(
BindParameter(Nan::Get(object, name).ToLocalChecked(), Nan::To<int32_t>(name).FromJust()));
}
else {
baton->parameters.push_back(BindParameter(Nan::Get(object, name).ToLocalChecked(),
*Nan::Utf8String(name)));
}
}
}
else {
return NULL;
}
}
return baton;
}
bool Statement::Bind(const Parameters & parameters) {
if (parameters.size() == 0) {
return true;
}
sqlite3_reset(_handle);
sqlite3_clear_bindings(_handle);
Parameters::const_iterator it = parameters.begin();
Parameters::const_iterator end = parameters.end();
for (; it < end; ++it) {
Values::Field* field = *it;
if (field != NULL) {
int pos;
if (field->index > 0) {
pos = field->index;
}
else {
pos = sqlite3_bind_parameter_index(_handle, field->name.c_str());
}
switch (field->type) {
case SQLITE_INTEGER: {
status = sqlite3_bind_int(_handle, pos,
((Values::Integer*)field)->value);
} break;
case SQLITE_FLOAT: {
status = sqlite3_bind_double(_handle, pos,
((Values::Float*)field)->value);
} break;
case SQLITE_TEXT: {
status = sqlite3_bind_text(_handle, pos,
((Values::Text*)field)->value.c_str(),
((Values::Text*)field)->value.size(), SQLITE_TRANSIENT);
} break;
case SQLITE_BLOB: {
status = sqlite3_bind_blob(_handle, pos,
((Values::Blob*)field)->value,
((Values::Blob*)field)->length, SQLITE_TRANSIENT);
} break;
case SQLITE_NULL: {
status = sqlite3_bind_null(_handle, pos);
} break;
}
if (status != SQLITE_OK) {
message = std::string(sqlite3_errmsg(db->_handle));
return false;
}
}
}
return true;
}
NAN_METHOD(Statement::Bind) {
Statement* stmt = Nan::ObjectWrap::Unwrap<Statement>(info.This());
Baton* baton = stmt->Bind<Baton>(info);
if (baton == NULL) {
return Nan::ThrowTypeError("Data type is not supported");
}
else {
stmt->Schedule(Work_BeginBind, baton);
info.GetReturnValue().Set(info.This());
}
}
void Statement::Work_BeginBind(Baton* baton) {
STATEMENT_BEGIN(Bind);
}
void Statement::Work_Bind(uv_work_t* req) {
STATEMENT_INIT(Baton);
sqlite3_mutex* mtx = sqlite3_db_mutex(stmt->db->_handle);
sqlite3_mutex_enter(mtx);
stmt->Bind(baton->parameters);
sqlite3_mutex_leave(mtx);
}
void Statement::Work_AfterBind(uv_work_t* req) {
Nan::HandleScope scope;
STATEMENT_INIT(Baton);
if (stmt->status != SQLITE_OK) {
Error(baton);
}
else {
// Fire callbacks.
Local<Function> cb = Nan::New(baton->callback);
if (!cb.IsEmpty() && cb->IsFunction()) {
Local<Value> argv[] = { Nan::Null() };
TRY_CATCH_CALL(stmt->handle(), cb, 1, argv);
}
}
STATEMENT_END();
}
NAN_METHOD(Statement::Get) {
Statement* stmt = Nan::ObjectWrap::Unwrap<Statement>(info.This());
Baton* baton = stmt->Bind<RowBaton>(info);
if (baton == NULL) {
return Nan::ThrowError("Data type is not supported");
}
else {
stmt->Schedule(Work_BeginGet, baton);
info.GetReturnValue().Set(info.This());
}
}
void Statement::Work_BeginGet(Baton* baton) {
STATEMENT_BEGIN(Get);
}
void Statement::Work_Get(uv_work_t* req) {
STATEMENT_INIT(RowBaton);
if (stmt->status != SQLITE_DONE || baton->parameters.size()) {
sqlite3_mutex* mtx = sqlite3_db_mutex(stmt->db->_handle);
sqlite3_mutex_enter(mtx);
if (stmt->Bind(baton->parameters)) {
stmt->status = sqlite3_step(stmt->_handle);
if (!(stmt->status == SQLITE_ROW || stmt->status == SQLITE_DONE)) {
stmt->message = std::string(sqlite3_errmsg(stmt->db->_handle));
}
}
sqlite3_mutex_leave(mtx);
if (stmt->status == SQLITE_ROW) {
// Acquire one result row before returning.
GetRow(&baton->row, stmt->_handle);
}
}
}
void Statement::Work_AfterGet(uv_work_t* req) {
Nan::HandleScope scope;
STATEMENT_INIT(RowBaton);
if (stmt->status != SQLITE_ROW && stmt->status != SQLITE_DONE) {
Error(baton);
}
else {
// Fire callbacks.
Local<Function> cb = Nan::New(baton->callback);
if (!cb.IsEmpty() && cb->IsFunction()) {
if (stmt->status == SQLITE_ROW) {
// Create the result array from the data we acquired.
Local<Value> argv[] = { Nan::Null(), RowToJS(&baton->row) };
TRY_CATCH_CALL(stmt->handle(), cb, 2, argv);
}
else {
Local<Value> argv[] = { Nan::Null() };
TRY_CATCH_CALL(stmt->handle(), cb, 1, argv);
}
}
}
STATEMENT_END();
}
NAN_METHOD(Statement::Run) {
Statement* stmt = Nan::ObjectWrap::Unwrap<Statement>(info.This());
Baton* baton = stmt->Bind<RunBaton>(info);
if (baton == NULL) {
return Nan::ThrowError("Data type is not supported");
}
else {
stmt->Schedule(Work_BeginRun, baton);
info.GetReturnValue().Set(info.This());
}
}
void Statement::Work_BeginRun(Baton* baton) {
STATEMENT_BEGIN(Run);
}
void Statement::Work_Run(uv_work_t* req) {
STATEMENT_INIT(RunBaton);
sqlite3_mutex* mtx = sqlite3_db_mutex(stmt->db->_handle);
sqlite3_mutex_enter(mtx);
// Make sure that we also reset when there are no parameters.
if (!baton->parameters.size()) {
sqlite3_reset(stmt->_handle);
}
if (stmt->Bind(baton->parameters)) {
stmt->status = sqlite3_step(stmt->_handle);
if (!(stmt->status == SQLITE_ROW || stmt->status == SQLITE_DONE)) {
stmt->message = std::string(sqlite3_errmsg(stmt->db->_handle));
}
else {
baton->inserted_id = sqlite3_last_insert_rowid(stmt->db->_handle);
baton->changes = sqlite3_changes(stmt->db->_handle);
}
}
sqlite3_mutex_leave(mtx);
}
void Statement::Work_AfterRun(uv_work_t* req) {
Nan::HandleScope scope;
STATEMENT_INIT(RunBaton);
if (stmt->status != SQLITE_ROW && stmt->status != SQLITE_DONE) {
Error(baton);
}
else {
// Fire callbacks.
Local<Function> cb = Nan::New(baton->callback);
if (!cb.IsEmpty() && cb->IsFunction()) {
Nan::Set(stmt->handle(), Nan::New("lastID").ToLocalChecked(), Nan::New<Number>(baton->inserted_id));
Nan::Set(stmt->handle(), Nan::New("changes").ToLocalChecked(), Nan::New(baton->changes));
Local<Value> argv[] = { Nan::Null() };
TRY_CATCH_CALL(stmt->handle(), cb, 1, argv);
}
}
STATEMENT_END();
}
NAN_METHOD(Statement::All) {
Statement* stmt = Nan::ObjectWrap::Unwrap<Statement>(info.This());
Baton* baton = stmt->Bind<RowsBaton>(info);
if (baton == NULL) {
return Nan::ThrowError("Data type is not supported");
}
else {
stmt->Schedule(Work_BeginAll, baton);
info.GetReturnValue().Set(info.This());
}
}
void Statement::Work_BeginAll(Baton* baton) {
STATEMENT_BEGIN(All);
}
void Statement::Work_All(uv_work_t* req) {
STATEMENT_INIT(RowsBaton);
sqlite3_mutex* mtx = sqlite3_db_mutex(stmt->db->_handle);
sqlite3_mutex_enter(mtx);
// Make sure that we also reset when there are no parameters.
if (!baton->parameters.size()) {
sqlite3_reset(stmt->_handle);
}
if (stmt->Bind(baton->parameters)) {
while ((stmt->status = sqlite3_step(stmt->_handle)) == SQLITE_ROW) {
Row* row = new Row();
GetRow(row, stmt->_handle);
baton->rows.push_back(row);
}
if (stmt->status != SQLITE_DONE) {
stmt->message = std::string(sqlite3_errmsg(stmt->db->_handle));
}
}
sqlite3_mutex_leave(mtx);
}
void Statement::Work_AfterAll(uv_work_t* req) {
Nan::HandleScope scope;
STATEMENT_INIT(RowsBaton);
if (stmt->status != SQLITE_DONE) {
Error(baton);
}
else {
// Fire callbacks.
Local<Function> cb = Nan::New(baton->callback);
if (!cb.IsEmpty() && cb->IsFunction()) {
if (baton->rows.size()) {
// Create the result array from the data we acquired.
Local<Array> result(Nan::New<Array>(baton->rows.size()));
Rows::const_iterator it = baton->rows.begin();
Rows::const_iterator end = baton->rows.end();
for (int i = 0; it < end; ++it, i++) {
Nan::Set(result, i, RowToJS(*it));
delete *it;
}
Local<Value> argv[] = { Nan::Null(), result };
TRY_CATCH_CALL(stmt->handle(), cb, 2, argv);
}
else {
// There were no result rows.
Local<Value> argv[] = {
Nan::Null(),
Nan::New<Array>(0)
};
TRY_CATCH_CALL(stmt->handle(), cb, 2, argv);
}
}
}
STATEMENT_END();
}
NAN_METHOD(Statement::Each) {
Statement* stmt = Nan::ObjectWrap::Unwrap<Statement>(info.This());
int last = info.Length();
Local<Function> completed;
if (last >= 2 && info[last - 1]->IsFunction() && info[last - 2]->IsFunction()) {
completed = Local<Function>::Cast(info[--last]);
}
EachBaton* baton = stmt->Bind<EachBaton>(info, 0, last);
if (baton == NULL) {
return Nan::ThrowError("Data type is not supported");
}
else {
baton->completed.Reset(completed);
stmt->Schedule(Work_BeginEach, baton);
info.GetReturnValue().Set(info.This());
}
}
void Statement::Work_BeginEach(Baton* baton) {
// Only create the Async object when we're actually going into
// the event loop. This prevents dangling events.
EachBaton* each_baton = static_cast<EachBaton*>(baton);
each_baton->async = new Async(each_baton->stmt, reinterpret_cast<uv_async_cb>(AsyncEach));
each_baton->async->item_cb.Reset(each_baton->callback);
each_baton->async->completed_cb.Reset(each_baton->completed);
STATEMENT_BEGIN(Each);
}
void Statement::Work_Each(uv_work_t* req) {
STATEMENT_INIT(EachBaton);
Async* async = baton->async;
sqlite3_mutex* mtx = sqlite3_db_mutex(stmt->db->_handle);
int retrieved = 0;
// Make sure that we also reset when there are no parameters.
if (!baton->parameters.size()) {
sqlite3_reset(stmt->_handle);
}
if (stmt->Bind(baton->parameters)) {
while (true) {
sqlite3_mutex_enter(mtx);
stmt->status = sqlite3_step(stmt->_handle);
if (stmt->status == SQLITE_ROW) {
sqlite3_mutex_leave(mtx);
Row* row = new Row();
GetRow(row, stmt->_handle);
NODE_SQLITE3_MUTEX_LOCK(&async->mutex)
async->data.push_back(row);
retrieved++;
NODE_SQLITE3_MUTEX_UNLOCK(&async->mutex)
uv_async_send(&async->watcher);
}
else {
if (stmt->status != SQLITE_DONE) {
stmt->message = std::string(sqlite3_errmsg(stmt->db->_handle));
}
sqlite3_mutex_leave(mtx);
break;
}
}
}
async->completed = true;
uv_async_send(&async->watcher);
}
void Statement::CloseCallback(uv_handle_t* handle) {
assert(handle != NULL);
assert(handle->data != NULL);
Async* async = static_cast<Async*>(handle->data);
delete async;
}
void Statement::AsyncEach(uv_async_t* handle, int status) {
Nan::HandleScope scope;
Async* async = static_cast<Async*>(handle->data);
while (true) {
// Get the contents out of the data cache for us to process in the JS callback.
Rows rows;
NODE_SQLITE3_MUTEX_LOCK(&async->mutex)
rows.swap(async->data);
NODE_SQLITE3_MUTEX_UNLOCK(&async->mutex)
if (rows.empty()) {
break;
}
Local<Function> cb = Nan::New(async->item_cb);
if (!cb.IsEmpty() && cb->IsFunction()) {
Local<Value> argv[2];
argv[0] = Nan::Null();
Rows::const_iterator it = rows.begin();
Rows::const_iterator end = rows.end();
for (int i = 0; it < end; ++it, i++) {
argv[1] = RowToJS(*it);
async->retrieved++;
TRY_CATCH_CALL(async->stmt->handle(), cb, 2, argv);
delete *it;
}
}
}
Local<Function> cb = Nan::New(async->completed_cb);
if (async->completed) {
if (!cb.IsEmpty() &&
cb->IsFunction()) {
Local<Value> argv[] = {
Nan::Null(),
Nan::New(async->retrieved)
};
TRY_CATCH_CALL(async->stmt->handle(), cb, 2, argv);
}
uv_close(reinterpret_cast<uv_handle_t*>(handle), CloseCallback);
}
}
void Statement::Work_AfterEach(uv_work_t* req) {
Nan::HandleScope scope;
STATEMENT_INIT(EachBaton);
if (stmt->status != SQLITE_DONE) {
Error(baton);
}
STATEMENT_END();
}
NAN_METHOD(Statement::Reset) {
Statement* stmt = Nan::ObjectWrap::Unwrap<Statement>(info.This());
OPTIONAL_ARGUMENT_FUNCTION(0, callback);
Baton* baton = new Baton(stmt, callback);
stmt->Schedule(Work_BeginReset, baton);
info.GetReturnValue().Set(info.This());
}
void Statement::Work_BeginReset(Baton* baton) {
STATEMENT_BEGIN(Reset);
}
void Statement::Work_Reset(uv_work_t* req) {
STATEMENT_INIT(Baton);
sqlite3_reset(stmt->_handle);
stmt->status = SQLITE_OK;
}
void Statement::Work_AfterReset(uv_work_t* req) {
Nan::HandleScope scope;
STATEMENT_INIT(Baton);
// Fire callbacks.
Local<Function> cb = Nan::New(baton->callback);
if (!cb.IsEmpty() && cb->IsFunction()) {
Local<Value> argv[] = { Nan::Null() };
TRY_CATCH_CALL(stmt->handle(), cb, 1, argv);
}
STATEMENT_END();
}
Local<Object> Statement::RowToJS(Row* row) {
Nan::EscapableHandleScope scope;
Local<Object> result = Nan::New<Object>();
Row::const_iterator it = row->begin();
Row::const_iterator end = row->end();
for (int i = 0; it < end; ++it, i++) {
Values::Field* field = *it;
Local<Value> value;
switch (field->type) {
case SQLITE_INTEGER: {
value = Nan::New<Number>(((Values::Integer*)field)->value);
} break;
case SQLITE_FLOAT: {
value = Nan::New<Number>(((Values::Float*)field)->value);
} break;
case SQLITE_TEXT: {
value = Nan::New<String>(((Values::Text*)field)->value.c_str(), ((Values::Text*)field)->value.size()).ToLocalChecked();
} break;
case SQLITE_BLOB: {
value = Nan::CopyBuffer(((Values::Blob*)field)->value, ((Values::Blob*)field)->length).ToLocalChecked();
} break;
case SQLITE_NULL: {
value = Nan::Null();
} break;
}
Nan::Set(result, Nan::New(field->name.c_str()).ToLocalChecked(), value);
DELETE_FIELD(field);
}
return scope.Escape(result);
}
void Statement::GetRow(Row* row, sqlite3_stmt* stmt) {
int rows = sqlite3_column_count(stmt);
for (int i = 0; i < rows; i++) {
int type = sqlite3_column_type(stmt, i);
const char* name = sqlite3_column_name(stmt, i);
switch (type) {
case SQLITE_INTEGER: {
row->push_back(new Values::Integer(name, sqlite3_column_int64(stmt, i)));
} break;
case SQLITE_FLOAT: {
row->push_back(new Values::Float(name, sqlite3_column_double(stmt, i)));
} break;
case SQLITE_TEXT: {
const char* text = (const char*)sqlite3_column_text(stmt, i);
int length = sqlite3_column_bytes(stmt, i);
row->push_back(new Values::Text(name, length, text));
} break;
case SQLITE_BLOB: {
const void* blob = sqlite3_column_blob(stmt, i);
int length = sqlite3_column_bytes(stmt, i);
row->push_back(new Values::Blob(name, length, blob));
} break;
case SQLITE_NULL: {
row->push_back(new Values::Null(name));
} break;
default:
assert(false);
}
}
}
NAN_METHOD(Statement::Finalize) {
Statement* stmt = Nan::ObjectWrap::Unwrap<Statement>(info.This());
OPTIONAL_ARGUMENT_FUNCTION(0, callback);
Baton* baton = new Baton(stmt, callback);
stmt->Schedule(Finalize, baton);
info.GetReturnValue().Set(stmt->db->handle());
}
void Statement::Finalize(Baton* baton) {
Nan::HandleScope scope;
baton->stmt->Finalize();
// Fire callback in case there was one.
Local<Function> cb = Nan::New(baton->callback);
if (!cb.IsEmpty() && cb->IsFunction()) {
TRY_CATCH_CALL(baton->stmt->handle(), cb, 0, NULL);
}
delete baton;
}
void Statement::Finalize() {
assert(!finalized);
finalized = true;
CleanQueue();
// Finalize returns the status code of the last operation. We already fired
// error events in case those failed.
sqlite3_finalize(_handle);
_handle = NULL;
db->Unref();
}
void Statement::CleanQueue() {
Nan::HandleScope scope;
if (prepared && !queue.empty()) {
// This statement has already been prepared and is now finalized.
// Fire error for all remaining items in the queue.
EXCEPTION("Statement is already finalized", SQLITE_MISUSE, exception);
Local<Value> argv[] = { exception };
bool called = false;
// Clear out the queue so that this object can get GC'ed.
while (!queue.empty()) {
Call* call = queue.front();
queue.pop();
Local<Function> cb = Nan::New(call->baton->callback);
if (prepared && !cb.IsEmpty() &&
cb->IsFunction()) {
TRY_CATCH_CALL(handle(), cb, 1, argv);
called = true;
}
// We don't call the actual callback, so we have to make sure that
// the baton gets destroyed.
delete call->baton;
delete call;
}
// When we couldn't call a callback function, emit an error on the
// Statement object.
if (!called) {
Local<Value> info[] = { Nan::New("error").ToLocalChecked(), exception };
EMIT_EVENT(handle(), 2, info);
}
}
else while (!queue.empty()) {
// Just delete all items in the queue; we already fired an event when
// preparing the statement failed.
Call* call = queue.front();
queue.pop();
// We don't call the actual callback, so we have to make sure that
// the baton gets destroyed.
delete call->baton;
delete call;
}
}

248
node_modules/sqlite3/src/statement.h generated vendored Normal file
View File

@@ -0,0 +1,248 @@
#ifndef NODE_SQLITE3_SRC_STATEMENT_H
#define NODE_SQLITE3_SRC_STATEMENT_H
#include "database.h"
#include "threading.h"
#include <cstdlib>
#include <cstring>
#include <string>
#include <queue>
#include <vector>
#include <sqlite3.h>
#include <nan.h>
using namespace v8;
using namespace node;
namespace node_sqlite3 {
namespace Values {
struct Field {
inline Field(unsigned short _index, unsigned short _type = SQLITE_NULL) :
type(_type), index(_index) {}
inline Field(const char* _name, unsigned short _type = SQLITE_NULL) :
type(_type), index(0), name(_name) {}
unsigned short type;
unsigned short index;
std::string name;
};
struct Integer : Field {
template <class T> inline Integer(T _name, int64_t val) :
Field(_name, SQLITE_INTEGER), value(val) {}
int64_t value;
};
struct Float : Field {
template <class T> inline Float(T _name, double val) :
Field(_name, SQLITE_FLOAT), value(val) {}
double value;
};
struct Text : Field {
template <class T> inline Text(T _name, size_t len, const char* val) :
Field(_name, SQLITE_TEXT), value(val, len) {}
std::string value;
};
struct Blob : Field {
template <class T> inline Blob(T _name, size_t len, const void* val) :
Field(_name, SQLITE_BLOB), length(len) {
value = (char*)malloc(len);
memcpy(value, val, len);
}
inline ~Blob() {
free(value);
}
int length;
char* value;
};
typedef Field Null;
}
typedef std::vector<Values::Field*> Row;
typedef std::vector<Row*> Rows;
typedef Row Parameters;
class Statement : public Nan::ObjectWrap {
public:
static Nan::Persistent<FunctionTemplate> constructor_template;
static NAN_MODULE_INIT(Init);
static NAN_METHOD(New);
struct Baton {
uv_work_t request;
Statement* stmt;
Nan::Persistent<Function> callback;
Parameters parameters;
Baton(Statement* stmt_, Local<Function> cb_) : stmt(stmt_) {
stmt->Ref();
request.data = this;
callback.Reset(cb_);
}
virtual ~Baton() {
for (unsigned int i = 0; i < parameters.size(); i++) {
Values::Field* field = parameters[i];
DELETE_FIELD(field);
}
stmt->Unref();
callback.Reset();
}
};
struct RowBaton : Baton {
RowBaton(Statement* stmt_, Local<Function> cb_) :
Baton(stmt_, cb_) {}
Row row;
};
struct RunBaton : Baton {
RunBaton(Statement* stmt_, Local<Function> cb_) :
Baton(stmt_, cb_), inserted_id(0), changes(0) {}
sqlite3_int64 inserted_id;
int changes;
};
struct RowsBaton : Baton {
RowsBaton(Statement* stmt_, Local<Function> cb_) :
Baton(stmt_, cb_) {}
Rows rows;
};
struct Async;
struct EachBaton : Baton {
Nan::Persistent<Function> completed;
Async* async; // Isn't deleted when the baton is deleted.
EachBaton(Statement* stmt_, Local<Function> cb_) :
Baton(stmt_, cb_) {}
virtual ~EachBaton() {
completed.Reset();
}
};
struct PrepareBaton : Database::Baton {
Statement* stmt;
std::string sql;
PrepareBaton(Database* db_, Local<Function> cb_, Statement* stmt_) :
Baton(db_, cb_), stmt(stmt_) {
stmt->Ref();
}
virtual ~PrepareBaton() {
stmt->Unref();
if (!db->IsOpen() && db->IsLocked()) {
// The database handle was closed before the statement could be
// prepared.
stmt->Finalize();
}
}
};
typedef void (*Work_Callback)(Baton* baton);
struct Call {
Call(Work_Callback cb_, Baton* baton_) : callback(cb_), baton(baton_) {};
Work_Callback callback;
Baton* baton;
};
struct Async {
uv_async_t watcher;
Statement* stmt;
Rows data;
NODE_SQLITE3_MUTEX_t;
bool completed;
int retrieved;
// Store the callbacks here because we don't have
// access to the baton in the async callback.
Nan::Persistent<Function> item_cb;
Nan::Persistent<Function> completed_cb;
Async(Statement* st, uv_async_cb async_cb) :
stmt(st), completed(false), retrieved(0) {
watcher.data = this;
NODE_SQLITE3_MUTEX_INIT
stmt->Ref();
uv_async_init(uv_default_loop(), &watcher, async_cb);
}
~Async() {
stmt->Unref();
item_cb.Reset();
completed_cb.Reset();
NODE_SQLITE3_MUTEX_DESTROY
}
};
Statement(Database* db_) : Nan::ObjectWrap(),
db(db_),
_handle(NULL),
status(SQLITE_OK),
prepared(false),
locked(true),
finalized(false) {
db->Ref();
}
~Statement() {
if (!finalized) Finalize();
}
WORK_DEFINITION(Bind);
WORK_DEFINITION(Get);
WORK_DEFINITION(Run);
WORK_DEFINITION(All);
WORK_DEFINITION(Each);
WORK_DEFINITION(Reset);
static NAN_METHOD(Finalize);
protected:
static void Work_BeginPrepare(Database::Baton* baton);
static void Work_Prepare(uv_work_t* req);
static void Work_AfterPrepare(uv_work_t* req);
static void AsyncEach(uv_async_t* handle, int status);
static void CloseCallback(uv_handle_t* handle);
static void Finalize(Baton* baton);
void Finalize();
template <class T> inline Values::Field* BindParameter(const Local<Value> source, T pos);
template <class T> T* Bind(Nan::NAN_METHOD_ARGS_TYPE info, int start = 0, int end = -1);
bool Bind(const Parameters &parameters);
static void GetRow(Row* row, sqlite3_stmt* stmt);
static Local<Object> RowToJS(Row* row);
void Schedule(Work_Callback callback, Baton* baton);
void Process();
void CleanQueue();
template <class T> static void Error(T* baton);
protected:
Database* db;
sqlite3_stmt* _handle;
int status;
std::string message;
bool prepared;
bool locked;
bool finalized;
std::queue<Call*> queue;
};
}
#endif

48
node_modules/sqlite3/src/threading.h generated vendored Normal file
View File

@@ -0,0 +1,48 @@
#ifndef NODE_SQLITE3_SRC_THREADING_H
#define NODE_SQLITE3_SRC_THREADING_H
#ifdef _WIN32
#include <windows.h>
#define NODE_SQLITE3_MUTEX_t HANDLE mutex;
#define NODE_SQLITE3_MUTEX_INIT mutex = CreateMutex(NULL, FALSE, NULL);
#define NODE_SQLITE3_MUTEX_LOCK(m) WaitForSingleObject(*m, INFINITE);
#define NODE_SQLITE3_MUTEX_UNLOCK(m) ReleaseMutex(*m);
#define NODE_SQLITE3_MUTEX_DESTROY CloseHandle(mutex);
#elif defined(NODE_SQLITE3_BOOST_THREADING)
#include <boost/thread/mutex.hpp>
#define NODE_SQLITE3_MUTEX_t boost::mutex mutex;
#define NODE_SQLITE3_MUTEX_INIT
#define NODE_SQLITE3_MUTEX_LOCK(m) (*m).lock();
#define NODE_SQLITE3_MUTEX_UNLOCK(m) (*m).unlock();
#define NODE_SQLITE3_MUTEX_DESTROY mutex.unlock();
#else
#define NODE_SQLITE3_MUTEX_t pthread_mutex_t mutex;
#define NODE_SQLITE3_MUTEX_INIT pthread_mutex_init(&mutex,NULL);
#define NODE_SQLITE3_MUTEX_LOCK(m) pthread_mutex_lock(m);
#define NODE_SQLITE3_MUTEX_UNLOCK(m) pthread_mutex_unlock(m);
#define NODE_SQLITE3_MUTEX_DESTROY pthread_mutex_destroy(&mutex);
#endif
#endif // NODE_SQLITE3_SRC_THREADING_H

View File

@@ -0,0 +1,81 @@
#!/bin/echo docker build . -f
# -*- coding: utf-8 -*-
# SPDX-License-Identifier: ISC
# Copyright 2019-present Samsung Electronics Co., Ltd. and other contributors
#{
# ISC License
# Copyright (c) 2004-2010 by Internet Systems Consortium, Inc. ("ISC")
# Copyright (c) 1995-2003 by Internet Software Consortium
# Permission to use, copy, modify, and /or distribute this software
# for any purpose with or without fee is hereby granted,
# provided that the above copyright notice
# and this permission notice appear in all copies.
# THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
# OF MERCHANTABILITY AND FITNESS.
# IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT,
# OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
# WHETHER IN AN ACTION OF CONTRACT,
# NEGLIGENCE OR OTHER TORTIOUS ACTION,
# ARISING OUT OF OR IN CONNECTION WITH THE USE
# OR PERFORMANCE OF THIS SOFTWARE.
#}
FROM resin/rpi-raspbian:stretch
MAINTAINER Philippe Coval (p.coval@samsung.com)
RUN [ "cross-build-start" ]
ENV DEBIAN_FRONTEND noninteractive
ENV LC_ALL en_US.UTF-8
ENV LANG ${LC_ALL}
RUN echo "#log: Configuring locales" \
&& set -x \
&& apt-get update -y \
&& apt-get install -y locales \
&& echo "${LC_ALL} UTF-8" | tee /etc/locale.gen \
&& locale-gen ${LC_ALL} \
&& dpkg-reconfigure locales \
&& sync
ENV project node-sqlite3
RUN echo "#log: ${project}: Setup system" \
&& set -x \
&& apt-get update -y \
&& apt-get install -y \
curl \
sudo \
build-essential \
python \
&& apt-get clean \
&& NVM_VERSION="v0.33.8" \
&& NODE_VERSION="--lts=carbon" \
&& curl -o- https://raw.githubusercontent.com/creationix/nvm/${NVM_VERSION}/install.sh | bash \
&& which nvm || . ~/.bashrc \
&& nvm install ${NODE_VERSION} \
&& nvm use ${NODE_VERSION} \
&& sync
ADD . /usr/local/opt/${project}/src/${project}
WORKDIR /usr/local/opt/${project}/src/${project}
RUN echo "#log: ${project}: Preparing sources" \
&& set -x \
&& which npm || . ~/.bashrc \
&& npm install || cat npm-debug.log \
&& npm install \
&& npm install --unsafe-perm --build-from-source \
&& sync
WORKDIR /usr/local/opt/${project}/src/${project}
RUN echo "#log: ${project}: Building sources" \
&& set -x \
&& which npm || . ~/.bashrc \
&& npm run pack \
&& npm pack \
&& find ${PWD}/build/stage/ -type f \
&& sync
RUN [ "cross-build-end" ]

View File

@@ -0,0 +1,53 @@
#!/bin/sh
# -*- coding: utf-8 -*-
# SPDX-License-Identifier: ISC
# Copyright 2019-present Samsung Electronics Co., Ltd. and other contributors
#{
# ISC License
# Copyright (c) 2004-2010 by Internet Systems Consortium, Inc. ("ISC")
# Copyright (c) 1995-2003 by Internet Software Consortium
# Permission to use, copy, modify, and /or distribute this software
# for any purpose with or without fee is hereby granted,
# provided that the above copyright notice
# and this permission notice appear in all copies.
# THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
# OF MERCHANTABILITY AND FITNESS.
# IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT,
# OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
# WHETHER IN AN ACTION OF CONTRACT,
# NEGLIGENCE OR OTHER TORTIOUS ACTION,
# ARISING OUT OF OR IN CONNECTION WITH THE USE
# OR PERFORMANCE OF THIS SOFTWARE.
#}
set -e
set -x
this_dir=$(dirname -- "$0")
this_dir=$(realpath "${this_dir}")
this_name=$(basename -- "$0")
top_dir="${this_dir}/../../.."
module_name="sqlite3"
project="node-${module_name}"
arch="arm"
architecture=$(basename "${this_dir}")
name="${project}-${architecture}"
dir="/usr/local/opt/${project}/"
dist_dir="${dir}/src/${project}/build"
tag=$(git describe --tags || echo v0.0.0)
version=$(echo "${tag}" | cut -dv -f2 | cut -d'-' -f1)
mkdir -p "${this_dir}/local" "${this_dir}/tmp"
cp -a "/usr/bin/qemu-${arch}-static" "${this_dir}/local"
time docker build -t "${name}" -f "${this_dir}/Dockerfile" .
container=$(docker create "${name}")
mkdir -p "${this_dir}/tmp/${dist_dir}"
rm -rf "${this_dir}/tmp/${dist_dir}"
docker cp "${container}:${dist_dir}" "${this_dir}/tmp/${dist_dir}"
file=$(ls "${this_dir}/tmp/${dist_dir}/stage/${module_name}/"*/*".tar.gz" | head -n1 \
|| echo "/tmp/${USER}/failure.tmp")
sha256sum "${file}"

View File

@@ -0,0 +1,80 @@
#!/bin/echo docker build . -f
# -*- coding: utf-8 -*-
# SPDX-License-Identifier: ISC
# Copyright 2019-present Samsung Electronics Co., Ltd. and other contributors
#{
# ISC License
# Copyright (c) 2004-2010 by Internet Systems Consortium, Inc. ("ISC")
# Copyright (c) 1995-2003 by Internet Software Consortium
# Permission to use, copy, modify, and /or distribute this software
# for any purpose with or without fee is hereby granted,
# provided that the above copyright notice
# and this permission notice appear in all copies.
# THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
# OF MERCHANTABILITY AND FITNESS.
# IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT,
# OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
# WHETHER IN AN ACTION OF CONTRACT,
# NEGLIGENCE OR OTHER TORTIOUS ACTION,
# ARISING OUT OF OR IN CONNECTION WITH THE USE
# OR PERFORMANCE OF THIS SOFTWARE.
#}
FROM arm64v8/node:carbon
ADD tools/docker/architecture/linux-arm64/local/qemu-aarch64-static /usr/bin/qemu-aarch64-static
MAINTAINER Philippe Coval (p.coval@samsung.com)
ENV DEBIAN_FRONTEND noninteractive
ENV LC_ALL en_US.UTF-8
ENV LANG ${LC_ALL}
RUN echo "#log: Configuring locales" \
&& set -x \
&& apt-get update -y \
&& apt-get install -y locales \
&& echo "${LC_ALL} UTF-8" | tee /etc/locale.gen \
&& locale-gen ${LC_ALL} \
&& dpkg-reconfigure locales \
&& sync
ENV project node-sqlite3
RUN echo "#log: ${project}: Setup system" \
&& set -x \
&& apt-get update -y \
&& apt-get install -y \
curl \
sudo \
build-essential \
python \
&& apt-get clean \
&& NVM_VERSION="v0.33.8" \
&& NODE_VERSION="--lts=carbon" \
&& curl -o- https://raw.githubusercontent.com/creationix/nvm/${NVM_VERSION}/install.sh | bash \
&& which nvm || . ~/.bashrc \
&& nvm install ${NODE_VERSION} \
&& nvm use ${NODE_VERSION} \
&& sync
ADD . /usr/local/opt/${project}/src/${project}
WORKDIR /usr/local/opt/${project}/src/${project}
RUN echo "#log: ${project}: Preparing sources" \
&& set -x \
&& which npm || . ~/.bashrc \
&& npm install || cat npm-debug.log \
&& npm install \
&& npm install --unsafe-perm --build-from-source \
&& sync
WORKDIR /usr/local/opt/${project}/src/${project}
RUN echo "#log: ${project}: Building sources" \
&& set -x \
&& which npm || . ~/.bashrc \
&& npm run pack \
&& npm pack \
&& find ${PWD}/build/stage/ -type f \
&& sync

View File

@@ -0,0 +1,53 @@
#!/bin/sh
# -*- coding: utf-8 -*-
# SPDX-License-Identifier: ISC
# Copyright 2019-present Samsung Electronics Co., Ltd. and other contributors
#{
# ISC License
# Copyright (c) 2004-2010 by Internet Systems Consortium, Inc. ("ISC")
# Copyright (c) 1995-2003 by Internet Software Consortium
# Permission to use, copy, modify, and /or distribute this software
# for any purpose with or without fee is hereby granted,
# provided that the above copyright notice
# and this permission notice appear in all copies.
# THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
# OF MERCHANTABILITY AND FITNESS.
# IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT,
# OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
# WHETHER IN AN ACTION OF CONTRACT,
# NEGLIGENCE OR OTHER TORTIOUS ACTION,
# ARISING OUT OF OR IN CONNECTION WITH THE USE
# OR PERFORMANCE OF THIS SOFTWARE.
#}
set -e
set -x
this_dir=$(dirname -- "$0")
this_dir=$(realpath "${this_dir}")
this_name=$(basename -- "$0")
top_dir="${this_dir}/../../.."
module_name="sqlite3"
project="node-${module_name}"
arch="aarch64" # AKA: arm64, arm64v8
architecture=$(basename "${this_dir}")
name="${project}-${architecture}"
dir="/usr/local/opt/${project}/"
dist_dir="${dir}/src/${project}/build"
tag=$(git describe --tags || echo v0.0.0)
version=$(echo "${tag}" | cut -dv -f2 | cut -d'-' -f1)
mkdir -p "${this_dir}/local" "${this_dir}/tmp"
cp -a "/usr/bin/qemu-${arch}-static" "${this_dir}/local"
time docker build -t "${name}" -f "${this_dir}/Dockerfile" .
container=$(docker create "${name}")
mkdir -p "${this_dir}/tmp/${dist_dir}"
rm -rf "${this_dir}/tmp/${dist_dir}"
docker cp "${container}:${dist_dir}" "${this_dir}/tmp/${dist_dir}"
file=$(ls "${this_dir}/tmp/${dist_dir}/stage/${module_name}/"*/*".tar.gz" | head -n1 \
|| echo "/tmp/${USER}/failure.tmp")
sha256sum "${file}"