From d587886f49fa42da7eea0d31d2ddb9dc54559937 Mon Sep 17 00:00:00 2001 From: Shautvast Date: Wed, 28 Aug 2024 14:58:52 +0200 Subject: [PATCH] import from gitlab --- .gitignore | 8 + LICENSE | 201 ++ README.md | 89 + ci_settings.xml | 16 + demo/api/README.md | 6 + demo/api/pom.xml | 76 + .../sqlighter/demo/DemoApplication.java | 13 + .../sqlighter/demo/model/Customer.java | 13 + .../demo/repository/CustomerRepository.java | 38 + .../demo/repository/RandomStuffGenerator.java | 54 + .../sqlighter/demo/rest/DemoRestApi.java | 27 + .../src/main/resources/application.properties | 7 + demo/start_api.sh | 3 + demo/start_ui.sh | 7 + demo/ui/.cert/cert.pem | 26 + demo/ui/.cert/key.pem | 28 + demo/ui/index.html | 23 + demo/ui/package-lock.json | 2360 +++++++++++++++++ demo/ui/package.json | 20 + demo/ui/pnpm-lock.yaml | 390 +++ demo/ui/src/app.js | 206 ++ demo/ui/src/database.js | 44 + demo/ui/src/item.js | 39 + demo/ui/src/result-count.js | 28 + demo/ui/src/sort.svg | 15 + demo/ui/src/styles.css | 38 + demo/ui/src/user-filter.js | 56 + demo/ui/src/virtual-scroll.js | 86 + demo/ui/vite.config.js | 27 + fileviewer/pom.xml | 46 + .../sqlighter/fileviewer/Main.java | 61 + .../sqlighter/fileviewer/RecordReader.java | 42 + .../sqlighter/fileviewer/SchemaReader.java | 52 + .../sqlighter/fileviewer/data/BlobValue.java | 35 + .../sqlighter/fileviewer/data/FloatValue.java | 31 + .../fileviewer/data/IntegerValue.java | 47 + .../fileviewer/data/ReadOnlyRecord.java | 76 + .../fileviewer/data/ReadOnlyValue.java | 98 + .../fileviewer/data/StringValue.java | 40 + .../sqlighter/fileviewer/model/Cell.java | 4 + .../sqlighter/fileviewer/model/Index.java | 19 + .../sqlighter/fileviewer/model/IndexCell.java | 23 + .../fileviewer/model/InteriorCell.java | 16 + .../sqlighter/fileviewer/model/LeafCell.java | 4 + .../fileviewer/model/Metadatabase.java | 93 + .../sqlighter/fileviewer/model/PageNode.java | 41 + .../sqlighter/fileviewer/model/Table.java | 26 + .../page/IndexInteriorPageReader.java | 16 + .../fileviewer/page/IndexLeafPageReader.java | 71 + .../sqlighter/fileviewer/page/PageReader.java | 30 + .../fileviewer/page/RootpageReader.java | 48 + .../page/TableInteriorPageReader.java | 54 + .../fileviewer/page/TableLeafPageReader.java | 44 + .../sqlighter/fileviewer/util/Encoding.java | 33 + .../sqlighter/fileviewer/util/HasCode.java | 15 + .../sqlighter/fileviewer/util/Printer.java | 22 + .../fileviewer/util/UnsignedIntReader.java | 22 + .../fileviewer/validation/Array.java | 38 + .../validation/ValidationException.java | 8 + .../fileviewer/validation/Validator.java | 16 + .../util/GetEncodingFromCodeTest.java | 15 + notes.md | 8 + pom.xml | 50 + screenshot.png | Bin 0 -> 321603 bytes sqlighter/pom.xml | 60 + .../nl/sanderhautvast/sqlighter/Database.java | 193 ++ .../sqlighter/DatabaseBuilder.java | 78 + .../sqlighter/SQLiteConstants.java | 38 + .../sqlighter/SchemaRecord.java | 47 + .../nl/sanderhautvast/sqlighter/Varint.java | 156 ++ .../sqlighter/data/LtRecord.java | 104 + .../sqlighter/data/LtValue.java | 127 + .../sqlighter/jdbc/ResulSet2SQLite.java | 49 + .../sqlighter/jdbc/ValueMapper.java | 62 + .../sanderhautvast/sqlighter/page/Page.java | 150 ++ .../sqlighter/page/PageCache.java | 43 + .../sqlighter/page/PageCacheFactory.java | 19 + .../sqlighter/page/PageType.java | 9 + .../sanderhautvast/sqlighter/ControlTest.java | 54 + .../sqlighter/LeafDbPageTest.java | 51 + .../sqlighter/LtRecordTest.java | 66 + .../sqlighter/SchemaCreationTests.java | 81 + .../sqlighter/SerialTypesTests.java | 65 + .../sqlighter/ToBytesTests.java | 69 + .../sanderhautvast/sqlighter/VarintTests.java | 70 + .../sqlighter/data/BlobValueTest.java | 15 + .../sqlighter/data/FloatValueTest.java | 19 + .../sqlighter/data/IntegerValueTest.java | 38 + .../sqlighter/data/StringValueTest.java | 17 + .../sqlighter/jdbc/ResulSet2SQLiteTest.java | 94 + 90 files changed, 6962 insertions(+) create mode 100644 .gitignore create mode 100644 LICENSE create mode 100644 README.md create mode 100644 ci_settings.xml create mode 100644 demo/api/README.md create mode 100644 demo/api/pom.xml create mode 100644 demo/api/src/main/java/nl/sanderhautvast/sqlighter/demo/DemoApplication.java create mode 100644 demo/api/src/main/java/nl/sanderhautvast/sqlighter/demo/model/Customer.java create mode 100644 demo/api/src/main/java/nl/sanderhautvast/sqlighter/demo/repository/CustomerRepository.java create mode 100644 demo/api/src/main/java/nl/sanderhautvast/sqlighter/demo/repository/RandomStuffGenerator.java create mode 100644 demo/api/src/main/java/nl/sanderhautvast/sqlighter/demo/rest/DemoRestApi.java create mode 100644 demo/api/src/main/resources/application.properties create mode 100644 demo/start_api.sh create mode 100644 demo/start_ui.sh create mode 100644 demo/ui/.cert/cert.pem create mode 100644 demo/ui/.cert/key.pem create mode 100644 demo/ui/index.html create mode 100644 demo/ui/package-lock.json create mode 100644 demo/ui/package.json create mode 100644 demo/ui/pnpm-lock.yaml create mode 100644 demo/ui/src/app.js create mode 100644 demo/ui/src/database.js create mode 100644 demo/ui/src/item.js create mode 100644 demo/ui/src/result-count.js create mode 100644 demo/ui/src/sort.svg create mode 100644 demo/ui/src/styles.css create mode 100644 demo/ui/src/user-filter.js create mode 100644 demo/ui/src/virtual-scroll.js create mode 100644 demo/ui/vite.config.js create mode 100644 fileviewer/pom.xml create mode 100644 fileviewer/src/main/java/nl/sanderhautvast/sqlighter/fileviewer/Main.java create mode 100644 fileviewer/src/main/java/nl/sanderhautvast/sqlighter/fileviewer/RecordReader.java create mode 100644 fileviewer/src/main/java/nl/sanderhautvast/sqlighter/fileviewer/SchemaReader.java create mode 100644 fileviewer/src/main/java/nl/sanderhautvast/sqlighter/fileviewer/data/BlobValue.java create mode 100644 fileviewer/src/main/java/nl/sanderhautvast/sqlighter/fileviewer/data/FloatValue.java create mode 100644 fileviewer/src/main/java/nl/sanderhautvast/sqlighter/fileviewer/data/IntegerValue.java create mode 100644 fileviewer/src/main/java/nl/sanderhautvast/sqlighter/fileviewer/data/ReadOnlyRecord.java create mode 100644 fileviewer/src/main/java/nl/sanderhautvast/sqlighter/fileviewer/data/ReadOnlyValue.java create mode 100644 fileviewer/src/main/java/nl/sanderhautvast/sqlighter/fileviewer/data/StringValue.java create mode 100644 fileviewer/src/main/java/nl/sanderhautvast/sqlighter/fileviewer/model/Cell.java create mode 100644 fileviewer/src/main/java/nl/sanderhautvast/sqlighter/fileviewer/model/Index.java create mode 100644 fileviewer/src/main/java/nl/sanderhautvast/sqlighter/fileviewer/model/IndexCell.java create mode 100644 fileviewer/src/main/java/nl/sanderhautvast/sqlighter/fileviewer/model/InteriorCell.java create mode 100644 fileviewer/src/main/java/nl/sanderhautvast/sqlighter/fileviewer/model/LeafCell.java create mode 100644 fileviewer/src/main/java/nl/sanderhautvast/sqlighter/fileviewer/model/Metadatabase.java create mode 100644 fileviewer/src/main/java/nl/sanderhautvast/sqlighter/fileviewer/model/PageNode.java create mode 100644 fileviewer/src/main/java/nl/sanderhautvast/sqlighter/fileviewer/model/Table.java create mode 100644 fileviewer/src/main/java/nl/sanderhautvast/sqlighter/fileviewer/page/IndexInteriorPageReader.java create mode 100644 fileviewer/src/main/java/nl/sanderhautvast/sqlighter/fileviewer/page/IndexLeafPageReader.java create mode 100644 fileviewer/src/main/java/nl/sanderhautvast/sqlighter/fileviewer/page/PageReader.java create mode 100644 fileviewer/src/main/java/nl/sanderhautvast/sqlighter/fileviewer/page/RootpageReader.java create mode 100644 fileviewer/src/main/java/nl/sanderhautvast/sqlighter/fileviewer/page/TableInteriorPageReader.java create mode 100644 fileviewer/src/main/java/nl/sanderhautvast/sqlighter/fileviewer/page/TableLeafPageReader.java create mode 100644 fileviewer/src/main/java/nl/sanderhautvast/sqlighter/fileviewer/util/Encoding.java create mode 100644 fileviewer/src/main/java/nl/sanderhautvast/sqlighter/fileviewer/util/HasCode.java create mode 100644 fileviewer/src/main/java/nl/sanderhautvast/sqlighter/fileviewer/util/Printer.java create mode 100644 fileviewer/src/main/java/nl/sanderhautvast/sqlighter/fileviewer/util/UnsignedIntReader.java create mode 100644 fileviewer/src/main/java/nl/sanderhautvast/sqlighter/fileviewer/validation/Array.java create mode 100644 fileviewer/src/main/java/nl/sanderhautvast/sqlighter/fileviewer/validation/ValidationException.java create mode 100644 fileviewer/src/main/java/nl/sanderhautvast/sqlighter/fileviewer/validation/Validator.java create mode 100644 fileviewer/src/test/java/nl/sanderhautvast/sqlighter/fileviewer/util/GetEncodingFromCodeTest.java create mode 100644 notes.md create mode 100644 pom.xml create mode 100644 screenshot.png create mode 100644 sqlighter/pom.xml create mode 100644 sqlighter/src/main/java/nl/sanderhautvast/sqlighter/Database.java create mode 100644 sqlighter/src/main/java/nl/sanderhautvast/sqlighter/DatabaseBuilder.java create mode 100644 sqlighter/src/main/java/nl/sanderhautvast/sqlighter/SQLiteConstants.java create mode 100644 sqlighter/src/main/java/nl/sanderhautvast/sqlighter/SchemaRecord.java create mode 100644 sqlighter/src/main/java/nl/sanderhautvast/sqlighter/Varint.java create mode 100644 sqlighter/src/main/java/nl/sanderhautvast/sqlighter/data/LtRecord.java create mode 100644 sqlighter/src/main/java/nl/sanderhautvast/sqlighter/data/LtValue.java create mode 100644 sqlighter/src/main/java/nl/sanderhautvast/sqlighter/jdbc/ResulSet2SQLite.java create mode 100644 sqlighter/src/main/java/nl/sanderhautvast/sqlighter/jdbc/ValueMapper.java create mode 100644 sqlighter/src/main/java/nl/sanderhautvast/sqlighter/page/Page.java create mode 100644 sqlighter/src/main/java/nl/sanderhautvast/sqlighter/page/PageCache.java create mode 100644 sqlighter/src/main/java/nl/sanderhautvast/sqlighter/page/PageCacheFactory.java create mode 100644 sqlighter/src/main/java/nl/sanderhautvast/sqlighter/page/PageType.java create mode 100644 sqlighter/src/test/java/nl/sanderhautvast/sqlighter/ControlTest.java create mode 100644 sqlighter/src/test/java/nl/sanderhautvast/sqlighter/LeafDbPageTest.java create mode 100644 sqlighter/src/test/java/nl/sanderhautvast/sqlighter/LtRecordTest.java create mode 100644 sqlighter/src/test/java/nl/sanderhautvast/sqlighter/SchemaCreationTests.java create mode 100644 sqlighter/src/test/java/nl/sanderhautvast/sqlighter/SerialTypesTests.java create mode 100644 sqlighter/src/test/java/nl/sanderhautvast/sqlighter/ToBytesTests.java create mode 100644 sqlighter/src/test/java/nl/sanderhautvast/sqlighter/VarintTests.java create mode 100644 sqlighter/src/test/java/nl/sanderhautvast/sqlighter/data/BlobValueTest.java create mode 100644 sqlighter/src/test/java/nl/sanderhautvast/sqlighter/data/FloatValueTest.java create mode 100644 sqlighter/src/test/java/nl/sanderhautvast/sqlighter/data/IntegerValueTest.java create mode 100644 sqlighter/src/test/java/nl/sanderhautvast/sqlighter/data/StringValueTest.java create mode 100644 sqlighter/src/test/java/nl/sanderhautvast/sqlighter/jdbc/ResulSet2SQLiteTest.java diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..fe55fa4 --- /dev/null +++ b/.gitignore @@ -0,0 +1,8 @@ +*.iml +*.db +*.sqlite +.idea/ +target/ +node_modules/ +dist/ +.cache/ \ No newline at end of file diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..261eeb9 --- /dev/null +++ b/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/README.md b/README.md new file mode 100644 index 0000000..ebb06b2 --- /dev/null +++ b/README.md @@ -0,0 +1,89 @@ +**Sqlighter** +* Inspired by a new feature in .Net blazor (see https://www.youtube.com/watch?v=lP_qdhAHFlg&t=300s) +* Creates a SQLite database file from any JDBC database or other tabular data +* So instead of a rest api serving json, enables binary download of data in native SQLite format +* So that SQLite in running in WASM (so in the browser) can be used to query the data. + +**Why not use the sqlite code serverside for this purpose?** + +*excellent question!* + +But: +1. I would have to first create and SQLite database and fill it with results and then load the database file and serve it for http requests. While this should also work, it sounds as more overhead. In Sqlighter the data stays in memory. (yes, that's a problem if the data gets reallly BIG; considering offload to file) +2. Learning this shit is fun! + * getting to know the fileformat. Most is nicely documented on https://sqlite.org (indeed, not everything) + * variable length integer encoding + * the nifty way strings and blobs are stored + * I finally got my head around java nio (even though in the end I switched from ByteBuffer to plain byte arrays) + * debugging this app lead me to debugging SQLite itself in xcode (really easy to set up btw). So I learnt a bit about that. + +**Usable when:** +* you have quite a lot of (tabular) data, that is read-only, or does not need to be (ultra) realtime. +* and your users need to quickly apply different search criteria on it. +* Using Sqlighter avoids server roundtrips and improves the user experience. +* There is a utility to transfer a regular JDBC ResultSet to SQLite format, but using the API you could put any tabular data in. +* Bear in mind that, while you, as a developer, cannot directly read the payload, like JSON allows, SQLite is available on pretty much any platform, +and then you can leverage the power of SQL to inspect the data. + +* other use case: you need to create an sqlite database from a file (like a CSV) in a java app. Sqlighter is much faster than jdbc+sqlite. There are no transactions, and no checks, so use at your own peril. +* Thing to note: Sqlite is really relaxed when it comes to schema validation. +That means that 2 records in the same table can contain values of totally different types(!). The number of values can also vary. All perfectly legal from the standpoint of Sqlighter. +And maybe not when writing to Sqlite itself, but perfectly readable! + +**About the name** +* It lights up an SQLite database :) + +**Usage** +Creating a database is as simple as: +```java +DatabaseBuilder databaseBuilder = new DatabaseBuilder(); +databaseBuilder.addSchema("foo", + "CREATE TABLE foo(bar integer,baz varchar(10))"); + +Record record = new Record(Value.of(12), Value.of("helloworld")); +databaseBuilder.addRecord(record); + +databaseBuilder.build().write("test.db"); +``` +* Instead of writing to file, you can also write to any `OutputStream` + * testing with (direct) bytebuffers did not yield performance improvements for http requests (for http 1 and 2, tomcat and undertow). + +**Be aware** +* The schema and the actual data don't have to match! But that is how SQLite itself also works, pretty much. +* And: 2 records in the same table can contain values of totally different types(!). The number of values can also vary. All perfectly legal from the standpoint of Sqlighter. + And maybe not when writing to Sqlite itself, but perfectly readable! + * unittest SchemaCreationTests is proof of this. + + +**Current status** +* It works for tables of any size, but probably not for indexes (may skip that feature) because you can always add them client-side(!) + +**Performance** +* Serverside the time that it costs is on par with [jackson](https://github.com/FasterXML/jackson): + * that is: ~400 ms for a 9.3 Mb database (100,000 records, on my Mac m1, using jdk19/arm64) + * versus ~430 ms using jackson (2.13.4) with the same data (payload size ~15.7Mb) + * So it's even better, BUT in jdk11 (with rosetta) the numbers were roughly the other way around, so performing worse than jackson... +* The response payload size is roughly 60% of the JSON. (mileage may vary, depending on the content) +* It is comparing apples and pears though, because clientside it's way faster (and different). +* And, it's most probably not a good idea to use the format for smaller payloads. + * I don't know currently where the cutoff point is. + +**DEMO** + +![screenshot](screenshot.png "Demo screenshot") +* Uses spring boot, but that is not a prerequisite for sqlighter itself. +* see `start_api.sh` and `start_ui.sh` +* api on http://localhost:8080 +* json on http://localhost:8080/api/customers (should provide a second ui that uses traditional json, for comparison) +* sqlite on http://localhost:8080/api/db/customers + * TODO should rely on content-type negotiation + +_Frontend_ +* Now uses LIT, a web worker and OPFS and upraded to the official SQLite/WASM instead of SQL.js +* OPFS also requires https and extra headers (see vite.config.js). +* So far it works in Chrome and Firefox (as of V111 (I think, I only tested in 114)). Safari should but does not work (yet). +* it has some issues still, but it supports scrolling and filtering the complete dataset. + +**Future plans?** +* There is now also a [rust](https://gitlab.com/sander-hautvast/sqlighte.rs) version... +* and what about a javascript library that parses the format, so that you can render the data without sql? This could be a solution for medium sized payloads (and up) and when you just want to show the data without using the power of sql. It would be smaller than json, at least as performant and still accessible for humans with sqlite3. diff --git a/ci_settings.xml b/ci_settings.xml new file mode 100644 index 0000000..57951e9 --- /dev/null +++ b/ci_settings.xml @@ -0,0 +1,16 @@ + + + + gitlab-maven + + + + Job-Token + ${CI_JOB_TOKEN} + + + + + + diff --git a/demo/api/README.md b/demo/api/README.md new file mode 100644 index 0000000..3a6bbe5 --- /dev/null +++ b/demo/api/README.md @@ -0,0 +1,6 @@ +**Run the Demo** + +NB. This demo requires docker + +* run script postgresdocker.sh +* \ No newline at end of file diff --git a/demo/api/pom.xml b/demo/api/pom.xml new file mode 100644 index 0000000..6b6f505 --- /dev/null +++ b/demo/api/pom.xml @@ -0,0 +1,76 @@ + + + + demo + nl.sanderhautvast + 1.1 + + 4.0.0 + + + 11 + 11 + UTF-8 + + + + + org.springframework.boot + spring-boot-starter-web + 2.7.5 + + + + org.projectlombok + lombok + 1.18.24 + + + nl.sanderhautvast + sqlighter + 1.1.1 + + + + org.springframework.boot + spring-boot-starter-test + 2.7.5 + test + + + + + + org.springframework.boot + spring-boot-maven-plugin + 2.7.10 + + nl.sanderhautvast.sqlighter.demo.DemoApplication + + + + + + + spring-milestones + Spring Milestones + https://repo.spring.io/milestone + + false + + + + + + spring-milestones + Spring Milestones + https://repo.spring.io/milestone + + false + + + + + \ No newline at end of file diff --git a/demo/api/src/main/java/nl/sanderhautvast/sqlighter/demo/DemoApplication.java b/demo/api/src/main/java/nl/sanderhautvast/sqlighter/demo/DemoApplication.java new file mode 100644 index 0000000..96d87d1 --- /dev/null +++ b/demo/api/src/main/java/nl/sanderhautvast/sqlighter/demo/DemoApplication.java @@ -0,0 +1,13 @@ +package nl.sanderhautvast.sqlighter.demo; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class DemoApplication { + + public static void main(String[] args) { + SpringApplication.run(DemoApplication.class, args); + } + +} diff --git a/demo/api/src/main/java/nl/sanderhautvast/sqlighter/demo/model/Customer.java b/demo/api/src/main/java/nl/sanderhautvast/sqlighter/demo/model/Customer.java new file mode 100644 index 0000000..e0efb7b --- /dev/null +++ b/demo/api/src/main/java/nl/sanderhautvast/sqlighter/demo/model/Customer.java @@ -0,0 +1,13 @@ +package nl.sanderhautvast.sqlighter.demo.model; + +import lombok.*; + +@Data +public class Customer { + String name; + String email; + String streetname; + int housenumber; + String city; + String country; +} diff --git a/demo/api/src/main/java/nl/sanderhautvast/sqlighter/demo/repository/CustomerRepository.java b/demo/api/src/main/java/nl/sanderhautvast/sqlighter/demo/repository/CustomerRepository.java new file mode 100644 index 0000000..01f9c6e --- /dev/null +++ b/demo/api/src/main/java/nl/sanderhautvast/sqlighter/demo/repository/CustomerRepository.java @@ -0,0 +1,38 @@ +package nl.sanderhautvast.sqlighter.demo.repository; + + +import nl.sanderhautvast.sqlighter.Database; +import nl.sanderhautvast.sqlighter.DatabaseBuilder; +import nl.sanderhautvast.sqlighter.data.LtRecord; +import nl.sanderhautvast.sqlighter.data.LtValue; +import org.springframework.stereotype.Repository; + +@Repository +public class CustomerRepository { + + public Database getAllCustomersAsSQLite() { + DatabaseBuilder databaseBuilder = new DatabaseBuilder(); + databaseBuilder.addSchema("customers", + "create table customers (name varchar(100), email varchar(100), streetname varchar(100), housenumber integer, city varchar(100), country varchar(100))"); + + final RandomStuffGenerator generator = new RandomStuffGenerator(); + long rowid = 1; + + for (int i = 0; i < 100_000; i++) { + LtRecord record = new LtRecord(rowid++); + record.addValues(); + + String firstName = generator.generateFirstName(); + String lastName = generator.generateLastName(); + record.addValues(LtValue.of(firstName + " " + lastName), + LtValue.of(firstName + "." + lastName + "@icemail.com"), + LtValue.of(generator.generateStreetName()), + LtValue.of(generator.generateSomeNumber()), + LtValue.of(generator.generateSomeCityInIceland()), + LtValue.of(generator.generateIceland())); + + databaseBuilder.addRecord(record); + } + return databaseBuilder.build(); + } +} diff --git a/demo/api/src/main/java/nl/sanderhautvast/sqlighter/demo/repository/RandomStuffGenerator.java b/demo/api/src/main/java/nl/sanderhautvast/sqlighter/demo/repository/RandomStuffGenerator.java new file mode 100644 index 0000000..cc0796d --- /dev/null +++ b/demo/api/src/main/java/nl/sanderhautvast/sqlighter/demo/repository/RandomStuffGenerator.java @@ -0,0 +1,54 @@ +package nl.sanderhautvast.sqlighter.demo.repository; + +import java.util.List; +import java.util.Random; + +public class RandomStuffGenerator { + + private final List firstNameParts = List.of("sa", "ka", "zo", "ja", "za", "ka", "po", "ji", "ne", "si", "wi", "ha", "ut", "va", "no", "bo" + , "jo", "fe", "gu"); + + private final List lastNameParts = List.of("fin", "wil", "cat", "loc", "der", "ter", "asp", "pen", "ill", "raf", "gut", "dax", "yin"); + private final List cities = List.of("Reykjavík", "Kópavogur", "Hafnarfjörður", "Akureyri", "Reykjanesbær", "Garðabær", "Mosfellsbær", "Selfoss", "Akranes", "Seltjarnarnes", "Vestmannaeyjar", "Grindavík", "Ísafjörður", "Álftanes", "Sauðárkrókur", "Hveragerði", "Egilsstaðir", "Húsavík", "Borgarnes", "Sandgerði", "Höfn", "Þorlákshöfn", "Garður", "Neskaupstaður", "Dalvík", "Reyðarfjörður", "Siglufjörður", "Vogar", "Stykkishólmur", "Eskifjörður", "Ólafsvík", "Hvolsvöllur", "Bolungarvík", "Hella", "Grundarfjörður", "Blönduós", "Ólafsfjörður", "Fáskrúðsfjörður", "Patreksfjörður", "Seyðisfjörður", "Grundarhverfi", "Hvammstangi", "Stokkseyri", "Eyrarbakki", "Vopnafjörður", "Skagaströnd", "Flúðir", "Vík", "Fellabær", "Hellissandur", "Djúpivogur", "Þórshöfn", "Svalbarðseyri", "Hólmavík", "Grenivík", "Hvanneyri", "Þingeyri", "Búðardalur", "Reykholt", "Hrafnagil", "Suðureyri", "Tálknafjörður", "Bíldudalur", "Mosfellsdalur", "Hnífsdalur", "Reykjahlíð", "Laugarvatn", "Raufarhöfn", "Stöðvarfjörður", "Bifröst", "Flateyri", "Kirkjubæjarklaustur", "Súðavík", "Hrísey", "Hofsós", "Breiðdalsvík", "Rif", "Reykhólar", "Varmahlíð", "Kópasker", "Laugarás", "Borg", "Hauganes", "Hafnir", "Laugar", "Melahverfi", "Tjarnabyggð", "Árskógssandur", "Lónsbakki", "Hólar", "Nesjahverfi", "Sólheimar", "Brúnahlíð", "Drangsnes", "Borgarfjörður eystri", "Árbæjarhverfi", "Brautarholt", "Rauðalækur", "Bakkafjörður", "Innnes", "Grímsey", "Þykkvabær", "Laugarbakki", "Reykholt", "Árnes", "Kristnes", "Kleppjárnsreykir"); + private final Random random = new Random(); + + public String generateFirstName() { + return generateName(firstNameParts); + } + + public String generateLastName() { + return generateName(lastNameParts); + } + + public String generateStreetName() { + StringBuilder name = new StringBuilder(); + int nLastNameParts = random.nextInt(5) + 1; + for (int i = 0; i < nLastNameParts; i++) { + name.append(firstNameParts.get(random.nextInt(firstNameParts.size()))); + name.append(lastNameParts.get(random.nextInt(lastNameParts.size()))); + } + name.append("götu"); + return name.toString(); + } + + public int generateSomeNumber() { + return random.nextInt(1000); + } + + public String generateSomeCityInIceland() { + return cities.get(random.nextInt(cities.size())); + } + + public String generateIceland() { + return "Iceland"; // meant to be humorous + } + + private String generateName(List parts) { + StringBuilder name = new StringBuilder(); + int size = random.nextInt(2) + 2; + for (int i = 0; i < size; i++) { + name.append(parts.get(random.nextInt(parts.size()))); + } + return name.toString(); + } +} diff --git a/demo/api/src/main/java/nl/sanderhautvast/sqlighter/demo/rest/DemoRestApi.java b/demo/api/src/main/java/nl/sanderhautvast/sqlighter/demo/rest/DemoRestApi.java new file mode 100644 index 0000000..2917472 --- /dev/null +++ b/demo/api/src/main/java/nl/sanderhautvast/sqlighter/demo/rest/DemoRestApi.java @@ -0,0 +1,27 @@ +package nl.sanderhautvast.sqlighter.demo.rest; + +import nl.sanderhautvast.sqlighter.Database; +import nl.sanderhautvast.sqlighter.demo.repository.CustomerRepository; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RestController; + +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; + +@RestController +public class DemoRestApi { + + private final CustomerRepository customerRepository; + + @Autowired + public DemoRestApi(CustomerRepository customerRepository) { + this.customerRepository = customerRepository; + } + + @GetMapping(value = "/api/db/customers", produces = "application/octet-stream") + public void getDataAsSqliteFile(HttpServletResponse response) throws IOException { + Database customers = customerRepository.getAllCustomersAsSQLite(); + customers.write(response.getOutputStream()); + } +} diff --git a/demo/api/src/main/resources/application.properties b/demo/api/src/main/resources/application.properties new file mode 100644 index 0000000..d569a80 --- /dev/null +++ b/demo/api/src/main/resources/application.properties @@ -0,0 +1,7 @@ +# compression and http2 +server.compression.enabled=true +server.compression.mime-types=application/octet-stream +server.compression.min-response-size=1024 +#server.http2.enabled=true +# try it with, for instance: +# curl http://localhost:8080/api/db/customers --output customers --compressed -v --http2 \ No newline at end of file diff --git a/demo/start_api.sh b/demo/start_api.sh new file mode 100644 index 0000000..32dd893 --- /dev/null +++ b/demo/start_api.sh @@ -0,0 +1,3 @@ +mvn -f api/pom.xml -DskipTests clean spring-boot:run + + diff --git a/demo/start_ui.sh b/demo/start_ui.sh new file mode 100644 index 0000000..9443282 --- /dev/null +++ b/demo/start_ui.sh @@ -0,0 +1,7 @@ +cd ui +npm run dev + +# https://localhost:5173/ +# NB. this demo does not run in firefox or safari, because it does not support OPFS yet! + +# NB2. TLS is enabled by signed dummy cert for localhost \ No newline at end of file diff --git a/demo/ui/.cert/cert.pem b/demo/ui/.cert/cert.pem new file mode 100644 index 0000000..76f6c5f --- /dev/null +++ b/demo/ui/.cert/cert.pem @@ -0,0 +1,26 @@ +-----BEGIN CERTIFICATE----- +MIIEdzCCAt+gAwIBAgIRAMyMIvlBA6nant7D7dumdNQwDQYJKoZIhvcNAQELBQAw +gaUxHjAcBgNVBAoTFW1rY2VydCBkZXZlbG9wbWVudCBDQTE9MDsGA1UECww0U2hh +dXR2YXN0QG1hY2Jvb2stcHJvLnR3aW5rbGVzcGFyayAoU2FuZGVyIEhhdXR2YXN0 +KTFEMEIGA1UEAww7bWtjZXJ0IFNoYXV0dmFzdEBtYWNib29rLXByby50d2lua2xl +c3BhcmsgKFNhbmRlciBIYXV0dmFzdCkwHhcNMjMwMzEzMTI0MzIyWhcNMjUwNjEz +MTE0MzIyWjBoMScwJQYDVQQKEx5ta2NlcnQgZGV2ZWxvcG1lbnQgY2VydGlmaWNh +dGUxPTA7BgNVBAsMNFNoYXV0dmFzdEBtYWNib29rLXByby50d2lua2xlc3Bhcmsg +KFNhbmRlciBIYXV0dmFzdCkwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB +AQDO3UIb3OjeSjRV+C9FQ00K16oYY5H41GjtbCav3ZChf0LCJVr1SOAyWtOpZlgP +5GxGVjaXvD3MSYog8SpMOMHd6+B7dp02sSJPV3RdcCtSKo1WgXGkSZ59neoSRSzF +BwR/3sGyPyXsl4BFR+moQfORuwLh2FIEAdQFGRbLpRfunjvVv8vvbFBtyFSMndMV +8jvs3k3MYiwqBVzaIuT/GZ+AVUSxSzHtKRO3+2er/6xtEQTZ03Icjb0vMBGfzBBK +zBcUZN4wXC2chSFI1Ptixp/yaec1dkZ2JvaGoznhmexvgWfBpvYPjmYM/bHm0BPm +9bsxGTft4vecbx4VGRT7PR5pAgMBAAGjXjBcMA4GA1UdDwEB/wQEAwIFoDATBgNV +HSUEDDAKBggrBgEFBQcDATAfBgNVHSMEGDAWgBT8C0UzAyzvp3PMf5SUIU76Xcqx +6TAUBgNVHREEDTALgglsb2NhbGhvc3QwDQYJKoZIhvcNAQELBQADggGBAHXoL9Zi +wq26HeOA5RA+7QRHJElCEz2Epl3nSURXggKUAtL8svzOPXtNLLBgKUjUErbT6rIy +PrkF9ZBwnbbMFpy/e//sJPNI/XfG4L6+ZIP/bmEYBc/GAkS3ybeJiNS0EK5M1Qm7 +z5g4wwOIg+eCOYu4e9chOa3p+Zoopdcp/jh6C7AF4+MxuQmHmA09e042TgNsZhph +SFcii10+vI+u0EH9N106jOGDF/YyV4i4oVdigds/YF5tGVf9QAUXl71pwE7upyz9 +JWXBTFGskvfNhW+6UNKPfe1KEWySd4BOQH4Vceqv8Om1jnBbPJSoI/vRJ0OO9cLH +PSUdyb9UCfc1ajk/79PzzWdnaZGKKRDwesnbm6v+P47nDZDIOfvOXgMpOFos1Ozk +nT8388vc0q0P7/VpKz5eQHPssWQgAd9aN74hLVz1Y7oGzVRef6A/pcGaJBbqgH24 +WWEPJF24qFWq9idBfq8Jd//T77x0BL5s2JHZlGNFJ7VRWnZZ5a8FaKgcxA== +-----END CERTIFICATE----- diff --git a/demo/ui/.cert/key.pem b/demo/ui/.cert/key.pem new file mode 100644 index 0000000..66dd135 --- /dev/null +++ b/demo/ui/.cert/key.pem @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDO3UIb3OjeSjRV ++C9FQ00K16oYY5H41GjtbCav3ZChf0LCJVr1SOAyWtOpZlgP5GxGVjaXvD3MSYog +8SpMOMHd6+B7dp02sSJPV3RdcCtSKo1WgXGkSZ59neoSRSzFBwR/3sGyPyXsl4BF +R+moQfORuwLh2FIEAdQFGRbLpRfunjvVv8vvbFBtyFSMndMV8jvs3k3MYiwqBVza +IuT/GZ+AVUSxSzHtKRO3+2er/6xtEQTZ03Icjb0vMBGfzBBKzBcUZN4wXC2chSFI +1Ptixp/yaec1dkZ2JvaGoznhmexvgWfBpvYPjmYM/bHm0BPm9bsxGTft4vecbx4V +GRT7PR5pAgMBAAECggEAALHFcwp+zaA6JL+8iOL88zheHc7XwpoT8BgY2SZJQgGH +W9d8Qq6H8iNT6pGpYgRGSMYpUMEVBAaLLCkjFzZpkDEmg8OWK4TUtKd6gIXL3269 +Irk0hHSqz4kkLAOHbvHjFfrNc6e6nNy1VYY0RphSFP8nt1JelBzddVbsOKrJNcfY +p7IQtyeS//H+CEQ66gvVytUbtNu3Zzn7oXmw7PS9+UkxrDoyu+P6joG4LE3B3QHS +LUXjersiDTuTKeWBSDd5PNSKAYX/FHdt3yoo98etDcZESpRnmJ6ANljREOwdbhaH +0vN8kG3GMvK+5eCs2YxUHCcukottpSc9AhDx8/DAAQKBgQDcnOyNG/Dnntid2pc+ ++u/lFPnEsYWIsEtsMGEdKb8LfwGAiptZtUYtdH1hYOYXfhJxGY3tJxImIE1WeFq9 +dH1pzMK4NRCUtm6+Tsex6lzVS9Cao8t3PvrIEo+ZgC8S2R6MKqAp1WPRhCzYH/1s +HzBBVUPIo+PgqiRau5mD7MgkaQKBgQDwC8TNspAs277d9TYTyK6+yzVc7PzqhhO0 +yMzzTG5xEEJcGN+ZR1kR6rwR5xu29AQuZ8JRCbcwO4nVXoTlx3bgIFRgFzhG59KA +ik5L3hBikB3gh4xZqRiYhX9dMX9iqQzZ3aWdx7x3xDnBx1HPFYcJltbq8+LxCIlp +ZTBqyiXqAQKBgBArA/8XdCFVd+Sht4HrHBe64M80f2fUG8LzDLr5a0Hpbe/AuL/r +VBhSuDmhw1snZyyYxdkCiwb2SRS0P1oxJlvRoNelM/DiKd2Sonn8hg8vvjsHFAtK +N1DgY1vJlCmade2p1hEazXT2bd7tAUKiSoQPPqd+s12suntX0lljygs5AoGBAOCN +cdYmsz5zdlJ2P9c0BVwQBmRegZ32PNsCeM8kcbAs0JcM4aammsjq+HIa6s8z5/Ft +ONbMKuTg3WiPWe0FscuqEqQtNIUH+eArAWFxY4yAWqKeyolZaNvNDj8kvZCSqaXo +9TPrFABJvOnsRjhdYAx1Yak66tIl9T113lwXrG4BAoGBAMVQbmaO4zEkUWNFfxd1 +WQTRtqQqdz4QBAmEf0HmrXGNKhqZNppMO2YndZzdxV2aEHPKgOe0SS3oyydxjAkF +MRJLPwIpMGMKoknC0lfT7jw2Ma6a2L4Lc6Ds9NCGTOJc8jpW6f6VSV6mYHxd7nOp +NRF8O60CKfz1144nBLmdiBUZ +-----END PRIVATE KEY----- diff --git a/demo/ui/index.html b/demo/ui/index.html new file mode 100644 index 0000000..06e9777 --- /dev/null +++ b/demo/ui/index.html @@ -0,0 +1,23 @@ + + + + Sqlighter demo + + + + +
+
name
+
email
+
street
+
number
+
city
+
country
+
+ + + + + + + diff --git a/demo/ui/package-lock.json b/demo/ui/package-lock.json new file mode 100644 index 0000000..e9048b8 --- /dev/null +++ b/demo/ui/package-lock.json @@ -0,0 +1,2360 @@ +{ + "name": "lit-virtual-scroll-basic", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "lit-virtual-scroll-basic", + "version": "1.0.0", + "dependencies": { + "lit": "^2.6.1", + "sqlite-wasm-esm": "^0.0.30" + }, + "devDependencies": { + "@vitejs/plugin-basic-ssl": "^1.0.1", + "@web/dev-server": "^0.1.35", + "vite": "^4.1.4", + "vite-plugin-cross-origin-isolation": "^0.1.6" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz", + "integrity": "sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==", + "dev": true, + "dependencies": { + "@babel/highlight": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.19.1", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz", + "integrity": "sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/highlight": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz", + "integrity": "sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==", + "dev": true, + "dependencies": { + "@babel/helper-validator-identifier": "^7.18.6", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.16.17", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.16.17.tgz", + "integrity": "sha512-N9x1CMXVhtWEAMS7pNNONyA14f71VPQN9Cnavj1XQh6T7bskqiLLrSca4O0Vr8Wdcga943eThxnVp3JLnBMYtw==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.16.17", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.16.17.tgz", + "integrity": "sha512-MIGl6p5sc3RDTLLkYL1MyL8BMRN4tLMRCn+yRJJmEDvYZ2M7tmAf80hx1kbNEUX2KJ50RRtxZ4JHLvCfuB6kBg==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.16.17", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.16.17.tgz", + "integrity": "sha512-a3kTv3m0Ghh4z1DaFEuEDfz3OLONKuFvI4Xqczqx4BqLyuFaFkuaG4j2MtA6fuWEFeC5x9IvqnX7drmRq/fyAQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.16.17", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.16.17.tgz", + "integrity": "sha512-/2agbUEfmxWHi9ARTX6OQ/KgXnOWfsNlTeLcoV7HSuSTv63E4DqtAc+2XqGw1KHxKMHGZgbVCZge7HXWX9Vn+w==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.16.17", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.16.17.tgz", + "integrity": "sha512-2By45OBHulkd9Svy5IOCZt376Aa2oOkiE9QWUK9fe6Tb+WDr8hXL3dpqi+DeLiMed8tVXspzsTAvd0jUl96wmg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.16.17", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.16.17.tgz", + "integrity": "sha512-mt+cxZe1tVx489VTb4mBAOo2aKSnJ33L9fr25JXpqQqzbUIw/yzIzi+NHwAXK2qYV1lEFp4OoVeThGjUbmWmdw==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.16.17", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.16.17.tgz", + "integrity": "sha512-8ScTdNJl5idAKjH8zGAsN7RuWcyHG3BAvMNpKOBaqqR7EbUhhVHOqXRdL7oZvz8WNHL2pr5+eIT5c65kA6NHug==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.16.17", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.16.17.tgz", + "integrity": "sha512-iihzrWbD4gIT7j3caMzKb/RsFFHCwqqbrbH9SqUSRrdXkXaygSZCZg1FybsZz57Ju7N/SHEgPyaR0LZ8Zbe9gQ==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.16.17", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.16.17.tgz", + "integrity": "sha512-7S8gJnSlqKGVJunnMCrXHU9Q8Q/tQIxk/xL8BqAP64wchPCTzuM6W3Ra8cIa1HIflAvDnNOt2jaL17vaW+1V0g==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.16.17", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.16.17.tgz", + "integrity": "sha512-kiX69+wcPAdgl3Lonh1VI7MBr16nktEvOfViszBSxygRQqSpzv7BffMKRPMFwzeJGPxcio0pdD3kYQGpqQ2SSg==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.16.17", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.16.17.tgz", + "integrity": "sha512-dTzNnQwembNDhd654cA4QhbS9uDdXC3TKqMJjgOWsC0yNCbpzfWoXdZvp0mY7HU6nzk5E0zpRGGx3qoQg8T2DQ==", + "cpu": [ + "loong64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.16.17", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.16.17.tgz", + "integrity": "sha512-ezbDkp2nDl0PfIUn0CsQ30kxfcLTlcx4Foz2kYv8qdC6ia2oX5Q3E/8m6lq84Dj/6b0FrkgD582fJMIfHhJfSw==", + "cpu": [ + "mips64el" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.16.17", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.16.17.tgz", + "integrity": "sha512-dzS678gYD1lJsW73zrFhDApLVdM3cUF2MvAa1D8K8KtcSKdLBPP4zZSLy6LFZ0jYqQdQ29bjAHJDgz0rVbLB3g==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.16.17", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.16.17.tgz", + "integrity": "sha512-ylNlVsxuFjZK8DQtNUwiMskh6nT0vI7kYl/4fZgV1llP5d6+HIeL/vmmm3jpuoo8+NuXjQVZxmKuhDApK0/cKw==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.16.17", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.16.17.tgz", + "integrity": "sha512-gzy7nUTO4UA4oZ2wAMXPNBGTzZFP7mss3aKR2hH+/4UUkCOyqmjXiKpzGrY2TlEUhbbejzXVKKGazYcQTZWA/w==", + "cpu": [ + "s390x" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.16.17", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.16.17.tgz", + "integrity": "sha512-mdPjPxfnmoqhgpiEArqi4egmBAMYvaObgn4poorpUaqmvzzbvqbowRllQ+ZgzGVMGKaPkqUmPDOOFQRUFDmeUw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.16.17", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.16.17.tgz", + "integrity": "sha512-/PzmzD/zyAeTUsduZa32bn0ORug+Jd1EGGAUJvqfeixoEISYpGnAezN6lnJoskauoai0Jrs+XSyvDhppCPoKOA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.16.17", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.16.17.tgz", + "integrity": "sha512-2yaWJhvxGEz2RiftSk0UObqJa/b+rIAjnODJgv2GbGGpRwAfpgzyrg1WLK8rqA24mfZa9GvpjLcBBg8JHkoodg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.16.17", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.16.17.tgz", + "integrity": "sha512-xtVUiev38tN0R3g8VhRfN7Zl42YCJvyBhRKw1RJjwE1d2emWTVToPLNEQj/5Qxc6lVFATDiy6LjVHYhIPrLxzw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.16.17", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.16.17.tgz", + "integrity": "sha512-ga8+JqBDHY4b6fQAmOgtJJue36scANy4l/rL97W+0wYmijhxKetzZdKOJI7olaBaMhWt8Pac2McJdZLxXWUEQw==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.16.17", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.16.17.tgz", + "integrity": "sha512-WnsKaf46uSSF/sZhwnqE4L/F89AYNMiD4YtEcYekBt9Q7nj0DiId2XH2Ng2PHM54qi5oPrQ8luuzGszqi/veig==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.16.17", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.16.17.tgz", + "integrity": "sha512-y+EHuSchhL7FjHgvQL/0fnnFmO4T1bhvWANX6gcnqTjtnKWbTvUMCpGnv2+t+31d7RzyEAYAd4u2fnIhHL6N/Q==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@lit-labs/ssr-dom-shim": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@lit-labs/ssr-dom-shim/-/ssr-dom-shim-1.0.0.tgz", + "integrity": "sha512-ic93MBXfApIFTrup4a70M/+ddD8xdt2zxxj9sRwHQzhS9ag/syqkD8JPdTXsc1gUy2K8TTirhlCqyTEM/sifNw==" + }, + "node_modules/@lit/reactive-element": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/@lit/reactive-element/-/reactive-element-1.6.1.tgz", + "integrity": "sha512-va15kYZr7KZNNPZdxONGQzpUr+4sxVu7V/VG7a8mRfPPXUyhEYj5RzXCQmGrlP3tAh0L3HHm5AjBMFYRqlM9SA==", + "dependencies": { + "@lit-labs/ssr-dom-shim": "^1.0.0" + } + }, + "node_modules/@types/accepts": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/@types/accepts/-/accepts-1.3.5.tgz", + "integrity": "sha512-jOdnI/3qTpHABjM5cx1Hc0sKsPoYCp+DP/GJRGtDlPd7fiV9oXGGIcjW/ZOxLIvjGz8MA+uMZI9metHlgqbgwQ==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/body-parser": { + "version": "1.19.2", + "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.2.tgz", + "integrity": "sha512-ALYone6pm6QmwZoAgeyNksccT9Q4AWZQ6PvfwR37GT6r6FWUPguq6sUmNGSMV2Wr761oQoBxwGGa6DR5o1DC9g==", + "dev": true, + "dependencies": { + "@types/connect": "*", + "@types/node": "*" + } + }, + "node_modules/@types/command-line-args": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@types/command-line-args/-/command-line-args-5.2.0.tgz", + "integrity": "sha512-UuKzKpJJ/Ief6ufIaIzr3A/0XnluX7RvFgwkV89Yzvm77wCh1kFaFmqN8XEnGcN62EuHdedQjEMb8mYxFLGPyA==", + "dev": true + }, + "node_modules/@types/connect": { + "version": "3.4.35", + "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.35.tgz", + "integrity": "sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/content-disposition": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/@types/content-disposition/-/content-disposition-0.5.5.tgz", + "integrity": "sha512-v6LCdKfK6BwcqMo+wYW05rLS12S0ZO0Fl4w1h4aaZMD7bqT3gVUns6FvLJKGZHQmYn3SX55JWGpziwJRwVgutA==", + "dev": true + }, + "node_modules/@types/cookies": { + "version": "0.7.7", + "resolved": "https://registry.npmjs.org/@types/cookies/-/cookies-0.7.7.tgz", + "integrity": "sha512-h7BcvPUogWbKCzBR2lY4oqaZbO3jXZksexYJVFvkrFeLgbZjQkU4x8pRq6eg2MHXQhY0McQdqmmsxRWlVAHooA==", + "dev": true, + "dependencies": { + "@types/connect": "*", + "@types/express": "*", + "@types/keygrip": "*", + "@types/node": "*" + } + }, + "node_modules/@types/estree": { + "version": "0.0.39", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.39.tgz", + "integrity": "sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==", + "dev": true + }, + "node_modules/@types/express": { + "version": "4.17.17", + "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.17.tgz", + "integrity": "sha512-Q4FmmuLGBG58btUnfS1c1r/NQdlp3DMfGDGig8WhfpA2YRUtEkxAjkZb0yvplJGYdF1fsQ81iMDcH24sSCNC/Q==", + "dev": true, + "dependencies": { + "@types/body-parser": "*", + "@types/express-serve-static-core": "^4.17.33", + "@types/qs": "*", + "@types/serve-static": "*" + } + }, + "node_modules/@types/express-serve-static-core": { + "version": "4.17.33", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.33.tgz", + "integrity": "sha512-TPBqmR/HRYI3eC2E5hmiivIzv+bidAfXofM+sbonAGvyDhySGw9/PQZFt2BLOrjUUR++4eJVpx6KnLQK1Fk9tA==", + "dev": true, + "dependencies": { + "@types/node": "*", + "@types/qs": "*", + "@types/range-parser": "*" + } + }, + "node_modules/@types/http-assert": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/@types/http-assert/-/http-assert-1.5.3.tgz", + "integrity": "sha512-FyAOrDuQmBi8/or3ns4rwPno7/9tJTijVW6aQQjK02+kOQ8zmoNg2XJtAuQhvQcy1ASJq38wirX5//9J1EqoUA==", + "dev": true + }, + "node_modules/@types/http-errors": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.1.tgz", + "integrity": "sha512-/K3ds8TRAfBvi5vfjuz8y6+GiAYBZ0x4tXv1Av6CWBWn0IlADc+ZX9pMq7oU0fNQPnBwIZl3rmeLp6SBApbxSQ==", + "dev": true + }, + "node_modules/@types/keygrip": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@types/keygrip/-/keygrip-1.0.2.tgz", + "integrity": "sha512-GJhpTepz2udxGexqos8wgaBx4I/zWIDPh/KOGEwAqtuGDkOUJu5eFvwmdBX4AmB8Odsr+9pHCQqiAqDL/yKMKw==", + "dev": true + }, + "node_modules/@types/koa": { + "version": "2.13.5", + "resolved": "https://registry.npmjs.org/@types/koa/-/koa-2.13.5.tgz", + "integrity": "sha512-HSUOdzKz3by4fnqagwthW/1w/yJspTgppyyalPVbgZf8jQWvdIXcVW5h2DGtw4zYntOaeRGx49r1hxoPWrD4aA==", + "dev": true, + "dependencies": { + "@types/accepts": "*", + "@types/content-disposition": "*", + "@types/cookies": "*", + "@types/http-assert": "*", + "@types/http-errors": "*", + "@types/keygrip": "*", + "@types/koa-compose": "*", + "@types/node": "*" + } + }, + "node_modules/@types/koa-compose": { + "version": "3.2.5", + "resolved": "https://registry.npmjs.org/@types/koa-compose/-/koa-compose-3.2.5.tgz", + "integrity": "sha512-B8nG/OoE1ORZqCkBVsup/AKcvjdgoHnfi4pZMn5UwAPCbhk/96xyv284eBYW8JlQbQ7zDmnpFr68I/40mFoIBQ==", + "dev": true, + "dependencies": { + "@types/koa": "*" + } + }, + "node_modules/@types/mime": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/mime/-/mime-3.0.1.tgz", + "integrity": "sha512-Y4XFY5VJAuw0FgAqPNd6NNoV44jbq9Bz2L7Rh/J6jLTiHBSBJa9fxqQIvkIld4GsoDOcCbvzOUAbLPsSKKg+uA==", + "dev": true + }, + "node_modules/@types/node": { + "version": "18.15.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.15.1.tgz", + "integrity": "sha512-U2TWca8AeHSmbpi314QBESRk7oPjSZjDsR+c+H4ECC1l+kFgpZf8Ydhv3SJpPy51VyZHHqxlb6mTTqYNNRVAIw==", + "dev": true + }, + "node_modules/@types/parse5": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/@types/parse5/-/parse5-6.0.3.tgz", + "integrity": "sha512-SuT16Q1K51EAVPz1K29DJ/sXjhSQ0zjvsypYJ6tlwVsRV9jwW5Adq2ch8Dq8kDBCkYnELS7N7VNCSB5nC56t/g==", + "dev": true + }, + "node_modules/@types/qs": { + "version": "6.9.7", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.7.tgz", + "integrity": "sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==", + "dev": true + }, + "node_modules/@types/range-parser": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.4.tgz", + "integrity": "sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==", + "dev": true + }, + "node_modules/@types/resolve": { + "version": "1.17.1", + "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.17.1.tgz", + "integrity": "sha512-yy7HuzQhj0dhGpD8RLXSZWEkLsV9ibvxvi6EiJ3bkqLAO1RGo0WbkWQiwpRlSFymTJRz0d3k5LM3kkx8ArDbLw==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/serve-static": { + "version": "1.15.1", + "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.1.tgz", + "integrity": "sha512-NUo5XNiAdULrJENtJXZZ3fHtfMolzZwczzBbnAeBbqBwG+LaG6YaJtuwzwGSQZ2wsCrxjEhNNjAkKigy3n8teQ==", + "dev": true, + "dependencies": { + "@types/mime": "*", + "@types/node": "*" + } + }, + "node_modules/@types/trusted-types": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.3.tgz", + "integrity": "sha512-NfQ4gyz38SL8sDNrSixxU2Os1a5xcdFxipAFxYEuLUlvU2uDwS4NUpsImcf1//SlWItCVMMLiylsxbmNMToV/g==" + }, + "node_modules/@types/ws": { + "version": "7.4.7", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-7.4.7.tgz", + "integrity": "sha512-JQbbmxZTZehdc2iszGKs5oC3NFnjeay7mtAWrdt7qNtAVK0g19muApzAy4bm9byz79xa2ZnO/BOBC2R8RC5Lww==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@vitejs/plugin-basic-ssl": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-basic-ssl/-/plugin-basic-ssl-1.0.1.tgz", + "integrity": "sha512-pcub+YbFtFhaGRTo1832FQHQSHvMrlb43974e2eS8EKleR3p1cDdkJFPci1UhwkEf1J9Bz+wKBSzqpKp7nNj2A==", + "dev": true, + "engines": { + "node": ">=14.6.0" + }, + "peerDependencies": { + "vite": "^3.0.0 || ^4.0.0" + } + }, + "node_modules/@web/config-loader": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@web/config-loader/-/config-loader-0.1.3.tgz", + "integrity": "sha512-XVKH79pk4d3EHRhofete8eAnqto1e8mCRAqPV00KLNFzCWSe8sWmLnqKCqkPNARC6nksMaGrATnA5sPDRllMpQ==", + "dev": true, + "dependencies": { + "semver": "^7.3.4" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/@web/dev-server": { + "version": "0.1.35", + "resolved": "https://registry.npmjs.org/@web/dev-server/-/dev-server-0.1.35.tgz", + "integrity": "sha512-E7TSTSFdGPzhkiE3kIVt8i49gsiAYpJIZHzs1vJmVfdt8U4rsmhE+5roezxZo0hkEw4mNsqj9zCc4Dzqy/IFHg==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.12.11", + "@types/command-line-args": "^5.0.0", + "@web/config-loader": "^0.1.3", + "@web/dev-server-core": "^0.3.19", + "@web/dev-server-rollup": "^0.3.19", + "camelcase": "^6.2.0", + "command-line-args": "^5.1.1", + "command-line-usage": "^6.1.1", + "debounce": "^1.2.0", + "deepmerge": "^4.2.2", + "ip": "^1.1.5", + "nanocolors": "^0.2.1", + "open": "^8.0.2", + "portfinder": "^1.0.32" + }, + "bin": { + "wds": "dist/bin.js", + "web-dev-server": "dist/bin.js" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/@web/dev-server-core": { + "version": "0.3.19", + "resolved": "https://registry.npmjs.org/@web/dev-server-core/-/dev-server-core-0.3.19.tgz", + "integrity": "sha512-Q/Xt4RMVebLWvALofz1C0KvP8qHbzU1EmdIA2Y1WMPJwiFJFhPxdr75p9YxK32P2t0hGs6aqqS5zE0HW9wYzYA==", + "dev": true, + "dependencies": { + "@types/koa": "^2.11.6", + "@types/ws": "^7.4.0", + "@web/parse5-utils": "^1.2.0", + "chokidar": "^3.4.3", + "clone": "^2.1.2", + "es-module-lexer": "^1.0.0", + "get-stream": "^6.0.0", + "is-stream": "^2.0.0", + "isbinaryfile": "^4.0.6", + "koa": "^2.13.0", + "koa-etag": "^4.0.0", + "koa-send": "^5.0.1", + "koa-static": "^5.0.0", + "lru-cache": "^6.0.0", + "mime-types": "^2.1.27", + "parse5": "^6.0.1", + "picomatch": "^2.2.2", + "ws": "^7.4.2" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/@web/dev-server-rollup": { + "version": "0.3.21", + "resolved": "https://registry.npmjs.org/@web/dev-server-rollup/-/dev-server-rollup-0.3.21.tgz", + "integrity": "sha512-138t+vMFkegRip6Rtlz68Bo5rl984C9c2rLg3dWl9JEEJSQcWgA3iEwXYh4xTc52WjXnM3/LpboAjTYQOMyfrA==", + "dev": true, + "dependencies": { + "@rollup/plugin-node-resolve": "^13.0.4", + "@web/dev-server-core": "^0.3.19", + "nanocolors": "^0.2.1", + "parse5": "^6.0.1", + "rollup": "^2.67.0", + "whatwg-url": "^11.0.0" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/@web/dev-server-rollup/node_modules/@rollup/plugin-node-resolve": { + "version": "13.3.0", + "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-13.3.0.tgz", + "integrity": "sha512-Lus8rbUo1eEcnS4yTFKLZrVumLPY+YayBdWXgFSHYhTT2iJbMhoaaBL3xl5NCdeRytErGr8tZ0L71BMRmnlwSw==", + "dev": true, + "dependencies": { + "@rollup/pluginutils": "^3.1.0", + "@types/resolve": "1.17.1", + "deepmerge": "^4.2.2", + "is-builtin-module": "^3.1.0", + "is-module": "^1.0.0", + "resolve": "^1.19.0" + }, + "engines": { + "node": ">= 10.0.0" + }, + "peerDependencies": { + "rollup": "^2.42.0" + } + }, + "node_modules/@web/dev-server-rollup/node_modules/@rollup/pluginutils": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-3.1.0.tgz", + "integrity": "sha512-GksZ6pr6TpIjHm8h9lSQ8pi8BE9VeubNT0OMJ3B5uZJ8pz73NPiqOtCog/x2/QzM1ENChPKxMDhiQuRHsqc+lg==", + "dev": true, + "dependencies": { + "@types/estree": "0.0.39", + "estree-walker": "^1.0.1", + "picomatch": "^2.2.2" + }, + "engines": { + "node": ">= 8.0.0" + }, + "peerDependencies": { + "rollup": "^1.20.0||^2.0.0" + } + }, + "node_modules/@web/dev-server-rollup/node_modules/rollup": { + "version": "2.79.1", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.79.1.tgz", + "integrity": "sha512-uKxbd0IhMZOhjAiD5oAFp7BqvkA4Dv47qpOCtaNvng4HBwdbWtdOh8f5nZNuk2rp51PMGk3bzfWu5oayNEuYnw==", + "dev": true, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=10.0.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/@web/dev-server-rollup/node_modules/tr46": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-3.0.0.tgz", + "integrity": "sha512-l7FvfAHlcmulp8kr+flpQZmVwtu7nfRV7NZujtN0OqES8EL4O4e0qqzL0DC5gAvx/ZC/9lk6rhcUwYvkBnBnYA==", + "dev": true, + "dependencies": { + "punycode": "^2.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@web/dev-server-rollup/node_modules/webidl-conversions": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz", + "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==", + "dev": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/@web/dev-server-rollup/node_modules/whatwg-url": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-11.0.0.tgz", + "integrity": "sha512-RKT8HExMpoYx4igMiVMY83lN6UeITKJlBQ+vR/8ZJ8OCdSiN3RwCq+9gH0+Xzj0+5IrM6i4j/6LuvzbZIQgEcQ==", + "dev": true, + "dependencies": { + "tr46": "^3.0.0", + "webidl-conversions": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@web/parse5-utils": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@web/parse5-utils/-/parse5-utils-1.3.0.tgz", + "integrity": "sha512-Pgkx3ECc8EgXSlS5EyrgzSOoUbM6P8OKS471HLAyvOBcP1NCBn0to4RN/OaKASGq8qa3j+lPX9H14uA5AHEnQg==", + "dev": true, + "dependencies": { + "@types/parse5": "^6.0.1", + "parse5": "^6.0.1" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/accepts": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", + "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", + "dev": true, + "dependencies": { + "mime-types": "~2.1.34", + "negotiator": "0.6.3" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dev": true, + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/array-back": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/array-back/-/array-back-3.1.0.tgz", + "integrity": "sha512-TkuxA4UCOvxuDK6NZYXCalszEzj+TLszyASooky+i742l9TqsOdYCMJJupxRic61hwquNtppB3hgcuq9SVSH1Q==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/async": { + "version": "2.6.4", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.4.tgz", + "integrity": "sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA==", + "dev": true, + "dependencies": { + "lodash": "^4.17.14" + } + }, + "node_modules/binary-extensions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "dependencies": { + "fill-range": "^7.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/builtin-modules": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.3.0.tgz", + "integrity": "sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==", + "dev": true, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cache-content-type": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/cache-content-type/-/cache-content-type-1.0.1.tgz", + "integrity": "sha512-IKufZ1o4Ut42YUrZSo8+qnMTrFuKkvyoLXUywKz9GJ5BrhOFGhLdkx9sG4KAnVvbY6kEcSFjLQul+DVmBm2bgA==", + "dev": true, + "dependencies": { + "mime-types": "^2.1.18", + "ylru": "^1.2.0" + }, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/camelcase": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/chokidar": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", + "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ], + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/clone": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz", + "integrity": "sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w==", + "dev": true, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/co": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", + "integrity": "sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==", + "dev": true, + "engines": { + "iojs": ">= 1.0.0", + "node": ">= 0.12.0" + } + }, + "node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true + }, + "node_modules/command-line-args": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/command-line-args/-/command-line-args-5.2.1.tgz", + "integrity": "sha512-H4UfQhZyakIjC74I9d34fGYDwk3XpSr17QhEd0Q3I9Xq1CETHo4Hcuo87WyWHpAF1aSLjLRf5lD9ZGX2qStUvg==", + "dev": true, + "dependencies": { + "array-back": "^3.1.0", + "find-replace": "^3.0.0", + "lodash.camelcase": "^4.3.0", + "typical": "^4.0.0" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/command-line-usage": { + "version": "6.1.3", + "resolved": "https://registry.npmjs.org/command-line-usage/-/command-line-usage-6.1.3.tgz", + "integrity": "sha512-sH5ZSPr+7UStsloltmDh7Ce5fb8XPlHyoPzTpyyMuYCtervL65+ubVZ6Q61cFtFl62UyJlc8/JwERRbAFPUqgw==", + "dev": true, + "dependencies": { + "array-back": "^4.0.2", + "chalk": "^2.4.2", + "table-layout": "^1.0.2", + "typical": "^5.2.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/command-line-usage/node_modules/array-back": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/array-back/-/array-back-4.0.2.tgz", + "integrity": "sha512-NbdMezxqf94cnNfWLL7V/im0Ub+Anbb0IoZhvzie8+4HJ4nMQuzHuy49FkGYCJK2yAloZ3meiB6AVMClbrI1vg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/command-line-usage/node_modules/typical": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/typical/-/typical-5.2.0.tgz", + "integrity": "sha512-dvdQgNDNJo+8B2uBQoqdb11eUCE1JQXhvjC/CZtgvZseVd5TYMXnq0+vuUemXbd/Se29cTaUuPX3YIc2xgbvIg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/content-disposition": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", + "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", + "dev": true, + "dependencies": { + "safe-buffer": "5.2.1" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/content-type": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", + "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookies": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/cookies/-/cookies-0.8.0.tgz", + "integrity": "sha512-8aPsApQfebXnuI+537McwYsDtjVxGm8gTIzQI3FDW6t5t/DAhERxtnbEPN/8RX+uZthoz4eCOgloXaE5cYyNow==", + "dev": true, + "dependencies": { + "depd": "~2.0.0", + "keygrip": "~1.1.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/debounce": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/debounce/-/debounce-1.2.1.tgz", + "integrity": "sha512-XRRe6Glud4rd/ZGQfiV1ruXSfbvfJedlV9Y6zOlP+2K04vBYiJEte6stfFkCP03aMnY5tsipamumUjL14fofug==", + "dev": true + }, + "node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/deep-equal": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.0.1.tgz", + "integrity": "sha512-bHtC0iYvWhyaTzvV3CZgPeZQqCOBGyGsVV7v4eevpdkLHfiSrXUdBG+qAuSz4RI70sszvjQ1QSZ98An1yNwpSw==", + "dev": true + }, + "node_modules/deep-extend": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", + "dev": true, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/deepmerge": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.0.tgz", + "integrity": "sha512-z2wJZXrmeHdvYJp/Ux55wIjqo81G5Bp4c+oELTW+7ar6SogWHajt5a9gO3s3IDaGSAXjDk0vlQKN3rms8ab3og==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/define-lazy-prop": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz", + "integrity": "sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/delegates": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", + "integrity": "sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==", + "dev": true + }, + "node_modules/depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/destroy": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", + "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", + "dev": true, + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", + "dev": true + }, + "node_modules/encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/es-module-lexer": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.2.0.tgz", + "integrity": "sha512-2BMfqBDeVCcOlLaL1ZAfp+D868SczNpKArrTM3dhpd7dK/OVlogzY15qpUngt+LMTq5UC/csb9vVQAgupucSbA==", + "dev": true + }, + "node_modules/esbuild": { + "version": "0.16.17", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.16.17.tgz", + "integrity": "sha512-G8LEkV0XzDMNwXKgM0Jwu3nY3lSTwSGY6XbxM9cr9+s0T/qSV1q1JVPBGzm3dcjhCic9+emZDmMffkwgPeOeLg==", + "dev": true, + "hasInstallScript": true, + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/android-arm": "0.16.17", + "@esbuild/android-arm64": "0.16.17", + "@esbuild/android-x64": "0.16.17", + "@esbuild/darwin-arm64": "0.16.17", + "@esbuild/darwin-x64": "0.16.17", + "@esbuild/freebsd-arm64": "0.16.17", + "@esbuild/freebsd-x64": "0.16.17", + "@esbuild/linux-arm": "0.16.17", + "@esbuild/linux-arm64": "0.16.17", + "@esbuild/linux-ia32": "0.16.17", + "@esbuild/linux-loong64": "0.16.17", + "@esbuild/linux-mips64el": "0.16.17", + "@esbuild/linux-ppc64": "0.16.17", + "@esbuild/linux-riscv64": "0.16.17", + "@esbuild/linux-s390x": "0.16.17", + "@esbuild/linux-x64": "0.16.17", + "@esbuild/netbsd-x64": "0.16.17", + "@esbuild/openbsd-x64": "0.16.17", + "@esbuild/sunos-x64": "0.16.17", + "@esbuild/win32-arm64": "0.16.17", + "@esbuild/win32-ia32": "0.16.17", + "@esbuild/win32-x64": "0.16.17" + } + }, + "node_modules/escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", + "dev": true + }, + "node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/estree-walker": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-1.0.1.tgz", + "integrity": "sha512-1fMXF3YP4pZZVozF8j/ZLfvnR8NSIljt56UhbZ5PeeDmmGHpgpdwQt7ITlGvYaQukCvuBRMLEiKiYC+oeIg4cg==", + "dev": true + }, + "node_modules/etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/find-replace": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-replace/-/find-replace-3.0.0.tgz", + "integrity": "sha512-6Tb2myMioCAgv5kfvP5/PkZZ/ntTpVK39fHY7WkWBgvbeE+VHd/tZuZ4mrC+bxh4cfOZeYKVPaJIZtZXV7GNCQ==", + "dev": true, + "dependencies": { + "array-back": "^3.0.1" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true + }, + "node_modules/get-stream": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.1" + }, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/has-symbols": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", + "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", + "dev": true, + "dependencies": { + "has-symbols": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/http-assert": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/http-assert/-/http-assert-1.5.0.tgz", + "integrity": "sha512-uPpH7OKX4H25hBmU6G1jWNaqJGpTXxey+YOUizJUAgu0AjLUeC8D73hTrhvDS5D+GJN1DN1+hhc/eF/wpxtp0w==", + "dev": true, + "dependencies": { + "deep-equal": "~1.0.1", + "http-errors": "~1.8.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/http-errors": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.8.1.tgz", + "integrity": "sha512-Kpk9Sm7NmI+RHhnj6OIWDI1d6fIoFAtFt9RLaTMRlg/8w49juAStsrBgp0Dp4OdxdVbRIeKhtCUvoi/RuAhO4g==", + "dev": true, + "dependencies": { + "depd": "~1.1.2", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": ">= 1.5.0 < 2", + "toidentifier": "1.0.1" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/http-errors/node_modules/depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "node_modules/ip": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.8.tgz", + "integrity": "sha512-PuExPYUiu6qMBQb4l06ecm6T6ujzhmh+MeJcW9wa89PoAz5pvd4zPgN5WJV104mb6S2T1AwNIAaB70JNrLQWhg==", + "dev": true + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-builtin-module": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-3.2.1.tgz", + "integrity": "sha512-BSLE3HnV2syZ0FK0iMA/yUGplUeMmNz4AW5fnTunbCIqZi4vG3WjJT9FHMy5D69xmAYBHXQhJdALdpwVxV501A==", + "dev": true, + "dependencies": { + "builtin-modules": "^3.3.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-core-module": { + "version": "2.11.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.11.0.tgz", + "integrity": "sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw==", + "dev": true, + "dependencies": { + "has": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-docker": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", + "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", + "dev": true, + "bin": { + "is-docker": "cli.js" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-generator-function": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.10.tgz", + "integrity": "sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==", + "dev": true, + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-module": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-module/-/is-module-1.0.0.tgz", + "integrity": "sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g==", + "dev": true + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-wsl": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", + "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", + "dev": true, + "dependencies": { + "is-docker": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/isbinaryfile": { + "version": "4.0.10", + "resolved": "https://registry.npmjs.org/isbinaryfile/-/isbinaryfile-4.0.10.tgz", + "integrity": "sha512-iHrqe5shvBUcFbmZq9zOQHBoeOhZJu6RQGrDpBgenUm/Am+F3JM2MgQj+rK3Z601fzrL5gLZWtAPH2OBaSVcyw==", + "dev": true, + "engines": { + "node": ">= 8.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/gjtorikian/" + } + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, + "node_modules/keygrip": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/keygrip/-/keygrip-1.1.0.tgz", + "integrity": "sha512-iYSchDJ+liQ8iwbSI2QqsQOvqv58eJCEanyJPJi+Khyu8smkcKSFUCbPwzFcL7YVtZ6eONjqRX/38caJ7QjRAQ==", + "dev": true, + "dependencies": { + "tsscmp": "1.0.6" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/koa": { + "version": "2.14.1", + "resolved": "https://registry.npmjs.org/koa/-/koa-2.14.1.tgz", + "integrity": "sha512-USJFyZgi2l0wDgqkfD27gL4YGno7TfUkcmOe6UOLFOVuN+J7FwnNu4Dydl4CUQzraM1lBAiGed0M9OVJoT0Kqw==", + "dev": true, + "dependencies": { + "accepts": "^1.3.5", + "cache-content-type": "^1.0.0", + "content-disposition": "~0.5.2", + "content-type": "^1.0.4", + "cookies": "~0.8.0", + "debug": "^4.3.2", + "delegates": "^1.0.0", + "depd": "^2.0.0", + "destroy": "^1.0.4", + "encodeurl": "^1.0.2", + "escape-html": "^1.0.3", + "fresh": "~0.5.2", + "http-assert": "^1.3.0", + "http-errors": "^1.6.3", + "is-generator-function": "^1.0.7", + "koa-compose": "^4.1.0", + "koa-convert": "^2.0.0", + "on-finished": "^2.3.0", + "only": "~0.0.2", + "parseurl": "^1.3.2", + "statuses": "^1.5.0", + "type-is": "^1.6.16", + "vary": "^1.1.2" + }, + "engines": { + "node": "^4.8.4 || ^6.10.1 || ^7.10.1 || >= 8.1.4" + } + }, + "node_modules/koa-compose": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/koa-compose/-/koa-compose-4.1.0.tgz", + "integrity": "sha512-8ODW8TrDuMYvXRwra/Kh7/rJo9BtOfPc6qO8eAfC80CnCvSjSl0bkRM24X6/XBBEyj0v1nRUQ1LyOy3dbqOWXw==", + "dev": true + }, + "node_modules/koa-convert": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/koa-convert/-/koa-convert-2.0.0.tgz", + "integrity": "sha512-asOvN6bFlSnxewce2e/DK3p4tltyfC4VM7ZwuTuepI7dEQVcvpyFuBcEARu1+Hxg8DIwytce2n7jrZtRlPrARA==", + "dev": true, + "dependencies": { + "co": "^4.6.0", + "koa-compose": "^4.1.0" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/koa-etag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/koa-etag/-/koa-etag-4.0.0.tgz", + "integrity": "sha512-1cSdezCkBWlyuB9l6c/IFoe1ANCDdPBxkDkRiaIup40xpUub6U/wwRXoKBZw/O5BifX9OlqAjYnDyzM6+l+TAg==", + "dev": true, + "dependencies": { + "etag": "^1.8.1" + } + }, + "node_modules/koa-send": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/koa-send/-/koa-send-5.0.1.tgz", + "integrity": "sha512-tmcyQ/wXXuxpDxyNXv5yNNkdAMdFRqwtegBXUaowiQzUKqJehttS0x2j0eOZDQAyloAth5w6wwBImnFzkUz3pQ==", + "dev": true, + "dependencies": { + "debug": "^4.1.1", + "http-errors": "^1.7.3", + "resolve-path": "^1.4.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/koa-static": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/koa-static/-/koa-static-5.0.0.tgz", + "integrity": "sha512-UqyYyH5YEXaJrf9S8E23GoJFQZXkBVJ9zYYMPGz919MSX1KuvAcycIuS0ci150HCoPf4XQVhQ84Qf8xRPWxFaQ==", + "dev": true, + "dependencies": { + "debug": "^3.1.0", + "koa-send": "^5.0.0" + }, + "engines": { + "node": ">= 7.6.0" + } + }, + "node_modules/koa-static/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/lit": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/lit/-/lit-2.6.1.tgz", + "integrity": "sha512-DT87LD64f8acR7uVp7kZfhLRrHkfC/N4BVzAtnw9Yg8087mbBJ//qedwdwX0kzDbxgPccWRW6mFwGbRQIxy0pw==", + "dependencies": { + "@lit/reactive-element": "^1.6.0", + "lit-element": "^3.2.0", + "lit-html": "^2.6.0" + } + }, + "node_modules/lit-element": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/lit-element/-/lit-element-3.2.2.tgz", + "integrity": "sha512-6ZgxBR9KNroqKb6+htkyBwD90XGRiqKDHVrW/Eh0EZ+l+iC+u+v+w3/BA5NGi4nizAVHGYvQBHUDuSmLjPp7NQ==", + "dependencies": { + "@lit/reactive-element": "^1.3.0", + "lit-html": "^2.2.0" + } + }, + "node_modules/lit-html": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/lit-html/-/lit-html-2.6.1.tgz", + "integrity": "sha512-Z3iw+E+3KKFn9t2YKNjsXNEu/LRLI98mtH/C6lnFg7kvaqPIzPn124Yd4eT/43lyqrejpc5Wb6BHq3fdv4S8Rw==", + "dependencies": { + "@types/trusted-types": "^2.0.2" + } + }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "dev": true + }, + "node_modules/lodash.camelcase": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", + "integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==", + "dev": true + }, + "node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dev": true, + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/mkdirp": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", + "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", + "dev": true, + "dependencies": { + "minimist": "^1.2.6" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, + "node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "node_modules/nanocolors": { + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/nanocolors/-/nanocolors-0.2.13.tgz", + "integrity": "sha512-0n3mSAQLPpGLV9ORXT5+C/D4mwew7Ebws69Hx4E2sgz2ZA5+32Q80B9tL8PbL7XHnRDiAxH/pnrUJ9a4fkTNTA==", + "dev": true + }, + "node_modules/nanoid": { + "version": "3.3.4", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz", + "integrity": "sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==", + "dev": true, + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/negotiator": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/on-finished": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "dev": true, + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/only": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/only/-/only-0.0.2.tgz", + "integrity": "sha512-Fvw+Jemq5fjjyWz6CpKx6w9s7xxqo3+JCyM0WXWeCSOboZ8ABkyvP8ID4CZuChA/wxSx+XSJmdOm8rGVyJ1hdQ==", + "dev": true + }, + "node_modules/open": { + "version": "8.4.2", + "resolved": "https://registry.npmjs.org/open/-/open-8.4.2.tgz", + "integrity": "sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==", + "dev": true, + "dependencies": { + "define-lazy-prop": "^2.0.0", + "is-docker": "^2.1.1", + "is-wsl": "^2.2.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/parse5": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", + "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==", + "dev": true + }, + "node_modules/parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true + }, + "node_modules/picocolors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", + "dev": true + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/portfinder": { + "version": "1.0.32", + "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.32.tgz", + "integrity": "sha512-on2ZJVVDXRADWE6jnQaX0ioEylzgBpQk8r55NE4wjXW1ZxO+BgDlY6DXwj20i0V8eB4SenDQ00WEaxfiIQPcxg==", + "dev": true, + "dependencies": { + "async": "^2.6.4", + "debug": "^3.2.7", + "mkdirp": "^0.5.6" + }, + "engines": { + "node": ">= 0.12.0" + } + }, + "node_modules/portfinder/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/punycode": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz", + "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/reduce-flatten": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/reduce-flatten/-/reduce-flatten-2.0.0.tgz", + "integrity": "sha512-EJ4UNY/U1t2P/2k6oqotuX2Cc3T6nxJwsM0N0asT7dhrtH1ltUxDn4NalSYmPE2rCkVpcf/X6R0wDwcFpzhd4w==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/resolve": { + "version": "1.22.1", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz", + "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==", + "dev": true, + "dependencies": { + "is-core-module": "^2.9.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve-path": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/resolve-path/-/resolve-path-1.4.0.tgz", + "integrity": "sha512-i1xevIst/Qa+nA9olDxLWnLk8YZbi8R/7JPbCMcgyWaFR6bKWaexgJgEB5oc2PKMjYdrHynyz0NY+if+H98t1w==", + "dev": true, + "dependencies": { + "http-errors": "~1.6.2", + "path-is-absolute": "1.0.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/resolve-path/node_modules/depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/resolve-path/node_modules/http-errors": { + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", + "integrity": "sha512-lks+lVC8dgGyh97jxvxeYTWQFvh4uw4yC12gVl63Cg30sjPX4wuGcdkICVXDAESr6OJGjqGA8Iz5mkeN6zlD7A==", + "dev": true, + "dependencies": { + "depd": "~1.1.2", + "inherits": "2.0.3", + "setprototypeof": "1.1.0", + "statuses": ">= 1.4.0 < 2" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/resolve-path/node_modules/inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==", + "dev": true + }, + "node_modules/resolve-path/node_modules/setprototypeof": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", + "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==", + "dev": true + }, + "node_modules/rollup": { + "version": "3.19.1", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.19.1.tgz", + "integrity": "sha512-lAbrdN7neYCg/8WaoWn/ckzCtz+jr70GFfYdlf50OF7387HTg+wiuiqJRFYawwSPpqfqDNYqK7smY/ks2iAudg==", + "dev": true, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=14.18.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/semver": { + "version": "7.3.8", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", + "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", + "dev": true + }, + "node_modules/source-map-js": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", + "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/sqlite-wasm-esm": { + "version": "0.0.30", + "resolved": "https://registry.npmjs.org/sqlite-wasm-esm/-/sqlite-wasm-esm-0.0.30.tgz", + "integrity": "sha512-rLl+STKLfGXyBcpQlH6uEMMh76YXixY3s+qDEMzIiMMsyN7iXLmo4Mk1Su/6GoJFprSWP+cgOCWQsAbLELCEPg==" + }, + "node_modules/statuses": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", + "integrity": "sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/table-layout": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/table-layout/-/table-layout-1.0.2.tgz", + "integrity": "sha512-qd/R7n5rQTRFi+Zf2sk5XVVd9UQl6ZkduPFC3S7WEGJAmetDTjY3qPN50eSKzwuzEyQKy5TN2TiZdkIjos2L6A==", + "dev": true, + "dependencies": { + "array-back": "^4.0.1", + "deep-extend": "~0.6.0", + "typical": "^5.2.0", + "wordwrapjs": "^4.0.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/table-layout/node_modules/array-back": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/array-back/-/array-back-4.0.2.tgz", + "integrity": "sha512-NbdMezxqf94cnNfWLL7V/im0Ub+Anbb0IoZhvzie8+4HJ4nMQuzHuy49FkGYCJK2yAloZ3meiB6AVMClbrI1vg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/table-layout/node_modules/typical": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/typical/-/typical-5.2.0.tgz", + "integrity": "sha512-dvdQgNDNJo+8B2uBQoqdb11eUCE1JQXhvjC/CZtgvZseVd5TYMXnq0+vuUemXbd/Se29cTaUuPX3YIc2xgbvIg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/toidentifier": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", + "dev": true, + "engines": { + "node": ">=0.6" + } + }, + "node_modules/tsscmp": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/tsscmp/-/tsscmp-1.0.6.tgz", + "integrity": "sha512-LxhtAkPDTkVCMQjt2h6eBVY28KCjikZqZfMcC15YBeNjkgUpdCfBu5HoiOTDu86v6smE8yOjyEktJ8hlbANHQA==", + "dev": true, + "engines": { + "node": ">=0.6.x" + } + }, + "node_modules/type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "dev": true, + "dependencies": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/typical": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/typical/-/typical-4.0.0.tgz", + "integrity": "sha512-VAH4IvQ7BDFYglMd7BPRDfLgxZZX4O4TFcRDA6EN5X7erNJJq+McIEp8np9aVtxrCJ6qx4GTYVfOWNjcqwZgRw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/vite": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/vite/-/vite-4.1.4.tgz", + "integrity": "sha512-3knk/HsbSTKEin43zHu7jTwYWv81f8kgAL99G5NWBcA1LKvtvcVAC4JjBH1arBunO9kQka+1oGbrMKOjk4ZrBg==", + "dev": true, + "dependencies": { + "esbuild": "^0.16.14", + "postcss": "^8.4.21", + "resolve": "^1.22.1", + "rollup": "^3.10.0" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + }, + "peerDependencies": { + "@types/node": ">= 14", + "less": "*", + "sass": "*", + "stylus": "*", + "sugarss": "*", + "terser": "^5.4.0" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "less": { + "optional": true + }, + "sass": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + } + } + }, + "node_modules/vite-plugin-cross-origin-isolation": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/vite-plugin-cross-origin-isolation/-/vite-plugin-cross-origin-isolation-0.1.6.tgz", + "integrity": "sha512-OY0naW9nPUDrKTffYnY7FRYXOgZdHoNwMGpPxUmj/n32mGZi01fcq+J536jkmwGWX7DLT95XBQVHHbrAJzTvrw==", + "dev": true + }, + "node_modules/vite/node_modules/postcss": { + "version": "8.4.21", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.21.tgz", + "integrity": "sha512-tP7u/Sn/dVxK2NnruI4H9BG+x+Wxz6oeZ1cJ8P6G/PZY0IKk4k/63TDsQf2kQq3+qoJeLm2kIBUNlZe3zgb4Zg==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + } + ], + "dependencies": { + "nanoid": "^3.3.4", + "picocolors": "^1.0.0", + "source-map-js": "^1.0.2" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/wordwrapjs": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/wordwrapjs/-/wordwrapjs-4.0.1.tgz", + "integrity": "sha512-kKlNACbvHrkpIw6oPeYDSmdCTu2hdMHoyXLTcUKala++lx5Y+wjJ/e474Jqv5abnVmwxw08DiTuHmw69lJGksA==", + "dev": true, + "dependencies": { + "reduce-flatten": "^2.0.0", + "typical": "^5.2.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/wordwrapjs/node_modules/typical": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/typical/-/typical-5.2.0.tgz", + "integrity": "sha512-dvdQgNDNJo+8B2uBQoqdb11eUCE1JQXhvjC/CZtgvZseVd5TYMXnq0+vuUemXbd/Se29cTaUuPX3YIc2xgbvIg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/ws": { + "version": "7.5.9", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.9.tgz", + "integrity": "sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q==", + "dev": true, + "engines": { + "node": ">=8.3.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "node_modules/ylru": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/ylru/-/ylru-1.3.2.tgz", + "integrity": "sha512-RXRJzMiK6U2ye0BlGGZnmpwJDPgakn6aNQ0A7gHRbD4I0uvK4TW6UqkK1V0pp9jskjJBAXd3dRrbzWkqJ+6cxA==", + "dev": true, + "engines": { + "node": ">= 4.0.0" + } + } + } +} diff --git a/demo/ui/package.json b/demo/ui/package.json new file mode 100644 index 0000000..520954e --- /dev/null +++ b/demo/ui/package.json @@ -0,0 +1,20 @@ +{ + "name": "lit-virtual-scroll-basic", + "type": "module", + "version": "1.0.0", + "description": "", + "scripts": { + "start": "npm run dev", + "dev": "vite", + "build": "vite build", + "serve": "vite preview" + }, + "dependencies": { + "lit": "^2.6.1", + "sqlite-wasm-esm": "^0.0.30" + }, + "devDependencies": { + "vite": "^4.1.4" + }, + "keywords": ["sqlite", "lit"] +} diff --git a/demo/ui/pnpm-lock.yaml b/demo/ui/pnpm-lock.yaml new file mode 100644 index 0000000..980c576 --- /dev/null +++ b/demo/ui/pnpm-lock.yaml @@ -0,0 +1,390 @@ +lockfileVersion: 5.4 + +specifiers: + lit: ^2.6.1 + sqlite-wasm-esm: ^0.0.30 + vite: ^4.1.4 + +dependencies: + lit: 2.6.1 + sqlite-wasm-esm: 0.0.30 + +devDependencies: + vite: 4.1.4 + +packages: + + /@esbuild/android-arm/0.16.17: + resolution: {integrity: sha512-N9x1CMXVhtWEAMS7pNNONyA14f71VPQN9Cnavj1XQh6T7bskqiLLrSca4O0Vr8Wdcga943eThxnVp3JLnBMYtw==} + engines: {node: '>=12'} + cpu: [arm] + os: [android] + requiresBuild: true + dev: true + optional: true + + /@esbuild/android-arm64/0.16.17: + resolution: {integrity: sha512-MIGl6p5sc3RDTLLkYL1MyL8BMRN4tLMRCn+yRJJmEDvYZ2M7tmAf80hx1kbNEUX2KJ50RRtxZ4JHLvCfuB6kBg==} + engines: {node: '>=12'} + cpu: [arm64] + os: [android] + requiresBuild: true + dev: true + optional: true + + /@esbuild/android-x64/0.16.17: + resolution: {integrity: sha512-a3kTv3m0Ghh4z1DaFEuEDfz3OLONKuFvI4Xqczqx4BqLyuFaFkuaG4j2MtA6fuWEFeC5x9IvqnX7drmRq/fyAQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [android] + requiresBuild: true + dev: true + optional: true + + /@esbuild/darwin-arm64/0.16.17: + resolution: {integrity: sha512-/2agbUEfmxWHi9ARTX6OQ/KgXnOWfsNlTeLcoV7HSuSTv63E4DqtAc+2XqGw1KHxKMHGZgbVCZge7HXWX9Vn+w==} + engines: {node: '>=12'} + cpu: [arm64] + os: [darwin] + requiresBuild: true + dev: true + optional: true + + /@esbuild/darwin-x64/0.16.17: + resolution: {integrity: sha512-2By45OBHulkd9Svy5IOCZt376Aa2oOkiE9QWUK9fe6Tb+WDr8hXL3dpqi+DeLiMed8tVXspzsTAvd0jUl96wmg==} + engines: {node: '>=12'} + cpu: [x64] + os: [darwin] + requiresBuild: true + dev: true + optional: true + + /@esbuild/freebsd-arm64/0.16.17: + resolution: {integrity: sha512-mt+cxZe1tVx489VTb4mBAOo2aKSnJ33L9fr25JXpqQqzbUIw/yzIzi+NHwAXK2qYV1lEFp4OoVeThGjUbmWmdw==} + engines: {node: '>=12'} + cpu: [arm64] + os: [freebsd] + requiresBuild: true + dev: true + optional: true + + /@esbuild/freebsd-x64/0.16.17: + resolution: {integrity: sha512-8ScTdNJl5idAKjH8zGAsN7RuWcyHG3BAvMNpKOBaqqR7EbUhhVHOqXRdL7oZvz8WNHL2pr5+eIT5c65kA6NHug==} + engines: {node: '>=12'} + cpu: [x64] + os: [freebsd] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-arm/0.16.17: + resolution: {integrity: sha512-iihzrWbD4gIT7j3caMzKb/RsFFHCwqqbrbH9SqUSRrdXkXaygSZCZg1FybsZz57Ju7N/SHEgPyaR0LZ8Zbe9gQ==} + engines: {node: '>=12'} + cpu: [arm] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-arm64/0.16.17: + resolution: {integrity: sha512-7S8gJnSlqKGVJunnMCrXHU9Q8Q/tQIxk/xL8BqAP64wchPCTzuM6W3Ra8cIa1HIflAvDnNOt2jaL17vaW+1V0g==} + engines: {node: '>=12'} + cpu: [arm64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-ia32/0.16.17: + resolution: {integrity: sha512-kiX69+wcPAdgl3Lonh1VI7MBr16nktEvOfViszBSxygRQqSpzv7BffMKRPMFwzeJGPxcio0pdD3kYQGpqQ2SSg==} + engines: {node: '>=12'} + cpu: [ia32] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-loong64/0.16.17: + resolution: {integrity: sha512-dTzNnQwembNDhd654cA4QhbS9uDdXC3TKqMJjgOWsC0yNCbpzfWoXdZvp0mY7HU6nzk5E0zpRGGx3qoQg8T2DQ==} + engines: {node: '>=12'} + cpu: [loong64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-mips64el/0.16.17: + resolution: {integrity: sha512-ezbDkp2nDl0PfIUn0CsQ30kxfcLTlcx4Foz2kYv8qdC6ia2oX5Q3E/8m6lq84Dj/6b0FrkgD582fJMIfHhJfSw==} + engines: {node: '>=12'} + cpu: [mips64el] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-ppc64/0.16.17: + resolution: {integrity: sha512-dzS678gYD1lJsW73zrFhDApLVdM3cUF2MvAa1D8K8KtcSKdLBPP4zZSLy6LFZ0jYqQdQ29bjAHJDgz0rVbLB3g==} + engines: {node: '>=12'} + cpu: [ppc64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-riscv64/0.16.17: + resolution: {integrity: sha512-ylNlVsxuFjZK8DQtNUwiMskh6nT0vI7kYl/4fZgV1llP5d6+HIeL/vmmm3jpuoo8+NuXjQVZxmKuhDApK0/cKw==} + engines: {node: '>=12'} + cpu: [riscv64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-s390x/0.16.17: + resolution: {integrity: sha512-gzy7nUTO4UA4oZ2wAMXPNBGTzZFP7mss3aKR2hH+/4UUkCOyqmjXiKpzGrY2TlEUhbbejzXVKKGazYcQTZWA/w==} + engines: {node: '>=12'} + cpu: [s390x] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-x64/0.16.17: + resolution: {integrity: sha512-mdPjPxfnmoqhgpiEArqi4egmBAMYvaObgn4poorpUaqmvzzbvqbowRllQ+ZgzGVMGKaPkqUmPDOOFQRUFDmeUw==} + engines: {node: '>=12'} + cpu: [x64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/netbsd-x64/0.16.17: + resolution: {integrity: sha512-/PzmzD/zyAeTUsduZa32bn0ORug+Jd1EGGAUJvqfeixoEISYpGnAezN6lnJoskauoai0Jrs+XSyvDhppCPoKOA==} + engines: {node: '>=12'} + cpu: [x64] + os: [netbsd] + requiresBuild: true + dev: true + optional: true + + /@esbuild/openbsd-x64/0.16.17: + resolution: {integrity: sha512-2yaWJhvxGEz2RiftSk0UObqJa/b+rIAjnODJgv2GbGGpRwAfpgzyrg1WLK8rqA24mfZa9GvpjLcBBg8JHkoodg==} + engines: {node: '>=12'} + cpu: [x64] + os: [openbsd] + requiresBuild: true + dev: true + optional: true + + /@esbuild/sunos-x64/0.16.17: + resolution: {integrity: sha512-xtVUiev38tN0R3g8VhRfN7Zl42YCJvyBhRKw1RJjwE1d2emWTVToPLNEQj/5Qxc6lVFATDiy6LjVHYhIPrLxzw==} + engines: {node: '>=12'} + cpu: [x64] + os: [sunos] + requiresBuild: true + dev: true + optional: true + + /@esbuild/win32-arm64/0.16.17: + resolution: {integrity: sha512-ga8+JqBDHY4b6fQAmOgtJJue36scANy4l/rL97W+0wYmijhxKetzZdKOJI7olaBaMhWt8Pac2McJdZLxXWUEQw==} + engines: {node: '>=12'} + cpu: [arm64] + os: [win32] + requiresBuild: true + dev: true + optional: true + + /@esbuild/win32-ia32/0.16.17: + resolution: {integrity: sha512-WnsKaf46uSSF/sZhwnqE4L/F89AYNMiD4YtEcYekBt9Q7nj0DiId2XH2Ng2PHM54qi5oPrQ8luuzGszqi/veig==} + engines: {node: '>=12'} + cpu: [ia32] + os: [win32] + requiresBuild: true + dev: true + optional: true + + /@esbuild/win32-x64/0.16.17: + resolution: {integrity: sha512-y+EHuSchhL7FjHgvQL/0fnnFmO4T1bhvWANX6gcnqTjtnKWbTvUMCpGnv2+t+31d7RzyEAYAd4u2fnIhHL6N/Q==} + engines: {node: '>=12'} + cpu: [x64] + os: [win32] + requiresBuild: true + dev: true + optional: true + + /@lit-labs/ssr-dom-shim/1.0.0: + resolution: {integrity: sha512-ic93MBXfApIFTrup4a70M/+ddD8xdt2zxxj9sRwHQzhS9ag/syqkD8JPdTXsc1gUy2K8TTirhlCqyTEM/sifNw==} + dev: false + + /@lit/reactive-element/1.6.1: + resolution: {integrity: sha512-va15kYZr7KZNNPZdxONGQzpUr+4sxVu7V/VG7a8mRfPPXUyhEYj5RzXCQmGrlP3tAh0L3HHm5AjBMFYRqlM9SA==} + dependencies: + '@lit-labs/ssr-dom-shim': 1.0.0 + dev: false + + /@types/trusted-types/2.0.3: + resolution: {integrity: sha512-NfQ4gyz38SL8sDNrSixxU2Os1a5xcdFxipAFxYEuLUlvU2uDwS4NUpsImcf1//SlWItCVMMLiylsxbmNMToV/g==} + dev: false + + /esbuild/0.16.17: + resolution: {integrity: sha512-G8LEkV0XzDMNwXKgM0Jwu3nY3lSTwSGY6XbxM9cr9+s0T/qSV1q1JVPBGzm3dcjhCic9+emZDmMffkwgPeOeLg==} + engines: {node: '>=12'} + hasBin: true + requiresBuild: true + optionalDependencies: + '@esbuild/android-arm': 0.16.17 + '@esbuild/android-arm64': 0.16.17 + '@esbuild/android-x64': 0.16.17 + '@esbuild/darwin-arm64': 0.16.17 + '@esbuild/darwin-x64': 0.16.17 + '@esbuild/freebsd-arm64': 0.16.17 + '@esbuild/freebsd-x64': 0.16.17 + '@esbuild/linux-arm': 0.16.17 + '@esbuild/linux-arm64': 0.16.17 + '@esbuild/linux-ia32': 0.16.17 + '@esbuild/linux-loong64': 0.16.17 + '@esbuild/linux-mips64el': 0.16.17 + '@esbuild/linux-ppc64': 0.16.17 + '@esbuild/linux-riscv64': 0.16.17 + '@esbuild/linux-s390x': 0.16.17 + '@esbuild/linux-x64': 0.16.17 + '@esbuild/netbsd-x64': 0.16.17 + '@esbuild/openbsd-x64': 0.16.17 + '@esbuild/sunos-x64': 0.16.17 + '@esbuild/win32-arm64': 0.16.17 + '@esbuild/win32-ia32': 0.16.17 + '@esbuild/win32-x64': 0.16.17 + dev: true + + /fsevents/2.3.2: + resolution: {integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + requiresBuild: true + dev: true + optional: true + + /function-bind/1.1.1: + resolution: {integrity: sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==} + dev: true + + /has/1.0.3: + resolution: {integrity: sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==} + engines: {node: '>= 0.4.0'} + dependencies: + function-bind: 1.1.1 + dev: true + + /is-core-module/2.11.0: + resolution: {integrity: sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw==} + dependencies: + has: 1.0.3 + dev: true + + /lit-element/3.2.2: + resolution: {integrity: sha512-6ZgxBR9KNroqKb6+htkyBwD90XGRiqKDHVrW/Eh0EZ+l+iC+u+v+w3/BA5NGi4nizAVHGYvQBHUDuSmLjPp7NQ==} + dependencies: + '@lit/reactive-element': 1.6.1 + lit-html: 2.6.1 + dev: false + + /lit-html/2.6.1: + resolution: {integrity: sha512-Z3iw+E+3KKFn9t2YKNjsXNEu/LRLI98mtH/C6lnFg7kvaqPIzPn124Yd4eT/43lyqrejpc5Wb6BHq3fdv4S8Rw==} + dependencies: + '@types/trusted-types': 2.0.3 + dev: false + + /lit/2.6.1: + resolution: {integrity: sha512-DT87LD64f8acR7uVp7kZfhLRrHkfC/N4BVzAtnw9Yg8087mbBJ//qedwdwX0kzDbxgPccWRW6mFwGbRQIxy0pw==} + dependencies: + '@lit/reactive-element': 1.6.1 + lit-element: 3.2.2 + lit-html: 2.6.1 + dev: false + + /nanoid/3.3.4: + resolution: {integrity: sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==} + engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + hasBin: true + dev: true + + /path-parse/1.0.7: + resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} + dev: true + + /picocolors/1.0.0: + resolution: {integrity: sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==} + dev: true + + /postcss/8.4.21: + resolution: {integrity: sha512-tP7u/Sn/dVxK2NnruI4H9BG+x+Wxz6oeZ1cJ8P6G/PZY0IKk4k/63TDsQf2kQq3+qoJeLm2kIBUNlZe3zgb4Zg==} + engines: {node: ^10 || ^12 || >=14} + dependencies: + nanoid: 3.3.4 + picocolors: 1.0.0 + source-map-js: 1.0.2 + dev: true + + /resolve/1.22.1: + resolution: {integrity: sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==} + hasBin: true + dependencies: + is-core-module: 2.11.0 + path-parse: 1.0.7 + supports-preserve-symlinks-flag: 1.0.0 + dev: true + + /rollup/3.19.1: + resolution: {integrity: sha512-lAbrdN7neYCg/8WaoWn/ckzCtz+jr70GFfYdlf50OF7387HTg+wiuiqJRFYawwSPpqfqDNYqK7smY/ks2iAudg==} + engines: {node: '>=14.18.0', npm: '>=8.0.0'} + hasBin: true + optionalDependencies: + fsevents: 2.3.2 + dev: true + + /source-map-js/1.0.2: + resolution: {integrity: sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==} + engines: {node: '>=0.10.0'} + dev: true + + /sqlite-wasm-esm/0.0.30: + resolution: {integrity: sha512-rLl+STKLfGXyBcpQlH6uEMMh76YXixY3s+qDEMzIiMMsyN7iXLmo4Mk1Su/6GoJFprSWP+cgOCWQsAbLELCEPg==} + dev: false + + /supports-preserve-symlinks-flag/1.0.0: + resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} + engines: {node: '>= 0.4'} + dev: true + + /vite/4.1.4: + resolution: {integrity: sha512-3knk/HsbSTKEin43zHu7jTwYWv81f8kgAL99G5NWBcA1LKvtvcVAC4JjBH1arBunO9kQka+1oGbrMKOjk4ZrBg==} + engines: {node: ^14.18.0 || >=16.0.0} + hasBin: true + peerDependencies: + '@types/node': '>= 14' + less: '*' + sass: '*' + stylus: '*' + sugarss: '*' + terser: ^5.4.0 + peerDependenciesMeta: + '@types/node': + optional: true + less: + optional: true + sass: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + dependencies: + esbuild: 0.16.17 + postcss: 8.4.21 + resolve: 1.22.1 + rollup: 3.19.1 + optionalDependencies: + fsevents: 2.3.2 + dev: true diff --git a/demo/ui/src/app.js b/demo/ui/src/app.js new file mode 100644 index 0000000..fe6fa41 --- /dev/null +++ b/demo/ui/src/app.js @@ -0,0 +1,206 @@ +import {LitElement, html} from 'lit'; +import './item.js'; +import './virtual-scroll'; +import './styles.css'; + +const columns = ['name', 'email', 'streetname', 'housenumber', 'city', 'country']; + +class App extends LitElement { + + static get properties() { + return { + data: {type: Array}, + dbWorker: {}, + filters: {type: Object}, + where: {}, + sort: {type: Object} + } + } + + constructor() { + super(); + this.filters = { + name: {visible: "hidden", value: ""}, + email: {visible: "hidden", value: ""}, + streetname: {visible: "hidden", value: ""}, + housenumber: {visible: "hidden", value: ""}, + city: {visible: "hidden", value: ""}, + country: {visible: "hidden", value: ""}, + } + this.where = ""; + this.data = []; + this.sort = { + prevColumn: undefined, + column: undefined, + order: undefined + } + + // sqlite needs a worker thread + // there is also a promise based sqlite wrapper, but the esm wrapper used here does not support that + this.dbWorker = new Worker(new URL('./database.js', import.meta.url), { + type: 'module', + }); + + // listen for events from the database worker + this.dbWorker.onmessage = (e) => { + if (e.data === "db ready") { + this.dbWorker.postMessage("SELECT rowid, name, email, streetname, housenumber, city, country FROM customers"); + } else { + if (e.data) { + this.data = e.data; + } + } + } + + // listen for user input, execute the updated query + this.addEventListener('filterupdate-event', e => { + this.where = e.detail.message; + this.updateQuery(); + }); + + document.getElementById("body").addEventListener("keyup", e => { + if (e.code === 'Escape') { + columns.forEach(c => this.filters[c].visible = "hidden"); + } + this.requestUpdate(); + }); + } + + updateQuery() { + let query = "SELECT rowid, name, email, streetname, housenumber, city, country FROM customers"; + if (this.where.length > 0) { + query += ` WHERE ${this.where}`; + } + if (this.sort.column && this.sort.order) { + query += ` ORDER BY ${this.sort.column} ${this.sort.order}` + } + this.dbWorker.postMessage(query); + } + + firstUpdated() { + columns.forEach(c => { + document.getElementById(c).addEventListener("click", e => { + this.filters[e.target.id].visible = "visible"; + this.requestUpdate(); + setTimeout(() => this.shadowRoot.getElementById(`i-${e.target.id}`).focus(), 10); + }); + + document.getElementById(`s-${c}`).addEventListener("click", e => { + this.sort.prevColumn = this.sort.column; + this.sort.column = e.target.id.substring(2); + if (this.sort.prevColumn !== this.sort.column){ + this.sort.order = undefined; + } + + if (!this.sort.order) { + this.sort.order = "ASC"; + } else if (this.sort.order === 'ASC') { + this.sort.order = "DESC"; + } else { + this.sort.order = undefined; + } + this.updateQuery(); + }); + + const element = this.shadowRoot.getElementById(`f-${c}`); + element.addEventListener("keyup", e => { + if (e.code === 'Escape' || e.code === 'Enter') { + this.filters[e.target.id.substring(2)].visible = "hidden"; + this.requestUpdate(); + } + } + ); + + element.addEventListener("focusout", e => { + this.filters[e.target.id.substring(2)].visible = "hidden"; + this.requestUpdate(); + } + ); + }); + } + + render() { + return html` + + +
+
+ this.change(e)}> +
+
+ this.change(e)}> +
+
+ this.change(e)}> +
+
+ this.change(e)}> +
+
+ this.change(e)}> +
+
+ this.change(e)}> +
+
+ + `}"> + +
${this.data.length} results
`; + } + + createWhereClause() { + return columns + .filter(item => this.filters[item].value && this.filters[item].value !== '') + .map(item => `${item} like '%${this.filters[item].value}%'`) + .join(" AND "); + } + + change(e) { + this.filters[e.target.id.substring(2)].value = e.target.value; + this.dispatchEvent(new CustomEvent('filterupdate-event', { + detail: {message: this.createWhereClause()}, + bubbles: true, + composed: true + })); + } +} + +if (!customElements.get('virtual-scroller')) { + customElements.define('virtual-scroller', App); +} \ No newline at end of file diff --git a/demo/ui/src/database.js b/demo/ui/src/database.js new file mode 100644 index 0000000..3168e56 --- /dev/null +++ b/demo/ui/src/database.js @@ -0,0 +1,44 @@ +import sqlite3InitModule from "sqlite-wasm-esm"; + +(async () => { + let db; + + const error = (...args) => console.log('error', ...args); + let sqlite3 = await sqlite3InitModule({printErr: error,}); + + const dataBuffer = await fetch("/api/db/customers"); + try { + // save the response in opfs:my.db + const root = await navigator.storage.getDirectory(); + const draftFile = await root.getFileHandle("my.db", {create: true}); + const accessHandle = await draftFile.createSyncAccessHandle(); + accessHandle.write(new Uint8Array(await dataBuffer.arrayBuffer())); + + // release the lock, so the database can read the file + await accessHandle.close(); + + // open database using opfs and my.db + db = new sqlite3.opfs.OpfsDb('my.db'); + postMessage("db ready"); + } catch (error) { + // getting the accessHandle may fail if there are other locks + console.log(error); + } + + // listens to events from main thread + onmessage = (e) => { + let data = []; + + db.exec({ + sql: e.data, // the query + callback: function (row) { + // fetch the data, row by row + // row is [value1, value2, ...] + data.push(row); + } + }); + + // pass the data as a message to the main thread + postMessage(data); + } +})(); \ No newline at end of file diff --git a/demo/ui/src/item.js b/demo/ui/src/item.js new file mode 100644 index 0000000..74f8dae --- /dev/null +++ b/demo/ui/src/item.js @@ -0,0 +1,39 @@ +import {LitElement, html} from 'lit'; + +class Item extends LitElement { + render() { + return html` + +
+
${this.item[1]}
+
${this.item[2]}
+
${this.item[3]}
+
${this.item[4]}
+
${this.item[5]}
+
${this.item[6]}
+
+ `; + } +} + +Item.properties = () => ({ + item: {type: Object, attribute: false, reflect: false}, +}); + +if (!customElements.get('x-item')) { + customElements.define('x-item', Item); +} diff --git a/demo/ui/src/result-count.js b/demo/ui/src/result-count.js new file mode 100644 index 0000000..5eaf45f --- /dev/null +++ b/demo/ui/src/result-count.js @@ -0,0 +1,28 @@ +import {LitElement, html} from "lit"; + +class ResultCount extends LitElement { + static get properties() { + return { + count: {type: Number, attribute: false}, + } + } + + constructor() { + super(); + this.count = 10; + this.addEventListener('someEvent', e => { + console.log("count"); + this.count = e.detail.message; + }); + } + + render() { + return html` +

${this.count} results

+ `; + } +} + +if (!customElements.get('x-result-count')) { + customElements.define('x-result-count', ResultCount); +} \ No newline at end of file diff --git a/demo/ui/src/sort.svg b/demo/ui/src/sort.svg new file mode 100644 index 0000000..8f14a0b --- /dev/null +++ b/demo/ui/src/sort.svg @@ -0,0 +1,15 @@ + + + + + + + + \ No newline at end of file diff --git a/demo/ui/src/styles.css b/demo/ui/src/styles.css new file mode 100644 index 0000000..44d093b --- /dev/null +++ b/demo/ui/src/styles.css @@ -0,0 +1,38 @@ +body { + font-family: sans-serif; +} + +virtual-scroller { + display: flex; + height: 80vh; + width: 100%; + overflow: scroll; +} + +.header { + height: 1em; + display: inline-block; + width: 15.9%; + font-weight: bold; +} + +img { + cursor: pointer; +} + +.filter { + cursor: pointer; + float: right; + color: gray; + font-size: larger; + transform: translate(0, -3px); +} + +img { + width: 1em; + height: 0.7em; +} + +.header-row { + border: solid #eee 1px; +} \ No newline at end of file diff --git a/demo/ui/src/user-filter.js b/demo/ui/src/user-filter.js new file mode 100644 index 0000000..5706bac --- /dev/null +++ b/demo/ui/src/user-filter.js @@ -0,0 +1,56 @@ +import {LitElement, html} from "lit"; + +class UserFilter extends LitElement { + static get properties() { + return { + + } + } + + constructor() { + super(); + this.name = ""; + this.email = ""; + this.streetname = ""; + this.housenumber = ""; + this.city = ""; + this.country = ""; + } + + createWhereClause() { + return ['name', 'email', 'streetname', 'housenumber', 'city', 'country'] + .filter(item => this[item] && this[item] !== '') + .map(item => `${item} like '%${this[item]}%'`) + .join(" AND "); + } + + change(e) { + this[e.target.id] = e.target.value; + this.dispatchEvent(new CustomEvent('filterupdate-event', { + detail: {message: this.createWhereClause()}, + bubbles: true, + composed: true + })); + } + + render() { + return html` + + `; + } + +} + +if (!customElements.get('x-user-filter')) { + customElements.define('x-user-filter', UserFilter); +} \ No newline at end of file diff --git a/demo/ui/src/virtual-scroll.js b/demo/ui/src/virtual-scroll.js new file mode 100644 index 0000000..725d22e --- /dev/null +++ b/demo/ui/src/virtual-scroll.js @@ -0,0 +1,86 @@ +import {LitElement, html} from 'lit'; +import {repeat} from 'lit/directives/repeat.js'; +import './user-filter.js'; + +class VirtualScroller extends LitElement { + constructor() { + super(); + this.currentBase = this.currentBase === undefined ? 0 : this.currentBase; + this.onScroll = this.onScroll.bind(this); + this.size = this.size || 18; + } + + connectedCallback() { + super.connectedCallback(); + this.addEventListener('scroll', this.onScroll); + this.wrapperHeight = this.getClientRects()[0].height; + } + + onScroll(event) { + if (this.scrollTicking) { + window.cancelAnimationFrame(this.scrollTicking); + this.scrollTicking = null; + } + this.scrollTicking = window.requestAnimationFrame(() => { + this.currentBase = Math.round(this.scrollTop / this.size); + }); + } + + register(inputElements){ + inputElements.addEventListener("change"); + } + + render() { + const listSize = Math.round(this.wrapperHeight / this.size) + 2; + const filteredList = this.items.slice( + this.currentBase, + this.currentBase + listSize + ); + this.style.setProperty( + '--vs-top-height', + `${this.currentBase * this.size}px` + ); + this.style.setProperty( + '--vs-bottom-heig ht', + `${(this.items.length - listSize - this.currentBase) * this.size}px` + ); + return html` + +
+ + ${repeat(filteredList, this.idFn, this.renderFn)} +
+ `; + } +} + +Object.defineProperty(VirtualScroller, 'properties', { + get: () => ({ + size: {type: Number, attribute: true, reflect: true}, + currentBase: {type: Number, attribute: true, reflect: true}, + items: {type: Array, attribute: false, reflect: false}, + idFn: {type: Function, attribute: false, reflect: false}, + renderFn: {type: Function, attribute: false, reflect: false}, + }), +}); + +if (!customElements.get('x-virtual-scroller')) { + customElements.define('x-virtual-scroller', VirtualScroller); +} diff --git a/demo/ui/vite.config.js b/demo/ui/vite.config.js new file mode 100644 index 0000000..a0309fd --- /dev/null +++ b/demo/ui/vite.config.js @@ -0,0 +1,27 @@ +import { defineConfig } from 'vite'; +import fs from 'fs'; + +export default defineConfig({ + optimizeDeps: { + exclude: ['sqlite-wasm-esm'], // TODO remove once fixed https://github.com/vitejs/vite/issues/8427 + }, + dbWorker: { + format: 'es' + }, + server: { + https: { + key: fs.readFileSync('./.cert/key.pem'), + cert: fs.readFileSync('./.cert/cert.pem'), + }, + headers: { + "Cross-Origin-Opener-Policy": "same-origin", + "Cross-Origin-Embedder-Policy": "require-corp" + }, + proxy: { + '/api': { + target: 'http://localhost:8080', + changeOrigin: true, + }, + }, + }, +}); \ No newline at end of file diff --git a/fileviewer/pom.xml b/fileviewer/pom.xml new file mode 100644 index 0000000..ab2da91 --- /dev/null +++ b/fileviewer/pom.xml @@ -0,0 +1,46 @@ + + + + sqlighter-pom + nl.sanderhautvast + 1.1.1 + + 4.0.0 + + fileviewer + 1.1.1 + + + nl.sanderhautvast + sqlighter + ${project.version} + compile + + + + com.fasterxml.jackson.core + jackson-databind + 2.14.2 + + + org.projectlombok + lombok + 1.18.26 + + + org.junit.jupiter + junit-jupiter-engine + 5.9.2 + test + + + + + 11 + 11 + UTF-8 + + + \ No newline at end of file diff --git a/fileviewer/src/main/java/nl/sanderhautvast/sqlighter/fileviewer/Main.java b/fileviewer/src/main/java/nl/sanderhautvast/sqlighter/fileviewer/Main.java new file mode 100644 index 0000000..bbce5bc --- /dev/null +++ b/fileviewer/src/main/java/nl/sanderhautvast/sqlighter/fileviewer/Main.java @@ -0,0 +1,61 @@ +package nl.sanderhautvast.sqlighter.fileviewer; + +import nl.sanderhautvast.sqlighter.fileviewer.model.Metadatabase; +import nl.sanderhautvast.sqlighter.fileviewer.page.PageReader; +import nl.sanderhautvast.sqlighter.fileviewer.page.RootpageReader; + +import java.io.FileInputStream; +import java.io.IOException; +import java.nio.ByteBuffer; + +/** + * Outputs the lowlevel structure of the database file as json object. + * Meant to be piped into jq / other. + *

+ *

+ * Can/should be extended to find more corruption in sqlite files. + */ +public class Main { + + public static void main(String[] args) throws IOException { + String filename = args[0]; //TODO cmdline arg validation + + // first 100 bytes contain the header part with the actual pagesize used, which is what we'll use as + // size of the bytebuffer as well. So first we read 100 bytes, then reopen the file + // reading the whole page (excluding the header) and then the following pages + Metadatabase metadatabase = readRootPage(filename); + + ByteBuffer buffer = ByteBuffer.allocate(metadatabase.getPagesize()); + PageReader pageReader = new PageReader(metadatabase); + + try (FileInputStream file = new FileInputStream(filename)) { + for (long pageNumber = 1; ; pageNumber += 1) { + buffer.position(0); + int nread = file.getChannel().read(buffer); + + if (nread == 0) { + break; //regular end + } else if (nread < metadatabase.getPagesize()) { + break; + } else { + buffer.position(0); + if (pageNumber == 1) { + SchemaReader schemaReader = new SchemaReader(metadatabase); + metadatabase.getSchemaRecords().addAll(schemaReader.readSchema(buffer)); + } else { + pageReader.readPage(buffer, pageNumber); + } + } + } + } + System.out.println(metadatabase.report()); + } + + private static Metadatabase readRootPage(String filename) throws IOException { + try (FileInputStream file = new FileInputStream(filename)) { + ByteBuffer headerDataBUffer = ByteBuffer.allocate(0x100); + file.getChannel().read(headerDataBUffer); + return RootpageReader.read(headerDataBUffer); + } + } +} diff --git a/fileviewer/src/main/java/nl/sanderhautvast/sqlighter/fileviewer/RecordReader.java b/fileviewer/src/main/java/nl/sanderhautvast/sqlighter/fileviewer/RecordReader.java new file mode 100644 index 0000000..d01d962 --- /dev/null +++ b/fileviewer/src/main/java/nl/sanderhautvast/sqlighter/fileviewer/RecordReader.java @@ -0,0 +1,42 @@ +package nl.sanderhautvast.sqlighter.fileviewer; + +import nl.sanderhautvast.sqlighter.Varint; +import nl.sanderhautvast.sqlighter.fileviewer.data.*; +import nl.sanderhautvast.sqlighter.fileviewer.data.ReadOnlyRecord; +import nl.sanderhautvast.sqlighter.fileviewer.model.Metadatabase; + +import java.nio.ByteBuffer; +import java.util.ArrayList; +import java.util.List; + +public class RecordReader { + + private final Metadatabase metadatabase; + + public RecordReader(Metadatabase metadatabase) { + this.metadatabase = metadatabase; + } + + @SuppressWarnings("unused") // leaving bits in, without using them, because it works as documentation + public ReadOnlyRecord read(ByteBuffer buffer) { + long payloadLength = Varint.read(buffer); + long rowId = Varint.read(buffer); + long columnLengthSum = Varint.read(buffer); + + int mark = buffer.position(); + + List columnTypes = new ArrayList<>(); + while (buffer.position() < mark + columnLengthSum -1) { + columnTypes.add(Varint.read(buffer)); + } + + ReadOnlyRecord record = new ReadOnlyRecord(rowId); + for (long columnType : columnTypes) { + record.addValue(ReadOnlyValue.read(buffer, columnType, metadatabase.getEncoding().toCharset())); + } + + return record; + } + + +} diff --git a/fileviewer/src/main/java/nl/sanderhautvast/sqlighter/fileviewer/SchemaReader.java b/fileviewer/src/main/java/nl/sanderhautvast/sqlighter/fileviewer/SchemaReader.java new file mode 100644 index 0000000..ee272f3 --- /dev/null +++ b/fileviewer/src/main/java/nl/sanderhautvast/sqlighter/fileviewer/SchemaReader.java @@ -0,0 +1,52 @@ +package nl.sanderhautvast.sqlighter.fileviewer; + +import nl.sanderhautvast.sqlighter.SchemaRecord; +import nl.sanderhautvast.sqlighter.fileviewer.data.ReadOnlyRecord; +import nl.sanderhautvast.sqlighter.fileviewer.model.Metadatabase; +import nl.sanderhautvast.sqlighter.fileviewer.model.Table; + +import java.nio.ByteBuffer; +import java.util.ArrayList; +import java.util.List; + +import static nl.sanderhautvast.sqlighter.fileviewer.util.UnsignedIntReader.readU16; +import static nl.sanderhautvast.sqlighter.fileviewer.util.UnsignedIntReader.readU8; + +public class SchemaReader { + private final Metadatabase meta; + + public SchemaReader(Metadatabase meta) { + this.meta = meta; + } + + + @SuppressWarnings("unused") + // leaving bits in, without using them, because it may work as documentation + List readSchema(ByteBuffer buffer) { + // skip page type 0x0D at #100 + buffer.position(101); + buffer.limit(meta.getPagesize()); + + long freeBlockStart = readU16(buffer); + long nrCells = readU16(buffer); + int startOfContentArea = readU16(buffer); + long nrFragmentedFreeBytes = readU8(buffer); + + buffer.position(startOfContentArea); + List records = new ArrayList<>(); + RecordReader recordReader = new RecordReader(meta); + + for (int i = 0; i < nrCells; i++) { + ReadOnlyRecord record = recordReader.read(buffer); + String name = record.getStringValue(1).getValue(); + long rootPage = record.getIntegerValue(3).getValue().intValue(); + String sqlObjectType = record.getStringValue(0).getValue(); + + String sql = record.getStringValue(4).getValue(); + records.add(new SchemaRecord(record.getRowId(), name, rootPage, sql)); + meta.addTable(new Table(name, rootPage)); + } + + return records; + } +} diff --git a/fileviewer/src/main/java/nl/sanderhautvast/sqlighter/fileviewer/data/BlobValue.java b/fileviewer/src/main/java/nl/sanderhautvast/sqlighter/fileviewer/data/BlobValue.java new file mode 100644 index 0000000..979831e --- /dev/null +++ b/fileviewer/src/main/java/nl/sanderhautvast/sqlighter/fileviewer/data/BlobValue.java @@ -0,0 +1,35 @@ +package nl.sanderhautvast.sqlighter.fileviewer.data; + + +import nl.sanderhautvast.sqlighter.Varint; + +import java.nio.BufferUnderflowException; +import java.nio.ByteBuffer; + +public class BlobValue extends ReadOnlyValue { + + public BlobValue(byte[] value) { + super(Varint.write(value.length * 2L + 12), value); + } + + + @Override + public byte[] getValue() { + return value; + } + + @Override + int getLength() { + return type.length + value.length; + } + + public static BlobValue read(int length, ByteBuffer in) { + byte[] bytes = new byte[length]; + try { + in.get(bytes); + return new BlobValue(bytes); + } catch (BufferUnderflowException e) { + throw new IllegalStateException("should have read " + length + " bytes", e); + } + } +} diff --git a/fileviewer/src/main/java/nl/sanderhautvast/sqlighter/fileviewer/data/FloatValue.java b/fileviewer/src/main/java/nl/sanderhautvast/sqlighter/fileviewer/data/FloatValue.java new file mode 100644 index 0000000..ff17421 --- /dev/null +++ b/fileviewer/src/main/java/nl/sanderhautvast/sqlighter/fileviewer/data/FloatValue.java @@ -0,0 +1,31 @@ +package nl.sanderhautvast.sqlighter.fileviewer.data; + + +import java.nio.ByteBuffer; + +/** + * 64-bit float type + */ +public class FloatValue extends ReadOnlyValue { + + final private double externalValue; + private static final byte FLOAT_TYPE = 7; + + + public FloatValue(double value) { + super(new byte[]{FLOAT_TYPE}, ByteBuffer.wrap(new byte[8]).putDouble(0, value).array()); + this.externalValue = value; + } + + @Override + public Double getValue() { + return externalValue; + } + + @Override + int getLength() { + return 9; // 1 for type, 8 for 64 bits + } + + +} diff --git a/fileviewer/src/main/java/nl/sanderhautvast/sqlighter/fileviewer/data/IntegerValue.java b/fileviewer/src/main/java/nl/sanderhautvast/sqlighter/fileviewer/data/IntegerValue.java new file mode 100644 index 0000000..30a1e2b --- /dev/null +++ b/fileviewer/src/main/java/nl/sanderhautvast/sqlighter/fileviewer/data/IntegerValue.java @@ -0,0 +1,47 @@ +package nl.sanderhautvast.sqlighter.fileviewer.data; + +import nl.sanderhautvast.sqlighter.data.LtValue; + +/* + * Uses long (s64) as standard integer representation + */ +public class IntegerValue extends ReadOnlyValue { + + private final long externalValue; + + public IntegerValue(long value) { + super(ReadOnlyValue.getIntegerType(value), LtValue.getValueAsBytes(value)); + this.externalValue = value; //See StringValue + } + + public IntegerValue(byte[] typeByteRep, byte[] valueByteRep) { + super(typeByteRep, valueByteRep); + this.externalValue = bytesToLong(valueByteRep); + } + + @Override + int getLength() { + return type.length + value.length; + } + + + + @Override + public Long getValue() { + return externalValue; + } + + public static long bytesToLong(final byte[] b) { + long n = 0; + for (int i = 0; i < b.length; i++) { + byte v = b[i]; + int shift = ((b.length - i - 1) * 8); + if (i == 0 && (v & 0x80) != 0) { + n -= (0x80L << shift); + v &= 0x7f; + } + n += ((long)(v&0xFF)) << shift; + } + return n; + } +} \ No newline at end of file diff --git a/fileviewer/src/main/java/nl/sanderhautvast/sqlighter/fileviewer/data/ReadOnlyRecord.java b/fileviewer/src/main/java/nl/sanderhautvast/sqlighter/fileviewer/data/ReadOnlyRecord.java new file mode 100644 index 0000000..e1183e3 --- /dev/null +++ b/fileviewer/src/main/java/nl/sanderhautvast/sqlighter/fileviewer/data/ReadOnlyRecord.java @@ -0,0 +1,76 @@ +package nl.sanderhautvast.sqlighter.fileviewer.data; + +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; + +/** + * Record in sqlite database. + * Used for reading and writing. + */ +public class ReadOnlyRecord { + + + private final long rowId; + + private final List> values = new ArrayList<>(); + + public ReadOnlyRecord(long rowId) { + this.rowId = rowId; + } + + public void addValue(ReadOnlyValue value) { + this.values.add(value); + } + + public int length() { + return values.stream().mapToInt(ReadOnlyValue::getLength).sum() + 1; + } + + public long getRowId() { + return rowId; + } + + @SuppressWarnings("unused") + public List> getValues() { + return values; + } + + /** + * returns the value at the specified column index (0 based) + */ + public ReadOnlyValue getValue(int column) { + return values.get(column); + } + + public StringValue getStringValue(int column) { + ReadOnlyValue value = getValue(column); + if (value instanceof StringValue) { + return (StringValue) value; + } else { + throw new IllegalCallerException("value is not a StringValue, but a " + value.getClass().getSimpleName()); + } + } + + public IntegerValue getIntegerValue(int column) { + ReadOnlyValue value = getValue(column); + if (value instanceof IntegerValue) { + return (IntegerValue) value; + } else { + throw new IllegalCallerException("value is not a IntegerValue, but a " + value.getClass().getSimpleName()); + } + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + ReadOnlyRecord record = (ReadOnlyRecord) o; + return rowId == record.rowId; + } + + @Override + public int hashCode() { + return Objects.hash(rowId); + } +} diff --git a/fileviewer/src/main/java/nl/sanderhautvast/sqlighter/fileviewer/data/ReadOnlyValue.java b/fileviewer/src/main/java/nl/sanderhautvast/sqlighter/fileviewer/data/ReadOnlyValue.java new file mode 100644 index 0000000..9d9796b --- /dev/null +++ b/fileviewer/src/main/java/nl/sanderhautvast/sqlighter/fileviewer/data/ReadOnlyValue.java @@ -0,0 +1,98 @@ +package nl.sanderhautvast.sqlighter.fileviewer.data; + +import nl.sanderhautvast.sqlighter.Varint; +import nl.sanderhautvast.sqlighter.data.LtValue; + +import java.nio.ByteBuffer; +import java.nio.charset.Charset; + +/* + * NB Value classes derive their equality from their identity. I.e. no equals/hashcode + */ +public abstract class ReadOnlyValue { + + protected final byte[] type; + protected final byte[] value; + + protected ReadOnlyValue(byte[] type, byte[] value) { + this.type = type; + this.value = value; + } + + /** + * returns the user representation of the value + */ + public abstract T getValue(); + + /** + * Returns the length of serialType + the length of the value + */ + abstract int getLength(); + + /** + * Reads a value from the buffer + * + * @param buffer Bytebuffer containing the database page. + * @param columnType sqlite type representation + * @param charset database charset + * + * @return the value implementation + */ + public static ReadOnlyValue read(ByteBuffer buffer, long columnType, Charset charset) { + if (columnType == 0) { + return null; + } else if (columnType < 6L) { + byte[] integerBytes = new byte[getvalueLengthForType(columnType)]; + buffer.get(integerBytes); + //TODO columnType is first decoded, then encoded again + return new IntegerValue(Varint.write(columnType), integerBytes); + } else if (columnType == 7) { + return new FloatValue(buffer.getDouble()); + } else if (columnType == 8) { + return new IntegerValue(0); + } else if (columnType == 9) { + return new IntegerValue(1); + } else if (columnType >= 12 && columnType % 2 == 0) { + return BlobValue.read(getvalueLengthForType(columnType), buffer); + } else if (columnType >= 13) { + return StringValue.read(getvalueLengthForType(columnType), buffer, charset); + } else throw new IllegalStateException("unknown column type" + columnType); + } + + private static int getvalueLengthForType(long columnType) { + // can't switch on long + if (columnType == 0 || columnType == 8 || columnType == 9) { + return 0; + } else if (columnType < 5) { + return (int) columnType; + } else if (columnType == 5) { + return 6; + } else if (columnType == 6 || columnType == 7) { + return 8; + } else if (columnType < 12) { + return -1; + } else { + if (columnType % 2 == 0) { + return (int) ((columnType - 12) >> 1); + } else { + return (int) ((columnType - 13) >> 1); + } + } + } + + + public static byte[] getIntegerType(long value) { + if (value == 0) { + return new byte[]{8}; + } else if (value == 1) { + return new byte[]{9}; + } else { + int length = LtValue.getLengthOfByteEncoding(value); + if (length < 5) { + return Varint.write(length); + } else if (length < 7) { + return Varint.write(5); + } else return Varint.write(6); + } + } +} diff --git a/fileviewer/src/main/java/nl/sanderhautvast/sqlighter/fileviewer/data/StringValue.java b/fileviewer/src/main/java/nl/sanderhautvast/sqlighter/fileviewer/data/StringValue.java new file mode 100644 index 0000000..16d6d4b --- /dev/null +++ b/fileviewer/src/main/java/nl/sanderhautvast/sqlighter/fileviewer/data/StringValue.java @@ -0,0 +1,40 @@ +package nl.sanderhautvast.sqlighter.fileviewer.data; + + +import nl.sanderhautvast.sqlighter.Varint; + +import java.nio.BufferUnderflowException; +import java.nio.ByteBuffer; +import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; + +public class StringValue extends ReadOnlyValue { + private final String externalValue; + + public StringValue(String value) { + super(Varint.write(value == null ? 0 : value.getBytes(StandardCharsets.UTF_8).length * 2L + 13), + value == null ? new byte[0] : value.getBytes(StandardCharsets.UTF_8)); + this.externalValue = value; /* only for reading from db. could be optimized by not storing this when writing, + or create separate value classes for reading and writing */ + } + + @Override + int getLength() { + return type.length + value.length; + } + + public static StringValue read(int length, ByteBuffer in, Charset charset) { + byte[] bytes = new byte[length]; + try { + in.get(bytes); + return new StringValue(new String(bytes, charset)); + } catch (BufferUnderflowException e) { + throw new IllegalStateException("should have read " + length + " bytes", e); + } + } + + @Override + public String getValue() { + return externalValue; + } +} diff --git a/fileviewer/src/main/java/nl/sanderhautvast/sqlighter/fileviewer/model/Cell.java b/fileviewer/src/main/java/nl/sanderhautvast/sqlighter/fileviewer/model/Cell.java new file mode 100644 index 0000000..27073da --- /dev/null +++ b/fileviewer/src/main/java/nl/sanderhautvast/sqlighter/fileviewer/model/Cell.java @@ -0,0 +1,4 @@ +package nl.sanderhautvast.sqlighter.fileviewer.model; + +public class Cell { +} diff --git a/fileviewer/src/main/java/nl/sanderhautvast/sqlighter/fileviewer/model/Index.java b/fileviewer/src/main/java/nl/sanderhautvast/sqlighter/fileviewer/model/Index.java new file mode 100644 index 0000000..9988853 --- /dev/null +++ b/fileviewer/src/main/java/nl/sanderhautvast/sqlighter/fileviewer/model/Index.java @@ -0,0 +1,19 @@ +package nl.sanderhautvast.sqlighter.fileviewer.model; + +import lombok.Data; + +import java.util.ArrayList; +import java.util.List; + +@Data +public class Index { + private final String name; + private final List indexCells = new ArrayList<>(); + + public void addCell(IndexCell indexCell) { + indexCells.add(indexCell); + } + + +} + diff --git a/fileviewer/src/main/java/nl/sanderhautvast/sqlighter/fileviewer/model/IndexCell.java b/fileviewer/src/main/java/nl/sanderhautvast/sqlighter/fileviewer/model/IndexCell.java new file mode 100644 index 0000000..f3eb19e --- /dev/null +++ b/fileviewer/src/main/java/nl/sanderhautvast/sqlighter/fileviewer/model/IndexCell.java @@ -0,0 +1,23 @@ +package nl.sanderhautvast.sqlighter.fileviewer.model; + +import lombok.Getter; +import lombok.Setter; +import nl.sanderhautvast.sqlighter.fileviewer.data.ReadOnlyValue; + +import java.util.ArrayList; +import java.util.List; + +@Getter +@Setter +public class IndexCell extends Cell{ + private int valueType; + private int rowIdType; + private final List> indexValues = new ArrayList<>(); + + /* reference to the row in the table */ + private long rowid; + + public void addIndexValue(ReadOnlyValue value) { + this.indexValues.add(value); + } +} diff --git a/fileviewer/src/main/java/nl/sanderhautvast/sqlighter/fileviewer/model/InteriorCell.java b/fileviewer/src/main/java/nl/sanderhautvast/sqlighter/fileviewer/model/InteriorCell.java new file mode 100644 index 0000000..42e4b0c --- /dev/null +++ b/fileviewer/src/main/java/nl/sanderhautvast/sqlighter/fileviewer/model/InteriorCell.java @@ -0,0 +1,16 @@ +package nl.sanderhautvast.sqlighter.fileviewer.model; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonInclude; +import lombok.Data; + +@Data +@JsonInclude(JsonInclude.Include.NON_NULL) +public class InteriorCell extends Cell{ + @JsonIgnore + private long pageReference; + @JsonIgnore + private long lastRowId; + + +} diff --git a/fileviewer/src/main/java/nl/sanderhautvast/sqlighter/fileviewer/model/LeafCell.java b/fileviewer/src/main/java/nl/sanderhautvast/sqlighter/fileviewer/model/LeafCell.java new file mode 100644 index 0000000..b6fa584 --- /dev/null +++ b/fileviewer/src/main/java/nl/sanderhautvast/sqlighter/fileviewer/model/LeafCell.java @@ -0,0 +1,4 @@ +package nl.sanderhautvast.sqlighter.fileviewer.model; + +public class LeafCell extends Cell{ +} diff --git a/fileviewer/src/main/java/nl/sanderhautvast/sqlighter/fileviewer/model/Metadatabase.java b/fileviewer/src/main/java/nl/sanderhautvast/sqlighter/fileviewer/model/Metadatabase.java new file mode 100644 index 0000000..a80c49f --- /dev/null +++ b/fileviewer/src/main/java/nl/sanderhautvast/sqlighter/fileviewer/model/Metadatabase.java @@ -0,0 +1,93 @@ +package nl.sanderhautvast.sqlighter.fileviewer.model; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.databind.ObjectMapper; +import lombok.Data; +import nl.sanderhautvast.sqlighter.SchemaRecord; +import nl.sanderhautvast.sqlighter.fileviewer.util.Encoding; +import nl.sanderhautvast.sqlighter.fileviewer.util.Printer; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; + +import static nl.sanderhautvast.sqlighter.fileviewer.validation.Validator.validate; + +@Data +public class Metadatabase { + + public static final String HEADER = "53 51 4C 69 74 65 20 66 6F 72 6D 61 74 20 33 00"; + public static final int MAX_EMBEDDED_PAYLOAD_FRACTION = 64; + public static final int MIN_EMBEDDED_PAYLOAD_FRACTION = 32; + public static final int LEAF_PAYLOAD_FRACTION = 32; + + private String magicHeader; + private int pagesize; + private int writeversion; + private int readversion; + private int unusedPerPageSize; + private int maxEmbeddedPayloadFraction; + private int minEmbeddedPayloadFraction; + private int leafPayloadFraction; + private long fileChangeCounter; + private long sizeInPages; + private long pageNrFirstFreelistTrunkpage; + private long totalNrOfFreelistPages; + private long schemaCookie; + private long schemaFormatNumber; + private int defaultPageCachesize; + private long pageNrLargestRootBtreePage; + private Encoding encoding; + private long userVersion; + private boolean incrementalVacuumMode; + private long applicationID; + private String expansion; + private long versionValidFor; + private long sqliteVersion; + + private final List schemaRecords = new ArrayList<>(); + + @JsonIgnore + private HashMap pages = new HashMap<>(); + + public void addPage(long nr, PageNode page) { + pages.put(nr, page); + } + + // @JsonIgnore + private final List tables = new ArrayList<>(); + + public void addTable(Table table) { + tables.add(table); + } + + public void setMagicHeader(byte[] magicHeader) { + this.magicHeader = Printer.printHex(magicHeader); + validate("magic header", HEADER, this.magicHeader); + } + + public void setMaxEmbeddedPayloadFraction(int maxEmbeddedPayloadFraction) { + this.maxEmbeddedPayloadFraction = maxEmbeddedPayloadFraction; + validate("max embedded payload fraction", MAX_EMBEDDED_PAYLOAD_FRACTION, maxEmbeddedPayloadFraction); + } + + public void setMinEmbeddedPayloadFraction(int minEmbeddedPayloadFraction) { + validate("min embedded payload fraction", MIN_EMBEDDED_PAYLOAD_FRACTION, minEmbeddedPayloadFraction); + this.minEmbeddedPayloadFraction = minEmbeddedPayloadFraction; + } + + public void setLeafPayloadFraction(int leafPayloadFraction) { + this.leafPayloadFraction = leafPayloadFraction; + validate("leaf payload fraction", LEAF_PAYLOAD_FRACTION, leafPayloadFraction); + } + + public String report() throws IOException { + return new ObjectMapper().writeValueAsString(this); + } + + public void setExpansion(byte[] expansion) { + this.expansion = Printer.printHex(expansion); + } + +} diff --git a/fileviewer/src/main/java/nl/sanderhautvast/sqlighter/fileviewer/model/PageNode.java b/fileviewer/src/main/java/nl/sanderhautvast/sqlighter/fileviewer/model/PageNode.java new file mode 100644 index 0000000..c8761e4 --- /dev/null +++ b/fileviewer/src/main/java/nl/sanderhautvast/sqlighter/fileviewer/model/PageNode.java @@ -0,0 +1,41 @@ +package nl.sanderhautvast.sqlighter.fileviewer.model; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonInclude; +import lombok.Data; +import nl.sanderhautvast.sqlighter.page.PageType; + +import java.util.ArrayList; +import java.util.List; + +@Data +@JsonInclude(JsonInclude.Include.NON_EMPTY) +public class PageNode { + private final long number; + private PageType type; + private long cellCount; + + + @JsonIgnore + private final List cells = new ArrayList<>(); + + private final List childPages = new ArrayList<>(); + + @JsonIgnore + private Long rightMostReference; + + private PageNode rightMostChildPage; + + public PageNode(long number) { + this.number = number; + } + + public void addCell(Cell cell) { + cells.add(cell); + } + + public void addChildPage(PageNode page) { + childPages.add(page); + } + +} diff --git a/fileviewer/src/main/java/nl/sanderhautvast/sqlighter/fileviewer/model/Table.java b/fileviewer/src/main/java/nl/sanderhautvast/sqlighter/fileviewer/model/Table.java new file mode 100644 index 0000000..62421a7 --- /dev/null +++ b/fileviewer/src/main/java/nl/sanderhautvast/sqlighter/fileviewer/model/Table.java @@ -0,0 +1,26 @@ +package nl.sanderhautvast.sqlighter.fileviewer.model; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import lombok.Data; +import nl.sanderhautvast.sqlighter.fileviewer.data.ReadOnlyRecord; + +import java.util.ArrayList; +import java.util.List; + +@Data +public class Table { + private final String name; + private final long rootPage; + @JsonIgnore + private final List records = new ArrayList<>(); + private int nRecords = 0; + + @JsonIgnore + private final List interiorCells = new ArrayList<>(); + + public void addRecord(ReadOnlyRecord record) { + records.add(record); + nRecords += 1; + } + +} diff --git a/fileviewer/src/main/java/nl/sanderhautvast/sqlighter/fileviewer/page/IndexInteriorPageReader.java b/fileviewer/src/main/java/nl/sanderhautvast/sqlighter/fileviewer/page/IndexInteriorPageReader.java new file mode 100644 index 0000000..573fbb9 --- /dev/null +++ b/fileviewer/src/main/java/nl/sanderhautvast/sqlighter/fileviewer/page/IndexInteriorPageReader.java @@ -0,0 +1,16 @@ +package nl.sanderhautvast.sqlighter.fileviewer.page; + +import nl.sanderhautvast.sqlighter.fileviewer.model.Metadatabase; + +//TODO implement +public class IndexInteriorPageReader { + private final Metadatabase metadatabase; + + public IndexInteriorPageReader(Metadatabase metadatabase) { + this.metadatabase = metadatabase; + } + + public void readPage() { + + } +} diff --git a/fileviewer/src/main/java/nl/sanderhautvast/sqlighter/fileviewer/page/IndexLeafPageReader.java b/fileviewer/src/main/java/nl/sanderhautvast/sqlighter/fileviewer/page/IndexLeafPageReader.java new file mode 100644 index 0000000..3858b61 --- /dev/null +++ b/fileviewer/src/main/java/nl/sanderhautvast/sqlighter/fileviewer/page/IndexLeafPageReader.java @@ -0,0 +1,71 @@ +package nl.sanderhautvast.sqlighter.fileviewer.page; + +import nl.sanderhautvast.sqlighter.Varint; +import nl.sanderhautvast.sqlighter.fileviewer.data.ReadOnlyValue; +import nl.sanderhautvast.sqlighter.fileviewer.model.*; +import nl.sanderhautvast.sqlighter.page.PageType; +import nl.sanderhautvast.sqlighter.fileviewer.util.UnsignedIntReader; + +import java.nio.ByteBuffer; +import java.nio.charset.Charset; +import java.util.ArrayList; + +/* + * WIP + */ +public class IndexLeafPageReader { + private final Metadatabase metadatabase; + private final Charset charset; //stored so that it doesn't have to be retrieved every time + + public IndexLeafPageReader(Metadatabase metadatabase) { + this.metadatabase = metadatabase; + this.charset = metadatabase.getEncoding().toCharset(); + } + + @SuppressWarnings("unused") // leaving bits in, without using them, because it works as documentation + public void readPage(ByteBuffer buffer, long pageNumber) { + int freeblockStartLocation = UnsignedIntReader.readU16(buffer); + int nrCells = UnsignedIntReader.readU16(buffer); + int startOfContentArea = UnsignedIntReader.readU16(buffer); + int nrFragmentedFreeBytes = UnsignedIntReader.readU8(buffer); + + PageNode newPage=new PageNode(pageNumber); + newPage.setType(PageType.INDEX_LEAF); + newPage.setCellCount(nrCells); + + for (int i = 0; i < nrCells; i++) { + int cellOffset = UnsignedIntReader.readU16(buffer); + int mark = buffer.position(); + + buffer.position(cellOffset); + newPage.addCell(read(buffer)); + buffer.position(mark); + } + } + + /* + * has a similar structure as RecordReader.read, but the rowId needs to be handled differently + */ + @SuppressWarnings("unused") // leaving bits in, without using them, because it works as documentation + public IndexCell read(ByteBuffer buffer) { + IndexCell indexCell = new IndexCell(); + long payloadLength = Varint.read(buffer); + long startOfValues = Varint.read(buffer); + int mark = buffer.position(); + + ArrayList columnTypes = new ArrayList<>(); + while (buffer.position() < mark + startOfValues -1) { + columnTypes.add((int) Varint.read(buffer)); + } + + for (int columnType : columnTypes) { + indexCell.addIndexValue(ReadOnlyValue.read(buffer, columnType, charset)); + } + + @SuppressWarnings({"unchecked", "ConstantConditions"}) + Long rowid = ((ReadOnlyValue) ReadOnlyValue.read(buffer, columnTypes.get(columnTypes.size() - 1), charset)).getValue(); + indexCell.setRowid(rowid); + + return indexCell; + } +} \ No newline at end of file diff --git a/fileviewer/src/main/java/nl/sanderhautvast/sqlighter/fileviewer/page/PageReader.java b/fileviewer/src/main/java/nl/sanderhautvast/sqlighter/fileviewer/page/PageReader.java new file mode 100644 index 0000000..05532a8 --- /dev/null +++ b/fileviewer/src/main/java/nl/sanderhautvast/sqlighter/fileviewer/page/PageReader.java @@ -0,0 +1,30 @@ +package nl.sanderhautvast.sqlighter.fileviewer.page; + +import nl.sanderhautvast.sqlighter.SQLiteConstants; +import nl.sanderhautvast.sqlighter.fileviewer.model.Metadatabase; +import nl.sanderhautvast.sqlighter.fileviewer.util.UnsignedIntReader; + +import java.nio.ByteBuffer; + +public class PageReader { + + private final Metadatabase metadatabase; + + public PageReader(Metadatabase metadatabase) { + this.metadatabase = metadatabase; + } + + public void readPage(ByteBuffer buffer, long pageNumber) { + int pagetype = UnsignedIntReader.readU8(buffer); + switch (pagetype) { + case SQLiteConstants.TABLE_LEAF_PAGE: new TableLeafPageReader(metadatabase).readPage(buffer, pageNumber); + break; + case SQLiteConstants.TABLE_INTERIOR_PAGE: new TableInteriorPageReader(metadatabase).readPage(buffer, pageNumber); + break; + case SQLiteConstants.INDEX_LEAF_PAGE: new IndexLeafPageReader(metadatabase).readPage(buffer, pageNumber); + break; + case SQLiteConstants.INDEX_INTERIOR_PAGE: new IndexInteriorPageReader(metadatabase).readPage(); + break; + } + } +} diff --git a/fileviewer/src/main/java/nl/sanderhautvast/sqlighter/fileviewer/page/RootpageReader.java b/fileviewer/src/main/java/nl/sanderhautvast/sqlighter/fileviewer/page/RootpageReader.java new file mode 100644 index 0000000..82ac2c0 --- /dev/null +++ b/fileviewer/src/main/java/nl/sanderhautvast/sqlighter/fileviewer/page/RootpageReader.java @@ -0,0 +1,48 @@ +package nl.sanderhautvast.sqlighter.fileviewer.page; + +import nl.sanderhautvast.sqlighter.fileviewer.model.Metadatabase; +import nl.sanderhautvast.sqlighter.fileviewer.util.Encoding; + +import java.nio.ByteBuffer; + +import static nl.sanderhautvast.sqlighter.fileviewer.util.UnsignedIntReader.*; + +public class RootpageReader { + + public static Metadatabase read(ByteBuffer in) { + in.position(0); //seems clearer to me than using reset/flip etc + in.limit(100); + + Metadatabase m = new Metadatabase(); + m.setMagicHeader(readBytes(in, 16)); + m.setPagesize(readU16(in)); + m.setWriteversion(readU8(in)); + m.setReadversion(readU8(in)); + m.setUnusedPerPageSize(readU8(in)); + m.setMaxEmbeddedPayloadFraction(readU8(in)); + m.setMinEmbeddedPayloadFraction(readU8(in)); + m.setLeafPayloadFraction(readU8(in)); + m.setFileChangeCounter(readU32(in)); + m.setSizeInPages(readU32(in)); + m.setPageNrFirstFreelistTrunkpage(readU32(in)); + m.setTotalNrOfFreelistPages(readU32(in)); + m.setSchemaCookie(readU32(in)); + m.setSchemaCookie(readU32(in)); + m.setDefaultPageCachesize(in.getInt()); // it's signed say the docs + m.setPageNrLargestRootBtreePage(readU32(in)); + m.setEncoding(Encoding.fromCode((int) readU32(in))); // no truncate expected + m.setUserVersion(readU32(in)); + m.setIncrementalVacuumMode(readU32(in) > 0); + m.setApplicationID(readU32(in)); + m.setExpansion(readBytes(in, 20)); + m.setVersionValidFor(readU32(in)); + m.setSqliteVersion(readU32(in)); + return m; + } + + static byte[] readBytes(ByteBuffer in, int length) { + byte[] header = new byte[length]; + in.get(header); + return header; + } +} diff --git a/fileviewer/src/main/java/nl/sanderhautvast/sqlighter/fileviewer/page/TableInteriorPageReader.java b/fileviewer/src/main/java/nl/sanderhautvast/sqlighter/fileviewer/page/TableInteriorPageReader.java new file mode 100644 index 0000000..e765e63 --- /dev/null +++ b/fileviewer/src/main/java/nl/sanderhautvast/sqlighter/fileviewer/page/TableInteriorPageReader.java @@ -0,0 +1,54 @@ +package nl.sanderhautvast.sqlighter.fileviewer.page; + +import nl.sanderhautvast.sqlighter.Varint; +import nl.sanderhautvast.sqlighter.fileviewer.util.UnsignedIntReader; +import nl.sanderhautvast.sqlighter.fileviewer.model.InteriorCell; +import nl.sanderhautvast.sqlighter.fileviewer.model.Metadatabase; +import nl.sanderhautvast.sqlighter.fileviewer.model.PageNode; +import nl.sanderhautvast.sqlighter.page.PageType; + +import java.nio.ByteBuffer; + +public class TableInteriorPageReader { + private final Metadatabase metadatabase; + + public TableInteriorPageReader(Metadatabase metadatabase) { + this.metadatabase = metadatabase; + } + + @SuppressWarnings("unused") // leaving bits in, without using them, because it works as documentation + public void readPage(ByteBuffer buffer, long pageNumber) { + int freeblockStartLocation = UnsignedIntReader.readU16(buffer); + int nrCells = UnsignedIntReader.readU16(buffer); + int startOfContentArea = UnsignedIntReader.readU16(buffer); + int nrFragmentedFreeBytes = UnsignedIntReader.readU8(buffer); + long rightMostPointer = UnsignedIntReader.readU32(buffer); //? + + + try { + PageNode newPage = new PageNode(pageNumber); + newPage.setType(PageType.TABLE_INTERIOR); + newPage.setCellCount(nrCells); + newPage.setRightMostReference(rightMostPointer); + metadatabase.addPage(pageNumber,newPage); + + + for (int i = 0; i < nrCells; i++) { + int cellOffset = UnsignedIntReader.readU16(buffer); + int mark = buffer.position(); + + InteriorCell interiorCell = new InteriorCell(); + buffer.position(cellOffset); + long childPageNumber = UnsignedIntReader.readU32(buffer); + interiorCell.setPageReference(childPageNumber); + interiorCell.setLastRowId(Varint.read(buffer)); + + newPage.addCell(interiorCell); + buffer.position(mark); + } + } catch (Exception e) { + System.err.printf("Error at page number %d index %d (%#06x): ", pageNumber, buffer.position(), buffer.position()); + throw e; + } + } +} diff --git a/fileviewer/src/main/java/nl/sanderhautvast/sqlighter/fileviewer/page/TableLeafPageReader.java b/fileviewer/src/main/java/nl/sanderhautvast/sqlighter/fileviewer/page/TableLeafPageReader.java new file mode 100644 index 0000000..de02d6d --- /dev/null +++ b/fileviewer/src/main/java/nl/sanderhautvast/sqlighter/fileviewer/page/TableLeafPageReader.java @@ -0,0 +1,44 @@ +package nl.sanderhautvast.sqlighter.fileviewer.page; + +import nl.sanderhautvast.sqlighter.fileviewer.model.Metadatabase; +import nl.sanderhautvast.sqlighter.fileviewer.RecordReader; +import nl.sanderhautvast.sqlighter.fileviewer.model.PageNode; +import nl.sanderhautvast.sqlighter.page.PageType; +import nl.sanderhautvast.sqlighter.fileviewer.model.Table; +import nl.sanderhautvast.sqlighter.fileviewer.util.UnsignedIntReader; + +import java.nio.ByteBuffer; + +public class TableLeafPageReader { + private final Metadatabase metadatabase; + + public TableLeafPageReader(Metadatabase metadatabase) { + this.metadatabase = metadatabase; + } + + @SuppressWarnings("unused") // leaving bits in, without using them, because it works as documentation + public void readPage(ByteBuffer buffer, long pageNumber) { + int freeblockStartLocation = UnsignedIntReader.readU16(buffer); + int nrCells = UnsignedIntReader.readU16(buffer); + int startOfContentArea = UnsignedIntReader.readU16(buffer); + int nrFragmentedFreeBytes = UnsignedIntReader.readU8(buffer); + RecordReader recordReader = new RecordReader(metadatabase); + + PageNode newPage = new PageNode(pageNumber); + newPage.setType(PageType.TABLE_LEAF); + newPage.setCellCount(nrCells); + metadatabase.addPage(pageNumber, newPage); + } + + + // reads the actual records, want we that? + // make cmdline arg + private static void readPage(ByteBuffer buffer, RecordReader recordReader, Table table) { + int cellOffset = UnsignedIntReader.readU16(buffer); + int mark = buffer.position(); + + buffer.position(cellOffset); + table.addRecord(recordReader.read(buffer)); + buffer.position(mark); + } +} diff --git a/fileviewer/src/main/java/nl/sanderhautvast/sqlighter/fileviewer/util/Encoding.java b/fileviewer/src/main/java/nl/sanderhautvast/sqlighter/fileviewer/util/Encoding.java new file mode 100644 index 0000000..87d34d4 --- /dev/null +++ b/fileviewer/src/main/java/nl/sanderhautvast/sqlighter/fileviewer/util/Encoding.java @@ -0,0 +1,33 @@ +package nl.sanderhautvast.sqlighter.fileviewer.util; + +import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; + +public enum Encoding implements HasCode { + + UTF_8(1, StandardCharsets.UTF_8), + UTF_16LE(2, StandardCharsets.UTF_16LE), + UTF_16BE(3, StandardCharsets.UTF_16BE); + + + private final int code; + private final Charset charset; + + Encoding(int code, Charset charset) { + this.code = code; + this.charset = charset; + } + + @Override + public int getCode() { + return code; + } + + public static Encoding fromCode(int code) { + return HasCode.getFromCode(Encoding.class, code); + } + + public Charset toCharset() { + return charset; + } +} diff --git a/fileviewer/src/main/java/nl/sanderhautvast/sqlighter/fileviewer/util/HasCode.java b/fileviewer/src/main/java/nl/sanderhautvast/sqlighter/fileviewer/util/HasCode.java new file mode 100644 index 0000000..6194b9c --- /dev/null +++ b/fileviewer/src/main/java/nl/sanderhautvast/sqlighter/fileviewer/util/HasCode.java @@ -0,0 +1,15 @@ +package nl.sanderhautvast.sqlighter.fileviewer.util; + +public interface HasCode { + static E getFromCode(Class type, int code) { + for (E candidate : type.getEnumConstants()) { + if (candidate.getCode() == code) { + return candidate; + } + } + + throw new IllegalArgumentException("Cannot create " + type.getName() + " from the code " + code); + } + + int getCode(); +} diff --git a/fileviewer/src/main/java/nl/sanderhautvast/sqlighter/fileviewer/util/Printer.java b/fileviewer/src/main/java/nl/sanderhautvast/sqlighter/fileviewer/util/Printer.java new file mode 100644 index 0000000..e9202ea --- /dev/null +++ b/fileviewer/src/main/java/nl/sanderhautvast/sqlighter/fileviewer/util/Printer.java @@ -0,0 +1,22 @@ +package nl.sanderhautvast.sqlighter.fileviewer.util; + +import java.util.StringJoiner; + +/** + * debug util + */ +public class Printer { + + public static String printHex(byte[] bytes) { + StringJoiner s = new StringJoiner(" "); + for (byte aByte : bytes) { + s.add(leftpad(Long.toString(aByte & 0xFF, 16).toUpperCase())); + } + + return s.toString(); + } + + private static String leftpad(String text) { + return String.format("%1$2s", text).replace(' ', '0'); + } +} diff --git a/fileviewer/src/main/java/nl/sanderhautvast/sqlighter/fileviewer/util/UnsignedIntReader.java b/fileviewer/src/main/java/nl/sanderhautvast/sqlighter/fileviewer/util/UnsignedIntReader.java new file mode 100644 index 0000000..a7ca50a --- /dev/null +++ b/fileviewer/src/main/java/nl/sanderhautvast/sqlighter/fileviewer/util/UnsignedIntReader.java @@ -0,0 +1,22 @@ +package nl.sanderhautvast.sqlighter.fileviewer.util; + +import java.nio.ByteBuffer; + +/** + * reads big-endian unsigned integers from bytebuffer + */ +public class UnsignedIntReader { + public static long readU32(ByteBuffer buffer) { + return buffer.getInt() & 0xFFFFFFFFL; + } + + public static int readU16(ByteBuffer buffer) { + return buffer.getShort() & 0xFFFF; + } + + public static int readU8(ByteBuffer buffer) { + return buffer.get() & 0xFF; + } + + +} diff --git a/fileviewer/src/main/java/nl/sanderhautvast/sqlighter/fileviewer/validation/Array.java b/fileviewer/src/main/java/nl/sanderhautvast/sqlighter/fileviewer/validation/Array.java new file mode 100644 index 0000000..1bb2f2e --- /dev/null +++ b/fileviewer/src/main/java/nl/sanderhautvast/sqlighter/fileviewer/validation/Array.java @@ -0,0 +1,38 @@ +package nl.sanderhautvast.sqlighter.fileviewer.validation; + +// TODO use +public class Array { + public static Result compare(byte[] a1, byte[] a2) { + if (a1 == null) { + if (a2 == null) { + return new Result(true, "both are null"); + } else { + return new Result(false, "first is null, second is non-null"); + } + } else { + if (a2 == null) { + return new Result(false, "first is non-null, second is null"); + } + } + if (a1.length != a2.length) { + return new Result(false, "arrays do not have equal lengths: " + a1.length + " vs: " + a2.length); + } else { + for (int i = 0; i < a1.length; i++) { + if (a1[i] != a2[i]) { + return new Result(false, "arrays differ at index: " + i); + } + } + return new Result(true, "Same"); + } + } + + static class Result { + final boolean areEqual; + final String userMessage; + + Result(boolean areEqual, String userMessage) { + this.areEqual = areEqual; + this.userMessage = userMessage; + } + } +} diff --git a/fileviewer/src/main/java/nl/sanderhautvast/sqlighter/fileviewer/validation/ValidationException.java b/fileviewer/src/main/java/nl/sanderhautvast/sqlighter/fileviewer/validation/ValidationException.java new file mode 100644 index 0000000..838e3e6 --- /dev/null +++ b/fileviewer/src/main/java/nl/sanderhautvast/sqlighter/fileviewer/validation/ValidationException.java @@ -0,0 +1,8 @@ +package nl.sanderhautvast.sqlighter.fileviewer.validation; + +public class ValidationException extends RuntimeException{ + + public ValidationException(String message){ + super(message); + } +} diff --git a/fileviewer/src/main/java/nl/sanderhautvast/sqlighter/fileviewer/validation/Validator.java b/fileviewer/src/main/java/nl/sanderhautvast/sqlighter/fileviewer/validation/Validator.java new file mode 100644 index 0000000..b6ed72f --- /dev/null +++ b/fileviewer/src/main/java/nl/sanderhautvast/sqlighter/fileviewer/validation/Validator.java @@ -0,0 +1,16 @@ +package nl.sanderhautvast.sqlighter.fileviewer.validation; + +public class Validator { + public static void validate(String message, Object v1, Object v2) { + if (!v1.equals(v2)) { + throw new ValidationException(message + ": Not OK: " + v1 + " != " + v2); + } + } + + //TODO use or remove + public static void notNull(String message, Object value) { + if (value == null) { + throw new ValidationException("Not OK: " + message + ": is NULL"); + } + } +} diff --git a/fileviewer/src/test/java/nl/sanderhautvast/sqlighter/fileviewer/util/GetEncodingFromCodeTest.java b/fileviewer/src/test/java/nl/sanderhautvast/sqlighter/fileviewer/util/GetEncodingFromCodeTest.java new file mode 100644 index 0000000..5c6b106 --- /dev/null +++ b/fileviewer/src/test/java/nl/sanderhautvast/sqlighter/fileviewer/util/GetEncodingFromCodeTest.java @@ -0,0 +1,15 @@ +package nl.sanderhautvast.sqlighter.fileviewer.util; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertSame; + +public class GetEncodingFromCodeTest { + + @Test + public void test() { + assertSame(Encoding.UTF_8, Encoding.fromCode(1)); + assertSame(Encoding.UTF_16LE, Encoding.fromCode(2)); + assertSame(Encoding.UTF_16BE, Encoding.fromCode(3)); + } +} diff --git a/notes.md b/notes.md new file mode 100644 index 0000000..e3e1008 --- /dev/null +++ b/notes.md @@ -0,0 +1,8 @@ +**compile sqlite amalgamation for debug** + +`gcc shell.c sqlite3.c -lpthread -ldl -lm \ +-DSQLITE_DEBUG \ +-DSQLITE_ENABLE_EXPLAIN_COMMENTS \ +-DSQLITE_ENABLE_TREETRACE \ +-DSQLITE_ENABLE_WHERETRACE \ +-o sqlite3` \ No newline at end of file diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..5654667 --- /dev/null +++ b/pom.xml @@ -0,0 +1,50 @@ + + + 4.0.0 + + nl.sanderhautvast + sqlighter-pom + pom + 1.1.1 + + sqlighter + fileviewer + + sqlighter + on the fly creation of sqlite native format from any database query + + 11 + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.8.0 + + 11 + + + + + + + + gitlab-maven + https://gitlab.com/api/v4/projects/40344554/packages/maven + + + + + + gitlab-maven + https://gitlab.com/api/v4/projects/40344554/packages/maven + + + + gitlab-maven + https://gitlab.com/api/v4/projects/40344554/packages/maven + + + diff --git a/screenshot.png b/screenshot.png new file mode 100644 index 0000000000000000000000000000000000000000..3a380f2e8f2eaacdbd53846131d9781dad9b9eee GIT binary patch literal 321603 zcma%i1y~%-vNjM1?iO5^;10pv-QC^YodmZK+}+*Xf;++8-5rAeoAc$I``vr;-+T6% z-RYf~?w+oydAqCXolrR$QFs_^7!VK;cyTcy1rU(;O&}oP%uw%vM*yw3%pf3e{N{p! za^ix5gmMnHCgxVgARuC)@v4w&ibEI~nlaIQ0?>qnfE%)q84v{lGtfLtekB1E!nhCb z`1_)0DVto7L2+6ra~43WvqI8^tMB_hht<$xoD8R;{czTOSo2z6c{t}aeRbShX?8sW z$?{2~!r0Hj2H6RPA+06?ji?@?fSXeE1H&c+G3493y6P)CIDi5f(R;eTI^*CoIz@*} zp5uLbvz*+4y>bU3oJ1U#@kr=`av4YrGJ}Qmw6`n0C7AZU8omx$ zkb2s*;4Lfm;nUa+ku>cmM<}X2VmeCyZZCUU*QK}Qs5k8^hx{)*WqQgZF#-L}!Gq5@B+q~7QiEQ7oh;P;VBn=;8YQYf3kT#6>ruZ??FuMj#@-8=4J{^*}S z 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 z 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 z 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%0AfbJ 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≧TwTQ#ln^@ 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

~f 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

2wZG%1Y{Vb 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 literal 0 HcmV?d00001 diff --git a/sqlighter/pom.xml b/sqlighter/pom.xml new file mode 100644 index 0000000..c8f99db --- /dev/null +++ b/sqlighter/pom.xml @@ -0,0 +1,60 @@ + + + + nl.sanderhautvast + sqlighter-pom + 1.1.1 + + 4.0.0 + + sqlighter + 1.1.1 + + + org.xerial + sqlite-jdbc + 3.39.3.0 + test + + + org.junit.jupiter + junit-jupiter-engine + 5.9.0 + test + + + org.mockito + mockito-core + 4.8.0 + test + + + org.mockito + mockito-junit-jupiter + 4.8.0 + test + + + + + 11 + 11 + UTF-8 + + + + + + maven-surefire-plugin + 2.22.2 + + + maven-failsafe-plugin + 2.22.2 + + + + + \ No newline at end of file diff --git a/sqlighter/src/main/java/nl/sanderhautvast/sqlighter/Database.java b/sqlighter/src/main/java/nl/sanderhautvast/sqlighter/Database.java new file mode 100644 index 0000000..9f113d1 --- /dev/null +++ b/sqlighter/src/main/java/nl/sanderhautvast/sqlighter/Database.java @@ -0,0 +1,193 @@ +package nl.sanderhautvast.sqlighter; + +import nl.sanderhautvast.sqlighter.page.Page; +import nl.sanderhautvast.sqlighter.page.PageCacheFactory; + +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.nio.ByteBuffer; +import java.util.ArrayList; +import java.util.List; + +import static nl.sanderhautvast.sqlighter.SQLiteConstants.*; + +/** + * Limited to one table. As this is the main use case, this will probably not change. + * Please note that you can put whatever in it (does not have to reflect the actual source database structure), + * including for example the result of a complex join + */ +public class Database { + + public static short pageSize = 0x1000; + + public static final String PAGESIZE_PROPERTY = "pagesize"; + + private final SchemaRecord schema; + + final List leafPages; + + private int pageCounter = 3; + + /* + * assumes 1 schema record ie 1 table. This might not change + */ + public Database(SchemaRecord schemaRecord, List leafPages) { + this.schema = schemaRecord; + this.leafPages = leafPages; + } + + /** + * Write the database as SQLite file to a file + * @param filename name to write to + * @throws IOException if underlying i/o raises error + */ + public void write(String filename) throws IOException { + try (FileOutputStream outputStream = new FileOutputStream(filename)) { + write(outputStream); + } + } + + /** + * Write the database as SQLite file to the stream + * @param outputStream any stream + * @throws IOException if underlying i/o raises error + */ + public void write(OutputStream outputStream) throws IOException { + List currentTopLayer = this.leafPages; + int nPages = currentTopLayer.size(); + while (currentTopLayer.size() > 1) { // interior page needed? + currentTopLayer = createInteriorPages(currentTopLayer); + nPages += currentTopLayer.size(); + } + assert !currentTopLayer.isEmpty(); + Page tableRootPage = currentTopLayer.get(0); // + outputStream.write(createHeaderPage(nPages + 1).getData()); + setChildReferencesAndWrite(tableRootPage, outputStream); + outputStream.close(); + } + + private void setChildReferencesAndWrite(Page page, OutputStream outputStream) { + if (page.isInterior()) { + setChildReferences(page); + } + write(page, outputStream); + PageCacheFactory.getPageCache().release(page); + //recurse + for (Page child : page.getChildren()) { + setChildReferencesAndWrite(child, outputStream); + } + } + + private void write(Page page, OutputStream outputStream) { + try { + outputStream.write(page.getData()); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + private void setChildReferences(Page page) { + page.setForwardPosition(Page.POSITION_CELL_COUNT); + page.putU16(page.getChildren().size() - 1); + + for (int i = 0; i < page.getChildren().size() - 1; i++) { // except right-most pointer + page.setForwardPosition(Page.START + i * 2); + int position = page.getU16(); // read the position that was written in an earlier pass + page.setForwardPosition(position); // go to the cell at that location + page.putU32(pageCounter++); // add page reference + } + page.setForwardPosition(Page.POSITION_RIGHTMOST_POINTER); + page.putU32(pageCounter++); + } + + private Page createHeaderPage(int nPages) { + Page headerPage = Page.newHeader(Database.pageSize); + writeHeader(headerPage, nPages); + int payloadLocationWriteLocation = headerPage.getForwardPosition(); // mark current position + + int payloadLocation = writeSchema(headerPage, schema); //write schema payload from the end + headerPage.setForwardPosition(payloadLocationWriteLocation); // go back to marked position + headerPage.putU16(payloadLocation); //payload start + headerPage.skipForward(1); // the number of fragmented free bytes within the cell content area + headerPage.putU16(payloadLocation); // first cell + return headerPage; + } + + private int writeSchema(Page rootPage, SchemaRecord schemaRecord) { + rootPage.putBackward(schemaRecord.toRecord().toBytes()); + return rootPage.getBackwardPosition(); + } + + private List createInteriorPages(List childPages) { + List interiorPages = new ArrayList<>(); + Page interiorPage = PageCacheFactory.getPageCache().getInteriorPage(); + interiorPage.setKey(childPages.stream().mapToLong(Page::getKey).max().orElse(-1)); + interiorPage.setForwardPosition(Page.START); + int pageIndex; + for (pageIndex = 0; pageIndex < childPages.size() - 1; pageIndex++) { + Page leafPage = childPages.get(pageIndex); + if (interiorPage.getBackwardPosition() < interiorPage.getForwardPosition() + 10) { + interiorPage.setForwardPosition(Page.START_OF_CONTENT_AREA); + interiorPage.putU16(interiorPage.getBackwardPosition()); + interiorPage.skipForward(5); + + interiorPages.add(interiorPage); + + interiorPage = PageCacheFactory.getPageCache().getInteriorPage(); + interiorPage.setForwardPosition(Page.START); + } + addCellWithPageRef(interiorPage, leafPage); + interiorPage.addChild(leafPage); + } + + // write start of payload + interiorPage.setForwardPosition(Page.START_OF_CONTENT_AREA); + interiorPage.putU16(interiorPage.getBackwardPosition()); + interiorPage.skipForward(5); + interiorPage.addChild(childPages.get(pageIndex)); + interiorPages.add(interiorPage); + return interiorPages; + } + + private void addCellWithPageRef(Page interiorPage, Page leafPage) { + byte[] keyAsBytes = Varint.write(leafPage.getKey()); + ByteBuffer cell = ByteBuffer.allocate(6 + keyAsBytes.length); + cell.position(5); + cell.put(keyAsBytes); + + // write cell to page, starting at the end + interiorPage.putBackward(cell.array()); + interiorPage.putU16(interiorPage.getBackwardPosition()); + } + + private void writeHeader(Page rootpage, int nPages) { + rootpage.putU8(MAGIC_HEADER); + rootpage.putU16(rootpage.size()); + rootpage.putU8(FILE_FORMAT_WRITE_VERSION); + rootpage.putU8(FILE_FORMAT_READ_VERSION); + rootpage.putU8(RESERVED_SIZE); + rootpage.putU8(MAX_EMBED_PAYLOAD_FRACTION); + rootpage.putU8(MIN_EMBED_PAYLOAD_FRACTION); + rootpage.putU8(LEAF_PAYLOAD_FRACTION); + rootpage.putU32(FILECHANGE_COUNTER); + rootpage.putU32(nPages);// file size in pages + rootpage.putU32(FREELIST_TRUNK_PAGE_HUMBER);// Page number of the first freelist trunk page. + rootpage.putU32(TOTAL_N_FREELIST_PAGES); + rootpage.putU32(SCHEMA_COOKIE); + rootpage.putU32(SQLITE_SCHEMAVERSION); + rootpage.putU32(SUGGESTED_CACHESIZE); + rootpage.putU32(LARGEST_ROOT_BTREE_PAGE); + rootpage.putU32(ENCODING_UTF8); + rootpage.putU32(USER_VERSION); + rootpage.putU32(VACUUM_MODE_OFF);// True (non-zero) for incremental-vacuum mode. False (zero) otherwise. + rootpage.putU32(APP_ID);// Application ID + rootpage.putU8(FILLER);// Reserved for expansion. Must be zero. + rootpage.putU8(VERSION_VALID_FOR);// The version-valid-for number + rootpage.putU8(SQLITE_VERSION);// SQLITE_VERSION_NUMBER + rootpage.putU8(SQLiteConstants.TABLE_LEAF_PAGE); // leaf table b-tree page for schema + rootpage.putU16(NO_FREE_BLOCKS); // zero if there are no freeblocks + rootpage.putU16(1); // the number of cells on the page + } + +} diff --git a/sqlighter/src/main/java/nl/sanderhautvast/sqlighter/DatabaseBuilder.java b/sqlighter/src/main/java/nl/sanderhautvast/sqlighter/DatabaseBuilder.java new file mode 100644 index 0000000..46506c8 --- /dev/null +++ b/sqlighter/src/main/java/nl/sanderhautvast/sqlighter/DatabaseBuilder.java @@ -0,0 +1,78 @@ +package nl.sanderhautvast.sqlighter; + +import nl.sanderhautvast.sqlighter.data.LtRecord; +import nl.sanderhautvast.sqlighter.page.Page; +import nl.sanderhautvast.sqlighter.page.PageCacheFactory; + +import java.util.ArrayList; +import java.util.List; + +/** + * The database builder is the main interface to create a database. + */ +public class DatabaseBuilder { + + private final List leafPages = new ArrayList<>(); + private Page currentPage; + + private SchemaRecord schemaRecord; + + private int nRecordsOnCurrentPage; + + public DatabaseBuilder() { + try { + Database.pageSize = Short.parseShort(System.getProperty(Database.PAGESIZE_PROPERTY)); + } catch (NumberFormatException ex) { + //ignore + } + + createPage(); + } + + public void addRecord(final LtRecord record) { + byte[] recordBytes = record.toBytes(); + if (!newRecordFits(recordBytes)) { + finishCurrentPage(); + createPage(); + } + currentPage.setKey(record.getRowId()); //gets updated until page is finished + currentPage.putBackward(recordBytes); + currentPage.putU16(currentPage.getBackwardPosition()); + nRecordsOnCurrentPage += 1; + } + + public void addSchema(String tableName, String ddl) { + this.schemaRecord = new SchemaRecord(1, tableName, 2, ddl); + } + + public Database build() { + currentPage.setForwardPosition(Page.POSITION_CELL_COUNT); + currentPage.putU16(nRecordsOnCurrentPage); + + if (nRecordsOnCurrentPage > 0) { + currentPage.putU16(currentPage.getBackwardPosition()); + } else { + currentPage.putU16(currentPage.getBackwardPosition() - 1); + } + + return new Database(schemaRecord, leafPages); + } + + private boolean newRecordFits(byte[] newBytes) { + return currentPage.getBackwardPosition() - newBytes.length -2 > currentPage.getForwardPosition(); + // 2 for cell pointer length + } + + private void finishCurrentPage() { + currentPage.setForwardPosition(Page.POSITION_CELL_COUNT); + currentPage.putU16(nRecordsOnCurrentPage); + currentPage.putU16(currentPage.getBackwardPosition()); + } + + private void createPage() { + currentPage = PageCacheFactory.getPageCache().getLeafPage(); + currentPage.setForwardPosition(8); + leafPages.add(currentPage); + nRecordsOnCurrentPage = 0; + } +} diff --git a/sqlighter/src/main/java/nl/sanderhautvast/sqlighter/SQLiteConstants.java b/sqlighter/src/main/java/nl/sanderhautvast/sqlighter/SQLiteConstants.java new file mode 100644 index 0000000..83c5623 --- /dev/null +++ b/sqlighter/src/main/java/nl/sanderhautvast/sqlighter/SQLiteConstants.java @@ -0,0 +1,38 @@ +package nl.sanderhautvast.sqlighter; + +/** + * special values for SQLite. + * + * See Database File Format + */ +public class SQLiteConstants { + public static final byte[] MAGIC_HEADER = new byte[]{0x53, 0x51, 0x4c, 0x69, 0x74, 0x65, 0x20, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x20, 0x33, 0x00}; + + public static final byte FILE_FORMAT_WRITE_VERSION = 1; // legacy + public static final byte FILE_FORMAT_READ_VERSION = 1; // legacy + public static final byte RESERVED_SIZE = 0; + public static final byte MAX_EMBED_PAYLOAD_FRACTION = 0x40; + public static final byte MIN_EMBED_PAYLOAD_FRACTION = 0x20; + public static final byte LEAF_PAYLOAD_FRACTION = 0x20; + public static final int FILECHANGE_COUNTER = 1; + public static final int FREELIST_TRUNK_PAGE_HUMBER = 0; + public static final int TOTAL_N_FREELIST_PAGES = 0; + public static final int SCHEMA_COOKIE = 1; + public static final int SQLITE_SCHEMAVERSION = 4; + public static final int SUGGESTED_CACHESIZE = 0; + public static final int LARGEST_ROOT_BTREE_PAGE = 0; // zero when not in auto-vacuum mode + public static final int ENCODING_UTF8 = 1; // The database text encoding. A value of 1 means UTF-8. A value of 2 means UTF-16le. A value of 3 means UTF-16be. + public static final int USER_VERSION = 0; + public static final int VACUUM_MODE_OFF = 0; // not used + public static final int APP_ID = 0; + public static final byte[] FILLER = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + }; // 20 bytes for some future use + public static final byte[] VERSION_VALID_FOR = {0, 0, 0x03, -123}; + public static final byte[] SQLITE_VERSION = {0x00, 0x2e, 0x5F, 0x1A}; + public static final short NO_FREE_BLOCKS = 0; + public static final byte TABLE_LEAF_PAGE = 0x0d; //TODO enum? + public static final byte TABLE_INTERIOR_PAGE = 0x05; + public static final byte INDEX_LEAF_PAGE = 0x0a; + public static final byte INDEX_INTERIOR_PAGE = 0x02; +} \ No newline at end of file diff --git a/sqlighter/src/main/java/nl/sanderhautvast/sqlighter/SchemaRecord.java b/sqlighter/src/main/java/nl/sanderhautvast/sqlighter/SchemaRecord.java new file mode 100644 index 0000000..4cc3bac --- /dev/null +++ b/sqlighter/src/main/java/nl/sanderhautvast/sqlighter/SchemaRecord.java @@ -0,0 +1,47 @@ +package nl.sanderhautvast.sqlighter; + +import nl.sanderhautvast.sqlighter.data.LtRecord; +import nl.sanderhautvast.sqlighter.data.LtValue; + +/* + * Is a record in the sqlites_schema table + * and a special case of a Record + * class is being used for both reading and writing + * + */ +public class SchemaRecord { + + private final long rowid; + private final String tableName; + private final long rootpage; + private final String sql; + + public SchemaRecord(long rowid, String tableName, long rootpage, String sql) { + this.rowid = rowid; + this.tableName = tableName; + this.rootpage = rootpage; + this.sql = sql; + } + + public String getTableName() { + return tableName; + } + + public long getRootpage() { + return rootpage; + } + + public String getSql() { + return sql; + } + + public LtRecord toRecord(){ + LtRecord record = new LtRecord(rowid); + record.addValue(LtValue.of("table")); + record.addValue(LtValue.of(getTableName().toLowerCase())); + record.addValue(LtValue.of(getTableName().toLowerCase())); + record.addValue(LtValue.of(getRootpage())); + record.addValue(LtValue.of(getSql())); + return record; + } +} diff --git a/sqlighter/src/main/java/nl/sanderhautvast/sqlighter/Varint.java b/sqlighter/src/main/java/nl/sanderhautvast/sqlighter/Varint.java new file mode 100644 index 0000000..2439f9c --- /dev/null +++ b/sqlighter/src/main/java/nl/sanderhautvast/sqlighter/Varint.java @@ -0,0 +1,156 @@ +package nl.sanderhautvast.sqlighter; + +import java.nio.ByteBuffer; + +/** + * Writes integers to byte representation like Sqlite's putVarint64 + * not threadsafe (take out B8 and B9 if you need that) + */ +public final class Varint { + + private Varint() { + } + + public static byte[] write(long v) { + if ((v & ((0xff000000L) << 32)) != 0) { + byte[] result = new byte[9]; + result[8] = (byte) v; + v >>= 8; + for (int i = 7; i >= 0; i--) { + result[i] = (byte) ((v & 0x7f) | 0x80); + v >>= 7; + } + return result; + } else { + int n; + byte[] buf = new byte[8]; + for (n = 0; v != 0; n++, v >>= 7) { + buf[n] = (byte) ((v & 0x7f) | 0x80); + } + buf[0] &= 0x7f; + byte[] result = new byte[n]; + for (int i = 0, j = n - 1; j >= 0; j--, i++) { + result[i] = buf[j]; + } + return result; + } + } + + /* + * read a long value from a variable nr of bytes in varint format + * NB the end is encoded in the bytes, and the passed byte array may be bigger, but the + * remainder is not read. It's up to the caller to do it right. + */ + public static long read(byte[] bytes) { + return read(ByteBuffer.wrap(bytes)); + } + + /* + * read a long value from a variable nr of bytes in varint format + * + * copied from the sqlite source, with some java specifics, most notably the addition of + * &0xFF for the right conversion from byte => signed in java, but to be interpreted as unsigned, + * to long + * + * Does not have the issue that the read(byte[] bytes) method has. The nr of bytes read is determined + * by the varint64 format. + * + * TODO write specialized version for u32 + */ + public static long read(ByteBuffer buffer) { + int SLOT_2_0 = 0x001fc07f; + int SLOT_4_2_0 = 0xf01fc07f; + + long a = buffer.get() & 0xFF; + if ((a & 0x80) == 0) { + return a; + } + + long b = buffer.get() & 0xFF; + if ((b & 0x80) == 0) { + a &= 0x7F; + a = a << 7; + a |= b; + return a; + } + + a = a << 14; + a |= (buffer.get() & 0xFF); + if ((a & 0x80) == 0) { + a &= SLOT_2_0; + b &= 0x7F; + b = b << 7; + a |= b; + return a; + } + + a &= SLOT_2_0; + b = b << 14; + b |= (buffer.get() & 0xFF); + if ((b & 0x80) == 0) { + b &= SLOT_2_0; + a = a << 7; + a |= b; + return a; + } + + b &= SLOT_2_0; + long s = a; + a = a << 14; + int m = buffer.get() & 0xFF; + a |= m; + if ((a & 0x80) == 0) { + b = b << 7; + a |= b; + s = s >> 18; + return (s << 32) | a; + } + + s = s << 7; + s |= b; + b = b << 14; + b |= (buffer.get() & 0xFF); + if ((b & 0x80) == 0) { + a &= SLOT_2_0; + a = a << 7; + a |= b; + s = s >> 18; + return (s << 32) | a; + } + + a = a << 14; + a |= (buffer.get() & 0xFF); + if ((a & 0x80) == 0) { + a &= SLOT_4_2_0; + b &= SLOT_2_0; + b = b << 7; + a |= b; + s = s >> 11; + return (s << 32) | a; + } + + a &= SLOT_2_0; + b = b << 14; + b |= (buffer.get() & 0xFF); + if ((b & 0x80) == 0) { + b &= SLOT_4_2_0; + a = a << 7; + a |= b; + s = s >> 4; + return (s << 32) | a; + } + + a = a << 15; + a |= (buffer.get() & 0xFF); + b &= SLOT_2_0; + + b = b << 8; + a |= b; + s = s << 4; + b = m; + b &= 0x7F; + b = b >> 3; + s |= b; + return (s << 32) | a; + } +} diff --git a/sqlighter/src/main/java/nl/sanderhautvast/sqlighter/data/LtRecord.java b/sqlighter/src/main/java/nl/sanderhautvast/sqlighter/data/LtRecord.java new file mode 100644 index 0000000..1b4a3fb --- /dev/null +++ b/sqlighter/src/main/java/nl/sanderhautvast/sqlighter/data/LtRecord.java @@ -0,0 +1,104 @@ +package nl.sanderhautvast.sqlighter.data; + +import nl.sanderhautvast.sqlighter.Varint; + +import java.nio.ByteBuffer; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Objects; + +/** + * Record in sqlite database. + * Used for reading and writing. + */ +public final class LtRecord { + + private final long rowId; + + private int dataTypesLength = -1; + private int valuesLength = -1; + + private final List values = new ArrayList<>(10); + + public LtRecord(long rowId) { + this.rowId = rowId; + } + + public void addValues(LtValue... values) { + this.values.addAll(Arrays.asList(values)); + } + + public void addValue(LtValue value) { + this.values.add(value); + } + + /** + * write the record to an array of bytes + */ + public byte[] toBytes() { + int dataLength = getDataLength(); + byte[] lengthBytes = Varint.write(dataLength); + byte[] rowIdBytes = Varint.write(rowId); + + ByteBuffer buffer = ByteBuffer.allocate(lengthBytes.length + rowIdBytes.length + dataLength); + buffer.put(lengthBytes); + buffer.put(rowIdBytes); + + buffer.put(Varint.write(dataTypesLength)); + + //types + for (LtValue value : values) { + value.writeType(buffer); + } + + //values + for (LtValue value : values) { + value.writeValue(buffer); + } + + return buffer.array(); + } + + public int getDataLength() { + if (dataTypesLength < 0 || valuesLength < 0) { + dataTypesLength = 1; + valuesLength = 0; + for (LtValue value : values) { + dataTypesLength += value.getDataTypeLength(); + valuesLength += value.getValueLength(); + } + } + return dataTypesLength + valuesLength; + } + + public long getRowId() { + return rowId; + } + + @SuppressWarnings("unused") + public List getValues() { + return values; + } + + /** + * returns the value at the specified column index (0 based) + */ + public LtValue getValue(int column) { + return values.get(column); + } + + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + LtRecord record = (LtRecord) o; + return rowId == record.rowId; + } + + @Override + public int hashCode() { + return Objects.hash(rowId); + } +} diff --git a/sqlighter/src/main/java/nl/sanderhautvast/sqlighter/data/LtValue.java b/sqlighter/src/main/java/nl/sanderhautvast/sqlighter/data/LtValue.java new file mode 100644 index 0000000..fb05d31 --- /dev/null +++ b/sqlighter/src/main/java/nl/sanderhautvast/sqlighter/data/LtValue.java @@ -0,0 +1,127 @@ +package nl.sanderhautvast.sqlighter.data; + +import nl.sanderhautvast.sqlighter.Varint; + +import java.nio.ByteBuffer; +import java.nio.charset.StandardCharsets; + +/* + * NB Value classes derive their equality from their identity. I.e. no equals/hashcode + */ +public class LtValue { + private static final byte FLOAT_TYPE = 7; + private static final int STRING_OFFSET = 13; + private static final int BYTES_OFFSET = 12; + + private final byte[] type; + private final byte[] value; + + protected LtValue(byte[] type, byte[] value) { + this.type = type; + this.value = value; + } + + /** + * Returns the length of serialType + the length of the value + */ + public int getValueLength() { + return value.length; + } + + public int getDataTypeLength() { + return type.length; + } + + public void writeType(ByteBuffer buffer) { + buffer.put(type); + } + + public void writeValue(ByteBuffer buffer) { + buffer.put(value); + } + + public byte[] getValue() { + return value; + } + + + public static LtValue of(String value) { + return new LtValue(Varint.write(value == null ? 0 : ((long) (value.getBytes(StandardCharsets.UTF_8).length) << 1) + STRING_OFFSET), + value == null ? new byte[0] : value.getBytes(StandardCharsets.UTF_8)); + } + + public static LtValue of(long value) { + byte[] valueAsBytes = getValueAsBytes(value); + return new LtValue(getIntegerType(value, valueAsBytes.length), valueAsBytes); + } + + public static LtValue of(double value) { + return new LtValue(new byte[]{FLOAT_TYPE}, ByteBuffer.wrap(new byte[8]).putDouble(0, value).array()); + } + + public static LtValue of(byte[] value) { + return new LtValue(Varint.write(((long) value.length << 1) + BYTES_OFFSET), value); + } + + public static byte[] getIntegerType(long value, int bytesLength) { + if (value == 0) { + return new byte[]{8}; + } else if (value == 1) { + return new byte[]{9}; + } else { + if (bytesLength < 5) { + return Varint.write(bytesLength); + } else if (bytesLength < 7) { + return Varint.write(5); + } else return Varint.write(6); + } + } + + /* + * static because it's used in the constructor + */ + public static byte[] getValueAsBytes(long value) { + if (value == 0) { + return new byte[0]; + } else if (value == 1) { + return new byte[0]; + } else { + return longToBytes(value, getLengthOfByteEncoding(value)); + } + } + + public static int getLengthOfByteEncoding(long value) { + long u; + if (value < 0) { + u = ~value; + } else { + u = value; + } + if (u <= 127) { + return 1; + } else if (u <= 32767) { + return 2; + } else if (u <= 8388607) { + return 3; + } else if (u <= 2147483647) { + return 4; + } else if (u <= 140737488355327L) { + return 6; + } else { + return 8; + } + } + + public static byte[] longToBytes(long n, int nbytes) { + byte[] b = new byte[nbytes]; + for (int i = 0; i < nbytes; i++) { + b[i] = (byte) ((n >> (nbytes - i - 1) * 8) & 0xFF); + } + + return b; + } + + public byte[] getType() { + return type; + } +} diff --git a/sqlighter/src/main/java/nl/sanderhautvast/sqlighter/jdbc/ResulSet2SQLite.java b/sqlighter/src/main/java/nl/sanderhautvast/sqlighter/jdbc/ResulSet2SQLite.java new file mode 100644 index 0000000..8c3f944 --- /dev/null +++ b/sqlighter/src/main/java/nl/sanderhautvast/sqlighter/jdbc/ResulSet2SQLite.java @@ -0,0 +1,49 @@ +package nl.sanderhautvast.sqlighter.jdbc; + +import nl.sanderhautvast.sqlighter.data.LtRecord; + +import java.sql.ResultSet; +import java.sql.ResultSetMetaData; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.List; + +/** + * Use this class to generate an SQLite database from your JDBC results + */ +public class ResulSet2SQLite { + + private final ValueMapper valueMapper; + private final int columnCount; + + private long rowid = 1; + + public ResulSet2SQLite(ResultSetMetaData metadata) throws SQLException { + valueMapper = new ValueMapper(getSqlTypesFromJdbcResult(metadata)); + + this.columnCount = getColumnCount(metadata); + } + + public LtRecord mapRow(ResultSet result) throws SQLException { + LtRecord record = new LtRecord(rowid++); + for (int columnIndex = 1; columnIndex <= columnCount; columnIndex++) { + valueMapper.addValueFromJdbcResult(result, record, columnIndex); + } + + return record; + } + + static List getSqlTypesFromJdbcResult(ResultSetMetaData metaData) throws SQLException { + List types = new ArrayList<>(); + for (int i = 1; i <= getColumnCount(metaData); i++) { + types.add(metaData.getColumnType(i)); + } + return types; + } + + private static int getColumnCount(ResultSetMetaData metaData) throws SQLException { + return metaData.getColumnCount(); + } + + +} diff --git a/sqlighter/src/main/java/nl/sanderhautvast/sqlighter/jdbc/ValueMapper.java b/sqlighter/src/main/java/nl/sanderhautvast/sqlighter/jdbc/ValueMapper.java new file mode 100644 index 0000000..8b1bf5f --- /dev/null +++ b/sqlighter/src/main/java/nl/sanderhautvast/sqlighter/jdbc/ValueMapper.java @@ -0,0 +1,62 @@ +package nl.sanderhautvast.sqlighter.jdbc; + +import nl.sanderhautvast.sqlighter.data.LtRecord; +import nl.sanderhautvast.sqlighter.data.LtValue; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Types; +import java.util.List; + +class ValueMapper { + + private final List types; + + public ValueMapper(List types) { + this.types = types; + } + + void addValueFromJdbcResult(ResultSet result, LtRecord record, int columnIndex) throws SQLException { + switch (types.get(columnIndex - 1)) { // index in metadata starts with 1, index in list starts with 0 + case Types.BLOB: + case Types.CLOB: // handle as string? + case Types.NCLOB: // handle as string? + case Types.VARBINARY: + case Types.LONGVARBINARY: + case Types.JAVA_OBJECT: + record.addValue(LtValue.of(result.getBytes(columnIndex))); + break; + case Types.NUMERIC: + case Types.BIGINT: + case Types.INTEGER: + case Types.SMALLINT: + case Types.DECIMAL: + case Types.TINYINT: + record.addValue(LtValue.of(result.getLong(columnIndex))); + break; + case Types.BOOLEAN: + case Types.BIT: //? + record.addValue(LtValue.of(result.getBoolean(columnIndex) ? 1 : 0)); + break; + case Types.DATE: + case Types.TIME: + case Types.TIME_WITH_TIMEZONE: + case Types.TIMESTAMP: + case Types.TIMESTAMP_WITH_TIMEZONE: + record.addValue(LtValue.of(result.getDate(columnIndex).getTime())); + break; + case Types.FLOAT: + case Types.DOUBLE: + record.addValue(LtValue.of(result.getDouble(columnIndex))); + break; + case Types.CHAR: + case Types.NCHAR: + case Types.VARCHAR: + case Types.NVARCHAR: + case Types.LONGVARCHAR: + case Types.LONGNVARCHAR: + record.addValue(LtValue.of(result.getString(columnIndex))); + break; + } + } +} diff --git a/sqlighter/src/main/java/nl/sanderhautvast/sqlighter/page/Page.java b/sqlighter/src/main/java/nl/sanderhautvast/sqlighter/page/Page.java new file mode 100644 index 0000000..dbcc97f --- /dev/null +++ b/sqlighter/src/main/java/nl/sanderhautvast/sqlighter/page/Page.java @@ -0,0 +1,150 @@ +package nl.sanderhautvast.sqlighter.page; + +import nl.sanderhautvast.sqlighter.Database; +import nl.sanderhautvast.sqlighter.SQLiteConstants; + +import java.util.ArrayList; +import java.util.List; + +/** + * Represents a SQLite page + */ +public final class Page { + + public static int POSITION_RIGHTMOST_POINTER = 8; // first position after page header + public static int START = 12; // first position after page header + + public static final int POSITION_CELL_COUNT = 3; + public static final int START_OF_CONTENT_AREA = 5; + + private final byte[] data; + + private long key; + + private final List children = new ArrayList<>(); + + private int forwardPosition; + private int backwardPosition; + + private final PageType type; + + static Page newLeaf() { + return newLeaf(Database.pageSize); + } + + static Page newInterior() { + return newInterior(Database.pageSize); + } + + static Page newLeaf(short pageSize) { + Page page = new Page(PageType.TABLE_LEAF, pageSize); + page.putU8(SQLiteConstants.TABLE_LEAF_PAGE); + page.skipForward(2); + return page; + } + + static Page newInterior(short pageSize) { + Page page = new Page(PageType.TABLE_INTERIOR, pageSize); + page.putU8(SQLiteConstants.TABLE_INTERIOR_PAGE); + return page; + } + + + public static Page newHeader(int size) { + return new Page(PageType.HEADER, size); + } + + public void addChild(Page child) { + children.add(child); + } + + private Page(PageType type, int size) { + this.type = type; + data = new byte[size]; + forwardPosition = 0; + backwardPosition = size; + } + + public int getForwardPosition() { + return forwardPosition; + } + + public int getBackwardPosition() { + return backwardPosition; + } + + public void setForwardPosition(int forwardPosition) { + this.forwardPosition = forwardPosition; + } + + public void putU16(int value) { + data[forwardPosition] = (byte) ((value >> 8) & 0xFF); + data[forwardPosition + 1] = (byte) (value & 0xFF); + forwardPosition += 2; + } + + public void putU32(long value) { + data[forwardPosition] = (byte) ((value >> 24) & 0xFF); + data[forwardPosition + 1] = (byte) ((value >> 16) & 0xFF); + data[forwardPosition + 2] = (byte) ((value >> 8) & 0xFF); + data[forwardPosition + 3] = (byte) (value & 0xFF); + forwardPosition += 4; + } + + public void putU8(int value) { + data[forwardPosition] = (byte) (value & 0xFF); + forwardPosition += 1; + } + + public void putU8(byte[] value) { + System.arraycopy(value, 0, data, forwardPosition, value.length); + forwardPosition += value.length; + } + + public int getU16() { + return ((data[forwardPosition] & 0xFF) << 8) + (data[forwardPosition + 1] & 0xFF); + } + + public void putBackward(byte[] value) { + backwardPosition -= value.length; + System.arraycopy(value, 0, data, backwardPosition, value.length); + } + + public void setKey(long key) { + this.key = key; + } + + public long getKey() { + return key; + } + + public int size() { + return data.length; + } + + public List getChildren() { + return children; + } + + public byte[] getData() { + return data; + } + + public void skipForward(int length) { + this.forwardPosition += length; + } + + public boolean isInterior() { + return type == PageType.TABLE_INTERIOR; + } + + public PageType getType() { + return type; + } + + void reset() { + this.forwardPosition = 0; + this.backwardPosition = Database.pageSize; + this.children.clear(); + } +} diff --git a/sqlighter/src/main/java/nl/sanderhautvast/sqlighter/page/PageCache.java b/sqlighter/src/main/java/nl/sanderhautvast/sqlighter/page/PageCache.java new file mode 100644 index 0000000..1e931e8 --- /dev/null +++ b/sqlighter/src/main/java/nl/sanderhautvast/sqlighter/page/PageCache.java @@ -0,0 +1,43 @@ +package nl.sanderhautvast.sqlighter.page; + +import java.util.Queue; +import java.util.concurrent.LinkedBlockingQueue; + +public class PageCache { + + protected final Queue leafPages = new LinkedBlockingQueue<>(); + protected final Queue interiorPages = new LinkedBlockingQueue<>(); + + public Page getInteriorPage() { + Page page = interiorPages.poll(); + if (page == null) { + page = Page.newInterior(); + } else { + page.reset(); + } + return page; + } + + public Page getLeafPage() { + Page page = leafPages.poll(); + if (page == null) { + page = Page.newLeaf(); + } else { + page.reset(); + } + return page; + } + + public void release(Page page) { + if (page.getType() == PageType.TABLE_INTERIOR) { + interiorPages.add(page); + } else if (page.getType() == PageType.TABLE_LEAF) { + leafPages.add(page); + } + } + + public void clear(){ + interiorPages.clear(); + leafPages.clear(); + } +} diff --git a/sqlighter/src/main/java/nl/sanderhautvast/sqlighter/page/PageCacheFactory.java b/sqlighter/src/main/java/nl/sanderhautvast/sqlighter/page/PageCacheFactory.java new file mode 100644 index 0000000..640a663 --- /dev/null +++ b/sqlighter/src/main/java/nl/sanderhautvast/sqlighter/page/PageCacheFactory.java @@ -0,0 +1,19 @@ +package nl.sanderhautvast.sqlighter.page; + +import java.lang.ref.SoftReference; +import java.util.Optional; + +public class PageCacheFactory { + + private static final ThreadLocal> threadlocalPageCache = new ThreadLocal<>(); + + public static PageCache getPageCache() { + return Optional.ofNullable(threadlocalPageCache.get()) + .map(SoftReference::get) + .orElseGet(() -> { + PageCache pageCache = new PageCache(); + threadlocalPageCache.set(new SoftReference<>(pageCache)); + return pageCache; + }); + } +} diff --git a/sqlighter/src/main/java/nl/sanderhautvast/sqlighter/page/PageType.java b/sqlighter/src/main/java/nl/sanderhautvast/sqlighter/page/PageType.java new file mode 100644 index 0000000..f85283f --- /dev/null +++ b/sqlighter/src/main/java/nl/sanderhautvast/sqlighter/page/PageType.java @@ -0,0 +1,9 @@ +package nl.sanderhautvast.sqlighter.page; + +public enum PageType { + TABLE_LEAF, + TABLE_INTERIOR, + INDEX_LEAF, + INDEX_INTERIOR, + HEADER, +} diff --git a/sqlighter/src/test/java/nl/sanderhautvast/sqlighter/ControlTest.java b/sqlighter/src/test/java/nl/sanderhautvast/sqlighter/ControlTest.java new file mode 100644 index 0000000..16b425c --- /dev/null +++ b/sqlighter/src/test/java/nl/sanderhautvast/sqlighter/ControlTest.java @@ -0,0 +1,54 @@ +package nl.sanderhautvast.sqlighter; + +import nl.sanderhautvast.sqlighter.data.LtRecord; +import nl.sanderhautvast.sqlighter.data.LtValue; +import org.junit.jupiter.api.Test; + +import java.io.IOException; +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.SQLException; +import java.sql.Statement; + +public class ControlTest { + public static void main(String[] args) { + System.out.println(Long.toString(520 * 4096L, 16)); + } + + @Test + public void createDatabaseUsingSqliteJdbc() throws SQLException { + try (Connection connection = DriverManager.getConnection("jdbc:sqlite:lite.db")) { + try (Statement statement = connection.createStatement()) { + statement.executeUpdate("drop table if exists foo"); + } + try (Statement statement = connection.createStatement()) { + statement.executeUpdate("create table foo (bar integer, baz varchar(1002))"); + String filler = "Hhgtttg".repeat(167); + + for (int i = 0; i < 2000; i++) { + statement.executeUpdate("insert into foo (bar, baz) values (42, '" + filler + "')"); + } + } + + try (Statement statement = connection.createStatement()) { + statement.executeUpdate("vacuum"); + } + } + } + + + @Test + public void createDatabaseUsingSqlighter() throws IOException { + DatabaseBuilder databaseBuilder = new DatabaseBuilder(); + databaseBuilder.addSchema("foo", + "CREATE TABLE foo(bar integer,baz varchar(1002))"); + + for (int i = 0; i < 2000; i++) { + LtRecord record = new LtRecord(i); + record.addValues(LtValue.of(42), LtValue.of("Hhgtttg".repeat(167))); + databaseBuilder.addRecord(record); + } + + databaseBuilder.build().write("light.db"); + } +} diff --git a/sqlighter/src/test/java/nl/sanderhautvast/sqlighter/LeafDbPageTest.java b/sqlighter/src/test/java/nl/sanderhautvast/sqlighter/LeafDbPageTest.java new file mode 100644 index 0000000..3e4a7ac --- /dev/null +++ b/sqlighter/src/test/java/nl/sanderhautvast/sqlighter/LeafDbPageTest.java @@ -0,0 +1,51 @@ +package nl.sanderhautvast.sqlighter; + +import nl.sanderhautvast.sqlighter.data.LtRecord; +import nl.sanderhautvast.sqlighter.data.LtValue; +import nl.sanderhautvast.sqlighter.page.Page; +import nl.sanderhautvast.sqlighter.page.PageCacheFactory; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import java.util.List; + +import static org.junit.jupiter.api.Assertions.assertArrayEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; + +class LeafDbPageTest { + + @BeforeEach + public void setup() { + Database.pageSize=64; + PageCacheFactory.getPageCache().clear(); + } + + @AfterEach + public void teardown() { + PageCacheFactory.getPageCache().clear(); + Database.pageSize=0x1000; + } + + @Test + void testWriteDataToLeafPage() { + LtRecord record1 = new LtRecord(1); + record1.addValues(LtValue.of("hello")); + LtRecord record2 = new LtRecord(2); + record2.addValues(LtValue.of("world")); + DatabaseBuilder databaseBuilder = new DatabaseBuilder(); + databaseBuilder.addRecord(record1); + databaseBuilder.addRecord(record2); + + List leafPages = databaseBuilder.build().leafPages; + + assertFalse(leafPages.isEmpty()); + assertArrayEquals(new byte[]{ + 0x0D, 0x00, 0x00, 0x00, 0x02, 0x00, 0x2E, 0x00, 0x00, 0x37, 0x00, 0x2e, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x02, + 0x02, 0x17, 0x77, 0x6F, 0x72, 0x6C, 0x64, 0x07, 0x01, 0x02, 0x17, 0x68, 0x65, 0x6C, 0x6C, 0x6F}, + leafPages.get(0).getData() + ); + } +} \ No newline at end of file diff --git a/sqlighter/src/test/java/nl/sanderhautvast/sqlighter/LtRecordTest.java b/sqlighter/src/test/java/nl/sanderhautvast/sqlighter/LtRecordTest.java new file mode 100644 index 0000000..6bc8fdd --- /dev/null +++ b/sqlighter/src/test/java/nl/sanderhautvast/sqlighter/LtRecordTest.java @@ -0,0 +1,66 @@ +package nl.sanderhautvast.sqlighter; + +import nl.sanderhautvast.sqlighter.data.LtRecord; +import nl.sanderhautvast.sqlighter.data.LtValue; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertArrayEquals; +import static org.junit.jupiter.api.Assertions.assertEquals; + +class LtRecordTest { + + @Test + void testStringValue() { + LtRecord record = new LtRecord(1); + record.addValue(LtValue.of("string")); + assertArrayEquals(new byte[]{8, 1, 2, 25, 115, 116, 114, 105, 110, 103}, record.toBytes()); + } + + + @Test + void testIntValue() { + LtRecord record = new LtRecord(1); + record.addValue(LtValue.of(2)); + assertArrayEquals(new byte[]{3, 1, 2, 1, 2}, record.toBytes()); + } + + @Test + void testIntValue_0() { + LtRecord record = new LtRecord(1); + record.addValue(LtValue.of(0)); + assertArrayEquals(new byte[]{2, 1, 2, 8}, record.toBytes()); + } + + @Test + void testFloatValue() { + LtRecord record = new LtRecord(1); + record.addValue(LtValue.of(2.0)); + assertArrayEquals(new byte[]{10, 1, 2, 7, 64, 0, 0, 0, 0, 0, 0, 0}, record.toBytes()); + assertEquals(10,record.getDataLength()); + } + + @Test + void testStringIntValues() { + LtRecord record = new LtRecord(1); + record.addValue(LtValue.of("string")); + record.addValue(LtValue.of(2)); + assertArrayEquals(new byte[]{10, 1, 3, 25, 1, 115, 116, 114, 105, 110, 103, 2}, record.toBytes()); + } + + @Test + void testStringInt_1Values() { + LtRecord record = new LtRecord(1); + record.addValue(LtValue.of("string")); + record.addValue(LtValue.of(1)); + assertArrayEquals(new byte[]{9, 1, 3, 25, 9, 115, 116, 114, 105, 110, 103}, record.toBytes()); + } + + @Test + void testStringIntFloatValues() { + LtRecord record = new LtRecord(1); + record.addValue(LtValue.of("string")); + record.addValue(LtValue.of(2)); + assertArrayEquals(new byte[]{10, 1, 3, 25, 1, 115, 116, 114, 105, 110, 103, 2}, record.toBytes()); + } + +} \ No newline at end of file diff --git a/sqlighter/src/test/java/nl/sanderhautvast/sqlighter/SchemaCreationTests.java b/sqlighter/src/test/java/nl/sanderhautvast/sqlighter/SchemaCreationTests.java new file mode 100644 index 0000000..e419026 --- /dev/null +++ b/sqlighter/src/test/java/nl/sanderhautvast/sqlighter/SchemaCreationTests.java @@ -0,0 +1,81 @@ +package nl.sanderhautvast.sqlighter; + +import nl.sanderhautvast.sqlighter.data.LtRecord; +import nl.sanderhautvast.sqlighter.data.LtValue; +import org.junit.jupiter.api.Test; + +import java.io.IOException; +import java.sql.*; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +/* + * end-to-end test that creates an SQLite database and tries to read it + */ +public class SchemaCreationTests { + + @Test + public void newDatabase() throws SQLException, IOException { + DatabaseBuilder databaseBuilder = new DatabaseBuilder(); + databaseBuilder.addSchema("foo", + "CREATE TABLE foo(bar integer,baz varchar(10), xeno float)"); + + + LtRecord record = new LtRecord(1); + record.addValues(LtValue.of(12), LtValue.of("hello1world"), LtValue.of(1.2)); + databaseBuilder.addRecord(record); + LtRecord record2 = new LtRecord(2); + record2.addValues(LtValue.of(12), LtValue.of(1.2)); // just 2 values + databaseBuilder.addRecord(record2); + + databaseBuilder.build().write("test.db"); + + try (Connection connection = DriverManager.getConnection("jdbc:sqlite:test.db"); + Statement statement = connection.createStatement()) { + ResultSet result1 = statement.executeQuery("select rowid, name, tbl_name, rootpage, sql from sqlite_master"); + assertTrue(result1.next()); + assertEquals("foo", result1.getString("name")); + assertEquals("foo", result1.getString("tbl_name")); + assertEquals(2, result1.getInt("rootpage")); + assertEquals("CREATE TABLE foo(bar integer,baz varchar(10), xeno float)", result1.getString("sql")); + + // baz is 'defined' as varchar, + // but it's translated to colummn #2 + // and that contains 1.2 as double! (in row 2) + // and the query runs without errors + ResultSet result3 = statement.executeQuery("select baz from foo where ROWID = 2"); + assertTrue(result3.next()); + assertEquals(1.2, result3.getDouble(1)); + } + } + + @Test + public void test100Records() throws SQLException, IOException { + DatabaseBuilder builder = new DatabaseBuilder(); + builder.addSchema("foo", "CREATE TABLE foo(bar integer,baz varchar(2000))"); + + for (int i = 0; i < 100; i++) { + LtRecord record = new LtRecord(i); + record.addValues(LtValue.of(12), LtValue.of("helloworld".repeat(200))); + builder.addRecord(record); + } + + builder.build().write("test.db"); + + try (Connection connection = DriverManager.getConnection("jdbc:sqlite:test.db"); + Statement statement = connection.createStatement()) { + ResultSet result1 = statement.executeQuery("select rowid, name, tbl_name, rootpage, sql from sqlite_master"); + assertTrue(result1.next()); + assertEquals("foo", result1.getString("name")); + assertEquals("foo", result1.getString("tbl_name")); + assertEquals(2, result1.getInt("rootpage")); + assertEquals("CREATE TABLE foo(bar integer,baz varchar(2000))", result1.getString("sql")); + + + ResultSet result2 = statement.executeQuery("select count(*) from foo"); + assertTrue(result2.next()); + assertEquals(100, result2.getInt(1)); + } + } +} diff --git a/sqlighter/src/test/java/nl/sanderhautvast/sqlighter/SerialTypesTests.java b/sqlighter/src/test/java/nl/sanderhautvast/sqlighter/SerialTypesTests.java new file mode 100644 index 0000000..e135f7e --- /dev/null +++ b/sqlighter/src/test/java/nl/sanderhautvast/sqlighter/SerialTypesTests.java @@ -0,0 +1,65 @@ +package nl.sanderhautvast.sqlighter; + +import nl.sanderhautvast.sqlighter.data.LtValue; +import org.junit.jupiter.api.Test; + +import java.nio.ByteBuffer; +import java.nio.charset.StandardCharsets; + +import static org.junit.jupiter.api.Assertions.assertArrayEquals; + +class SerialTypesTests { + + @Test + void testInteger0() { + ByteBuffer out = ByteBuffer.allocate(1); + LtValue.of(0).writeType(out); + assertArrayEquals(new byte[]{8}, out.array()); + } + + @Test + void testInteger1() { + ByteBuffer out = ByteBuffer.allocate(1); + LtValue.of(1).writeType(out); + assertArrayEquals(new byte[]{9}, out.array()); + } + + @Test + void testInteger2() { + ByteBuffer out = ByteBuffer.allocate(1); + LtValue.of(2).writeType(out); + assertArrayEquals(new byte[]{1}, out.array()); + } + + @Test + void testInteger128() { + ByteBuffer out = ByteBuffer.allocate(1); + LtValue.of(128).writeType(out); + assertArrayEquals(new byte[]{2}, out.array()); + } + + @Test + void testString() { + // 'helloworld' is length 10 in characters + // 10*2+13 = 33 = 0x21 + ByteBuffer out = ByteBuffer.allocate(1); + LtValue.of("helloworld").writeType(out); + assertArrayEquals(new byte[]{0x21}, out.array()); + } + + @Test + void testBlob() { + // 'helloworld' is length 10 in bytes + // 10*2+12 = 32 = 0x20 + ByteBuffer out = ByteBuffer.allocate(1); + LtValue.of("helloworld".getBytes(StandardCharsets.UTF_8)).writeType(out); + assertArrayEquals(new byte[]{0x20}, out.array()); + } + + @Test + void testFloat() { + ByteBuffer out = ByteBuffer.allocate(1); + LtValue.of(1.0).writeType(out); + assertArrayEquals(new byte[]{7}, out.array()); + } +} diff --git a/sqlighter/src/test/java/nl/sanderhautvast/sqlighter/ToBytesTests.java b/sqlighter/src/test/java/nl/sanderhautvast/sqlighter/ToBytesTests.java new file mode 100644 index 0000000..be1d3b4 --- /dev/null +++ b/sqlighter/src/test/java/nl/sanderhautvast/sqlighter/ToBytesTests.java @@ -0,0 +1,69 @@ +package nl.sanderhautvast.sqlighter; + +import nl.sanderhautvast.sqlighter.data.LtValue; +import org.junit.jupiter.api.Test; + +import java.nio.ByteBuffer; +import java.nio.charset.StandardCharsets; + +import static org.junit.jupiter.api.Assertions.assertArrayEquals; + +public class ToBytesTests { + + @Test + public void testInteger0() { + // 0 and 1 are special values that are encoded in the type itself, which saves 8 bits + ByteBuffer out = ByteBuffer.allocate(0); + LtValue.of(0).writeValue(out); + assertArrayEquals(new byte[0], out.array()); + } + + @Test + public void testInteger1() { + // 0 and 1 are special values that are encoded in the type itself, which saves 8 bits + ByteBuffer out = ByteBuffer.allocate(0); + LtValue.of(1).writeValue(out); + assertArrayEquals(new byte[]{}, out.array()); + } + + @Test + public void testInteger2() { + ByteBuffer out = ByteBuffer.allocate(1); + LtValue.of(2).writeValue(out); + assertArrayEquals(new byte[]{0x02}, out.array()); + } + + @Test + public void testInteger128() { + ByteBuffer out = ByteBuffer.allocate(2); + LtValue.of(128).writeValue(out); + assertArrayEquals(new byte[]{0,-128}, out.array()); //0x80 as signed byte + } + + @Test + public void testString() { + // 'helloworld' is length 10 in characters + // 10*2+13 = 33 = 0x21 + ByteBuffer out = ByteBuffer.allocate(10); + LtValue.of("helloworld").writeValue(out); + assertArrayEquals(new byte[]{0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x77, 0x6f, 0x72, 0x6c, 0x64}, out.array() + ); + } + + @Test + public void testBlob() { + // 'helloworld' is length 10 in bytes + // 10*2+12 = 32 = 0x20 + ByteBuffer out = ByteBuffer.allocate(10); + LtValue.of("helloworld".getBytes(StandardCharsets.UTF_8)).writeValue(out); + assertArrayEquals(new byte[]{0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x77, 0x6f, 0x72, 0x6c, 0x64}, out.array()); + } + + @Test + public void testFloat() { + // tested the expected binary representation against the actual sqlite file + ByteBuffer out = ByteBuffer.allocate(8); + LtValue.of(1.1).writeValue(out); + assertArrayEquals(new byte[]{0x3f, (byte) 0xf1, (byte) 0x99, (byte) 0x99, (byte) 0x99, (byte) 0x99, (byte) 0x99, (byte) 0x9a}, out.array()); + } +} diff --git a/sqlighter/src/test/java/nl/sanderhautvast/sqlighter/VarintTests.java b/sqlighter/src/test/java/nl/sanderhautvast/sqlighter/VarintTests.java new file mode 100644 index 0000000..005d38c --- /dev/null +++ b/sqlighter/src/test/java/nl/sanderhautvast/sqlighter/VarintTests.java @@ -0,0 +1,70 @@ +package nl.sanderhautvast.sqlighter; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertArrayEquals; +import static org.junit.jupiter.api.Assertions.assertEquals; + +public class VarintTests { + + @Test + public void testWriteMin1() { + assertArrayEquals(new byte[]{-1, -1, -1, -1, -1, -1, -1, -1, -1}, Varint.write(0xffffffffffffffffL)); + } + + @Test + public void testWrite1() { + Varint.write(220); + assertArrayEquals(new byte[]{1}, Varint.write(0x01)); + } + + @Test + public void testWrite() { + assertArrayEquals(new byte[]{-1, -1, -1, -1, -1, -1, -1, 127}, Varint.write(0xffffffffffffffL)); + } + + @Test + public void testReadMin1() { + assertEquals(0xffffffffffffffffL, Varint.read(new byte[]{-1, -1, -1, -1, -1, -1, -1, -1, -1})); + } + + @Test + public void testRead1() { + assertEquals(1, Varint.read(new byte[]{1})); + } + + @Test + public void testRead() { + assertEquals(0xffffffffffffffL, Varint.read(new byte[]{-1, -1, -1, -1, -1, -1, -1, 127})); + } + + @Test + public void testRead2() { + assertEquals(562949953421311L, Varint.read(new byte[]{-1, -1, -1, -1, -1, -1, 127})); + } + + @Test + public void testRead3() { + assertEquals(4398046511103L, Varint.read(new byte[]{-1, -1, -1, -1, -1, 127})); + } + + @Test + public void testRead4() { + assertEquals(34359738367L, Varint.read(new byte[]{-1, -1, -1, -1, 127})); + } + + @Test + public void testRead5() { + assertEquals(268435455, Varint.read(new byte[]{-1, -1, -1, 127})); + } + + @Test + public void testRead6() { + assertEquals(2097151, Varint.read(new byte[]{-1, -1, 127})); + } + + @Test + public void testRead7() { + assertEquals( 16383, Varint.read(new byte[]{-1, 127})); + } +} diff --git a/sqlighter/src/test/java/nl/sanderhautvast/sqlighter/data/BlobValueTest.java b/sqlighter/src/test/java/nl/sanderhautvast/sqlighter/data/BlobValueTest.java new file mode 100644 index 0000000..0df221e --- /dev/null +++ b/sqlighter/src/test/java/nl/sanderhautvast/sqlighter/data/BlobValueTest.java @@ -0,0 +1,15 @@ +package nl.sanderhautvast.sqlighter.data; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertArrayEquals; + +class BlobValueTest { + + @Test + public void test() { + LtValue blobValue = LtValue.of(new byte[]{1, 2, 3, 4, -128}); + assertArrayEquals(new byte[]{1, 2, 3, 4, -128}, blobValue.getValue()); + assertArrayEquals(new byte[]{22}, blobValue.getType()); + } +} \ No newline at end of file diff --git a/sqlighter/src/test/java/nl/sanderhautvast/sqlighter/data/FloatValueTest.java b/sqlighter/src/test/java/nl/sanderhautvast/sqlighter/data/FloatValueTest.java new file mode 100644 index 0000000..a9af7b8 --- /dev/null +++ b/sqlighter/src/test/java/nl/sanderhautvast/sqlighter/data/FloatValueTest.java @@ -0,0 +1,19 @@ +package nl.sanderhautvast.sqlighter.data; + +import org.junit.jupiter.api.Test; + +import java.nio.ByteBuffer; + +import static org.junit.jupiter.api.Assertions.assertArrayEquals; + +class FloatValueTest { + @Test + public void test() { + LtValue floatValue = LtValue.of(1.5D); + ByteBuffer floatValueBytes = ByteBuffer.allocate(8).putDouble(1.5D); + assertArrayEquals( + floatValueBytes.array(), + floatValue.getValue()); + assertArrayEquals(new byte[]{7}, floatValue.getType()); + } +} \ No newline at end of file diff --git a/sqlighter/src/test/java/nl/sanderhautvast/sqlighter/data/IntegerValueTest.java b/sqlighter/src/test/java/nl/sanderhautvast/sqlighter/data/IntegerValueTest.java new file mode 100644 index 0000000..5da1853 --- /dev/null +++ b/sqlighter/src/test/java/nl/sanderhautvast/sqlighter/data/IntegerValueTest.java @@ -0,0 +1,38 @@ +package nl.sanderhautvast.sqlighter.data; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertArrayEquals; + +class IntegerValueTest { + @Test + public void testInteger0() { + // 0 and 1 are special values that are encoded in the type itself, which saves 8 bits + LtValue integerValue = LtValue.of(0); + assertArrayEquals(new byte[0], integerValue.getValue()); + assertArrayEquals(new byte[]{8}, integerValue.getType()); + } + + @Test + public void testInteger1() { + // 0 and 1 are special values that are encoded in the type itself, which saves 8 bits + LtValue integerValue = LtValue.of(1); + assertArrayEquals(new byte[]{}, integerValue.getValue()); + assertArrayEquals(new byte[]{9}, integerValue.getType()); + } + + @Test + public void testInteger2() { + LtValue integerValue = LtValue.of(2); + assertArrayEquals(new byte[]{0x02}, integerValue.getValue()); + assertArrayEquals(new byte[]{1}, integerValue.getType()); + } + + @Test + public void testInteger132() { + LtValue integerValue = LtValue.of(132); + assertArrayEquals(new byte[]{0,-124}, integerValue.getValue()); //0x80 as signed byte + assertArrayEquals(new byte[]{2}, integerValue.getType()); + } + +} \ No newline at end of file diff --git a/sqlighter/src/test/java/nl/sanderhautvast/sqlighter/data/StringValueTest.java b/sqlighter/src/test/java/nl/sanderhautvast/sqlighter/data/StringValueTest.java new file mode 100644 index 0000000..31178ec --- /dev/null +++ b/sqlighter/src/test/java/nl/sanderhautvast/sqlighter/data/StringValueTest.java @@ -0,0 +1,17 @@ +package nl.sanderhautvast.sqlighter.data; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertArrayEquals; + +class StringValueTest { + + @Test + public void testString() { + String helloworld = "helloworld"; + LtValue stringValue = LtValue.of(helloworld); + assertArrayEquals(new byte[]{0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x77, 0x6f, 0x72, 0x6c, 0x64}, stringValue.getValue()); + assertArrayEquals(new byte[]{(byte) (helloworld.length() * 2 + 13)}, stringValue.getType()); + } + +} \ No newline at end of file diff --git a/sqlighter/src/test/java/nl/sanderhautvast/sqlighter/jdbc/ResulSet2SQLiteTest.java b/sqlighter/src/test/java/nl/sanderhautvast/sqlighter/jdbc/ResulSet2SQLiteTest.java new file mode 100644 index 0000000..a4a576f --- /dev/null +++ b/sqlighter/src/test/java/nl/sanderhautvast/sqlighter/jdbc/ResulSet2SQLiteTest.java @@ -0,0 +1,94 @@ +package nl.sanderhautvast.sqlighter.jdbc; + +import nl.sanderhautvast.sqlighter.data.LtRecord; +import nl.sanderhautvast.sqlighter.data.LtValue; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mock; +import org.mockito.invocation.InvocationOnMock; +import org.mockito.junit.jupiter.MockitoExtension; +import org.mockito.stubbing.Answer; + +import java.sql.ResultSet; +import java.sql.ResultSetMetaData; +import java.sql.SQLException; +import java.sql.Types; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import static org.junit.jupiter.api.Assertions.assertArrayEquals; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.mockito.Mockito.*; + +@ExtendWith(MockitoExtension.class) +class ResulSet2SQLiteTest { + + @Mock + private ResultSet jdbcResult; + + @Mock + private ResultSetMetaData metaData; + + @Test + public void testWhatGoesInShouldComeOut() throws SQLException { + when(metaData.getColumnCount()).thenReturn(2); + when(metaData.getColumnType(1)).thenReturn(Types.INTEGER); + when(metaData.getColumnType(2)).thenReturn(Types.VARCHAR); + + when(jdbcResult.getMetaData()).thenReturn(metaData); + + List> table = List.of( + List.of(1L, "Dr. John"), + List.of(2L, "Allen Toussaint")); + StatefulAnswer inputRows = new StatefulAnswer(table.iterator()); + + when(jdbcResult.next()).thenAnswer(invocationOnMock -> inputRows.hasNext()); + when(jdbcResult.getLong(anyInt())).thenAnswer(inputRows); + when(jdbcResult.getString(anyInt())).thenAnswer(inputRows); + + ArrayList rows = new ArrayList<>(); + ResulSet2SQLite resulSet2SQLite = new ResulSet2SQLite(jdbcResult.getMetaData()); + while (jdbcResult.next()) { + rows.add(resulSet2SQLite.mapRow(jdbcResult)); + } + assertEquals(2, rows.size()); + LtRecord record = rows.get(0); + LtValue value = record.getValue(0); + assertArrayEquals(new byte[]{9}, value.getType()); + + value = record.getValue(1); + assertEquals(8, value.getValue().length); + + record = rows.get(1); + value = record.getValue(0); + assertArrayEquals(new byte[]{2}, value.getValue()); + + value = record.getValue(1); + assertEquals(15, value.getValue().length); + } + + static class StatefulAnswer implements Answer { + + private final Iterator> records; + private List current; + + StatefulAnswer(Iterator> records) { + this.records = records; + } + + @Override + public Object answer(InvocationOnMock invocationOnMock) { + int colIndex = invocationOnMock.getArgument(0); + return current.get(colIndex - 1); // ResultSet column index starts with 1 + } + + boolean hasNext() { + boolean hasNext = records.hasNext(); + if (hasNext) { + current = records.next(); + } + return hasNext; + } + } +} \ No newline at end of file