@rocicorp/zero-sqlite3 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2017 Joshua Wise
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,92 @@
1
+ # better-sqlite3 [![Build Status](https://github.com/JoshuaWise/better-sqlite3/actions/workflows/build.yml/badge.svg)](https://github.com/JoshuaWise/better-sqlite3/actions/workflows/build.yml?query=branch%3Amaster)
2
+
3
+ The fastest and simplest library for SQLite3 in Node.js.
4
+
5
+ - Full transaction support
6
+ - High performance, efficiency, and safety
7
+ - Easy-to-use synchronous API *(better concurrency than an asynchronous API... yes, you read that correctly)*
8
+ - Support for user-defined functions, aggregates, virtual tables, and extensions
9
+ - 64-bit integers *(invisible until you need them)*
10
+ - Worker thread support *(for large/slow queries)*
11
+
12
+ ## Help this project stay strong! 💪
13
+
14
+ `better-sqlite3` is used by thousands of developers and engineers on a daily basis. Long nights and weekends were spent keeping this project strong and dependable, with no ask for compensation or funding, until now. If your company uses `better-sqlite3`, ask your manager to consider supporting the project:
15
+
16
+ - [Become a GitHub sponsor](https://github.com/sponsors/JoshuaWise)
17
+ - [Become a backer on Patreon](https://www.patreon.com/joshuawise)
18
+ - [Make a one-time donation on PayPal](https://www.paypal.me/joshuathomaswise)
19
+
20
+ ## How other libraries compare
21
+
22
+ | |select 1 row  `get()` |select 100 rows   `all()`  |select 100 rows `iterate()` 1-by-1|insert 1 row `run()`|insert 100 rows in a transaction|
23
+ |---|---|---|---|---|---|
24
+ |better-sqlite3|1x|1x|1x|1x|1x|
25
+ |[sqlite](https://www.npmjs.com/package/sqlite) and [sqlite3](https://www.npmjs.com/package/sqlite3)|11.7x slower|2.9x slower|24.4x slower|2.8x slower|15.6x slower|
26
+
27
+ > You can verify these results by [running the benchmark yourself](./docs/benchmark.md).
28
+
29
+ ## Installation
30
+
31
+ ```bash
32
+ npm install better-sqlite3
33
+ ```
34
+
35
+ > You must be using Node.js v14.21.1 or above. Prebuilt binaries are available for [LTS versions](https://nodejs.org/en/about/releases/). If you have trouble installing, check the [troubleshooting guide](./docs/troubleshooting.md).
36
+
37
+ ## Usage
38
+
39
+ ```js
40
+ const db = require('better-sqlite3')('foobar.db', options);
41
+
42
+ const row = db.prepare('SELECT * FROM users WHERE id = ?').get(userId);
43
+ console.log(row.firstName, row.lastName, row.email);
44
+ ```
45
+
46
+ Though not required, [it is generally important to set the WAL pragma for performance reasons](https://github.com/WiseLibs/better-sqlite3/blob/master/docs/performance.md).
47
+
48
+ ```js
49
+ db.pragma('journal_mode = WAL');
50
+ ```
51
+
52
+ ##### In ES6 module notation:
53
+
54
+ ```js
55
+ import Database from 'better-sqlite3';
56
+ const db = new Database('foobar.db', options);
57
+ db.pragma('journal_mode = WAL');
58
+ ```
59
+
60
+ ## Why should I use this instead of [node-sqlite3](https://github.com/mapbox/node-sqlite3)?
61
+
62
+ - `node-sqlite3` uses asynchronous APIs for tasks that are either CPU-bound or serialized. That's not only bad design, but it wastes tons of resources. It also causes [mutex thrashing](https://en.wikipedia.org/wiki/Resource_contention) which has devastating effects on performance.
63
+ - `node-sqlite3` exposes low-level (C language) memory management functions. `better-sqlite3` does it the JavaScript way, allowing the garbage collector to worry about memory management.
64
+ - `better-sqlite3` is simpler to use, and it provides nice utilities for some operations that are very difficult or impossible in `node-sqlite3`.
65
+ - `better-sqlite3` is much faster than `node-sqlite3` in most cases, and just as fast in all other cases.
66
+
67
+ #### When is this library not appropriate?
68
+
69
+ In most cases, if you're attempting something that cannot be reasonably accomplished with `better-sqlite3`, it probably cannot be reasonably accomplished with SQLite3 in general. For example, if you're executing queries that take one second to complete, and you expect to have many concurrent users executing those queries, no amount of asynchronicity will save you from SQLite3's serialized nature. Fortunately, SQLite3 is very *very* fast. With proper indexing, we've been able to achieve upward of 2000 queries per second with 5-way-joins in a 60 GB database, where each query was handling 5–50 kilobytes of real data.
70
+
71
+ If you have a performance problem, the most likely causes are inefficient queries, improper indexing, or a lack of [WAL mode](./docs/performance.md)—not `better-sqlite3` itself. However, there are some cases where `better-sqlite3` could be inappropriate:
72
+
73
+ - If you expect a high volume of concurrent reads each returning many megabytes of data (i.e., videos)
74
+ - If you expect a high volume of concurrent writes (i.e., a social media site)
75
+ - If your database's size is near the terabyte range
76
+
77
+ For these situations, you should probably use a full-fledged RDBMS such as [PostgreSQL](https://www.postgresql.org/).
78
+
79
+ # Documentation
80
+
81
+ - [API documentation](./docs/api.md)
82
+ - [Performance](./docs/performance.md) (also see [benchmark results](./docs/benchmark.md))
83
+ - [64-bit integer support](./docs/integer.md)
84
+ - [Worker thread support](./docs/threads.md)
85
+ - [Unsafe mode (advanced)](./docs/unsafe.md)
86
+ - [SQLite3 compilation (advanced)](./docs/compilation.md)
87
+ - [Contribution rules](./docs/contribution.md)
88
+ - [Code of conduct](./docs/conduct.md)
89
+
90
+ # License
91
+
92
+ [MIT](./LICENSE)
package/binding.gyp ADDED
@@ -0,0 +1,71 @@
1
+ # ===
2
+ # This is the main GYP file, which builds better-sqlite3 with SQLite3 itself.
3
+ # ===
4
+
5
+ {
6
+ 'includes': ['deps/common.gypi'],
7
+ 'targets': [
8
+ {
9
+ 'target_name': 'better_sqlite3',
10
+ 'dependencies': ['deps/sqlite3.gyp:sqlite3'],
11
+ 'sources': ['src/better_sqlite3.cpp'],
12
+ 'cflags_cc': ['-std=c++20'],
13
+ 'xcode_settings': {
14
+ 'OTHER_CPLUSPLUSFLAGS': ['-std=c++20', '-stdlib=libc++'],
15
+ },
16
+ 'msvs_settings': {
17
+ 'VCCLCompilerTool': {
18
+ 'AdditionalOptions': [
19
+ '/std:c++20',
20
+ ],
21
+ },
22
+ },
23
+ 'conditions': [
24
+ ['OS=="linux"', {
25
+ 'ldflags': [
26
+ '-Wl,-Bsymbolic',
27
+ '-Wl,--exclude-libs,ALL',
28
+ ],
29
+ }],
30
+ ],
31
+ },
32
+ {
33
+ 'target_name': 'shell',
34
+ 'type': 'executable',
35
+ 'dependencies': ['deps/sqlite3.gyp:locate_sqlite3'],
36
+ 'sources': ['<(SHARED_INTERMEDIATE_DIR)/sqlite3/sqlite3.c', '<(SHARED_INTERMEDIATE_DIR)/sqlite3/shell.c'],
37
+ 'include_dirs': ['<(SHARED_INTERMEDIATE_DIR)/sqlite3/'],
38
+ 'direct_dependent_settings': {
39
+ 'include_dirs': ['<(SHARED_INTERMEDIATE_DIR)/sqlite3/'],
40
+ },
41
+ 'cflags': ['-std=c99', '-w'],
42
+ 'xcode_settings': {
43
+ 'OTHER_CFLAGS': ['-std=c99'],
44
+ 'WARNING_CFLAGS': ['-w'],
45
+ },
46
+ 'conditions': [
47
+ ['sqlite3 == ""', {
48
+ 'includes': ['deps/defines.gypi'],
49
+ }, {
50
+ 'defines': [
51
+ # This is currently required by better-sqlite3.
52
+ 'SQLITE_ENABLE_COLUMN_METADATA',
53
+ ],
54
+ }]
55
+ ],
56
+ 'configurations': {
57
+ 'Debug': {
58
+ 'msvs_settings': { 'VCCLCompilerTool': { 'RuntimeLibrary': 1 } }, # static debug
59
+ },
60
+ 'Release': {
61
+ 'msvs_settings': { 'VCCLCompilerTool': { 'RuntimeLibrary': 0 } }, # static release
62
+ },
63
+ },
64
+ },
65
+ {
66
+ 'target_name': 'test_extension',
67
+ 'dependencies': ['deps/sqlite3.gyp:sqlite3'],
68
+ 'conditions': [['sqlite3 == ""', { 'sources': ['deps/test_extension.c'] }]],
69
+ },
70
+ ],
71
+ }
@@ -0,0 +1,68 @@
1
+ # ===
2
+ # This configuration defines the differences between Release and Debug builds.
3
+ # Some miscellaneous Windows settings are also defined here.
4
+ # ===
5
+
6
+ {
7
+ 'variables': { 'sqlite3%': '' },
8
+ 'target_defaults': {
9
+ 'default_configuration': 'Release',
10
+ 'msvs_settings': {
11
+ 'VCCLCompilerTool': {
12
+ 'ExceptionHandling': 1,
13
+ },
14
+ },
15
+ 'conditions': [
16
+ ['OS == "win"', {
17
+ 'defines': ['WIN32'],
18
+ }],
19
+ ],
20
+ 'configurations': {
21
+ 'Debug': {
22
+ 'defines!': [
23
+ 'NDEBUG',
24
+ ],
25
+ 'defines': [
26
+ 'DEBUG',
27
+ '_DEBUG',
28
+ 'SQLITE_DEBUG',
29
+ 'SQLITE_MEMDEBUG',
30
+ 'SQLITE_ENABLE_API_ARMOR',
31
+ 'SQLITE_WIN32_MALLOC_VALIDATE',
32
+ ],
33
+ 'cflags': [
34
+ '-O0',
35
+ ],
36
+ 'xcode_settings': {
37
+ 'MACOSX_DEPLOYMENT_TARGET': '10.7',
38
+ 'GCC_OPTIMIZATION_LEVEL': '0',
39
+ 'GCC_GENERATE_DEBUGGING_SYMBOLS': 'YES',
40
+ },
41
+ 'msvs_settings': {
42
+ 'VCLinkerTool': {
43
+ 'GenerateDebugInformation': 'true',
44
+ },
45
+ },
46
+ },
47
+ 'Release': {
48
+ 'defines!': [
49
+ 'DEBUG',
50
+ '_DEBUG',
51
+ ],
52
+ 'defines': [
53
+ 'NDEBUG',
54
+ ],
55
+ 'cflags': [
56
+ '-O3',
57
+ ],
58
+ 'xcode_settings': {
59
+ 'MACOSX_DEPLOYMENT_TARGET': '10.7',
60
+ 'GCC_OPTIMIZATION_LEVEL': '3',
61
+ 'GCC_GENERATE_DEBUGGING_SYMBOLS': 'NO',
62
+ 'DEAD_CODE_STRIPPING': 'YES',
63
+ 'GCC_INLINES_ARE_PRIVATE_EXTERN': 'YES',
64
+ },
65
+ },
66
+ },
67
+ },
68
+ }
package/deps/copy.js ADDED
@@ -0,0 +1,32 @@
1
+ 'use strict';
2
+ const path = require('path');
3
+ const fs = require('fs');
4
+
5
+ const dest = process.argv[2];
6
+ const source = path.resolve(path.sep, process.argv[3] || path.join(__dirname, 'sqlite3'));
7
+ const files = [
8
+ { filename: 'shell.c', optional: false },
9
+ { filename: 'sqlite3.c', optional: false },
10
+ { filename: 'sqlite3.h', optional: false },
11
+ ];
12
+
13
+ if (process.argv[3]) {
14
+ // Support "_HAVE_SQLITE_CONFIG_H" in custom builds.
15
+ files.push({ filename: 'config.h', optional: true });
16
+ } else {
17
+ // Required for some tests.
18
+ files.push({ filename: 'sqlite3ext.h', optional: false });
19
+ }
20
+
21
+ for (const { filename, optional } of files) {
22
+ const sourceFilepath = path.join(source, filename);
23
+ const destFilepath = path.join(dest, filename);
24
+
25
+ if (optional && !fs.existsSync(sourceFilepath)) {
26
+ continue;
27
+ }
28
+
29
+ fs.accessSync(sourceFilepath);
30
+ fs.mkdirSync(path.dirname(destFilepath), { recursive: true });
31
+ fs.copyFileSync(sourceFilepath, destFilepath);
32
+ }
@@ -0,0 +1,42 @@
1
+ # THIS FILE IS AUTOMATICALLY GENERATED BY deps/download.sh (DO NOT EDIT)
2
+
3
+ {
4
+ 'defines': [
5
+ 'HAVE_INT16_T=1',
6
+ 'HAVE_INT32_T=1',
7
+ 'HAVE_INT8_T=1',
8
+ 'HAVE_STDINT_H=1',
9
+ 'HAVE_UINT16_T=1',
10
+ 'HAVE_UINT32_T=1',
11
+ 'HAVE_UINT8_T=1',
12
+ 'HAVE_USLEEP=1',
13
+ 'SQLITE_DEFAULT_CACHE_SIZE=-16000',
14
+ 'SQLITE_DEFAULT_FOREIGN_KEYS=1',
15
+ 'SQLITE_DEFAULT_MEMSTATUS=0',
16
+ 'SQLITE_DEFAULT_WAL_SYNCHRONOUS=1',
17
+ 'SQLITE_DQS=0',
18
+ 'SQLITE_ENABLE_COLUMN_METADATA',
19
+ 'SQLITE_ENABLE_DBSTAT_VTAB',
20
+ 'SQLITE_ENABLE_DESERIALIZE',
21
+ 'SQLITE_ENABLE_FTS3',
22
+ 'SQLITE_ENABLE_FTS3_PARENTHESIS',
23
+ 'SQLITE_ENABLE_FTS4',
24
+ 'SQLITE_ENABLE_FTS5',
25
+ 'SQLITE_ENABLE_GEOPOLY',
26
+ 'SQLITE_ENABLE_JSON1',
27
+ 'SQLITE_ENABLE_MATH_FUNCTIONS',
28
+ 'SQLITE_ENABLE_RTREE',
29
+ 'SQLITE_ENABLE_STAT4',
30
+ 'SQLITE_ENABLE_UPDATE_DELETE_LIMIT',
31
+ 'SQLITE_LIKE_DOESNT_MATCH_BLOBS',
32
+ 'SQLITE_OMIT_DEPRECATED',
33
+ 'SQLITE_OMIT_PROGRESS_CALLBACK',
34
+ 'SQLITE_OMIT_SHARED_CACHE',
35
+ 'SQLITE_OMIT_TCL_VARIABLE',
36
+ 'SQLITE_SOUNDEX',
37
+ 'SQLITE_THREADSAFE=2',
38
+ 'SQLITE_TRACE_SIZE_LIMIT=32',
39
+ 'SQLITE_USE_URI=0',
40
+ 'SQLITE_OMIT_LOAD_EXTENSION',
41
+ ],
42
+ }
@@ -0,0 +1,122 @@
1
+ #!/usr/bin/env bash
2
+
3
+ # ===
4
+ # This script defines and generates the bundled SQLite3 unit (sqlite3.c).
5
+ #
6
+ # The following steps are taken:
7
+ # 1. populate the shell environment with the defined compile-time options.
8
+ # 2. download and extract the SQLite3 source code into a temporary directory.
9
+ # 3. run "sh configure" and "make sqlite3.c" within the source directory.
10
+ # 4. copy the generated amalgamation into the output directory (./sqlite3).
11
+ # 5. export the defined compile-time options to a gyp file (./defines.gypi).
12
+ # 6. update the docs (../docs/compilation.md) with details of this distribution.
13
+ #
14
+ # When a user builds better-sqlite3, the following steps are taken:
15
+ # 1. node-gyp loads the previously exported compile-time options (defines.gypi).
16
+ # 2. the copy.js script copies the bundled amalgamation into the build folder.
17
+ # 3. node-gyp compiles the copied sqlite3.c along with better_sqlite3.cpp.
18
+ # 4. node-gyp links the two resulting binaries to generate better_sqlite3.node.
19
+ # ===
20
+
21
+ CHECKIN="d2d954d4"
22
+
23
+ # Defines below are sorted alphabetically
24
+ DEFINES="
25
+ HAVE_INT16_T=1
26
+ HAVE_INT32_T=1
27
+ HAVE_INT8_T=1
28
+ HAVE_STDINT_H=1
29
+ HAVE_UINT16_T=1
30
+ HAVE_UINT32_T=1
31
+ HAVE_UINT8_T=1
32
+ HAVE_USLEEP=1
33
+ SQLITE_DEFAULT_CACHE_SIZE=-16000
34
+ SQLITE_DEFAULT_FOREIGN_KEYS=1
35
+ SQLITE_DEFAULT_MEMSTATUS=0
36
+ SQLITE_DEFAULT_WAL_SYNCHRONOUS=1
37
+ SQLITE_DQS=0
38
+ SQLITE_ENABLE_COLUMN_METADATA
39
+ SQLITE_ENABLE_DBSTAT_VTAB
40
+ SQLITE_ENABLE_DESERIALIZE
41
+ SQLITE_ENABLE_FTS3
42
+ SQLITE_ENABLE_FTS3_PARENTHESIS
43
+ SQLITE_ENABLE_FTS4
44
+ SQLITE_ENABLE_FTS5
45
+ SQLITE_ENABLE_GEOPOLY
46
+ SQLITE_ENABLE_JSON1
47
+ SQLITE_ENABLE_MATH_FUNCTIONS
48
+ SQLITE_ENABLE_RTREE
49
+ SQLITE_ENABLE_STAT4
50
+ SQLITE_ENABLE_UPDATE_DELETE_LIMIT
51
+ SQLITE_LIKE_DOESNT_MATCH_BLOBS
52
+ SQLITE_OMIT_DEPRECATED
53
+ SQLITE_OMIT_PROGRESS_CALLBACK
54
+ SQLITE_OMIT_SHARED_CACHE
55
+ SQLITE_OMIT_TCL_VARIABLE
56
+ SQLITE_SOUNDEX
57
+ SQLITE_THREADSAFE=2
58
+ SQLITE_TRACE_SIZE_LIMIT=32
59
+ SQLITE_USE_URI=0
60
+ SQLITE_OMIT_LOAD_EXTENSION
61
+ "
62
+
63
+ # ========== START SCRIPT ========== #
64
+
65
+ echo "setting up environment..."
66
+ DEPS="$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)"
67
+ TEMP="$DEPS/temp"
68
+ OUTPUT="$DEPS/sqlite3"
69
+ rm -rf "$TEMP"
70
+ rm -rf "$OUTPUT"
71
+ mkdir -p "$TEMP"
72
+ mkdir -p "$OUTPUT"
73
+ export CFLAGS=`echo $(echo "$DEFINES" | sed -e "/^\s*$/d" -e "s/^/-D/")`
74
+
75
+ echo "downloading source..."
76
+ curl -#f "https://sqlite.org/src/zip/$CHECKIN/SQLite-$CHECKIN.zip" > "$TEMP/source.zip" || exit 1
77
+
78
+ echo "extracting source..."
79
+ unzip "$TEMP/source.zip" -d "$TEMP" > /dev/null || exit 1
80
+ cd "$TEMP/SQLite-$CHECKIN" || exit 1
81
+
82
+ echo "configuring amalgamation..."
83
+ sh configure > /dev/null || exit 1
84
+
85
+ echo "building amalgamation..."
86
+ make sqlite3.c > /dev/null || exit 1
87
+
88
+ echo "copying amalgamation..."
89
+ cp sqlite3.c sqlite3.h sqlite3ext.h shell.c "$OUTPUT/" || exit 1
90
+
91
+ echo "applying patches..."
92
+ cd "$DEPS" || exit 1
93
+ for patch in patches/*.patch; do
94
+ # If a patch fails, just skip it an move on.
95
+ # By default `patch` tries to be clever and reverse the patch, so we have to specify `--forward`.
96
+ # If the patch fails, we # don't write .orig and .rej files, so we have to specify `--no-backup-if-mismatch` and `--reject-file=-`.
97
+ patch --batch --forward --no-backup-if-mismatch --reject-file=- -p2 < "$patch"
98
+ done
99
+
100
+ echo "updating gyp configs..."
101
+ GYP="$DEPS/defines.gypi"
102
+ printf "# THIS FILE IS AUTOMATICALLY GENERATED BY deps/download.sh (DO NOT EDIT)\n\n{\n 'defines': [\n" > "$GYP"
103
+ printf "$DEFINES" | sed -e "/^\s*$/d" -e "s/\(.*\)/ '\1',/" >> "$GYP"
104
+ printf " ],\n}\n" >> "$GYP"
105
+
106
+ echo "updating docs..."
107
+ DOCS="$DEPS/../docs/compilation.md"
108
+ MAJOR=`expr "${VERSION:0:1}" + 0`
109
+ MINOR=`expr "${VERSION:1:2}" + 0`
110
+ PATCH=`expr "${VERSION:3:2}" + 0`
111
+ sed -Ei.bak -e "s/version [0-9]+\.[0-9]+\.[0-9]+/version $MAJOR.$MINOR.$PATCH/g" "$DOCS"
112
+ sed -i.bak -e "/^SQLITE_/,\$d" "$DOCS"
113
+ sed -i.bak -e "/^HAVE_/,\$d" "$DOCS"
114
+ rm "$DOCS".bak
115
+ printf "$DEFINES" | sed -e "/^\s*$/d" >> "$DOCS"
116
+ printf "\`\`\`\n" >> "$DOCS"
117
+
118
+ echo "cleaning up..."
119
+ cd - > /dev/null || exit 1
120
+ rm -rf "$TEMP"
121
+
122
+ echo "done!"
@@ -0,0 +1,15 @@
1
+ diff --git a/deps/sqlite3/sqlite3.c b/deps/sqlite3/sqlite3.c
2
+ index b1a807f..38bd1e6 100644
3
+ --- a/deps/sqlite3/sqlite3.c
4
+ +++ b/deps/sqlite3/sqlite3.c
5
+ @@ -24887,8 +24887,8 @@ static const struct {
6
+ /* 1 */ { 6, "minute", 7.7379e+12, 60.0 },
7
+ /* 2 */ { 4, "hour", 1.2897e+11, 3600.0 },
8
+ /* 3 */ { 3, "day", 5373485.0, 86400.0 },
9
+ - /* 4 */ { 5, "month", 176546.0, 30.0*86400.0 },
10
+ - /* 5 */ { 4, "year", 14713.0, 365.0*86400.0 },
11
+ + /* 4 */ { 5, "month", 176546.0, 2592000.0 },
12
+ + /* 5 */ { 4, "year", 14713.0, 31536000.0 },
13
+ };
14
+
15
+ /*