├── .github └── workflows │ └── publish.yml ├── .gitignore ├── Dockerfile ├── LICENSE ├── Makefile ├── README.md ├── pack.pl ├── prolog └── terminus_store.pl ├── rust ├── Cargo.lock ├── Cargo.toml ├── terminus-store-prolog-core │ ├── Cargo.lock │ ├── Cargo.toml │ └── src │ │ ├── builder.rs │ │ ├── csv.rs │ │ ├── layer.rs │ │ ├── lib.rs │ │ ├── named_graph.rs │ │ └── store.rs └── terminus-store-prolog-dylib │ ├── Cargo.toml │ └── src │ └── lib.rs └── script ├── swiarch.pl ├── swipl ├── swipl-cmd.sh ├── swipl_callgrind ├── swipl_gdb ├── swipl_valgrind └── test /.github/workflows/publish.yml: -------------------------------------------------------------------------------- 1 | name: Publish 2 | 3 | on: [push, pull_request] 4 | 5 | jobs: 6 | lint: 7 | runs-on: ubuntu-latest 8 | 9 | steps: 10 | - uses: actions/checkout@v2 11 | - name: Install python requirements 12 | run: pip install beautifulsoup4 requests 13 | # Can be found on: https://github.com/terminusdb-labs/swipl-lint/ 14 | - name: Download script 15 | run: curl -L 'https://raw.githubusercontent.com/terminusdb-labs/swipl-lint/v0.1/lint_modules.py' > lint_modules.py 16 | - name: Run linter 17 | run: python3 lint_modules.py 18 | 19 | docker: 20 | runs-on: ubuntu-latest 21 | env: 22 | IMAGE_NAME: terminusdb/terminus_store_prolog 23 | RUST_BACKTRACE: 1 24 | steps: 25 | - uses: actions/checkout@v2 26 | 27 | - name: Build image 28 | run: docker build -t terminusdb/terminus_store_prolog:latest . 29 | 30 | - name: Run tests 31 | run: docker run -e RUST_BACKTRACE=$RUST_BACKTRACE --rm terminusdb/terminus_store_prolog:latest bash -c "./script/test" 32 | 33 | - name: Log into Docker Container Registry 34 | if: github.event_name != 'pull_request' && (contains(github.ref, 'tag') || contains(github.ref, 'main')) 35 | run: echo '${{ secrets.DOCKER_PASS }}' | docker login -u terminusdb --password-stdin 36 | 37 | - name: Push to the Docker registry 38 | if: github.event_name != 'pull_request' && (contains(github.ref, 'tag') || contains(github.ref, 'main')) 39 | run: | 40 | IMAGE_ID=$IMAGE_NAME 41 | # Change all uppercase to lowercase 42 | IMAGE_ID=$(echo $IMAGE_ID | tr '[A-Z]' '[a-z]') 43 | # Strip git ref prefix from version 44 | VERSION=$(echo "${{ github.ref }}" | sed -e 's,.*/\(.*\),\1,') 45 | 46 | # Use Docker `latest` tag convention 47 | [ "$VERSION" == "main" ] && VERSION=latest 48 | 49 | echo IMAGE_ID=$IMAGE_ID 50 | echo VERSION=$VERSION 51 | 52 | docker tag $IMAGE_NAME $IMAGE_ID:$VERSION 53 | docker push $IMAGE_ID:$VERSION 54 | 55 | windows: 56 | runs-on: windows-latest 57 | steps: 58 | - uses: actions/checkout@v2 59 | 60 | - name: Install Rust 61 | uses: actions-rs/toolchain@v1 62 | with: 63 | profile: minimal 64 | toolchain: stable 65 | 66 | - name: Cache Rust build files 67 | uses: Swatinem/rust-cache@v1 68 | with: 69 | working-directory: ./rust 70 | 71 | - name: Install LLVM and SWI Prolog 72 | run: | 73 | # Install the latest stable LLVM and SWI Prolog using Chocolatey. 74 | choco install llvm swi-prolog --no-progress 75 | # Abort early since it doesn't seem that failure causes an exit here. 76 | if ($lastExitCode -ne 0) { throw "choco install failed: $lastExitCode" } 77 | 78 | # Update the $PATH to include the new packages. See 79 | # 80 | Import-Module "$env:ProgramData\chocolatey\helpers\chocolateyInstaller.psm1" 81 | Update-SessionEnvironment 82 | 83 | # Display versions for debugging 84 | swipl --version 85 | clang --version 86 | 87 | # The following commands update GitHub files to make the environment 88 | # variables persistent across steps. See 89 | # 90 | 91 | # Append the `swipl` path to the $PATH. 92 | echo (Split-Path -Path (Get-Command swipl).Source) ` 93 | | Out-File -Encoding utf8 -Append -FilePath $env:GITHUB_PATH 94 | 95 | # Set $LIBCLANG_PATH with the `clang` path. 96 | echo "LIBCLANG_PATH=$(Split-Path -Path (Get-Command clang).Source)" ` 97 | | Out-File -Encoding utf8 -Append -FilePath $env:GITHUB_ENV 98 | 99 | - name: Build 100 | # Use Git Bash because the Makefile does not work in other shells. 101 | shell: bash 102 | run: make 103 | 104 | - name: Test 105 | shell: bash 106 | run: ./script/test 107 | 108 | - name: Upload Windows artifact DLL 109 | uses: actions/upload-artifact@v1 110 | with: 111 | name: libterminus_store.dll 112 | path: lib/x64-win64/libterminus_store.dll 113 | 114 | mac: 115 | runs-on: macos-latest 116 | steps: 117 | - uses: actions/checkout@v2 118 | 119 | - name: Install Rust 120 | uses: actions-rs/toolchain@v1 121 | with: 122 | profile: minimal 123 | toolchain: stable 124 | 125 | - name: Cache Rust build files 126 | uses: Swatinem/rust-cache@v1 127 | with: 128 | working-directory: ./rust 129 | 130 | - name: Install SWI Prolog 131 | run: | 132 | brew install swi-prolog 133 | 134 | # Display version for debugging 135 | swipl --version 136 | 137 | - name: Build 138 | run: make 139 | 140 | - name: Test 141 | run: ./script/test 142 | 143 | - name: Upload macOS artifact dylib 144 | uses: actions/upload-artifact@v1 145 | with: 146 | name: libterminus_store.dylib 147 | path: lib/x86_64-darwin/libterminus_store.dylib 148 | 149 | pack: 150 | runs-on: ubuntu-latest 151 | if: github.event_name != 'pull_request' && contains(github.ref, 'tag') 152 | steps: 153 | - name: Install SWI Prolog 154 | run: | 155 | sudo apt-add-repository ppa:swi-prolog/stable 156 | sudo apt update 157 | sudo apt install swi-prolog-nox 158 | 159 | - name: Install Rust 160 | uses: actions-rs/toolchain@v1 161 | with: 162 | profile: minimal 163 | toolchain: stable 164 | 165 | - name: Install pack 166 | run: | 167 | VERSION=$(echo "${{ github.ref }}" | sed -e 's,.*/\(.*\),\1,') 168 | swipl -g "pack_install('https://github.com/terminusdb/terminus_store_prolog/archive/$VERSION.zip', [interactive(false)])" -g halt 169 | 170 | deploy: 171 | runs-on: ubuntu-latest 172 | if: github.event_name != 'pull_request' && contains(github.ref, 'tag') 173 | needs: [docker, windows, mac, pack] 174 | steps: 175 | - name: Set release name 176 | id: release_name 177 | run: | 178 | TAG=$(echo "${{ github.ref }}" | sed -e 's,.*/\(.*\),\1,') 179 | echo "::set-output name=tag::$TAG" 180 | 181 | - uses: actions/download-artifact@v2 182 | 183 | - name: Create a Release 184 | id: create_release 185 | uses: softprops/action-gh-release@v1 186 | env: 187 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 188 | with: 189 | tag_name: ${{ steps.release_name.outputs.tag }} 190 | files: | 191 | libterminus_store.dylib/libterminus_store.dylib 192 | libterminus_store.dll/libterminus_store.dll 193 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | **/target 2 | lib 3 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | # First build with rust and c libs 2 | FROM terminusdb/swipl:v8.4.2 3 | WORKDIR /usr/share/swi-prolog/pack/terminus_store_prolog 4 | COPY . . 5 | RUN BUILD_DEPS="git build-essential curl clang" && apt-get update \ 6 | && apt-get install -y --no-install-recommends $BUILD_DEPS \ 7 | ca-certificates \ 8 | make 9 | RUN curl https://sh.rustup.rs -sSf | bash -s -- -y 10 | ENV PATH="/root/.cargo/bin:${PATH}" 11 | RUN make && apt-get purge -y --auto-remove $BUILD_DEPS \ 12 | && rm -rf rust/target/release/build && rm -rf rust/target/release/deps 13 | 14 | FROM terminusdb/swipl:v8.4.2 15 | WORKDIR /usr/share/swi-prolog/pack/terminus_store_prolog 16 | COPY --from=0 /usr/share/swi-prolog/pack/terminus_store_prolog /usr/share/swi-prolog/pack/terminus_store_prolog 17 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | 2 | Apache License 3 | Version 2.0, January 2004 4 | https://www.apache.org/licenses/ 5 | 6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 7 | 8 | 1. Definitions. 9 | 10 | "License" shall mean the terms and conditions for use, reproduction, 11 | and distribution as defined by Sections 1 through 9 of this document. 12 | 13 | "Licensor" shall mean the copyright owner or entity authorized by 14 | the copyright owner that is granting the License. 15 | 16 | "Legal Entity" shall mean the union of the acting entity and all 17 | other entities that control, are controlled by, or are under common 18 | control with that entity. For the purposes of this definition, 19 | "control" means (i) the power, direct or indirect, to cause the 20 | direction or management of such entity, whether by contract or 21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 22 | outstanding shares, or (iii) beneficial ownership of such entity. 23 | 24 | "You" (or "Your") shall mean an individual or Legal Entity 25 | exercising permissions granted by this License. 26 | 27 | "Source" form shall mean the preferred form for making modifications, 28 | including but not limited to software source code, documentation 29 | source, and configuration files. 30 | 31 | "Object" form shall mean any form resulting from mechanical 32 | transformation or translation of a Source form, including but 33 | not limited to compiled object code, generated documentation, 34 | and conversions to other media types. 35 | 36 | "Work" shall mean the work of authorship, whether in Source or 37 | Object form, made available under the License, as indicated by a 38 | copyright notice that is included in or attached to the work 39 | (an example is provided in the Appendix below). 40 | 41 | "Derivative Works" shall mean any work, whether in Source or Object 42 | form, that is based on (or derived from) the Work and for which the 43 | editorial revisions, annotations, elaborations, or other modifications 44 | represent, as a whole, an original work of authorship. For the purposes 45 | of this License, Derivative Works shall not include works that remain 46 | separable from, or merely link (or bind by name) to the interfaces of, 47 | the Work and Derivative Works thereof. 48 | 49 | "Contribution" shall mean any work of authorship, including 50 | the original version of the Work and any modifications or additions 51 | to that Work or Derivative Works thereof, that is intentionally 52 | submitted to Licensor for inclusion in the Work by the copyright owner 53 | or by an individual or Legal Entity authorized to submit on behalf of 54 | the copyright owner. For the purposes of this definition, "submitted" 55 | means any form of electronic, verbal, or written communication sent 56 | to the Licensor or its representatives, including but not limited to 57 | communication on electronic mailing lists, source code control systems, 58 | and issue tracking systems that are managed by, or on behalf of, the 59 | Licensor for the purpose of discussing and improving the Work, but 60 | excluding communication that is conspicuously marked or otherwise 61 | designated in writing by the copyright owner as "Not a Contribution." 62 | 63 | "Contributor" shall mean Licensor and any individual or Legal Entity 64 | on behalf of whom a Contribution has been received by Licensor and 65 | subsequently incorporated within the Work. 66 | 67 | 2. Grant of Copyright License. Subject to the terms and conditions of 68 | this License, each Contributor hereby grants to You a perpetual, 69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 70 | copyright license to reproduce, prepare Derivative Works of, 71 | publicly display, publicly perform, sublicense, and distribute the 72 | Work and such Derivative Works in Source or Object form. 73 | 74 | 3. Grant of Patent License. Subject to the terms and conditions of 75 | this License, each Contributor hereby grants to You a perpetual, 76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 77 | (except as stated in this section) patent license to make, have made, 78 | use, offer to sell, sell, import, and otherwise transfer the Work, 79 | where such license applies only to those patent claims licensable 80 | by such Contributor that are necessarily infringed by their 81 | Contribution(s) alone or by combination of their Contribution(s) 82 | with the Work to which such Contribution(s) was submitted. If You 83 | institute patent litigation against any entity (including a 84 | cross-claim or counterclaim in a lawsuit) alleging that the Work 85 | or a Contribution incorporated within the Work constitutes direct 86 | or contributory patent infringement, then any patent licenses 87 | granted to You under this License for that Work shall terminate 88 | as of the date such litigation is filed. 89 | 90 | 4. Redistribution. You may reproduce and distribute copies of the 91 | Work or Derivative Works thereof in any medium, with or without 92 | modifications, and in Source or Object form, provided that You 93 | meet the following conditions: 94 | 95 | (a) You must give any other recipients of the Work or 96 | Derivative Works a copy of this License; and 97 | 98 | (b) You must cause any modified files to carry prominent notices 99 | stating that You changed the files; and 100 | 101 | (c) You must retain, in the Source form of any Derivative Works 102 | that You distribute, all copyright, patent, trademark, and 103 | attribution notices from the Source form of the Work, 104 | excluding those notices that do not pertain to any part of 105 | the Derivative Works; and 106 | 107 | (d) If the Work includes a "NOTICE" text file as part of its 108 | distribution, then any Derivative Works that You distribute must 109 | include a readable copy of the attribution notices contained 110 | within such NOTICE file, excluding those notices that do not 111 | pertain to any part of the Derivative Works, in at least one 112 | of the following places: within a NOTICE text file distributed 113 | as part of the Derivative Works; within the Source form or 114 | documentation, if provided along with the Derivative Works; or, 115 | within a display generated by the Derivative Works, if and 116 | wherever such third-party notices normally appear. The contents 117 | of the NOTICE file are for informational purposes only and 118 | do not modify the License. You may add Your own attribution 119 | notices within Derivative Works that You distribute, alongside 120 | or as an addendum to the NOTICE text from the Work, provided 121 | that such additional attribution notices cannot be construed 122 | as modifying the License. 123 | 124 | You may add Your own copyright statement to Your modifications and 125 | may provide additional or different license terms and conditions 126 | for use, reproduction, or distribution of Your modifications, or 127 | for any such Derivative Works as a whole, provided Your use, 128 | reproduction, and distribution of the Work otherwise complies with 129 | the conditions stated in this License. 130 | 131 | 5. Submission of Contributions. Unless You explicitly state otherwise, 132 | any Contribution intentionally submitted for inclusion in the Work 133 | by You to the Licensor shall be under the terms and conditions of 134 | this License, without any additional terms or conditions. 135 | Notwithstanding the above, nothing herein shall supersede or modify 136 | the terms of any separate license agreement you may have executed 137 | with Licensor regarding such Contributions. 138 | 139 | 6. Trademarks. This License does not grant permission to use the trade 140 | names, trademarks, service marks, or product names of the Licensor, 141 | except as required for reasonable and customary use in describing the 142 | origin of the Work and reproducing the content of the NOTICE file. 143 | 144 | 7. Disclaimer of Warranty. Unless required by applicable law or 145 | agreed to in writing, Licensor provides the Work (and each 146 | Contributor provides its Contributions) on an "AS IS" BASIS, 147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 148 | implied, including, without limitation, any warranties or conditions 149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 150 | PARTICULAR PURPOSE. You are solely responsible for determining the 151 | appropriateness of using or redistributing the Work and assume any 152 | risks associated with Your exercise of permissions under this License. 153 | 154 | 8. Limitation of Liability. In no event and under no legal theory, 155 | whether in tort (including negligence), contract, or otherwise, 156 | unless required by applicable law (such as deliberate and grossly 157 | negligent acts) or agreed to in writing, shall any Contributor be 158 | liable to You for damages, including any direct, indirect, special, 159 | incidental, or consequential damages of any character arising as a 160 | result of this License or out of the use or inability to use the 161 | Work (including but not limited to damages for loss of goodwill, 162 | work stoppage, computer failure or malfunction, or any and all 163 | other commercial damages or losses), even if such Contributor 164 | has been advised of the possibility of such damages. 165 | 166 | 9. Accepting Warranty or Additional Liability. While redistributing 167 | the Work or Derivative Works thereof, You may choose to offer, 168 | and charge a fee for, acceptance of support, warranty, indemnity, 169 | or other liability obligations and/or rights consistent with this 170 | License. However, in accepting such obligations, You may act only 171 | on Your own behalf and on Your sole responsibility, not on behalf 172 | of any other Contributor, and only if You agree to indemnify, 173 | defend, and hold each Contributor harmless for any liability 174 | incurred by, or claims asserted against, such Contributor by reason 175 | of your accepting any such warranty or additional liability. 176 | 177 | END OF TERMS AND CONDITIONS 178 | 179 | Copyright 2020 TerminusDB 180 | 181 | Licensed under the Apache License, Version 2.0 (the "License"); 182 | you may not use this file except in compliance with the License. 183 | You may obtain a copy of the License at 184 | 185 | https://www.apache.org/licenses/LICENSE-2.0 186 | 187 | Unless required by applicable law or agreed to in writing, software 188 | distributed under the License is distributed on an "AS IS" BASIS, 189 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 190 | See the License for the specific language governing permissions and 191 | limitations under the License. 192 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | # See for documentation on 2 | # creating a pack using non-Prolog code. 3 | 4 | # The variables `SWIARCH` and `PACKSODIR` are set by `swipl`. It calls `make` 5 | # when the pack is installed with `pack_install(terminus_store_prolog)`. 6 | # However, we also want to be able to build this without using `swipl`. If these 7 | # variables are not already set, we run a script with `swipl` to look up their 8 | # values. 9 | 10 | # Architecture string used by `swipl`. 11 | SWIARCH ?= $(shell ./script/swiarch.pl) 12 | 13 | # Pack shared object directory used by `swipl`. 14 | PACKSODIR ?= lib/$(SWIARCH) 15 | 16 | # Rust and Cargo variables 17 | RUST_LIB_NAME := terminus_store_prolog_dylib 18 | RUST_TARGET := release 19 | CARGO_FLAGS := 20 | 21 | # Set some architecture-dependent variables. 22 | ifeq ($(SWIARCH), x64-win64) 23 | # Shared object file extension 24 | SOEXT := dll 25 | else 26 | RUST_LIB_NAME := lib$(RUST_LIB_NAME) 27 | ifneq (,$(filter $(SWIARCH), x86_64-darwin arm64-darwin)) 28 | # While SOEXT is set by `swipl`, the value for macOS is not what we want 29 | # ("so"). So, we set it correctly here. 30 | SOEXT := dylib 31 | else 32 | SOEXT := so 33 | endif 34 | endif 35 | 36 | all: release 37 | 38 | build: 39 | mkdir -p $(PACKSODIR) 40 | cd rust; cargo build $(CARGO_FLAGS) 41 | cp rust/target/$(RUST_TARGET)/$(RUST_LIB_NAME).$(SOEXT) \ 42 | $(PACKSODIR)/libterminus_store.$(SOEXT) 43 | 44 | check:: 45 | 46 | debug: RUST_TARGET = debug 47 | debug: build 48 | 49 | release: CARGO_FLAGS += --release 50 | release: build 51 | 52 | install:: 53 | 54 | clean: 55 | rm -rf lib 56 | cd rust; cargo clean 57 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # terminus-store prolog bindings 2 | 3 | [![Actions Status](https://github.com/terminusdb/terminus_store_prolog/workflows/Publish/badge.svg)](https://github.com/terminusdb/terminus_store_prolog/actions) 4 | 5 | Prolog bindings for the [terminus-store](https://github.com/terminusdb/terminus-store/) Rust library. 6 | 7 | ## Archival notice 8 | This project has been archived. Its primary user, [TerminusDB](https://github.com/terminusdb/terminusdb), has directly integrated the code of this repository, and all development is now happening there. 9 | 10 | ## Requirements 11 | 12 | * cargo 13 | * clang 14 | * swi-prolog (with the include headers) 15 | 16 | ## Installing 17 | This library is downloadable through SWI-Prolog's package management system. In a swipl instance, run 18 | ```prolog 19 | pack_install(terminus_store_prolog). 20 | ``` 21 | 22 | Then you can use the library with 23 | ```prolog 24 | use_module(library(terminus_store)). 25 | ``` 26 | ## Compiling and running without installing (for testing purposes) 27 | If you need to compile manually, for example to test a change without reinstalling the pack, follow these instructions. 28 | 29 | Also, use the provided `./script/swipl` script to start a test instance. This will ensure the foreign library will be located properly. 30 | ``` 31 | make 32 | ./script/swipl 33 | ``` 34 | 35 | ## Running the tests 36 | ``` 37 | make 38 | ./script/test 39 | ``` 40 | 41 | 42 | ## Examples 43 | 44 | ### Creating a named graph and adding a triple 45 | Create a new directory (`testdir` in this example), then do the following: 46 | 47 | ```prolog 48 | open_directory_store("testdir", Store), 49 | open_write(Store, Builder), 50 | create_named_graph(Store, "sometestdb", DB), 51 | nb_add_triple(Builder, "Subject", "Predicate", value("Object")), 52 | nb_commit(Builder, Layer), 53 | nb_set_head(DB, Layer). 54 | ``` 55 | 56 | ### Add a triple to an existing named graph 57 | 58 | ```prolog 59 | open_directory_store("testdir", Store), 60 | open_named_graph(Store, "sometestdb", DB), 61 | open_write(DB, Builder), 62 | nb_add_triple(Builder, "Subject2", "Predicate2", value("Object2")), 63 | nb_commit(Builder, Layer), 64 | nb_set_head(DB, Layer), 65 | ``` 66 | 67 | ### Query triples 68 | ```prolog 69 | open_directory_store("testdir", Store), 70 | open_named_graph(Store, "sometestdb", DB), 71 | head(DB, Layer), 72 | triple(Layer, Subject, Predicate, Object). 73 | ``` 74 | 75 | ### Convert strings to ids and query by id 76 | ```prolog 77 | open_directory_store("testdir", Store), 78 | open_named_graph(Store, "sometestdb", DB), 79 | head(DB, Layer), 80 | subject_id(Layer, "Subject", S_Id), 81 | id_triple(Layer, S_Id, P_Id, O_Id), 82 | predicate_id(Layer, Predicate, P_Id), 83 | object_id(Layer, Object, O_Id). 84 | ``` 85 | -------------------------------------------------------------------------------- /pack.pl: -------------------------------------------------------------------------------- 1 | name('terminus_store_prolog'). 2 | version('0.19.8'). 3 | keywords(['triple', 'storage']). 4 | title('Use the Terminus-Store Rust library from Prolog'). 5 | home( 'https://github.com/terminusdb/terminus_store_prolog' ). 6 | -------------------------------------------------------------------------------- /prolog/terminus_store.pl: -------------------------------------------------------------------------------- 1 | :- module(terminus_store, [ 2 | open_memory_store/1, 3 | open_directory_store/2, 4 | 5 | create_named_graph/3, 6 | open_named_graph/3, 7 | delete_named_graph/2, 8 | 9 | head/2, 10 | head/3, 11 | nb_set_head/2, 12 | nb_force_set_head/2, 13 | nb_force_set_head/3, 14 | 15 | open_write/2, 16 | 17 | nb_add_triple/4, 18 | nb_remove_triple/4, 19 | nb_commit/2, 20 | builder_committed/1, 21 | nb_apply_delta/2, 22 | nb_apply_diff/2, 23 | 24 | node_and_value_count/2, 25 | predicate_count/2, 26 | subject_id/3, 27 | predicate_id/3, 28 | object_id/3, 29 | 30 | id_triple/4, 31 | triple/4, 32 | 33 | id_triple_addition/4, 34 | triple_addition/4, 35 | 36 | id_triple_removal/4, 37 | triple_removal/4, 38 | 39 | sp_card/4, 40 | 41 | parent/2, 42 | squash/2, 43 | 44 | layer_addition_count/2, 45 | layer_removal_count/2, 46 | layer_total_addition_count/2, 47 | layer_total_removal_count/2, 48 | layer_total_triple_count/2, 49 | 50 | layer_to_id/2, 51 | store_id_layer/3, 52 | 53 | pack_export/3, 54 | pack_layerids_and_parents/2, 55 | pack_import/3, 56 | 57 | csv_builder/3, 58 | csv_builder/4, 59 | csv_builder/5, 60 | csv_iri/3, 61 | 62 | count_layer_stack_size/2, 63 | 64 | rollup/1, 65 | rollup_upto/2, 66 | imprecise_rollup_upto/2, 67 | 68 | layer_stack_names/2, 69 | layer_equals/2 70 | ]). 71 | 72 | % There is two ways that this library is used. 73 | % 1. Standalone - in this case we need to load the internal foreign library. 74 | % 2. As part of TerminusDB - in this case we expect all the foreign 75 | % predicates to have been preloaded into the module '$terminus_store'. 76 | % 77 | % The reason for this is that TerminusDB builds its own rust module 78 | % which bundles the internal foreign library. This is necessary cause 79 | % otherwise TerminusDB is unable to make use of the types defined in 80 | % this library, as these are not exposed through ordinarly shared 81 | % objects. TerminusDB needs these types in order to build 82 | % TerminusDB-specific native logic that works with store, graph, 83 | % layer, and builder blobs. 84 | % 85 | % In order to switch between the two kinds of behavior, TerminusDB 86 | % defines a special prolog flag, 'terminusdb_monolithic_module'. This 87 | % suppresses loading of the internal library, and instead imports 88 | % foreign predicates which are expected to have been preloaded into 89 | % '$terminus_store'. 90 | :- if(current_prolog_flag(terminusdb_monolithic_module, true)). 91 | :- add_import_module('terminus_store', '$terminus_store', start). 92 | :- else. 93 | :- use_foreign_library(foreign(libterminus_store)). 94 | :- endif. 95 | 96 | :- use_module(library(lists)). 97 | :- use_module(library(option)). 98 | :- use_module(library(plunit)). 99 | :- use_module(library(random)). 100 | 101 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 102 | %%% pldocs for the foreign predicates %%% 103 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 104 | 105 | %! open_memory_store(-Store:store) is det 106 | % 107 | % Opens an in-memory store and unifies it with Store. 108 | % 109 | % @arg Store the returned in-memory store. 110 | 111 | %! open_directory_store(+Path:text, -Store:store) is det. 112 | % 113 | % Opens a store backed by a directory, and unifies it with Store. 114 | % 115 | % This predicate does not check if the directory actually exists, but 116 | % other store-related predicates will error when used with a store 117 | % backed by a non-existent directory. 118 | % 119 | % @arg Path a file system path to the store directory. This can be either absolute and relative. 120 | % @arg Store the returned directory store. 121 | 122 | %! create_named_graph(+Store:store, +Name:text, -Graph:named_graph) is det. 123 | % 124 | % Create a new named graph with the given name, and unifies it with Graph. 125 | % 126 | % @arg Store the store to create the graph in. 127 | % @arg Name the name which the new graph should have. 128 | % @arg Graph the returned named graph. 129 | % @throws if a graph with the given name already exists. 130 | 131 | %! open_named_graph(+Store:store, +Name:text, -Graph:named_graph) is semidet. 132 | % 133 | % Opens an existing named graph with the given name. 134 | % 135 | % Fails if no graph with that name exists. 136 | % 137 | % @arg Store the store to create the graph in. 138 | % @arg Name the name of the graph to be opened. 139 | % @arg Graph the returned named graph. 140 | 141 | %! delete_named_graph(+Store:store, +Name:text) is semidet. 142 | % 143 | % Deletes an existing named graph with the given name. 144 | % 145 | % Fails if no graph with that name exists. 146 | % 147 | % @arg Store the store to create the graph in. 148 | % @arg Name the name of the graph to be opened. 149 | 150 | %! head(+Graph:named_graph, -Layer:layer) is semidet. 151 | % 152 | % Retrieve the layer that a named graph points at. 153 | % This is the equivalent of opening a read transaction with snapshot isolation on a named graph. 154 | % 155 | % Fails if the given graph has no head yet. 156 | % 157 | % @arg Graph the named graph to retrieve the head layer from. 158 | % @arg Layer the returned head layer. 159 | 160 | 161 | %! head(+Graph:named_graph, -Layer:layer, -Version:version) is semidet. 162 | % 163 | % Retrieve the layer that a named graph points at and retrieve the version. 164 | % This is the equivalent of opening a read transaction with snapshot isolation on a named graph. 165 | % 166 | % Fails if the given graph has no head yet. 167 | % 168 | % @arg Graph the named graph to retrieve the head layer from. 169 | % @arg Layer the returned head layer. 170 | % @arg Version the version of the label. 171 | 172 | %! nb_set_head(+Graph:named_graph, +Layer:layer) is semidet. 173 | % 174 | % Set the given layer as the new head of the given graph. 175 | % 176 | % Fails if the new layer is not a proper child of the current head. 177 | % 178 | % This predicate does not support backtracking. 179 | % 180 | % @arg Graph the named graph to set the head layer of. 181 | % @arg Layer the layer to make the new head of the graph. 182 | 183 | 184 | %! nb_set_head(+Graph:named_graph, +Layer:layer, +Version:version) is semidet. 185 | % 186 | % Set the given layer as the new head of the given graph and checks if version 187 | % matches. 188 | % 189 | % Fails if the new layer is not a proper child of the current head. 190 | % 191 | % This predicate does not support backtracking. 192 | % 193 | % @arg Graph the named graph to set the head layer of. 194 | % @arg Layer the layer to make the new head of the graph. 195 | % @arg Version the version of the label. 196 | 197 | %! open_write(+Store_Or_Layer:term, -Builder:layer_builder) is det. 198 | % 199 | % Creates a layer builder from either a parent layer, or a store. 200 | % 201 | % When Store_Or_Layer is a store, the resulting builder will create a 202 | % base layer. 203 | % 204 | % When Store_Or_Layer is a layer, the resulting builder will create a 205 | % child layer whose parent is the given layer. 206 | % 207 | % @arg Store_Or_layer a store when creating a new base layer, or the parent layer when creating a child layer. 208 | % @arg Builder a layer builder to create the new layer. 209 | 210 | %! nb_add_id_triple(+Builder:layer_builder, +Subject_Id:integer, +Predicate_Id:integer, +Object_Id: integer) is semidet. 211 | % 212 | % Add the given subject, predicate and object as a triple to the builder object. 213 | % 214 | % This fails if any of the Ids is out of range, or if the triple 215 | % already exists, either in this builder or in a parent layer. 216 | % 217 | % @arg Builder the builder object to add this triple to. 218 | % @arg Subject_Id the id of the triple subject. 219 | % @arg Predicate_Id the id of the triple predicate. 220 | % @arg Object_Id the id of the triple object. 221 | 222 | %! nb_add_string_node_triple(+Builder:layer_builder, +Subject:text, +Predicate:text, +Object:text) is semidet. 223 | % 224 | % Add the given subject, predicate, and object as a triple to the 225 | % builder object. The object is interpreted as pointing at a node, 226 | % rather than being a literal value. 227 | % 228 | % This fails if the triple already exists in this builder object or a parent layer. 229 | % 230 | % @arg Builder the builder object to add this triple to. 231 | % @arg Subject the triple subject. 232 | % @arg Predicate the triple predicate. 233 | % @arg Object the triple object, which is interpreted as a node. 234 | 235 | %! nb_add_string_value_triple(+Builder:layer_builder, +Subject:text, +Predicate:text, +Object:text) is semidet. 236 | % 237 | % Add the given subject, predicate, and object as a triple to the 238 | % builder object. The object is interpreted as a value, rather than a node. 239 | % 240 | % This fails if the triple already exists in this builder object or a parent layer. 241 | % 242 | % @arg Builder the builder object to add this triple to. 243 | % @arg Subject the triple subject. 244 | % @arg Predicate the triple predicate. 245 | % @arg Object the triple object, which is interpreted as a value. 246 | 247 | %! nb_remove_id_triple(+Builder:layer_builder, +Subject_Id:integer, +Predicate_Id:integer, +Object_Id: integer) is semidet. 248 | % 249 | % Add the given subject, predicate and object as a triple removal to the builder object. 250 | % 251 | % This fails if any of the Ids is out of range, or if the triple does 252 | % not exist in a parent layer, or if the removal has already been 253 | % registered in this builder. 254 | % 255 | % @arg Builder the builder object to add this triple removal to. 256 | % @arg Subject_Id the id of the triple subject. 257 | % @arg Predicate_Id the id of the triple predicate. 258 | % @arg Object_Id the id of the triple object. 259 | 260 | %! nb_remove_string_node_triple(+Builder:layer_builder, +Subject:text, +Predicate:text, +Object:text) is semidet. 261 | % 262 | % Add the given subject, predicate, and object as a triple removal to the 263 | % builder object. The object is interpreted as pointing at a node, 264 | % rather than being a literal value. 265 | % 266 | % This fails if the triple does not exist in a parent layer, or if the 267 | % removal has already been registered in this builder. 268 | % 269 | % @arg Builder the builder object to add this triple removal to. 270 | % @arg Subject the triple subject. 271 | % @arg Predicate the triple predicate. 272 | % @arg Object the triple object, which is interpreted as a node. 273 | 274 | %! nb_remove_string_value_triple(+Builder:layer_builder, +Subject:text, +Predicate:text, +Object:text) is semidet. 275 | % 276 | % Add the given subject, predicate, and object as a triple removal to 277 | % the builder object. The object is interpreted as a value, rather 278 | % than a node. 279 | % 280 | % This fails if the triple does not exist in a parent layer, or if the 281 | % removal has already been registered in this builder. 282 | % 283 | % @arg Builder the builder object to add this triple removal to. 284 | % @arg Subject the triple subject. 285 | % @arg Predicate the triple predicate. 286 | % @arg Object the triple object, which is interpreted as a node. 287 | 288 | %! nb_apply_delta(+Builder:layer_builder, +Layer:layer) is det. 289 | % 290 | % Add and remove all additions and removals from Layer into Builder 291 | % 292 | % @arg Builder the layer builder to make changes to. 293 | % @arg Layer the layer that will apply changes from. 294 | % @throws if the builder has already been committed. 295 | 296 | %! nb_apply_diff(+Builder:layer_builder, +Layer:layer) is det. 297 | % 298 | % Make whatever changes are necessary to Builder, to bring it in line 299 | % with Layer. Our final visabile state should be as layer, so we are 300 | % calculating the diff which should go into builder to do so. 301 | % 302 | % @arg Builder the layer builder to make changes to. 303 | % @arg Layer the layer that we will view as a prototype. 304 | % @throws if the builder has already been committed. 305 | 306 | %! nb_commit(+Builder:layer_builder, -Layer:layer) is det. 307 | % 308 | % Commit the layer builder, turning it into a layer. 309 | % 310 | % @arg Builder the layer builder to commit. 311 | % @arg Layer the layer that will be returned. 312 | % @throws if the builder has already been committed. 313 | 314 | %! node_and_value_count(+Layer:layer, -Count:integer) is det. 315 | % 316 | % Unify Count with the amount of nodes and values known to this layer, 317 | % including all parent layers. 318 | % 319 | % @arg Layer the layer for which to get a count. 320 | % @arg Count the returned count. 321 | 322 | %! predicate_count(+Layer:layer, -Count:integer) is det. 323 | % 324 | % Unify Count with the amount of predicates known to this layer, 325 | % including all parent layers. 326 | % 327 | % @arg Layer the layer for which to get a count. 328 | % @arg Count the returned count. 329 | 330 | %! subject_to_id(+Layer:layer, +Subject:text, -Id:integer) is semidet. 331 | % 332 | % Convert the given subject to its id representation in the given layer. 333 | % Fails if this subject is not known in the given layer. 334 | % 335 | % @arg Layer the layer to use for the conversion. 336 | % @arg Subject an atom or string containing the subject. 337 | % @arg Id the id of the subject in the given layer. 338 | 339 | %! id_to_subject(Layer:layer, +Id:integer, -Subject:string) is semidet. 340 | % 341 | % Convert the given id to a subject using the given layer. 342 | % Fails if the id is out of range for subjects. 343 | % 344 | % @arg Layer the layer to use for the conversion. 345 | % @arg Id the id to convert into a subject. 346 | % @arg Subject the subject which the id refers to. 347 | 348 | %! predicate_to_id(+Layer:layer, +Predicate:text, -Id:integer) is semidet. 349 | % 350 | % Convert the given predicate to its id representation in the given layer. 351 | % Fails if this predicate is not known in the given layer. 352 | % 353 | % @arg Layer the layer to use for the conversion. 354 | % @arg Predicate an atom or string containing the predicate. 355 | % @arg Id the id of the predicate in the given layer. 356 | 357 | %! id_to_predicate(Layer:layer, +Id:integer, -Predicate:string) is semidet. 358 | % 359 | % Convert the given id to a predicate using the given layer. 360 | % Fails if the id is out of range for predicates. 361 | % 362 | % @arg Layer the layer to use for the conversion. 363 | % @arg Id the id to convert into a predicate. 364 | % @arg Predicate the predicate which the id refers to. 365 | 366 | %! object_to_id(+Layer:layer, +Object:text, -Id:integer) is semidet. 367 | % 368 | % Convert the given node object to its id representation in the given layer. 369 | % Fails if this subject is not known in the given layer. 370 | % 371 | % @arg Layer the layer to use for the conversion. 372 | % @arg Object an atom or string containing the object. The object is assumed to refer to a node. 373 | % @arg Id the id of the object in the given layer. 374 | 375 | %! id_to_object(Layer:layer, +Id:integer, -Object:string, -Object_Type:atom) is semidet. 376 | % 377 | % Convert the given id to a object using the given layer. 378 | % Fails if the id is out of range for objects. 379 | % 380 | % @arg Layer the layer to use for the conversion. 381 | % @arg Id the id to convert into a object. 382 | % @arg Object the object which the id refers to. 383 | % @arg Object_Type the type of the object, either 'node' or 'value'. 384 | 385 | %! parent(+Layer:layer, +Parent:layer) is semidet. 386 | % 387 | % Unifies Parent with the parent layer of Layer. Fails if that layer 388 | % has no parent. 389 | % 390 | % @arg Layer the layer for which to do the parent lookup. 391 | % @arg Parent the retrieved parent layer. 392 | 393 | %! squash(+Layer:layer, +Squash:layer) is semidet. 394 | % 395 | % Squashes a layer-stack to create a new fresh layer 396 | % 397 | % @arg Layer the layer for which to do the parent lookup. 398 | % @arg Parent the retrieved parent layer. 399 | 400 | %! rollup(+Layer:layer) is semidet. 401 | % 402 | % Produces a rollup of the current layer 403 | % 404 | % @arg Layer the layer for which to do the parent lookup. 405 | 406 | %! rollup_upto(+Layer:layer, +Upto:layer) is semidet. 407 | % 408 | % Produces a rollup of the current layer upto (but not including) 409 | % the specified layer 410 | % 411 | % @arg Layer the layer for which to do the parent lookup. 412 | % @arg Upto the layer at which to stop the rollup. 413 | 414 | %! csv_builder(+Name:string, +Csv:path, +Builder:builder, +Options:options) is det 415 | % 416 | % Creates a layer with the contents of a csv as triples 417 | % 418 | % @arg Name Name of the CSV object 419 | % @arg Csv The path to the csv to be loaded 420 | % @arg Builder The builder into which to place the CSV 421 | % @arg Layer The returned Layer 422 | % @arg Options A list containing any of the following: 423 | % * data_prefix(Prefix) (default is "csv:///data#") 424 | % * predicate_prefix(Prefix) (default is "csv:///schema#") 425 | % * header(Bool) (Boolean to read a header, default true) 426 | % * skip_header(Bool) (Skip the header regardless of presence, 427 | % default false) 428 | 429 | %! csv_builder(+Name:string, +Csv:path, +Builder:builder) is det 430 | % 431 | % Creates a layer with the contents of a csv as triples. Options are defaults. 432 | % 433 | % @arg Name Name of the CSV object 434 | % @arg Csv The path to the csv to be loaded 435 | % @arg Builder The builder into which to place the CSV 436 | % @arg Layer The returned Layer 437 | 438 | %! csv_iri(Name, Prefix, IRI) is det. 439 | % 440 | % Creates a CSV IRI from a name and prefix 441 | 442 | %! layer_stack_names(+Layer:layer, -Stack:list) is det. 443 | % 444 | % Creates a layer-id stack from a layer which contains all ancestor 445 | % layers. 446 | % 447 | % @arg Layer The layer from which to obtain the stack. 448 | % @arg Stack A list of the layer-ids of all ancestors. 449 | 450 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 451 | %%% End of foreign predicate pldocs %%% 452 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 453 | 454 | %! nb_add_triple(+Builder, +Subject, +Predicate, +Object) is semidet 455 | % 456 | % Add a triple to the builder. 457 | nb_add_triple(Builder, Subject, Predicate, Object) :- 458 | integer(Subject), 459 | integer(Predicate), 460 | integer(Object), 461 | !, 462 | nb_add_id_triple(Builder, Subject, Predicate, Object). 463 | 464 | nb_add_triple(Builder, Subject, Predicate, Object) :- 465 | !, 466 | nb_add_string_triple(Builder, Subject, Predicate, Object). 467 | 468 | /* 469 | * nb_add_triple(+Builder, +Subject, +Predicate, +Object) is semidet 470 | * 471 | * Remove a trible from the builder 472 | */ 473 | nb_remove_triple(Builder, Subject, Predicate, Object) :- 474 | integer(Subject), 475 | integer(Predicate), 476 | integer(Object), 477 | !, 478 | nb_remove_id_triple(Builder, Subject, Predicate, Object). 479 | 480 | nb_remove_triple(Builder, Subject, Predicate, Object) :- 481 | !, 482 | nb_remove_string_triple(Builder, Subject, Predicate, Object). 483 | 484 | /* 485 | * subject_id(+Layer, +Subject, -Id) is semidet 486 | * 487 | * Get the ID from a subject 488 | */ 489 | subject_id(Layer, Subject, Id) :- 490 | ground(Id), 491 | !, 492 | id_to_subject(Layer, Id, Subject). 493 | 494 | subject_id(Layer, Subject, Id) :- 495 | ground(Subject), 496 | !, 497 | subject_to_id(Layer, Subject, Id). 498 | 499 | subject_id(Layer, Subject, Id) :- 500 | node_and_value_count(Layer, Count), 501 | between(1, Count, Id), 502 | id_to_subject(Layer, Id, Subject). 503 | 504 | 505 | /* 506 | * predicate_id(+Layer, +Predicate, -Id) is semidet 507 | * 508 | * Get the ID from a predicate 509 | */ 510 | predicate_id(Layer, Predicate, Id) :- 511 | ground(Id), 512 | !, 513 | id_to_predicate(Layer, Id, Predicate). 514 | 515 | predicate_id(Layer, Predicate, Id) :- 516 | ground(Predicate), 517 | !, 518 | predicate_to_id(Layer, Predicate, Id). 519 | 520 | predicate_id(Layer, Predicate, Id) :- 521 | node_and_value_count(Layer, Count), 522 | between(1, Count, Id), 523 | id_to_predicate(Layer, Id, Predicate). 524 | 525 | 526 | /* 527 | * object_id(+Layer, +Predicate, -Id) is semidet 528 | * 529 | * Get the ID from an object 530 | */ 531 | object_id(Layer, Object, Id) :- 532 | ground(Id), 533 | !, 534 | id_to_object(Layer, Id, Object). 535 | 536 | object_id(Layer, node(Object), Id) :- 537 | ground(Object), 538 | !, 539 | object_to_id(Layer, node(Object), Id). 540 | 541 | object_id(Layer, value(Object), Id) :- 542 | ground(Object), 543 | !, 544 | object_to_id(Layer, value(Object), Id). 545 | 546 | object_id(Layer, Object, Id) :- 547 | node_and_value_count(Layer, Count), 548 | between(1, Count, Id), 549 | id_to_object(Layer, Id, Object). 550 | 551 | triple(Layer, Subject, Predicate, Object) :- 552 | ( ground(Subject) 553 | -> subject_id(Layer, Subject, S_Id) 554 | ; true), 555 | 556 | ( ground(Predicate) 557 | -> predicate_id(Layer, Predicate, P_Id) 558 | ; true), 559 | 560 | ( ground(Object) 561 | -> object_id(Layer, Object, O_Id) 562 | ; true), 563 | 564 | id_triple(Layer, S_Id, P_Id, O_Id), 565 | 566 | ( ground(Subject) 567 | -> true 568 | ; subject_id(Layer, Subject, S_Id)), 569 | 570 | 571 | ( ground(Predicate) 572 | -> true 573 | ; predicate_id(Layer, Predicate, P_Id)), 574 | 575 | 576 | ( ground(Object) 577 | -> true 578 | ; object_id(Layer,Object, O_Id)). 579 | 580 | csv_builder(Name, Csv, Builder) :- 581 | csv_builder(Name, Csv,Builder,[]). 582 | 583 | csv_builder(Name, Csv, Builder, Options) :- 584 | option(data_prefix(Data), Options, 'csv:///data/'), 585 | option(schema_prefix(Schema), Options, 'csv:///schema#'), 586 | option(header(Header), Options, true), 587 | option(skip_header(Skip), Options, false), 588 | csv_builder(Name, Csv, Builder, Data, Schema, Header, Skip). 589 | 590 | csv_builder(Name, Csv, Builder, Schema_Builder, Options) :- 591 | option(data_prefix(Data), Options, 'csv:///data/'), 592 | option(schema_prefix(Schema), Options, 'csv:///schema#'), 593 | option(header(Header), Options, true), 594 | option(skip_header(Skip), Options, false), 595 | csv_builder(Name, Csv, Builder, Schema_Builder, Data, Schema, Header, Skip). 596 | 597 | triple_addition(Layer, Subject, Predicate, Object) :- 598 | ( ground(Subject) 599 | -> subject_id(Layer, Subject, S_Id) 600 | ; true), 601 | 602 | ( ground(Predicate) 603 | -> predicate_id(Layer, Predicate, P_Id) 604 | ; true), 605 | 606 | ( ground(Object) 607 | -> object_id(Layer, Object, O_Id) 608 | ; true), 609 | 610 | id_triple_addition(Layer, S_Id, P_Id, O_Id), 611 | 612 | ( ground(Subject) 613 | -> true 614 | ; subject_id(Layer, Subject, S_Id)), 615 | 616 | 617 | ( ground(Predicate) 618 | -> true 619 | ; predicate_id(Layer, Predicate, P_Id)), 620 | 621 | 622 | ( ground(Object) 623 | -> true 624 | ; object_id(Layer,Object, O_Id)). 625 | 626 | triple_removal(Layer, Subject, Predicate, Object) :- 627 | ( ground(Subject) 628 | -> subject_id(Layer, Subject, S_Id) 629 | ; true), 630 | 631 | ( ground(Predicate) 632 | -> predicate_id(Layer, Predicate, P_Id) 633 | ; true), 634 | 635 | ( ground(Object) 636 | -> object_id(Layer, Object, O_Id) 637 | ; true), 638 | 639 | id_triple_removal(Layer, S_Id, P_Id, O_Id), 640 | 641 | ( ground(Subject) 642 | -> true 643 | ; subject_id(Layer, Subject, S_Id)), 644 | 645 | 646 | ( ground(Predicate) 647 | -> true 648 | ; predicate_id(Layer, Predicate, P_Id)), 649 | 650 | 651 | ( ground(Object) 652 | -> true 653 | ; object_id(Layer,Object, O_Id)). 654 | 655 | count_layer_stack_size(Layer, Acc, Count) :- 656 | parent(Layer, Parent), 657 | !, 658 | NextAcc is Acc + 1, 659 | count_layer_stack_size(Parent, NextAcc, Count). 660 | count_layer_stack_size(_Layer, Acc, Count) :- 661 | Count is Acc + 1. 662 | 663 | count_layer_stack_size(Layer, Count) :- 664 | count_layer_stack_size(Layer, 0, Count). 665 | 666 | 667 | layer_stack_names(Layer, Stack) :- 668 | ground(Layer), 669 | !, 670 | retrieve_layer_stack_names(Layer, Stack). 671 | layer_stack_names(_Layer, _Stack) :- 672 | throw(error(domain_error('Layer not bound in layer_stack_names/2'),_)). 673 | 674 | :- begin_tests(terminus_store). 675 | 676 | :- use_module(library(filesex)). 677 | 678 | /******************************* 679 | * Developer Utilities * 680 | *******************************/ 681 | 682 | /** 683 | * random_string(String) is det. 684 | */ 685 | random_string(String) :- 686 | Size is 2 ** (20 * 8), 687 | random(0, Size, Num), 688 | format(string(String), '~36r', [Num]). 689 | 690 | clean(TestDir) :- 691 | delete_directory_and_contents(TestDir). 692 | 693 | createng(TestDir) :- 694 | random_string(RandomString), 695 | atomic_list_concat(["testdir", RandomString], TestDir), 696 | make_directory(TestDir), 697 | open_directory_store(TestDir, X), 698 | create_named_graph(X, "sometestdb", _). 699 | 700 | create_memory_ng(DB) :- 701 | open_memory_store(X), 702 | create_named_graph(X, "sometestdb", DB). 703 | 704 | test(open_memory_store) :- 705 | open_memory_store(_). 706 | 707 | test(open_directory_store_atom) :- 708 | open_directory_store(this_is_an_atom, _), 709 | open_directory_store("this is a string", _). 710 | 711 | test(open_directory_store_atom_exception, [ 712 | throws(error(type_error(text,234), _)) 713 | ]) :- 714 | open_directory_store(234, _). 715 | 716 | test(create_db, [cleanup(clean(TestDir))]) :- 717 | make_directory("testdir"), 718 | TestDir = 'testdir', 719 | open_directory_store("testdir", X), 720 | create_named_graph(X, "sometestdb", _). 721 | 722 | 723 | test(create_db_on_memory) :- 724 | open_memory_store(X), 725 | create_named_graph(X, "sometestdb", _). 726 | 727 | test(open_named_graph, [cleanup(clean(TestDir)), setup(createng(TestDir))]) :- 728 | open_directory_store(TestDir, X), 729 | open_named_graph(X, "sometestdb", _). 730 | 731 | test(open_named_graph_memory) :- 732 | open_memory_store(X), 733 | create_named_graph(X, "sometestdb", _), 734 | open_named_graph(X, "sometestdb", _). 735 | 736 | test(delete_named_graph_memory) :- 737 | open_memory_store(X), 738 | create_named_graph(X, "sometestdb", _), 739 | delete_named_graph(X, "sometestdb"), 740 | \+ open_named_graph(X, "sometestdb", _). 741 | 742 | test(delete_named_graph_directory, [cleanup(clean(TestDir)), setup(createng(TestDir))]) :- 743 | open_directory_store(TestDir, X), 744 | \+ delete_named_graph(X, "unknowndb"). 745 | 746 | test(head_from_empty_db, [fail, cleanup(clean(TestDir)), setup(createng(TestDir))]) :- 747 | open_directory_store(TestDir, X), 748 | open_named_graph(X, "sometestdb", DB), 749 | head(DB, _). % should be false because we have no HEAD yet 750 | 751 | test(head_from_empty_db_memory, [fail, setup(create_memory_ng(DB))]) :- 752 | head(DB, _). 753 | 754 | test(open_write_from_db_without_head, [ 755 | cleanup(clean(TestDir)), 756 | setup(createng(TestDir)), 757 | throws( 758 | error(cannot_open_named_graph_without_base_layer, _) 759 | )]) :- 760 | open_directory_store(TestDir, X), 761 | open_named_graph(X, "sometestdb", DB), 762 | open_write(DB, _). 763 | 764 | test(open_write_from_db_with_head, [ 765 | cleanup(clean(TestDir)), 766 | setup(createng(TestDir)) 767 | ]) :- 768 | open_directory_store(TestDir, Store), 769 | open_write(Store, Builder), 770 | nb_commit(Builder, Layer), 771 | open_named_graph(Store, "sometestdb", DB), 772 | nb_set_head(DB, Layer), 773 | open_write(DB, _). 774 | 775 | 776 | test(open_write_from_memory_ng_without_head, [ 777 | setup(create_memory_ng(DB)), 778 | throws( 779 | error(cannot_open_named_graph_without_base_layer, _) 780 | )]) :- 781 | open_write(DB, _). 782 | 783 | test(create_base_layer, [cleanup(clean(TestDir)), setup(createng(TestDir))]) :- 784 | open_directory_store(TestDir, Store), 785 | open_write(Store, _). 786 | 787 | 788 | test(create_base_layer_memory) :- 789 | open_memory_store(Store), 790 | open_write(Store, _). 791 | 792 | test(write_value_triple, [cleanup(clean(TestDir)), setup(createng(TestDir))]) :- 793 | open_directory_store(TestDir, Store), 794 | open_write(Store, Builder), 795 | nb_add_string_triple(Builder, "Subject", "Predicate", value("Object")). 796 | 797 | test(write_value_triple_memory) :- 798 | open_memory_store(Store), 799 | open_write(Store, Builder), 800 | nb_add_string_triple(Builder, "Subject", "Predicate", value("Object")). 801 | 802 | test(commit_and_set_header, [cleanup(clean(TestDir)), setup(createng(TestDir))]) :- 803 | open_directory_store(TestDir, Store), 804 | open_write(Store, Builder), 805 | open_named_graph(Store, "sometestdb", DB), 806 | nb_add_triple(Builder, "Subject", "Predicate", value("Object")), 807 | nb_commit(Builder, Layer), 808 | nb_set_head(DB, Layer). 809 | 810 | 811 | test(commit_and_set_header_version_first, [cleanup(clean(TestDir)), setup(createng(TestDir))]) :- 812 | open_directory_store(TestDir, Store), 813 | open_write(Store, Builder), 814 | open_named_graph(Store, "sometestdb", DB), 815 | nb_add_triple(Builder, "Subject", "Predicate", value("Object")), 816 | nb_commit(Builder, Layer), 817 | nb_force_set_head(DB, Layer, 0). 818 | 819 | 820 | test(commit_and_set_header_version_first_wrong_version, [cleanup(clean(TestDir)), setup(createng(TestDir))]) :- 821 | open_directory_store(TestDir, Store), 822 | open_write(Store, Builder), 823 | open_named_graph(Store, "sometestdb", DB), 824 | nb_add_triple(Builder, "Subject", "Predicate", value("Object")), 825 | nb_commit(Builder, Layer), 826 | \+ nb_force_set_head(DB, Layer, 1). 827 | 828 | test(commit_and_set_header_version_multiple_commits, [cleanup(clean(TestDir)), setup(createng(TestDir))]) :- 829 | open_directory_store(TestDir, Store), 830 | open_write(Store, Builder), 831 | open_named_graph(Store, "sometestdb", DB), 832 | nb_add_triple(Builder, "Subject", "Predicate", value("Object")), 833 | nb_commit(Builder, Layer), 834 | nb_force_set_head(DB, Layer, 0), 835 | 836 | head(DB, _, 1), 837 | 838 | open_write(Store, Builder2), 839 | nb_add_triple(Builder2, "Subject2", "Predicate2", value("Object2")), 840 | nb_commit(Builder2, Layer2), 841 | nb_force_set_head(DB, Layer2, 1), 842 | 843 | head(DB, _, 2), 844 | \+ head(DB, _, 3). 845 | 846 | 847 | test(commit_and_set_header_version_incorrect, [cleanup(clean(TestDir)), setup(createng(TestDir))]) :- 848 | open_directory_store(TestDir, Store), 849 | open_write(Store, Builder), 850 | open_named_graph(Store, "sometestdb", DB), 851 | nb_add_triple(Builder, "Subject", "Predicate", value("Object")), 852 | nb_commit(Builder, Layer), 853 | \+ nb_force_set_head(DB, Layer, 1). 854 | 855 | 856 | test(commit_and_set_header_version_multiples_incorrect, [cleanup(clean(TestDir)), setup(createng(TestDir))]) :- 857 | open_directory_store(TestDir, Store), 858 | open_write(Store, Builder), 859 | open_named_graph(Store, "sometestdb", DB), 860 | nb_add_triple(Builder, "Subject", "Predicate", value("Object")), 861 | nb_commit(Builder, Layer), 862 | nb_force_set_head(DB, Layer, 0), 863 | 864 | head(DB, _, 1), 865 | 866 | open_write(Store, Builder2), 867 | nb_add_triple(Builder2, "Subject2", "Predicate2", value("Object2")), 868 | nb_commit(Builder2, Layer2), 869 | \+ nb_force_set_head(DB, Layer2, 0). 870 | 871 | 872 | test(commit_and_set_header_memory) :- 873 | open_memory_store(Store), 874 | open_write(Store, Builder), 875 | create_named_graph(Store, "sometestdb", DB), 876 | nb_add_triple(Builder, "Subject", "Predicate", value("Object")), 877 | nb_commit(Builder, Layer), 878 | nb_set_head(DB, Layer). 879 | 880 | test(head_after_first_commit, [cleanup(clean(TestDir)), setup(createng(TestDir))]) :- 881 | open_directory_store(TestDir, Store), 882 | open_named_graph(Store, "sometestdb", DB), 883 | open_write(Store, Builder), 884 | nb_add_triple(Builder, "Subject", "Predicate", value("Object")), 885 | nb_commit(Builder, Layer), 886 | nb_set_head(DB, Layer), 887 | head(DB, _). 888 | 889 | test(predicate_count, [cleanup(clean(TestDir)), setup(createng(TestDir))]) :- 890 | open_directory_store(TestDir, Store), 891 | open_named_graph(Store, "sometestdb", DB), 892 | open_write(Store, Builder), 893 | nb_add_triple(Builder, "Subject", "Predicate", value("Object")), 894 | nb_commit(Builder, Layer), 895 | nb_set_head(DB, Layer), 896 | head(DB, LayerHead), 897 | predicate_count(LayerHead, Count), 898 | Count == 1. 899 | 900 | test(node_and_value_count, [cleanup(clean(TestDir)), setup(createng(TestDir))]) :- 901 | open_directory_store(TestDir, Store), 902 | open_write(Store, Builder), 903 | nb_add_triple(Builder, "Subject", "Predicate", value("Object")), 904 | nb_commit(Builder, Layer), 905 | node_and_value_count(Layer, Count), 906 | Count == 2. 907 | 908 | test(predicate_count_2, [cleanup(clean(TestDir)), setup(createng(TestDir))]) :- 909 | open_directory_store(TestDir, Store), 910 | open_named_graph(Store, "sometestdb", DB), 911 | open_write(Store, Builder), 912 | nb_add_triple(Builder, "Subject", "Predicate", value("Object")), 913 | nb_add_triple(Builder, "Subject2", "Predicate2", value("Object2")), 914 | nb_commit(Builder, Layer), 915 | nb_set_head(DB, Layer), 916 | predicate_count(Layer, Count), 917 | Count == 2. 918 | 919 | test(remove_triple, [cleanup(clean(TestDir)), setup(createng(TestDir))]) :- 920 | open_directory_store(TestDir, Store), 921 | open_write(Store, Builder), 922 | nb_add_triple(Builder, "Subject", "Predicate", value("Object")), 923 | nb_commit(Builder, Layer), 924 | open_write(Layer, LayerBuilder), 925 | nb_remove_triple(LayerBuilder, "Subject", "Predicate", value("Object")). 926 | 927 | test(triple_search_test, [cleanup(clean(TestDir)), setup(createng(TestDir))]) :- 928 | open_directory_store(TestDir, Store), 929 | open_write(Store, Builder), 930 | nb_add_triple(Builder, "Subject", "Predicate", value("Object")), 931 | nb_commit(Builder, Layer), 932 | setof(X, triple(Layer, "Subject", "Predicate", value(X)), Bag), 933 | Bag == ["Object"]. 934 | 935 | 936 | test(triple_search_test, [cleanup(clean(TestDir)), setup(createng(TestDir))]) :- 937 | open_directory_store(TestDir, Store), 938 | open_write(Store, Builder), 939 | nb_add_triple(Builder, "Subject", "Predicate", value("Object")), 940 | nb_commit(Builder, Layer), 941 | setof(Y-X, triple(Layer, "Subject", Y, value(X)), Bag), 942 | Bag == ["Predicate"-"Object"]. 943 | 944 | 945 | test(triple_search_test, [cleanup(clean(TestDir)), setup(createng(TestDir))]) :- 946 | open_directory_store(TestDir, Store), 947 | open_write(Store, Builder), 948 | nb_add_triple(Builder, "Subject", "Predicate", value("Object")), 949 | nb_commit(Builder, Layer), 950 | setof(X-Y-Z, triple(Layer, X, Y, value(Z)), Bag), 951 | Bag == ["Subject"-"Predicate"-"Object"]. 952 | 953 | test(backtracking_test, [cleanup(clean(TestDir)), setup(createng(TestDir))]) :- 954 | open_directory_store(TestDir, Store), 955 | open_write(Store, Builder), 956 | create_named_graph(Store, "testdb", DB), 957 | nb_add_triple(Builder, "A", "B", node("C")), 958 | nb_add_triple(Builder, "A", "D", node("C")), 959 | nb_add_triple(Builder, "A", "E", node("C")), 960 | nb_add_triple(Builder, "A", "E", node("O")), 961 | nb_add_triple(Builder, "A", "D", node("O")), 962 | nb_commit(Builder, Layer), 963 | nb_set_head(DB, Layer), 964 | 965 | findall(P, triple(Layer, "A", P, node("O")), Ps), 966 | Ps = ["D", "E"]. 967 | 968 | test(query_builder_for_committed, [cleanup(clean(TestDir)),setup(createng(TestDir))]) :- 969 | open_directory_store(TestDir, Store), 970 | open_write(Store, Builder), 971 | 972 | \+ builder_committed(Builder), 973 | 974 | nb_commit(Builder, _Layer), 975 | 976 | builder_committed(Builder). 977 | 978 | test(squash_a_tower,[cleanup(clean(TestDir)), setup(createng(TestDir))]) :- 979 | open_directory_store(TestDir, Store), 980 | open_write(Store, Builder), 981 | create_named_graph(Store, "testdb", DB), 982 | nb_add_triple(Builder, "joe", "eats", node("urchin")), 983 | nb_commit(Builder, Layer), 984 | 985 | open_write(Layer,Builder2), 986 | nb_add_triple(Builder2, "jill", "eats", node("caviar")), 987 | nb_commit(Builder2, Layer2), 988 | 989 | squash(Layer2,Squashed_Layer), 990 | 991 | nb_set_head(DB, Squashed_Layer), 992 | 993 | open_named_graph(Store, "testdb", DB2), 994 | head(DB2,Squash), 995 | 996 | findall(X-P-Y, triple(Squash, X, P, Y), Triples), 997 | 998 | Triples = ["jill"-"eats"-node("caviar"), 999 | "joe"-"eats"-node("urchin") 1000 | ], 1001 | \+ parent(Squash,_). 1002 | 1003 | 1004 | test(force_set_head,[cleanup(clean(TestDir)), setup(createng(TestDir))]) :- 1005 | open_directory_store(TestDir, Store), 1006 | open_write(Store, Builder1), 1007 | create_named_graph(Store, "testdb", DB1), 1008 | nb_add_triple(Builder1, "joe", "eats", node("urchin")), 1009 | nb_commit(Builder1, _Layer1), 1010 | 1011 | open_write(Store, Builder2), 1012 | nb_add_triple(Builder2, "jill", "eats", node("caviar")), 1013 | nb_commit(Builder2, Layer2), 1014 | 1015 | nb_force_set_head(DB1,Layer2), 1016 | 1017 | head(DB1,Layer3), 1018 | findall(X-P-Y, triple(Layer3, X, P, Y), Triples), 1019 | 1020 | Triples = ["jill"-"eats"-node("caviar")], 1021 | 1022 | \+ parent(Layer3,_). 1023 | 1024 | test(apply_a_delta,[cleanup(clean(TestDir)), setup(createng(TestDir))]) :- 1025 | open_directory_store(TestDir, Store), 1026 | open_write(Store, Builder), 1027 | nb_add_triple(Builder, "joe", "eats", node("urchin")), 1028 | nb_commit(Builder, Layer), 1029 | 1030 | open_write(Layer,Builder2), 1031 | nb_add_triple(Builder2, "jill", "eats", node("caviar")), 1032 | nb_commit(Builder2, Delta), 1033 | 1034 | open_write(Store, Builder_Base), 1035 | nb_add_triple(Builder_Base, "cathie", "eats", node("seaweed")), 1036 | nb_commit(Builder_Base, Base), 1037 | 1038 | open_write(Base, Builder_New), 1039 | nb_apply_delta(Builder_New,Delta), 1040 | nb_commit(Builder_New,Final_Layer), 1041 | 1042 | findall(X-P-Y, triple(Final_Layer, X, P, Y), Triples), 1043 | 1044 | Triples = ["cathie"-"eats"-node("seaweed"), 1045 | "jill"-"eats"-node("caviar") 1046 | ]. 1047 | 1048 | test(apply_a_diff,[cleanup(clean(TestDir)), setup(createng(TestDir))]) :- 1049 | open_directory_store(TestDir, Store), 1050 | open_write(Store, Builder), 1051 | nb_add_triple(Builder, "joe", "eats", node("urchin")), 1052 | nb_add_triple(Builder, "jill", "eats", node("caviar")), 1053 | nb_add_triple(Builder, "cathie", "eats", node("seaweed")), 1054 | nb_commit(Builder, Layer), 1055 | 1056 | open_write(Store, Builder2), 1057 | nb_add_triple(Builder2, "joe", "eats", node("seals")), 1058 | nb_add_triple(Builder2, "jill", "eats", node("caviar")), 1059 | nb_commit(Builder2, Prototype), 1060 | 1061 | open_write(Layer, Diff_Builder), 1062 | nb_apply_diff(Diff_Builder,Prototype), 1063 | nb_commit(Diff_Builder,Final_Layer), 1064 | 1065 | findall(X-P-Y, triple(Final_Layer, X, P, Y), Triples), 1066 | Triples = [ 1067 | "jill"-"eats"-node("caviar"), 1068 | "joe"-"eats"-node("seals") 1069 | ], 1070 | 1071 | findall(X-P-Y, triple_addition(Final_Layer, X, P, Y), Triple_Additions), 1072 | Triple_Additions = [ 1073 | "joe"-"eats"-node("seals") 1074 | ], 1075 | 1076 | findall(X-P-Y, triple_removal(Final_Layer, X, P, Y), Triple_Removals), 1077 | Triple_Removals = [ 1078 | "cathie"-"eats"-node("seaweed"), 1079 | "joe"-"eats"-node("urchin") 1080 | ]. 1081 | 1082 | test(apply_empty_diff,[cleanup(clean(TestDir)), setup(createng(TestDir))]) :- 1083 | open_directory_store(TestDir, Store), 1084 | open_write(Store, Builder), 1085 | nb_add_triple(Builder, "joe", "eats", node("urchin")), 1086 | nb_add_triple(Builder, "jill", "eats", node("caviar")), 1087 | nb_add_triple(Builder, "cathie", "eats", node("seaweed")), 1088 | nb_commit(Builder, Prototype), 1089 | 1090 | open_write(Store, Diff_Builder), 1091 | nb_apply_diff(Diff_Builder,Prototype), 1092 | nb_commit(Diff_Builder,Final_Layer), 1093 | 1094 | findall(X-P-Y, triple(Final_Layer, X, P, Y), Triples), 1095 | 1096 | Triples = [ 1097 | "cathie"-"eats"-node("seaweed"), 1098 | "jill"-"eats"-node("caviar"), 1099 | "joe"-"eats"-node("urchin") 1100 | ], 1101 | 1102 | findall(X-P-Y, triple_addition(Final_Layer, X, P, Y), Triple_Additions), 1103 | Triple_Additions = Triples, 1104 | findall(X-P-Y, triple_removal(Final_Layer, X, P, Y), Triple_Removals), 1105 | Triple_Removals = []. 1106 | 1107 | test(add_csv,[cleanup(clean(TestDir)), setup(createng(TestDir))]) :- 1108 | open_directory_store(TestDir, Store), 1109 | open_write(Store, Builder), 1110 | tmp_file_stream(Filename, Stream, [encoding(utf8)]), 1111 | format(Stream, "some,header~n", []), 1112 | format(Stream, "1,2~n", []), 1113 | format(Stream, "3,4~n", []), 1114 | close(Stream), 1115 | csv_builder("csv",Filename, Builder, []), 1116 | nb_commit(Builder, Layer), 1117 | findall(X-P-Y, triple(Layer, X, P, Y), Triples), 1118 | 1119 | Triples = [ 1120 | X-"csv:///schema#csv_column_header"-value("\"2\"^^'http://www.w3.org/2001/XMLSchema#string'"), 1121 | X-"csv:///schema#csv_column_some"-value("\"1\"^^'http://www.w3.org/2001/XMLSchema#string'"), 1122 | X-"http://www.w3.org/1999/02/22-rdf-syntax-ns#type"-node(Row1), 1123 | Y-"csv:///schema#csv_column_header"-value("\"4\"^^'http://www.w3.org/2001/XMLSchema#string'"), 1124 | Y-"csv:///schema#csv_column_some"-value("\"3\"^^'http://www.w3.org/2001/XMLSchema#string'"), 1125 | Y-"http://www.w3.org/1999/02/22-rdf-syntax-ns#type"-node(Row1), 1126 | "csv:///data/CSV_csv"-"csv:///schema#csv_column"-node("csv:///data/ColumnObject_csv_header"), 1127 | "csv:///data/CSV_csv"-"csv:///schema#csv_column"-node("csv:///data/ColumnObject_csv_some"), 1128 | "csv:///data/CSV_csv"-"csv:///schema#csv_row"-node(X), 1129 | "csv:///data/CSV_csv"-"csv:///schema#csv_row"-node(Y), 1130 | "csv:///data/CSV_csv"-"http://www.w3.org/1999/02/22-rdf-syntax-ns#type"-node("csv:///schema#CSV"), 1131 | "csv:///data/CSV_csv"-"http://www.w3.org/2000/01/rdf-schema#label"-value("\"csv\"@en"), 1132 | "csv:///data/ColumnObject_csv_header"-"csv:///schema#csv_column_index"-value("1^^'http://www.w3.org/2001/XMLSchema#integer'"), 1133 | "csv:///data/ColumnObject_csv_header"-"csv:///schema#csv_column_name"-value("\"header\"^^'http://www.w3.org/2001/XMLSchema#string'"), 1134 | "csv:///data/ColumnObject_csv_header"-"http://www.w3.org/1999/02/22-rdf-syntax-ns#type"-node("csv:///schema#Column"), 1135 | "csv:///data/ColumnObject_csv_some"-"csv:///schema#csv_column_index"-value("0^^'http://www.w3.org/2001/XMLSchema#integer'"), 1136 | "csv:///data/ColumnObject_csv_some"-"csv:///schema#csv_column_name"-value("\"some\"^^'http://www.w3.org/2001/XMLSchema#string'"), 1137 | "csv:///data/ColumnObject_csv_some"-"http://www.w3.org/1999/02/22-rdf-syntax-ns#type"-node("csv:///schema#Column") 1138 | ]. 1139 | 1140 | test(add_csv_skip_header,[cleanup(clean(TestDir)), setup(createng(TestDir))]) :- 1141 | open_directory_store(TestDir, Store), 1142 | open_write(Store, Builder), 1143 | tmp_file_stream(Filename, Stream, [encoding(utf8)]), 1144 | format(Stream, "1,2~n", []), 1145 | format(Stream, "3,4~n", []), 1146 | close(Stream), 1147 | csv_builder("csv",Filename, Builder, [skip_header(true)]), 1148 | nb_commit(Builder, Layer), 1149 | findall(X-P-Y, triple(Layer, X, P, Y), Triples), 1150 | Triples = [ 1151 | Row1-"csv:///schema#csv_column_0"-value("\"1\"^^'http://www.w3.org/2001/XMLSchema#string'"), 1152 | Row1-"csv:///schema#csv_column_1"-value("\"2\"^^'http://www.w3.org/2001/XMLSchema#string'"), 1153 | Row1-"http://www.w3.org/1999/02/22-rdf-syntax-ns#type"-node(Row_Type), 1154 | Row2-"csv:///schema#csv_column_0"-value("\"3\"^^'http://www.w3.org/2001/XMLSchema#string'"), 1155 | Row2-"csv:///schema#csv_column_1"-value("\"4\"^^'http://www.w3.org/2001/XMLSchema#string'"), 1156 | Row2-"http://www.w3.org/1999/02/22-rdf-syntax-ns#type"-node(Row_Type), 1157 | "csv:///data/CSV_csv"-"csv:///schema#csv_column"-node("csv:///data/ColumnObject_csv_0"), 1158 | "csv:///data/CSV_csv"-"csv:///schema#csv_column"-node("csv:///data/ColumnObject_csv_1"), 1159 | "csv:///data/CSV_csv"-"csv:///schema#csv_row"-node(Row1), 1160 | "csv:///data/CSV_csv"-"csv:///schema#csv_row"-node(Row2), 1161 | "csv:///data/CSV_csv"-"http://www.w3.org/1999/02/22-rdf-syntax-ns#type"-node("csv:///schema#CSV"), 1162 | "csv:///data/CSV_csv"-"http://www.w3.org/2000/01/rdf-schema#label"-value("\"csv\"@en"), 1163 | "csv:///data/ColumnObject_csv_0"-"csv:///schema#csv_column_index"-value("0^^'http://www.w3.org/2001/XMLSchema#integer'"), 1164 | "csv:///data/ColumnObject_csv_0"-"csv:///schema#csv_column_name"-value("\"0\"^^'http://www.w3.org/2001/XMLSchema#string'"), 1165 | "csv:///data/ColumnObject_csv_0"-"http://www.w3.org/1999/02/22-rdf-syntax-ns#type"-node("csv:///schema#Column"), 1166 | "csv:///data/ColumnObject_csv_1"-"csv:///schema#csv_column_index"-value("1^^'http://www.w3.org/2001/XMLSchema#integer'"), 1167 | "csv:///data/ColumnObject_csv_1"-"csv:///schema#csv_column_name"-value("\"1\"^^'http://www.w3.org/2001/XMLSchema#string'"), 1168 | "csv:///data/ColumnObject_csv_1"-"http://www.w3.org/1999/02/22-rdf-syntax-ns#type"-node("csv:///schema#Column") 1169 | ]. 1170 | 1171 | test(csv_prefixes,[cleanup(clean(TestDir)), setup(createng(TestDir))]) :- 1172 | open_directory_store(TestDir, Store), 1173 | open_write(Store, Builder), 1174 | 1175 | tmp_file_stream(Filename, Stream, [encoding(utf8)]), 1176 | format(Stream, "some,header~n", []), 1177 | format(Stream, "1,2~n", []), 1178 | close(Stream), 1179 | 1180 | csv_builder("csv",Filename, Builder, [data_prefix('that/'), 1181 | schema_prefix('this#')]), 1182 | nb_commit(Builder, Layer), 1183 | findall(X-P-Y, triple(Layer, X, P, Y), Triples), 1184 | 1185 | Triples = [ 1186 | Row1-"http://www.w3.org/1999/02/22-rdf-syntax-ns#type"-node(_), 1187 | Row1-"this#csv_column_header"-value("\"2\"^^'http://www.w3.org/2001/XMLSchema#string'"), 1188 | Row1-"this#csv_column_some"-value("\"1\"^^'http://www.w3.org/2001/XMLSchema#string'"), 1189 | "that/CSV_csv"-"http://www.w3.org/1999/02/22-rdf-syntax-ns#type"-node("this#CSV"), 1190 | "that/CSV_csv"-"http://www.w3.org/2000/01/rdf-schema#label"-value("\"csv\"@en"), 1191 | "that/CSV_csv"-"this#csv_column"-node("that/ColumnObject_csv_header"), 1192 | "that/CSV_csv"-"this#csv_column"-node("that/ColumnObject_csv_some"), 1193 | "that/CSV_csv"-"this#csv_row"-node(Row1), 1194 | "that/ColumnObject_csv_header"-"http://www.w3.org/1999/02/22-rdf-syntax-ns#type"-node("this#Column"), 1195 | "that/ColumnObject_csv_header"-"this#csv_column_index"-value("1^^'http://www.w3.org/2001/XMLSchema#integer'"), 1196 | "that/ColumnObject_csv_header"-"this#csv_column_name"-value("\"header\"^^'http://www.w3.org/2001/XMLSchema#string'"), 1197 | "that/ColumnObject_csv_some"-"http://www.w3.org/1999/02/22-rdf-syntax-ns#type"-node("this#Column"), 1198 | "that/ColumnObject_csv_some"-"this#csv_column_index"-value("0^^'http://www.w3.org/2001/XMLSchema#integer'"), 1199 | "that/ColumnObject_csv_some"-"this#csv_column_name"-value("\"some\"^^'http://www.w3.org/2001/XMLSchema#string'") 1200 | ]. 1201 | 1202 | test(csv_with_schema,[cleanup(clean(TestDir)), setup(createng(TestDir))]) :- 1203 | open_directory_store(TestDir, Store), 1204 | open_write(Store, Builder), 1205 | open_write(Store, Schema_Builder), 1206 | tmp_file_stream(Filename, Stream, [encoding(utf8)]), 1207 | format(Stream, "some,header~n", []), 1208 | format(Stream, "1,2~n", []), 1209 | format(Stream, "3,4~n", []), 1210 | close(Stream), 1211 | csv_builder("csv",Filename, Builder, Schema_Builder, 1212 | [data_prefix('data/'), 1213 | schema_prefix('')]), 1214 | nb_commit(Schema_Builder, Schema_Layer), 1215 | findall(X-P-Y, triple(Schema_Layer, X, P, Y), Schema_Triples), 1216 | 1217 | Schema_Expected = [ 1218 | "CSV"-"http://www.w3.org/1999/02/22-rdf-syntax-ns#type"-node("http://www.w3.org/2002/07/owl#Class"), 1219 | "CSV"-"http://www.w3.org/2000/01/rdf-schema#comment"-value("\"CSV object\"@en"), 1220 | "CSV"-"http://www.w3.org/2000/01/rdf-schema#label"-value("\"CSV\"@en"), 1221 | "CSV"-"http://www.w3.org/2000/01/rdf-schema#subClassOf"-node("http://terminusdb.com/schema/system#Document"), 1222 | "CSVRow"-"http://www.w3.org/1999/02/22-rdf-syntax-ns#type"-node("http://www.w3.org/2002/07/owl#Class"), 1223 | "CSVRow"-"http://www.w3.org/2000/01/rdf-schema#comment"-value("\"Generic Row of a CSV file\"@en"), 1224 | "CSVRow"-"http://www.w3.org/2000/01/rdf-schema#label"-value("\"CSV Row\"@en"), 1225 | Row_Type-"http://terminusdb.com/schema/system#csv_name"-value("\"csv\"@en"), 1226 | Row_Type-"http://www.w3.org/1999/02/22-rdf-syntax-ns#type"-node("http://www.w3.org/2002/07/owl#Class"), 1227 | Row_Type-"http://www.w3.org/2000/01/rdf-schema#comment"-value("\"CSV Row object for columns [\\\"header\\\", \\\"some\\\"]\"@en"), 1228 | Row_Type-"http://www.w3.org/2000/01/rdf-schema#label"-value("\"CSV Row from csv\"@en"), 1229 | Row_Type-"http://www.w3.org/2000/01/rdf-schema#subClassOf"-node("CSVRow"), 1230 | "Column"-"http://www.w3.org/1999/02/22-rdf-syntax-ns#type"-node("http://www.w3.org/2002/07/owl#Class"), 1231 | "Column"-"http://www.w3.org/2000/01/rdf-schema#comment"-value("\"Column information object for a CSV\"@en"), 1232 | "Column"-"http://www.w3.org/2000/01/rdf-schema#label"-value("\"Column\"@en"), 1233 | "csv_column_header"-"http://www.w3.org/1999/02/22-rdf-syntax-ns#type"-node("http://www.w3.org/2002/07/owl#DatatypeProperty"), 1234 | "csv_column_header"-"http://www.w3.org/2000/01/rdf-schema#comment"-value("\"CSV Column for header name header\"@en"), 1235 | "csv_column_header"-"http://www.w3.org/2000/01/rdf-schema#domain"-node(Row_Type), 1236 | "csv_column_header"-"http://www.w3.org/2000/01/rdf-schema#label"-value("\"Column header\"@en"), 1237 | "csv_column_header"-"http://www.w3.org/2000/01/rdf-schema#range"-node("http://www.w3.org/2001/XMLSchema#string"), 1238 | "csv_column_some"-"http://www.w3.org/1999/02/22-rdf-syntax-ns#type"-node("http://www.w3.org/2002/07/owl#DatatypeProperty"), 1239 | "csv_column_some"-"http://www.w3.org/2000/01/rdf-schema#comment"-value("\"CSV Column for header name some\"@en"), 1240 | "csv_column_some"-"http://www.w3.org/2000/01/rdf-schema#domain"-node(Row_Type), 1241 | "csv_column_some"-"http://www.w3.org/2000/01/rdf-schema#label"-value("\"Column some\"@en"), 1242 | "csv_column_some"-"http://www.w3.org/2000/01/rdf-schema#range"-node("http://www.w3.org/2001/XMLSchema#string"), 1243 | "csv_column"-"http://www.w3.org/1999/02/22-rdf-syntax-ns#type"-node("http://www.w3.org/2002/07/owl#ObjectProperty"), 1244 | "csv_column"-"http://www.w3.org/2000/01/rdf-schema#comment"-value("\"Associates a CSV with a column object\"@en"), 1245 | "csv_column"-"http://www.w3.org/2000/01/rdf-schema#domain"-node("CSV"), 1246 | "csv_column"-"http://www.w3.org/2000/01/rdf-schema#label"-value("\"csv column\"@en"), 1247 | "csv_column"-"http://www.w3.org/2000/01/rdf-schema#range"-node("Column"), 1248 | "csv_column_index"-"http://www.w3.org/1999/02/22-rdf-syntax-ns#type"-node("http://www.w3.org/2002/07/owl#DatatypeProperty"), 1249 | "csv_column_index"-"http://www.w3.org/2000/01/rdf-schema#comment"-value("\"The ordering index for a column in a csv\"@en"),"csv_column_index"-"http://www.w3.org/2000/01/rdf-schema#domain"-node("Column"), 1250 | "csv_column_index"-"http://www.w3.org/2000/01/rdf-schema#label"-value("\"csv column index\"@en"),"csv_column_index"-"http://www.w3.org/2000/01/rdf-schema#range"-node("http://www.w3.org/2001/XMLSchema#integer"), 1251 | "csv_column_name"-"http://www.w3.org/1999/02/22-rdf-syntax-ns#type"-node("http://www.w3.org/2002/07/owl#DatatypeProperty"), 1252 | "csv_column_name"-"http://www.w3.org/2000/01/rdf-schema#comment"-value("\"The name of the column as it was verbatim in the CSV\"@en"), 1253 | "csv_column_name"-"http://www.w3.org/2000/01/rdf-schema#domain"-node("Column"), 1254 | "csv_column_name"-"http://www.w3.org/2000/01/rdf-schema#label"-value("\"csv column name\"@en"), 1255 | "csv_column_name"-"http://www.w3.org/2000/01/rdf-schema#range"-node("http://www.w3.org/2001/XMLSchema#string"), 1256 | "csv_row"-"http://www.w3.org/1999/02/22-rdf-syntax-ns#type"-node("http://www.w3.org/2002/07/owl#ObjectProperty"), 1257 | "csv_row"-"http://www.w3.org/2000/01/rdf-schema#comment"-value("\"Connects a CSV to its rows\"@en"), 1258 | "csv_row"-"http://www.w3.org/2000/01/rdf-schema#domain"-node("CSV"), 1259 | "csv_row"-"http://www.w3.org/2000/01/rdf-schema#label"-value("\"csv row\"@en"), 1260 | "csv_row"-"http://www.w3.org/2000/01/rdf-schema#range"-node("CSVRow") 1261 | ], 1262 | 1263 | forall(member(Triple,Schema_Triples), 1264 | ( member(Triple,Schema_Expected))). 1265 | 1266 | test(so_mode,[cleanup(clean(TestDir)), setup(createng(TestDir))]) :- 1267 | open_directory_store(TestDir, Store), 1268 | open_write(Store, Builder), 1269 | nb_add_triple(Builder, "A", "B", node("C")), 1270 | nb_add_triple(Builder, "A", "B", node("D")), 1271 | nb_commit(Builder, Layer), 1272 | findall(X-C, triple(Layer, X, "B", C), Ps), 1273 | Ps = ["A"-node("C"), 1274 | "A"-node("D")]. 1275 | 1276 | test(sp_mode,[cleanup(clean(TestDir)), setup(createng(TestDir))]) :- 1277 | open_directory_store(TestDir, Store), 1278 | open_write(Store, Builder), 1279 | nb_add_triple(Builder, "A", "B", node("D")), 1280 | nb_add_triple(Builder, "C", "B", node("D")), 1281 | nb_commit(Builder, Layer), 1282 | findall(X-C, triple(Layer, X, C, node("D")), Ps), 1283 | Ps = ["A"-"B", 1284 | "C"-"B"]. 1285 | 1286 | test(op_mode,[cleanup(clean(TestDir)), setup(createng(TestDir))]) :- 1287 | open_directory_store(TestDir, Store), 1288 | open_write(Store, Builder), 1289 | nb_add_triple(Builder, "A", "B", node("D")), 1290 | nb_add_triple(Builder, "C", "B", node("D")), 1291 | nb_commit(Builder, Layer), 1292 | findall(X, triple(Layer, X, "B", node("D")), Ps), 1293 | Ps = ["A","C"]. 1294 | 1295 | test(p_mode,[cleanup(clean(TestDir)), setup(createng(TestDir))]) :- 1296 | open_directory_store(TestDir, Store), 1297 | open_write(Store, Builder), 1298 | nb_add_triple(Builder, "A", "B", node("D")), 1299 | nb_add_triple(Builder, "C", "B", node("D")), 1300 | nb_commit(Builder, Layer), 1301 | findall(X, triple(Layer, "A", X, node("D")), Ps), 1302 | Ps = ["B"]. 1303 | 1304 | test(rollup,[cleanup(clean(TestDir)), setup(createng(TestDir))]) :- 1305 | open_directory_store(TestDir, Store), 1306 | open_write(Store, Builder), 1307 | nb_add_triple(Builder, "A", "B", node("D")), 1308 | nb_add_triple(Builder, "C", "B", node("D")), 1309 | nb_commit(Builder, Layer), 1310 | 1311 | open_write(Layer, New_Builder), 1312 | nb_add_triple(New_Builder, "E", "F", node("G")), 1313 | nb_remove_triple(New_Builder, "C", "B", node("D")), 1314 | nb_commit(New_Builder, New_Layer), 1315 | rollup(New_Layer), 1316 | layer_to_id(New_Layer, Id), 1317 | store_id_layer(Store, Id, Rollup), 1318 | findall(X-P-Y, triple(Rollup, X, P, node(Y)), Triples), 1319 | 1320 | Triples = ["A"-"B"-"D","E"-"F"-"G"]. 1321 | 1322 | test(rollup_upto,[cleanup(clean(TestDir)), setup(createng(TestDir))]) :- 1323 | open_directory_store(TestDir, Store), 1324 | open_write(Store, Builder), 1325 | nb_add_triple(Builder, "A", "B", node("D")), 1326 | nb_add_triple(Builder, "C", "B", node("D")), 1327 | nb_commit(Builder, Layer), 1328 | 1329 | open_write(Layer, New_Builder), 1330 | nb_add_triple(New_Builder, "E", "F", node("G")), 1331 | nb_remove_triple(New_Builder, "C", "B", node("D")), 1332 | nb_commit(New_Builder, New_Layer), 1333 | 1334 | open_write(New_Layer, New_Builder_2), 1335 | nb_add_triple(New_Builder_2, "G", "H", node("I")), 1336 | nb_remove_triple(New_Builder_2, "A", "B", node("D")), 1337 | nb_commit(New_Builder_2, New_Layer_2), 1338 | 1339 | rollup_upto(New_Layer_2, Layer), 1340 | layer_to_id(New_Layer_2, Id), 1341 | 1342 | store_id_layer(Store, Id, Rollup), 1343 | findall(X-P-Y, triple(Rollup, X, P, node(Y)), Triples), 1344 | 1345 | Triples = ["E"-"F"-"G","G"-"H"-"I"]. 1346 | 1347 | test(layer_stack_names,[cleanup(clean(TestDir)), setup(createng(TestDir))]) :- 1348 | open_directory_store(TestDir, Store), 1349 | open_write(Store, Builder), 1350 | nb_add_triple(Builder, "A", "B", node("D")), 1351 | nb_add_triple(Builder, "C", "B", node("D")), 1352 | nb_commit(Builder, Layer), 1353 | layer_to_id(Layer, Layer_Id), 1354 | 1355 | open_write(Layer, New_Builder), 1356 | nb_add_triple(New_Builder, "E", "F", node("G")), 1357 | nb_remove_triple(New_Builder, "C", "B", node("D")), 1358 | nb_commit(New_Builder, New_Layer), 1359 | layer_to_id(New_Layer, New_Layer_Id), 1360 | 1361 | open_write(New_Layer, New_Builder_2), 1362 | nb_add_triple(New_Builder_2, "G", "H", node("I")), 1363 | nb_remove_triple(New_Builder_2, "A", "B", node("D")), 1364 | nb_commit(New_Builder_2, New_Layer_2), 1365 | layer_to_id(New_Layer_2, New_Layer_2_Id), 1366 | 1367 | layer_stack_names(New_Layer_2, Layers), 1368 | 1369 | Expected = [Layer_Id,New_Layer_Id,New_Layer_2_Id], 1370 | 1371 | Expected = Layers. 1372 | 1373 | test(precise_rollup_rolls_up_precisely,[cleanup(clean(TestDir)), setup(createng(TestDir))]) :- 1374 | open_directory_store(TestDir, Store), 1375 | open_write(Store, Builder), 1376 | nb_add_triple(Builder, "a", "a", value("a")), 1377 | nb_add_triple(Builder, "a", "b", value("a")), 1378 | nb_add_triple(Builder, "c", "c", node("a")), 1379 | nb_commit(Builder, Layer), 1380 | 1381 | open_write(Layer, Builder2), 1382 | nb_remove_triple(Builder2, "a", "a", value("a")), 1383 | nb_add_triple(Builder2, "c", "b", node("d")), 1384 | nb_commit(Builder2, Layer2), 1385 | 1386 | open_write(Layer2, Builder3), 1387 | nb_add_triple(Builder3, "c", "c", node("c")), 1388 | nb_remove_triple(Builder3, "c", "b", node("d")), 1389 | nb_commit(Builder3, Layer3), 1390 | 1391 | open_write(Layer3, Builder4), 1392 | nb_add_triple(Builder4, "a", "a", value("a")), 1393 | nb_add_triple(Builder4, "x", "y", node("z")), 1394 | nb_commit(Builder4, Layer4), 1395 | 1396 | rollup_upto(Layer3, Layer), 1397 | 1398 | % lets reload the top layer 1399 | layer_to_id(Layer4, Layer4_Id), 1400 | store_id_layer(Store, Layer4_Id, Layer4_Reloaded), 1401 | 1402 | % and rollup again 1403 | rollup_upto(Layer4_Reloaded, Layer2), 1404 | 1405 | % and reload again! 1406 | store_id_layer(Store, Layer4_Id, Layer4_Reloaded_Again), 1407 | 1408 | findall(t(S,P,O), triple(Layer4_Reloaded_Again, S, P, O), Triples), 1409 | 1410 | Expected = [ 1411 | t("a", "a", value("a")), 1412 | t("a", "b", value("a")), 1413 | t("c", "c", node("a")), 1414 | t("c", "c", node("c")), 1415 | t("x", "y", node("z")) 1416 | ], 1417 | 1418 | Triples = Expected. 1419 | 1420 | test(imprecise_rollup_rolls_up_imprecisely,[cleanup(clean(TestDir)), setup(createng(TestDir))]) :- 1421 | open_directory_store(TestDir, Store), 1422 | open_write(Store, Builder), 1423 | nb_add_triple(Builder, "a", "a", value("a")), 1424 | nb_add_triple(Builder, "a", "b", value("a")), 1425 | nb_add_triple(Builder, "c", "c", node("a")), 1426 | nb_commit(Builder, Layer), 1427 | 1428 | open_write(Layer, Builder2), 1429 | nb_remove_triple(Builder2, "a", "a", value("a")), 1430 | nb_add_triple(Builder2, "c", "b", node("d")), 1431 | nb_commit(Builder2, Layer2), 1432 | 1433 | open_write(Layer2, Builder3), 1434 | nb_add_triple(Builder3, "c", "c", node("c")), 1435 | nb_remove_triple(Builder3, "c", "b", node("d")), 1436 | nb_commit(Builder3, Layer3), 1437 | 1438 | open_write(Layer3, Builder4), 1439 | nb_add_triple(Builder4, "a", "a", value("a")), 1440 | nb_add_triple(Builder4, "x", "y", node("z")), 1441 | nb_commit(Builder4, Layer4), 1442 | 1443 | rollup_upto(Layer3, Layer), 1444 | 1445 | % lets reload the top layer 1446 | layer_to_id(Layer4, Layer4_Id), 1447 | store_id_layer(Store, Layer4_Id, Layer4_Reloaded), 1448 | 1449 | % and rollup again 1450 | imprecise_rollup_upto(Layer4_Reloaded, Layer2), 1451 | 1452 | % and reload again! 1453 | store_id_layer(Store, Layer4_Id, Layer4_Reloaded_Again), 1454 | 1455 | findall(t(S,P,O), triple(Layer4_Reloaded_Again, S, P, O), Triples), 1456 | 1457 | Expected = [ 1458 | t("a", "a", value("a")), 1459 | t("a", "b", value("a")), 1460 | t("c", "c", node("a")), 1461 | t("c", "c", node("c")), 1462 | t("x", "y", node("z")) 1463 | ], 1464 | 1465 | Triples = Expected. 1466 | 1467 | test(sp_card,[cleanup(clean(TestDir)), setup(createng(TestDir))]) :- 1468 | open_directory_store(TestDir, Store), 1469 | open_write(Store, Builder), 1470 | nb_add_triple(Builder, "A", "B", node("C")), 1471 | nb_add_triple(Builder, "A", "B", node("D")), 1472 | nb_commit(Builder, Layer), 1473 | subject_id(Layer, "A", A_Id), 1474 | predicate_id(Layer, "B", B_Id), 1475 | sp_card(Layer, A_Id, B_Id, Count), 1476 | Count = 2. 1477 | 1478 | :- end_tests(terminus_store). 1479 | -------------------------------------------------------------------------------- /rust/Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 3 4 | 5 | [[package]] 6 | name = "adler" 7 | version = "1.0.2" 8 | source = "registry+https://github.com/rust-lang/crates.io-index" 9 | checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" 10 | 11 | [[package]] 12 | name = "aho-corasick" 13 | version = "0.7.18" 14 | source = "registry+https://github.com/rust-lang/crates.io-index" 15 | checksum = "1e37cfd5e7657ada45f742d6e99ca5788580b5c529dc78faf11ece6dc702656f" 16 | dependencies = [ 17 | "memchr", 18 | ] 19 | 20 | [[package]] 21 | name = "ansi_term" 22 | version = "0.12.1" 23 | source = "registry+https://github.com/rust-lang/crates.io-index" 24 | checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2" 25 | dependencies = [ 26 | "winapi", 27 | ] 28 | 29 | [[package]] 30 | name = "async-trait" 31 | version = "0.1.53" 32 | source = "registry+https://github.com/rust-lang/crates.io-index" 33 | checksum = "ed6aa3524a2dfcf9fe180c51eae2b58738348d819517ceadf95789c51fff7600" 34 | dependencies = [ 35 | "proc-macro2", 36 | "quote", 37 | "syn", 38 | ] 39 | 40 | [[package]] 41 | name = "atty" 42 | version = "0.2.14" 43 | source = "registry+https://github.com/rust-lang/crates.io-index" 44 | checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" 45 | dependencies = [ 46 | "hermit-abi", 47 | "libc", 48 | "winapi", 49 | ] 50 | 51 | [[package]] 52 | name = "autocfg" 53 | version = "1.1.0" 54 | source = "registry+https://github.com/rust-lang/crates.io-index" 55 | checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" 56 | 57 | [[package]] 58 | name = "bindgen" 59 | version = "0.59.2" 60 | source = "registry+https://github.com/rust-lang/crates.io-index" 61 | checksum = "2bd2a9a458e8f4304c52c43ebb0cfbd520289f8379a52e329a38afda99bf8eb8" 62 | dependencies = [ 63 | "bitflags", 64 | "cexpr", 65 | "clang-sys", 66 | "clap", 67 | "env_logger", 68 | "lazy_static", 69 | "lazycell", 70 | "log", 71 | "peeking_take_while", 72 | "proc-macro2", 73 | "quote", 74 | "regex", 75 | "rustc-hash", 76 | "shlex", 77 | "which", 78 | ] 79 | 80 | [[package]] 81 | name = "bitflags" 82 | version = "1.3.2" 83 | source = "registry+https://github.com/rust-lang/crates.io-index" 84 | checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" 85 | 86 | [[package]] 87 | name = "block-buffer" 88 | version = "0.9.0" 89 | source = "registry+https://github.com/rust-lang/crates.io-index" 90 | checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" 91 | dependencies = [ 92 | "generic-array", 93 | ] 94 | 95 | [[package]] 96 | name = "bstr" 97 | version = "0.2.17" 98 | source = "registry+https://github.com/rust-lang/crates.io-index" 99 | checksum = "ba3569f383e8f1598449f1a423e72e99569137b47740b1da11ef19af3d5c3223" 100 | dependencies = [ 101 | "lazy_static", 102 | "memchr", 103 | "regex-automata", 104 | "serde", 105 | ] 106 | 107 | [[package]] 108 | name = "byteorder" 109 | version = "1.4.3" 110 | source = "registry+https://github.com/rust-lang/crates.io-index" 111 | checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" 112 | 113 | [[package]] 114 | name = "bytes" 115 | version = "0.5.6" 116 | source = "registry+https://github.com/rust-lang/crates.io-index" 117 | checksum = "0e4cec68f03f32e44924783795810fa50a7035d8c8ebe78580ad7e6c703fba38" 118 | 119 | [[package]] 120 | name = "bytes" 121 | version = "1.1.0" 122 | source = "registry+https://github.com/rust-lang/crates.io-index" 123 | checksum = "c4872d67bab6358e59559027aa3b9157c53d9358c51423c17554809a8858e0f8" 124 | 125 | [[package]] 126 | name = "cexpr" 127 | version = "0.6.0" 128 | source = "registry+https://github.com/rust-lang/crates.io-index" 129 | checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766" 130 | dependencies = [ 131 | "nom", 132 | ] 133 | 134 | [[package]] 135 | name = "cfg-if" 136 | version = "1.0.0" 137 | source = "registry+https://github.com/rust-lang/crates.io-index" 138 | checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" 139 | 140 | [[package]] 141 | name = "chardetng" 142 | version = "0.1.17" 143 | source = "registry+https://github.com/rust-lang/crates.io-index" 144 | checksum = "14b8f0b65b7b08ae3c8187e8d77174de20cb6777864c6b832d8ad365999cf1ea" 145 | dependencies = [ 146 | "cfg-if", 147 | "encoding_rs", 148 | "memchr", 149 | ] 150 | 151 | [[package]] 152 | name = "clang-sys" 153 | version = "1.3.1" 154 | source = "registry+https://github.com/rust-lang/crates.io-index" 155 | checksum = "4cc00842eed744b858222c4c9faf7243aafc6d33f92f96935263ef4d8a41ce21" 156 | dependencies = [ 157 | "glob", 158 | "libc", 159 | "libloading", 160 | ] 161 | 162 | [[package]] 163 | name = "clap" 164 | version = "2.34.0" 165 | source = "registry+https://github.com/rust-lang/crates.io-index" 166 | checksum = "a0610544180c38b88101fecf2dd634b174a62eef6946f84dfc6a7127512b381c" 167 | dependencies = [ 168 | "ansi_term", 169 | "atty", 170 | "bitflags", 171 | "strsim", 172 | "textwrap", 173 | "unicode-width", 174 | "vec_map", 175 | ] 176 | 177 | [[package]] 178 | name = "cpufeatures" 179 | version = "0.2.2" 180 | source = "registry+https://github.com/rust-lang/crates.io-index" 181 | checksum = "59a6001667ab124aebae2a495118e11d30984c3a653e99d86d58971708cf5e4b" 182 | dependencies = [ 183 | "libc", 184 | ] 185 | 186 | [[package]] 187 | name = "crc32fast" 188 | version = "1.3.2" 189 | source = "registry+https://github.com/rust-lang/crates.io-index" 190 | checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" 191 | dependencies = [ 192 | "cfg-if", 193 | ] 194 | 195 | [[package]] 196 | name = "crossbeam-channel" 197 | version = "0.5.4" 198 | source = "registry+https://github.com/rust-lang/crates.io-index" 199 | checksum = "5aaa7bd5fb665c6864b5f963dd9097905c54125909c7aa94c9e18507cdbe6c53" 200 | dependencies = [ 201 | "cfg-if", 202 | "crossbeam-utils", 203 | ] 204 | 205 | [[package]] 206 | name = "crossbeam-deque" 207 | version = "0.8.1" 208 | source = "registry+https://github.com/rust-lang/crates.io-index" 209 | checksum = "6455c0ca19f0d2fbf751b908d5c55c1f5cbc65e03c4225427254b46890bdde1e" 210 | dependencies = [ 211 | "cfg-if", 212 | "crossbeam-epoch", 213 | "crossbeam-utils", 214 | ] 215 | 216 | [[package]] 217 | name = "crossbeam-epoch" 218 | version = "0.9.8" 219 | source = "registry+https://github.com/rust-lang/crates.io-index" 220 | checksum = "1145cf131a2c6ba0615079ab6a638f7e1973ac9c2634fcbeaaad6114246efe8c" 221 | dependencies = [ 222 | "autocfg", 223 | "cfg-if", 224 | "crossbeam-utils", 225 | "lazy_static", 226 | "memoffset", 227 | "scopeguard", 228 | ] 229 | 230 | [[package]] 231 | name = "crossbeam-utils" 232 | version = "0.8.8" 233 | source = "registry+https://github.com/rust-lang/crates.io-index" 234 | checksum = "0bf124c720b7686e3c2663cf54062ab0f68a88af2fb6a030e87e30bf721fcb38" 235 | dependencies = [ 236 | "cfg-if", 237 | "lazy_static", 238 | ] 239 | 240 | [[package]] 241 | name = "csv" 242 | version = "1.1.6" 243 | source = "registry+https://github.com/rust-lang/crates.io-index" 244 | checksum = "22813a6dc45b335f9bade10bf7271dc477e81113e89eb251a0bc2a8a81c536e1" 245 | dependencies = [ 246 | "bstr", 247 | "csv-core", 248 | "itoa", 249 | "ryu", 250 | "serde", 251 | ] 252 | 253 | [[package]] 254 | name = "csv-core" 255 | version = "0.1.10" 256 | source = "registry+https://github.com/rust-lang/crates.io-index" 257 | checksum = "2b2466559f260f48ad25fe6317b3c8dac77b5bdb5763ac7d9d6103530663bc90" 258 | dependencies = [ 259 | "memchr", 260 | ] 261 | 262 | [[package]] 263 | name = "digest" 264 | version = "0.9.0" 265 | source = "registry+https://github.com/rust-lang/crates.io-index" 266 | checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" 267 | dependencies = [ 268 | "generic-array", 269 | ] 270 | 271 | [[package]] 272 | name = "either" 273 | version = "1.6.1" 274 | source = "registry+https://github.com/rust-lang/crates.io-index" 275 | checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457" 276 | 277 | [[package]] 278 | name = "encoding_rs" 279 | version = "0.8.31" 280 | source = "registry+https://github.com/rust-lang/crates.io-index" 281 | checksum = "9852635589dc9f9ea1b6fe9f05b50ef208c85c834a562f0c6abb1c475736ec2b" 282 | dependencies = [ 283 | "cfg-if", 284 | ] 285 | 286 | [[package]] 287 | name = "env_logger" 288 | version = "0.9.0" 289 | source = "registry+https://github.com/rust-lang/crates.io-index" 290 | checksum = "0b2cf0344971ee6c64c31be0d530793fba457d322dfec2810c453d0ef228f9c3" 291 | dependencies = [ 292 | "atty", 293 | "humantime", 294 | "log", 295 | "regex", 296 | "termcolor", 297 | ] 298 | 299 | [[package]] 300 | name = "filetime" 301 | version = "0.2.16" 302 | source = "registry+https://github.com/rust-lang/crates.io-index" 303 | checksum = "c0408e2626025178a6a7f7ffc05a25bc47103229f19c113755de7bf63816290c" 304 | dependencies = [ 305 | "cfg-if", 306 | "libc", 307 | "redox_syscall", 308 | "winapi", 309 | ] 310 | 311 | [[package]] 312 | name = "flate2" 313 | version = "1.0.23" 314 | source = "registry+https://github.com/rust-lang/crates.io-index" 315 | checksum = "b39522e96686d38f4bc984b9198e3a0613264abaebaff2c5c918bfa6b6da09af" 316 | dependencies = [ 317 | "cfg-if", 318 | "crc32fast", 319 | "libc", 320 | "miniz_oxide", 321 | ] 322 | 323 | [[package]] 324 | name = "fs2" 325 | version = "0.4.3" 326 | source = "registry+https://github.com/rust-lang/crates.io-index" 327 | checksum = "9564fc758e15025b46aa6643b1b77d047d1a56a1aea6e01002ac0c7026876213" 328 | dependencies = [ 329 | "libc", 330 | "winapi", 331 | ] 332 | 333 | [[package]] 334 | name = "futures" 335 | version = "0.3.21" 336 | source = "registry+https://github.com/rust-lang/crates.io-index" 337 | checksum = "f73fe65f54d1e12b726f517d3e2135ca3125a437b6d998caf1962961f7172d9e" 338 | dependencies = [ 339 | "futures-channel", 340 | "futures-core", 341 | "futures-executor", 342 | "futures-io", 343 | "futures-sink", 344 | "futures-task", 345 | "futures-util", 346 | ] 347 | 348 | [[package]] 349 | name = "futures-channel" 350 | version = "0.3.21" 351 | source = "registry+https://github.com/rust-lang/crates.io-index" 352 | checksum = "c3083ce4b914124575708913bca19bfe887522d6e2e6d0952943f5eac4a74010" 353 | dependencies = [ 354 | "futures-core", 355 | "futures-sink", 356 | ] 357 | 358 | [[package]] 359 | name = "futures-core" 360 | version = "0.3.21" 361 | source = "registry+https://github.com/rust-lang/crates.io-index" 362 | checksum = "0c09fd04b7e4073ac7156a9539b57a484a8ea920f79c7c675d05d289ab6110d3" 363 | 364 | [[package]] 365 | name = "futures-executor" 366 | version = "0.3.21" 367 | source = "registry+https://github.com/rust-lang/crates.io-index" 368 | checksum = "9420b90cfa29e327d0429f19be13e7ddb68fa1cccb09d65e5706b8c7a749b8a6" 369 | dependencies = [ 370 | "futures-core", 371 | "futures-task", 372 | "futures-util", 373 | ] 374 | 375 | [[package]] 376 | name = "futures-io" 377 | version = "0.3.21" 378 | source = "registry+https://github.com/rust-lang/crates.io-index" 379 | checksum = "fc4045962a5a5e935ee2fdedaa4e08284547402885ab326734432bed5d12966b" 380 | 381 | [[package]] 382 | name = "futures-locks" 383 | version = "0.6.0" 384 | source = "registry+https://github.com/rust-lang/crates.io-index" 385 | checksum = "50c4e684ddb2d8a4db5ca8a02b35156da129674ba4412b6f528698d58c594954" 386 | dependencies = [ 387 | "futures", 388 | "tokio 0.2.25", 389 | ] 390 | 391 | [[package]] 392 | name = "futures-macro" 393 | version = "0.3.21" 394 | source = "registry+https://github.com/rust-lang/crates.io-index" 395 | checksum = "33c1e13800337f4d4d7a316bf45a567dbcb6ffe087f16424852d97e97a91f512" 396 | dependencies = [ 397 | "proc-macro2", 398 | "quote", 399 | "syn", 400 | ] 401 | 402 | [[package]] 403 | name = "futures-sink" 404 | version = "0.3.21" 405 | source = "registry+https://github.com/rust-lang/crates.io-index" 406 | checksum = "21163e139fa306126e6eedaf49ecdb4588f939600f0b1e770f4205ee4b7fa868" 407 | 408 | [[package]] 409 | name = "futures-task" 410 | version = "0.3.21" 411 | source = "registry+https://github.com/rust-lang/crates.io-index" 412 | checksum = "57c66a976bf5909d801bbef33416c41372779507e7a6b3a5e25e4749c58f776a" 413 | 414 | [[package]] 415 | name = "futures-util" 416 | version = "0.3.21" 417 | source = "registry+https://github.com/rust-lang/crates.io-index" 418 | checksum = "d8b7abd5d659d9b90c8cba917f6ec750a74e2dc23902ef9cd4cc8c8b22e6036a" 419 | dependencies = [ 420 | "futures-channel", 421 | "futures-core", 422 | "futures-io", 423 | "futures-macro", 424 | "futures-sink", 425 | "futures-task", 426 | "memchr", 427 | "pin-project-lite 0.2.9", 428 | "pin-utils", 429 | "slab", 430 | ] 431 | 432 | [[package]] 433 | name = "generic-array" 434 | version = "0.14.5" 435 | source = "registry+https://github.com/rust-lang/crates.io-index" 436 | checksum = "fd48d33ec7f05fbfa152300fdad764757cbded343c1aa1cff2fbaf4134851803" 437 | dependencies = [ 438 | "typenum", 439 | "version_check", 440 | ] 441 | 442 | [[package]] 443 | name = "getrandom" 444 | version = "0.2.6" 445 | source = "registry+https://github.com/rust-lang/crates.io-index" 446 | checksum = "9be70c98951c83b8d2f8f60d7065fa6d5146873094452a1008da8c2f1e4205ad" 447 | dependencies = [ 448 | "cfg-if", 449 | "libc", 450 | "wasi 0.10.2+wasi-snapshot-preview1", 451 | ] 452 | 453 | [[package]] 454 | name = "glob" 455 | version = "0.3.0" 456 | source = "registry+https://github.com/rust-lang/crates.io-index" 457 | checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574" 458 | 459 | [[package]] 460 | name = "hermit-abi" 461 | version = "0.1.19" 462 | source = "registry+https://github.com/rust-lang/crates.io-index" 463 | checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" 464 | dependencies = [ 465 | "libc", 466 | ] 467 | 468 | [[package]] 469 | name = "hex" 470 | version = "0.4.3" 471 | source = "registry+https://github.com/rust-lang/crates.io-index" 472 | checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" 473 | 474 | [[package]] 475 | name = "humantime" 476 | version = "2.1.0" 477 | source = "registry+https://github.com/rust-lang/crates.io-index" 478 | checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" 479 | 480 | [[package]] 481 | name = "itoa" 482 | version = "0.4.8" 483 | source = "registry+https://github.com/rust-lang/crates.io-index" 484 | checksum = "b71991ff56294aa922b450139ee08b3bfc70982c6b2c7562771375cf73542dd4" 485 | 486 | [[package]] 487 | name = "lazy_static" 488 | version = "1.4.0" 489 | source = "registry+https://github.com/rust-lang/crates.io-index" 490 | checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" 491 | 492 | [[package]] 493 | name = "lazycell" 494 | version = "1.3.0" 495 | source = "registry+https://github.com/rust-lang/crates.io-index" 496 | checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" 497 | 498 | [[package]] 499 | name = "libc" 500 | version = "0.2.125" 501 | source = "registry+https://github.com/rust-lang/crates.io-index" 502 | checksum = "5916d2ae698f6de9bfb891ad7a8d65c09d232dc58cc4ac433c7da3b2fd84bc2b" 503 | 504 | [[package]] 505 | name = "libloading" 506 | version = "0.7.3" 507 | source = "registry+https://github.com/rust-lang/crates.io-index" 508 | checksum = "efbc0f03f9a775e9f6aed295c6a1ba2253c5757a9e03d55c6caa46a681abcddd" 509 | dependencies = [ 510 | "cfg-if", 511 | "winapi", 512 | ] 513 | 514 | [[package]] 515 | name = "lock_api" 516 | version = "0.4.7" 517 | source = "registry+https://github.com/rust-lang/crates.io-index" 518 | checksum = "327fa5b6a6940e4699ec49a9beae1ea4845c6bab9314e4f84ac68742139d8c53" 519 | dependencies = [ 520 | "autocfg", 521 | "scopeguard", 522 | ] 523 | 524 | [[package]] 525 | name = "log" 526 | version = "0.4.17" 527 | source = "registry+https://github.com/rust-lang/crates.io-index" 528 | checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e" 529 | dependencies = [ 530 | "cfg-if", 531 | ] 532 | 533 | [[package]] 534 | name = "memchr" 535 | version = "2.5.0" 536 | source = "registry+https://github.com/rust-lang/crates.io-index" 537 | checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" 538 | 539 | [[package]] 540 | name = "memoffset" 541 | version = "0.6.5" 542 | source = "registry+https://github.com/rust-lang/crates.io-index" 543 | checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce" 544 | dependencies = [ 545 | "autocfg", 546 | ] 547 | 548 | [[package]] 549 | name = "minimal-lexical" 550 | version = "0.2.1" 551 | source = "registry+https://github.com/rust-lang/crates.io-index" 552 | checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" 553 | 554 | [[package]] 555 | name = "miniz_oxide" 556 | version = "0.5.1" 557 | source = "registry+https://github.com/rust-lang/crates.io-index" 558 | checksum = "d2b29bd4bc3f33391105ebee3589c19197c4271e3e5a9ec9bfe8127eeff8f082" 559 | dependencies = [ 560 | "adler", 561 | ] 562 | 563 | [[package]] 564 | name = "mio" 565 | version = "0.8.2" 566 | source = "registry+https://github.com/rust-lang/crates.io-index" 567 | checksum = "52da4364ffb0e4fe33a9841a98a3f3014fb964045ce4f7a45a398243c8d6b0c9" 568 | dependencies = [ 569 | "libc", 570 | "log", 571 | "miow", 572 | "ntapi", 573 | "wasi 0.11.0+wasi-snapshot-preview1", 574 | "winapi", 575 | ] 576 | 577 | [[package]] 578 | name = "miow" 579 | version = "0.3.7" 580 | source = "registry+https://github.com/rust-lang/crates.io-index" 581 | checksum = "b9f1c5b025cda876f66ef43a113f91ebc9f4ccef34843000e0adf6ebbab84e21" 582 | dependencies = [ 583 | "winapi", 584 | ] 585 | 586 | [[package]] 587 | name = "nom" 588 | version = "7.1.1" 589 | source = "registry+https://github.com/rust-lang/crates.io-index" 590 | checksum = "a8903e5a29a317527874d0402f867152a3d21c908bb0b933e416c65e301d4c36" 591 | dependencies = [ 592 | "memchr", 593 | "minimal-lexical", 594 | ] 595 | 596 | [[package]] 597 | name = "ntapi" 598 | version = "0.3.7" 599 | source = "registry+https://github.com/rust-lang/crates.io-index" 600 | checksum = "c28774a7fd2fbb4f0babd8237ce554b73af68021b5f695a3cebd6c59bac0980f" 601 | dependencies = [ 602 | "winapi", 603 | ] 604 | 605 | [[package]] 606 | name = "num_cpus" 607 | version = "1.13.1" 608 | source = "registry+https://github.com/rust-lang/crates.io-index" 609 | checksum = "19e64526ebdee182341572e50e9ad03965aa510cd94427a4549448f285e957a1" 610 | dependencies = [ 611 | "hermit-abi", 612 | "libc", 613 | ] 614 | 615 | [[package]] 616 | name = "once_cell" 617 | version = "1.10.0" 618 | source = "registry+https://github.com/rust-lang/crates.io-index" 619 | checksum = "87f3e037eac156d1775da914196f0f37741a274155e34a0b7e427c35d2a2ecb9" 620 | 621 | [[package]] 622 | name = "opaque-debug" 623 | version = "0.3.0" 624 | source = "registry+https://github.com/rust-lang/crates.io-index" 625 | checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" 626 | 627 | [[package]] 628 | name = "parking_lot" 629 | version = "0.12.0" 630 | source = "registry+https://github.com/rust-lang/crates.io-index" 631 | checksum = "87f5ec2493a61ac0506c0f4199f99070cbe83857b0337006a30f3e6719b8ef58" 632 | dependencies = [ 633 | "lock_api", 634 | "parking_lot_core", 635 | ] 636 | 637 | [[package]] 638 | name = "parking_lot_core" 639 | version = "0.9.3" 640 | source = "registry+https://github.com/rust-lang/crates.io-index" 641 | checksum = "09a279cbf25cb0757810394fbc1e359949b59e348145c643a939a525692e6929" 642 | dependencies = [ 643 | "cfg-if", 644 | "libc", 645 | "redox_syscall", 646 | "smallvec", 647 | "windows-sys", 648 | ] 649 | 650 | [[package]] 651 | name = "peeking_take_while" 652 | version = "0.1.2" 653 | source = "registry+https://github.com/rust-lang/crates.io-index" 654 | checksum = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099" 655 | 656 | [[package]] 657 | name = "pin-project-lite" 658 | version = "0.1.12" 659 | source = "registry+https://github.com/rust-lang/crates.io-index" 660 | checksum = "257b64915a082f7811703966789728173279bdebb956b143dbcd23f6f970a777" 661 | 662 | [[package]] 663 | name = "pin-project-lite" 664 | version = "0.2.9" 665 | source = "registry+https://github.com/rust-lang/crates.io-index" 666 | checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116" 667 | 668 | [[package]] 669 | name = "pin-utils" 670 | version = "0.1.0" 671 | source = "registry+https://github.com/rust-lang/crates.io-index" 672 | checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" 673 | 674 | [[package]] 675 | name = "ppv-lite86" 676 | version = "0.2.16" 677 | source = "registry+https://github.com/rust-lang/crates.io-index" 678 | checksum = "eb9f9e6e233e5c4a35559a617bf40a4ec447db2e84c20b55a6f83167b7e57872" 679 | 680 | [[package]] 681 | name = "proc-macro-crate" 682 | version = "0.1.5" 683 | source = "registry+https://github.com/rust-lang/crates.io-index" 684 | checksum = "1d6ea3c4595b96363c13943497db34af4460fb474a95c43f4446ad341b8c9785" 685 | dependencies = [ 686 | "toml", 687 | ] 688 | 689 | [[package]] 690 | name = "proc-macro2" 691 | version = "1.0.37" 692 | source = "registry+https://github.com/rust-lang/crates.io-index" 693 | checksum = "ec757218438d5fda206afc041538b2f6d889286160d649a86a24d37e1235afd1" 694 | dependencies = [ 695 | "unicode-xid", 696 | ] 697 | 698 | [[package]] 699 | name = "quote" 700 | version = "1.0.18" 701 | source = "registry+https://github.com/rust-lang/crates.io-index" 702 | checksum = "a1feb54ed693b93a84e14094943b84b7c4eae204c512b7ccb95ab0c66d278ad1" 703 | dependencies = [ 704 | "proc-macro2", 705 | ] 706 | 707 | [[package]] 708 | name = "rand" 709 | version = "0.8.5" 710 | source = "registry+https://github.com/rust-lang/crates.io-index" 711 | checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" 712 | dependencies = [ 713 | "libc", 714 | "rand_chacha", 715 | "rand_core", 716 | ] 717 | 718 | [[package]] 719 | name = "rand_chacha" 720 | version = "0.3.1" 721 | source = "registry+https://github.com/rust-lang/crates.io-index" 722 | checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" 723 | dependencies = [ 724 | "ppv-lite86", 725 | "rand_core", 726 | ] 727 | 728 | [[package]] 729 | name = "rand_core" 730 | version = "0.6.3" 731 | source = "registry+https://github.com/rust-lang/crates.io-index" 732 | checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7" 733 | dependencies = [ 734 | "getrandom", 735 | ] 736 | 737 | [[package]] 738 | name = "rayon" 739 | version = "1.5.2" 740 | source = "registry+https://github.com/rust-lang/crates.io-index" 741 | checksum = "fd249e82c21598a9a426a4e00dd7adc1d640b22445ec8545feef801d1a74c221" 742 | dependencies = [ 743 | "autocfg", 744 | "crossbeam-deque", 745 | "either", 746 | "rayon-core", 747 | ] 748 | 749 | [[package]] 750 | name = "rayon-core" 751 | version = "1.9.2" 752 | source = "registry+https://github.com/rust-lang/crates.io-index" 753 | checksum = "9f51245e1e62e1f1629cbfec37b5793bbabcaeb90f30e94d2ba03564687353e4" 754 | dependencies = [ 755 | "crossbeam-channel", 756 | "crossbeam-deque", 757 | "crossbeam-utils", 758 | "num_cpus", 759 | ] 760 | 761 | [[package]] 762 | name = "redox_syscall" 763 | version = "0.2.13" 764 | source = "registry+https://github.com/rust-lang/crates.io-index" 765 | checksum = "62f25bc4c7e55e0b0b7a1d43fb893f4fa1361d0abe38b9ce4f323c2adfe6ef42" 766 | dependencies = [ 767 | "bitflags", 768 | ] 769 | 770 | [[package]] 771 | name = "regex" 772 | version = "1.5.5" 773 | source = "registry+https://github.com/rust-lang/crates.io-index" 774 | checksum = "1a11647b6b25ff05a515cb92c365cec08801e83423a235b51e231e1808747286" 775 | dependencies = [ 776 | "aho-corasick", 777 | "memchr", 778 | "regex-syntax", 779 | ] 780 | 781 | [[package]] 782 | name = "regex-automata" 783 | version = "0.1.10" 784 | source = "registry+https://github.com/rust-lang/crates.io-index" 785 | checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" 786 | 787 | [[package]] 788 | name = "regex-syntax" 789 | version = "0.6.25" 790 | source = "registry+https://github.com/rust-lang/crates.io-index" 791 | checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b" 792 | 793 | [[package]] 794 | name = "rustc-hash" 795 | version = "1.1.0" 796 | source = "registry+https://github.com/rust-lang/crates.io-index" 797 | checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" 798 | 799 | [[package]] 800 | name = "ryu" 801 | version = "1.0.9" 802 | source = "registry+https://github.com/rust-lang/crates.io-index" 803 | checksum = "73b4b750c782965c211b42f022f59af1fbceabdd026623714f104152f1ec149f" 804 | 805 | [[package]] 806 | name = "scopeguard" 807 | version = "1.1.0" 808 | source = "registry+https://github.com/rust-lang/crates.io-index" 809 | checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" 810 | 811 | [[package]] 812 | name = "serde" 813 | version = "1.0.137" 814 | source = "registry+https://github.com/rust-lang/crates.io-index" 815 | checksum = "61ea8d54c77f8315140a05f4c7237403bf38b72704d031543aa1d16abbf517d1" 816 | 817 | [[package]] 818 | name = "sha-1" 819 | version = "0.9.8" 820 | source = "registry+https://github.com/rust-lang/crates.io-index" 821 | checksum = "99cd6713db3cf16b6c84e06321e049a9b9f699826e16096d23bbcc44d15d51a6" 822 | dependencies = [ 823 | "block-buffer", 824 | "cfg-if", 825 | "cpufeatures", 826 | "digest", 827 | "opaque-debug", 828 | ] 829 | 830 | [[package]] 831 | name = "shlex" 832 | version = "1.1.0" 833 | source = "registry+https://github.com/rust-lang/crates.io-index" 834 | checksum = "43b2853a4d09f215c24cc5489c992ce46052d359b5109343cbafbf26bc62f8a3" 835 | 836 | [[package]] 837 | name = "signal-hook-registry" 838 | version = "1.4.0" 839 | source = "registry+https://github.com/rust-lang/crates.io-index" 840 | checksum = "e51e73328dc4ac0c7ccbda3a494dfa03df1de2f46018127f60c693f2648455b0" 841 | dependencies = [ 842 | "libc", 843 | ] 844 | 845 | [[package]] 846 | name = "slab" 847 | version = "0.4.6" 848 | source = "registry+https://github.com/rust-lang/crates.io-index" 849 | checksum = "eb703cfe953bccee95685111adeedb76fabe4e97549a58d16f03ea7b9367bb32" 850 | 851 | [[package]] 852 | name = "smallvec" 853 | version = "1.8.0" 854 | source = "registry+https://github.com/rust-lang/crates.io-index" 855 | checksum = "f2dd574626839106c320a323308629dcb1acfc96e32a8cba364ddc61ac23ee83" 856 | 857 | [[package]] 858 | name = "socket2" 859 | version = "0.4.4" 860 | source = "registry+https://github.com/rust-lang/crates.io-index" 861 | checksum = "66d72b759436ae32898a2af0a14218dbf55efde3feeb170eb623637db85ee1e0" 862 | dependencies = [ 863 | "libc", 864 | "winapi", 865 | ] 866 | 867 | [[package]] 868 | name = "strsim" 869 | version = "0.8.0" 870 | source = "registry+https://github.com/rust-lang/crates.io-index" 871 | checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" 872 | 873 | [[package]] 874 | name = "swipl" 875 | version = "0.3.6" 876 | source = "registry+https://github.com/rust-lang/crates.io-index" 877 | checksum = "c2b98b973f28e775f54d07e6db4b78d5605a98fedbe15322af0f51fd4e9ae050" 878 | dependencies = [ 879 | "lazy_static", 880 | "swipl-fli", 881 | "swipl-macros", 882 | "thiserror", 883 | ] 884 | 885 | [[package]] 886 | name = "swipl-fli" 887 | version = "0.3.3" 888 | source = "registry+https://github.com/rust-lang/crates.io-index" 889 | checksum = "97401209985d55fc7513fc9ba5f73e0de3886f42620e6d0d9e945c636dcd4102" 890 | dependencies = [ 891 | "bindgen", 892 | "swipl-info", 893 | ] 894 | 895 | [[package]] 896 | name = "swipl-info" 897 | version = "0.3.2" 898 | source = "registry+https://github.com/rust-lang/crates.io-index" 899 | checksum = "d3c24ee13ef4f59cce23ccaff3006a861c7f8b02984c2a7821e7f1ced54b6c1a" 900 | dependencies = [ 901 | "regex", 902 | ] 903 | 904 | [[package]] 905 | name = "swipl-macros" 906 | version = "0.3.4" 907 | source = "registry+https://github.com/rust-lang/crates.io-index" 908 | checksum = "e0405e02344511d55b247696212748d0b90f673b763121534fee73355d4020da" 909 | dependencies = [ 910 | "proc-macro-crate", 911 | "proc-macro2", 912 | "quote", 913 | "syn", 914 | ] 915 | 916 | [[package]] 917 | name = "syn" 918 | version = "1.0.92" 919 | source = "registry+https://github.com/rust-lang/crates.io-index" 920 | checksum = "7ff7c592601f11445996a06f8ad0c27f094a58857c2f89e97974ab9235b92c52" 921 | dependencies = [ 922 | "proc-macro2", 923 | "quote", 924 | "unicode-xid", 925 | ] 926 | 927 | [[package]] 928 | name = "tar" 929 | version = "0.4.38" 930 | source = "registry+https://github.com/rust-lang/crates.io-index" 931 | checksum = "4b55807c0344e1e6c04d7c965f5289c39a8d94ae23ed5c0b57aabac549f871c6" 932 | dependencies = [ 933 | "filetime", 934 | "libc", 935 | "xattr", 936 | ] 937 | 938 | [[package]] 939 | name = "termcolor" 940 | version = "1.1.3" 941 | source = "registry+https://github.com/rust-lang/crates.io-index" 942 | checksum = "bab24d30b911b2376f3a13cc2cd443142f0c81dda04c118693e35b3835757755" 943 | dependencies = [ 944 | "winapi-util", 945 | ] 946 | 947 | [[package]] 948 | name = "terminus-store" 949 | version = "0.19.6" 950 | source = "registry+https://github.com/rust-lang/crates.io-index" 951 | checksum = "088b651d11c0c36cbd8e941f1086e003d600c52b94221cba772558dd2128875c" 952 | dependencies = [ 953 | "async-trait", 954 | "byteorder", 955 | "bytes 1.1.0", 956 | "flate2", 957 | "fs2", 958 | "futures", 959 | "futures-locks", 960 | "lazy_static", 961 | "rand", 962 | "rayon", 963 | "tar", 964 | "thiserror", 965 | "tokio 1.18.1", 966 | "tokio-util", 967 | ] 968 | 969 | [[package]] 970 | name = "terminus-store-prolog" 971 | version = "0.2.0" 972 | dependencies = [ 973 | "chardetng", 974 | "csv", 975 | "encoding_rs", 976 | "hex", 977 | "sha-1", 978 | "swipl", 979 | "terminus-store", 980 | "urlencoding", 981 | ] 982 | 983 | [[package]] 984 | name = "terminus-store-prolog-dylib" 985 | version = "0.1.0" 986 | dependencies = [ 987 | "terminus-store-prolog", 988 | ] 989 | 990 | [[package]] 991 | name = "textwrap" 992 | version = "0.11.0" 993 | source = "registry+https://github.com/rust-lang/crates.io-index" 994 | checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" 995 | dependencies = [ 996 | "unicode-width", 997 | ] 998 | 999 | [[package]] 1000 | name = "thiserror" 1001 | version = "1.0.31" 1002 | source = "registry+https://github.com/rust-lang/crates.io-index" 1003 | checksum = "bd829fe32373d27f76265620b5309d0340cb8550f523c1dda251d6298069069a" 1004 | dependencies = [ 1005 | "thiserror-impl", 1006 | ] 1007 | 1008 | [[package]] 1009 | name = "thiserror-impl" 1010 | version = "1.0.31" 1011 | source = "registry+https://github.com/rust-lang/crates.io-index" 1012 | checksum = "0396bc89e626244658bef819e22d0cc459e795a5ebe878e6ec336d1674a8d79a" 1013 | dependencies = [ 1014 | "proc-macro2", 1015 | "quote", 1016 | "syn", 1017 | ] 1018 | 1019 | [[package]] 1020 | name = "tokio" 1021 | version = "0.2.25" 1022 | source = "registry+https://github.com/rust-lang/crates.io-index" 1023 | checksum = "6703a273949a90131b290be1fe7b039d0fc884aa1935860dfcbe056f28cd8092" 1024 | dependencies = [ 1025 | "bytes 0.5.6", 1026 | "pin-project-lite 0.1.12", 1027 | "slab", 1028 | ] 1029 | 1030 | [[package]] 1031 | name = "tokio" 1032 | version = "1.18.1" 1033 | source = "registry+https://github.com/rust-lang/crates.io-index" 1034 | checksum = "dce653fb475565de9f6fb0614b28bca8df2c430c0cf84bcd9c843f15de5414cc" 1035 | dependencies = [ 1036 | "bytes 1.1.0", 1037 | "libc", 1038 | "memchr", 1039 | "mio", 1040 | "num_cpus", 1041 | "once_cell", 1042 | "parking_lot", 1043 | "pin-project-lite 0.2.9", 1044 | "signal-hook-registry", 1045 | "socket2", 1046 | "tokio-macros", 1047 | "winapi", 1048 | ] 1049 | 1050 | [[package]] 1051 | name = "tokio-macros" 1052 | version = "1.7.0" 1053 | source = "registry+https://github.com/rust-lang/crates.io-index" 1054 | checksum = "b557f72f448c511a979e2564e55d74e6c4432fc96ff4f6241bc6bded342643b7" 1055 | dependencies = [ 1056 | "proc-macro2", 1057 | "quote", 1058 | "syn", 1059 | ] 1060 | 1061 | [[package]] 1062 | name = "tokio-util" 1063 | version = "0.6.9" 1064 | source = "registry+https://github.com/rust-lang/crates.io-index" 1065 | checksum = "9e99e1983e5d376cd8eb4b66604d2e99e79f5bd988c3055891dcd8c9e2604cc0" 1066 | dependencies = [ 1067 | "bytes 1.1.0", 1068 | "futures-core", 1069 | "futures-sink", 1070 | "log", 1071 | "pin-project-lite 0.2.9", 1072 | "tokio 1.18.1", 1073 | ] 1074 | 1075 | [[package]] 1076 | name = "toml" 1077 | version = "0.5.9" 1078 | source = "registry+https://github.com/rust-lang/crates.io-index" 1079 | checksum = "8d82e1a7758622a465f8cee077614c73484dac5b836c02ff6a40d5d1010324d7" 1080 | dependencies = [ 1081 | "serde", 1082 | ] 1083 | 1084 | [[package]] 1085 | name = "typenum" 1086 | version = "1.15.0" 1087 | source = "registry+https://github.com/rust-lang/crates.io-index" 1088 | checksum = "dcf81ac59edc17cc8697ff311e8f5ef2d99fcbd9817b34cec66f90b6c3dfd987" 1089 | 1090 | [[package]] 1091 | name = "unicode-width" 1092 | version = "0.1.9" 1093 | source = "registry+https://github.com/rust-lang/crates.io-index" 1094 | checksum = "3ed742d4ea2bd1176e236172c8429aaf54486e7ac098db29ffe6529e0ce50973" 1095 | 1096 | [[package]] 1097 | name = "unicode-xid" 1098 | version = "0.2.3" 1099 | source = "registry+https://github.com/rust-lang/crates.io-index" 1100 | checksum = "957e51f3646910546462e67d5f7599b9e4fb8acdd304b087a6494730f9eebf04" 1101 | 1102 | [[package]] 1103 | name = "urlencoding" 1104 | version = "1.3.3" 1105 | source = "registry+https://github.com/rust-lang/crates.io-index" 1106 | checksum = "5a1f0175e03a0973cf4afd476bef05c26e228520400eb1fd473ad417b1c00ffb" 1107 | 1108 | [[package]] 1109 | name = "vec_map" 1110 | version = "0.8.2" 1111 | source = "registry+https://github.com/rust-lang/crates.io-index" 1112 | checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191" 1113 | 1114 | [[package]] 1115 | name = "version_check" 1116 | version = "0.9.4" 1117 | source = "registry+https://github.com/rust-lang/crates.io-index" 1118 | checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" 1119 | 1120 | [[package]] 1121 | name = "wasi" 1122 | version = "0.10.2+wasi-snapshot-preview1" 1123 | source = "registry+https://github.com/rust-lang/crates.io-index" 1124 | checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" 1125 | 1126 | [[package]] 1127 | name = "wasi" 1128 | version = "0.11.0+wasi-snapshot-preview1" 1129 | source = "registry+https://github.com/rust-lang/crates.io-index" 1130 | checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" 1131 | 1132 | [[package]] 1133 | name = "which" 1134 | version = "4.2.5" 1135 | source = "registry+https://github.com/rust-lang/crates.io-index" 1136 | checksum = "5c4fb54e6113b6a8772ee41c3404fb0301ac79604489467e0a9ce1f3e97c24ae" 1137 | dependencies = [ 1138 | "either", 1139 | "lazy_static", 1140 | "libc", 1141 | ] 1142 | 1143 | [[package]] 1144 | name = "winapi" 1145 | version = "0.3.9" 1146 | source = "registry+https://github.com/rust-lang/crates.io-index" 1147 | checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" 1148 | dependencies = [ 1149 | "winapi-i686-pc-windows-gnu", 1150 | "winapi-x86_64-pc-windows-gnu", 1151 | ] 1152 | 1153 | [[package]] 1154 | name = "winapi-i686-pc-windows-gnu" 1155 | version = "0.4.0" 1156 | source = "registry+https://github.com/rust-lang/crates.io-index" 1157 | checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" 1158 | 1159 | [[package]] 1160 | name = "winapi-util" 1161 | version = "0.1.5" 1162 | source = "registry+https://github.com/rust-lang/crates.io-index" 1163 | checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" 1164 | dependencies = [ 1165 | "winapi", 1166 | ] 1167 | 1168 | [[package]] 1169 | name = "winapi-x86_64-pc-windows-gnu" 1170 | version = "0.4.0" 1171 | source = "registry+https://github.com/rust-lang/crates.io-index" 1172 | checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" 1173 | 1174 | [[package]] 1175 | name = "windows-sys" 1176 | version = "0.36.1" 1177 | source = "registry+https://github.com/rust-lang/crates.io-index" 1178 | checksum = "ea04155a16a59f9eab786fe12a4a450e75cdb175f9e0d80da1e17db09f55b8d2" 1179 | dependencies = [ 1180 | "windows_aarch64_msvc", 1181 | "windows_i686_gnu", 1182 | "windows_i686_msvc", 1183 | "windows_x86_64_gnu", 1184 | "windows_x86_64_msvc", 1185 | ] 1186 | 1187 | [[package]] 1188 | name = "windows_aarch64_msvc" 1189 | version = "0.36.1" 1190 | source = "registry+https://github.com/rust-lang/crates.io-index" 1191 | checksum = "9bb8c3fd39ade2d67e9874ac4f3db21f0d710bee00fe7cab16949ec184eeaa47" 1192 | 1193 | [[package]] 1194 | name = "windows_i686_gnu" 1195 | version = "0.36.1" 1196 | source = "registry+https://github.com/rust-lang/crates.io-index" 1197 | checksum = "180e6ccf01daf4c426b846dfc66db1fc518f074baa793aa7d9b9aaeffad6a3b6" 1198 | 1199 | [[package]] 1200 | name = "windows_i686_msvc" 1201 | version = "0.36.1" 1202 | source = "registry+https://github.com/rust-lang/crates.io-index" 1203 | checksum = "e2e7917148b2812d1eeafaeb22a97e4813dfa60a3f8f78ebe204bcc88f12f024" 1204 | 1205 | [[package]] 1206 | name = "windows_x86_64_gnu" 1207 | version = "0.36.1" 1208 | source = "registry+https://github.com/rust-lang/crates.io-index" 1209 | checksum = "4dcd171b8776c41b97521e5da127a2d86ad280114807d0b2ab1e462bc764d9e1" 1210 | 1211 | [[package]] 1212 | name = "windows_x86_64_msvc" 1213 | version = "0.36.1" 1214 | source = "registry+https://github.com/rust-lang/crates.io-index" 1215 | checksum = "c811ca4a8c853ef420abd8592ba53ddbbac90410fab6903b3e79972a631f7680" 1216 | 1217 | [[package]] 1218 | name = "xattr" 1219 | version = "0.2.3" 1220 | source = "registry+https://github.com/rust-lang/crates.io-index" 1221 | checksum = "6d1526bbe5aaeb5eb06885f4d987bcdfa5e23187055de9b83fe00156a821fabc" 1222 | dependencies = [ 1223 | "libc", 1224 | ] 1225 | -------------------------------------------------------------------------------- /rust/Cargo.toml: -------------------------------------------------------------------------------- 1 | [workspace] 2 | members = ["terminus-store-prolog-core", "terminus-store-prolog-dylib"] -------------------------------------------------------------------------------- /rust/terminus-store-prolog-core/Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 3 4 | 5 | [[package]] 6 | name = "adler" 7 | version = "1.0.2" 8 | source = "registry+https://github.com/rust-lang/crates.io-index" 9 | checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" 10 | 11 | [[package]] 12 | name = "aho-corasick" 13 | version = "0.7.18" 14 | source = "registry+https://github.com/rust-lang/crates.io-index" 15 | checksum = "1e37cfd5e7657ada45f742d6e99ca5788580b5c529dc78faf11ece6dc702656f" 16 | dependencies = [ 17 | "memchr", 18 | ] 19 | 20 | [[package]] 21 | name = "ansi_term" 22 | version = "0.12.1" 23 | source = "registry+https://github.com/rust-lang/crates.io-index" 24 | checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2" 25 | dependencies = [ 26 | "winapi", 27 | ] 28 | 29 | [[package]] 30 | name = "async-trait" 31 | version = "0.1.52" 32 | source = "registry+https://github.com/rust-lang/crates.io-index" 33 | checksum = "061a7acccaa286c011ddc30970520b98fa40e00c9d644633fb26b5fc63a265e3" 34 | dependencies = [ 35 | "proc-macro2", 36 | "quote", 37 | "syn", 38 | ] 39 | 40 | [[package]] 41 | name = "atty" 42 | version = "0.2.14" 43 | source = "registry+https://github.com/rust-lang/crates.io-index" 44 | checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" 45 | dependencies = [ 46 | "hermit-abi", 47 | "libc", 48 | "winapi", 49 | ] 50 | 51 | [[package]] 52 | name = "autocfg" 53 | version = "1.1.0" 54 | source = "registry+https://github.com/rust-lang/crates.io-index" 55 | checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" 56 | 57 | [[package]] 58 | name = "bindgen" 59 | version = "0.59.2" 60 | source = "registry+https://github.com/rust-lang/crates.io-index" 61 | checksum = "2bd2a9a458e8f4304c52c43ebb0cfbd520289f8379a52e329a38afda99bf8eb8" 62 | dependencies = [ 63 | "bitflags", 64 | "cexpr", 65 | "clang-sys", 66 | "clap", 67 | "env_logger", 68 | "lazy_static", 69 | "lazycell", 70 | "log", 71 | "peeking_take_while", 72 | "proc-macro2", 73 | "quote", 74 | "regex", 75 | "rustc-hash", 76 | "shlex", 77 | "which", 78 | ] 79 | 80 | [[package]] 81 | name = "bitflags" 82 | version = "1.3.2" 83 | source = "registry+https://github.com/rust-lang/crates.io-index" 84 | checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" 85 | 86 | [[package]] 87 | name = "block-buffer" 88 | version = "0.9.0" 89 | source = "registry+https://github.com/rust-lang/crates.io-index" 90 | checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" 91 | dependencies = [ 92 | "generic-array", 93 | ] 94 | 95 | [[package]] 96 | name = "bstr" 97 | version = "0.2.17" 98 | source = "registry+https://github.com/rust-lang/crates.io-index" 99 | checksum = "ba3569f383e8f1598449f1a423e72e99569137b47740b1da11ef19af3d5c3223" 100 | dependencies = [ 101 | "lazy_static", 102 | "memchr", 103 | "regex-automata", 104 | "serde", 105 | ] 106 | 107 | [[package]] 108 | name = "byteorder" 109 | version = "1.4.3" 110 | source = "registry+https://github.com/rust-lang/crates.io-index" 111 | checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" 112 | 113 | [[package]] 114 | name = "bytes" 115 | version = "0.5.6" 116 | source = "registry+https://github.com/rust-lang/crates.io-index" 117 | checksum = "0e4cec68f03f32e44924783795810fa50a7035d8c8ebe78580ad7e6c703fba38" 118 | 119 | [[package]] 120 | name = "bytes" 121 | version = "1.1.0" 122 | source = "registry+https://github.com/rust-lang/crates.io-index" 123 | checksum = "c4872d67bab6358e59559027aa3b9157c53d9358c51423c17554809a8858e0f8" 124 | 125 | [[package]] 126 | name = "cexpr" 127 | version = "0.6.0" 128 | source = "registry+https://github.com/rust-lang/crates.io-index" 129 | checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766" 130 | dependencies = [ 131 | "nom", 132 | ] 133 | 134 | [[package]] 135 | name = "cfg-if" 136 | version = "1.0.0" 137 | source = "registry+https://github.com/rust-lang/crates.io-index" 138 | checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" 139 | 140 | [[package]] 141 | name = "chardetng" 142 | version = "0.1.17" 143 | source = "registry+https://github.com/rust-lang/crates.io-index" 144 | checksum = "14b8f0b65b7b08ae3c8187e8d77174de20cb6777864c6b832d8ad365999cf1ea" 145 | dependencies = [ 146 | "cfg-if", 147 | "encoding_rs", 148 | "memchr", 149 | ] 150 | 151 | [[package]] 152 | name = "clang-sys" 153 | version = "1.3.1" 154 | source = "registry+https://github.com/rust-lang/crates.io-index" 155 | checksum = "4cc00842eed744b858222c4c9faf7243aafc6d33f92f96935263ef4d8a41ce21" 156 | dependencies = [ 157 | "glob", 158 | "libc", 159 | "libloading", 160 | ] 161 | 162 | [[package]] 163 | name = "clap" 164 | version = "2.34.0" 165 | source = "registry+https://github.com/rust-lang/crates.io-index" 166 | checksum = "a0610544180c38b88101fecf2dd634b174a62eef6946f84dfc6a7127512b381c" 167 | dependencies = [ 168 | "ansi_term", 169 | "atty", 170 | "bitflags", 171 | "strsim", 172 | "textwrap", 173 | "unicode-width", 174 | "vec_map", 175 | ] 176 | 177 | [[package]] 178 | name = "cpufeatures" 179 | version = "0.2.1" 180 | source = "registry+https://github.com/rust-lang/crates.io-index" 181 | checksum = "95059428f66df56b63431fdb4e1947ed2190586af5c5a8a8b71122bdf5a7f469" 182 | dependencies = [ 183 | "libc", 184 | ] 185 | 186 | [[package]] 187 | name = "crc32fast" 188 | version = "1.3.2" 189 | source = "registry+https://github.com/rust-lang/crates.io-index" 190 | checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" 191 | dependencies = [ 192 | "cfg-if", 193 | ] 194 | 195 | [[package]] 196 | name = "crossbeam-channel" 197 | version = "0.5.2" 198 | source = "registry+https://github.com/rust-lang/crates.io-index" 199 | checksum = "e54ea8bc3fb1ee042f5aace6e3c6e025d3874866da222930f70ce62aceba0bfa" 200 | dependencies = [ 201 | "cfg-if", 202 | "crossbeam-utils", 203 | ] 204 | 205 | [[package]] 206 | name = "crossbeam-deque" 207 | version = "0.8.1" 208 | source = "registry+https://github.com/rust-lang/crates.io-index" 209 | checksum = "6455c0ca19f0d2fbf751b908d5c55c1f5cbc65e03c4225427254b46890bdde1e" 210 | dependencies = [ 211 | "cfg-if", 212 | "crossbeam-epoch", 213 | "crossbeam-utils", 214 | ] 215 | 216 | [[package]] 217 | name = "crossbeam-epoch" 218 | version = "0.9.7" 219 | source = "registry+https://github.com/rust-lang/crates.io-index" 220 | checksum = "c00d6d2ea26e8b151d99093005cb442fb9a37aeaca582a03ec70946f49ab5ed9" 221 | dependencies = [ 222 | "cfg-if", 223 | "crossbeam-utils", 224 | "lazy_static", 225 | "memoffset", 226 | "scopeguard", 227 | ] 228 | 229 | [[package]] 230 | name = "crossbeam-utils" 231 | version = "0.8.7" 232 | source = "registry+https://github.com/rust-lang/crates.io-index" 233 | checksum = "b5e5bed1f1c269533fa816a0a5492b3545209a205ca1a54842be180eb63a16a6" 234 | dependencies = [ 235 | "cfg-if", 236 | "lazy_static", 237 | ] 238 | 239 | [[package]] 240 | name = "csv" 241 | version = "1.1.6" 242 | source = "registry+https://github.com/rust-lang/crates.io-index" 243 | checksum = "22813a6dc45b335f9bade10bf7271dc477e81113e89eb251a0bc2a8a81c536e1" 244 | dependencies = [ 245 | "bstr", 246 | "csv-core", 247 | "itoa", 248 | "ryu", 249 | "serde", 250 | ] 251 | 252 | [[package]] 253 | name = "csv-core" 254 | version = "0.1.10" 255 | source = "registry+https://github.com/rust-lang/crates.io-index" 256 | checksum = "2b2466559f260f48ad25fe6317b3c8dac77b5bdb5763ac7d9d6103530663bc90" 257 | dependencies = [ 258 | "memchr", 259 | ] 260 | 261 | [[package]] 262 | name = "digest" 263 | version = "0.9.0" 264 | source = "registry+https://github.com/rust-lang/crates.io-index" 265 | checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" 266 | dependencies = [ 267 | "generic-array", 268 | ] 269 | 270 | [[package]] 271 | name = "either" 272 | version = "1.6.1" 273 | source = "registry+https://github.com/rust-lang/crates.io-index" 274 | checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457" 275 | 276 | [[package]] 277 | name = "encoding_rs" 278 | version = "0.8.30" 279 | source = "registry+https://github.com/rust-lang/crates.io-index" 280 | checksum = "7896dc8abb250ffdda33912550faa54c88ec8b998dec0b2c55ab224921ce11df" 281 | dependencies = [ 282 | "cfg-if", 283 | ] 284 | 285 | [[package]] 286 | name = "env_logger" 287 | version = "0.9.0" 288 | source = "registry+https://github.com/rust-lang/crates.io-index" 289 | checksum = "0b2cf0344971ee6c64c31be0d530793fba457d322dfec2810c453d0ef228f9c3" 290 | dependencies = [ 291 | "atty", 292 | "humantime", 293 | "log", 294 | "regex", 295 | "termcolor", 296 | ] 297 | 298 | [[package]] 299 | name = "filetime" 300 | version = "0.2.15" 301 | source = "registry+https://github.com/rust-lang/crates.io-index" 302 | checksum = "975ccf83d8d9d0d84682850a38c8169027be83368805971cc4f238c2b245bc98" 303 | dependencies = [ 304 | "cfg-if", 305 | "libc", 306 | "redox_syscall", 307 | "winapi", 308 | ] 309 | 310 | [[package]] 311 | name = "flate2" 312 | version = "1.0.22" 313 | source = "registry+https://github.com/rust-lang/crates.io-index" 314 | checksum = "1e6988e897c1c9c485f43b47a529cef42fde0547f9d8d41a7062518f1d8fc53f" 315 | dependencies = [ 316 | "cfg-if", 317 | "crc32fast", 318 | "libc", 319 | "miniz_oxide", 320 | ] 321 | 322 | [[package]] 323 | name = "fs2" 324 | version = "0.4.3" 325 | source = "registry+https://github.com/rust-lang/crates.io-index" 326 | checksum = "9564fc758e15025b46aa6643b1b77d047d1a56a1aea6e01002ac0c7026876213" 327 | dependencies = [ 328 | "libc", 329 | "winapi", 330 | ] 331 | 332 | [[package]] 333 | name = "futures" 334 | version = "0.3.21" 335 | source = "registry+https://github.com/rust-lang/crates.io-index" 336 | checksum = "f73fe65f54d1e12b726f517d3e2135ca3125a437b6d998caf1962961f7172d9e" 337 | dependencies = [ 338 | "futures-channel", 339 | "futures-core", 340 | "futures-executor", 341 | "futures-io", 342 | "futures-sink", 343 | "futures-task", 344 | "futures-util", 345 | ] 346 | 347 | [[package]] 348 | name = "futures-channel" 349 | version = "0.3.21" 350 | source = "registry+https://github.com/rust-lang/crates.io-index" 351 | checksum = "c3083ce4b914124575708913bca19bfe887522d6e2e6d0952943f5eac4a74010" 352 | dependencies = [ 353 | "futures-core", 354 | "futures-sink", 355 | ] 356 | 357 | [[package]] 358 | name = "futures-core" 359 | version = "0.3.21" 360 | source = "registry+https://github.com/rust-lang/crates.io-index" 361 | checksum = "0c09fd04b7e4073ac7156a9539b57a484a8ea920f79c7c675d05d289ab6110d3" 362 | 363 | [[package]] 364 | name = "futures-executor" 365 | version = "0.3.21" 366 | source = "registry+https://github.com/rust-lang/crates.io-index" 367 | checksum = "9420b90cfa29e327d0429f19be13e7ddb68fa1cccb09d65e5706b8c7a749b8a6" 368 | dependencies = [ 369 | "futures-core", 370 | "futures-task", 371 | "futures-util", 372 | ] 373 | 374 | [[package]] 375 | name = "futures-io" 376 | version = "0.3.21" 377 | source = "registry+https://github.com/rust-lang/crates.io-index" 378 | checksum = "fc4045962a5a5e935ee2fdedaa4e08284547402885ab326734432bed5d12966b" 379 | 380 | [[package]] 381 | name = "futures-locks" 382 | version = "0.6.0" 383 | source = "registry+https://github.com/rust-lang/crates.io-index" 384 | checksum = "50c4e684ddb2d8a4db5ca8a02b35156da129674ba4412b6f528698d58c594954" 385 | dependencies = [ 386 | "futures", 387 | "tokio 0.2.25", 388 | ] 389 | 390 | [[package]] 391 | name = "futures-macro" 392 | version = "0.3.21" 393 | source = "registry+https://github.com/rust-lang/crates.io-index" 394 | checksum = "33c1e13800337f4d4d7a316bf45a567dbcb6ffe087f16424852d97e97a91f512" 395 | dependencies = [ 396 | "proc-macro2", 397 | "quote", 398 | "syn", 399 | ] 400 | 401 | [[package]] 402 | name = "futures-sink" 403 | version = "0.3.21" 404 | source = "registry+https://github.com/rust-lang/crates.io-index" 405 | checksum = "21163e139fa306126e6eedaf49ecdb4588f939600f0b1e770f4205ee4b7fa868" 406 | 407 | [[package]] 408 | name = "futures-task" 409 | version = "0.3.21" 410 | source = "registry+https://github.com/rust-lang/crates.io-index" 411 | checksum = "57c66a976bf5909d801bbef33416c41372779507e7a6b3a5e25e4749c58f776a" 412 | 413 | [[package]] 414 | name = "futures-util" 415 | version = "0.3.21" 416 | source = "registry+https://github.com/rust-lang/crates.io-index" 417 | checksum = "d8b7abd5d659d9b90c8cba917f6ec750a74e2dc23902ef9cd4cc8c8b22e6036a" 418 | dependencies = [ 419 | "futures-channel", 420 | "futures-core", 421 | "futures-io", 422 | "futures-macro", 423 | "futures-sink", 424 | "futures-task", 425 | "memchr", 426 | "pin-project-lite 0.2.8", 427 | "pin-utils", 428 | "slab", 429 | ] 430 | 431 | [[package]] 432 | name = "generic-array" 433 | version = "0.14.5" 434 | source = "registry+https://github.com/rust-lang/crates.io-index" 435 | checksum = "fd48d33ec7f05fbfa152300fdad764757cbded343c1aa1cff2fbaf4134851803" 436 | dependencies = [ 437 | "typenum", 438 | "version_check", 439 | ] 440 | 441 | [[package]] 442 | name = "getrandom" 443 | version = "0.2.4" 444 | source = "registry+https://github.com/rust-lang/crates.io-index" 445 | checksum = "418d37c8b1d42553c93648be529cb70f920d3baf8ef469b74b9638df426e0b4c" 446 | dependencies = [ 447 | "cfg-if", 448 | "libc", 449 | "wasi", 450 | ] 451 | 452 | [[package]] 453 | name = "glob" 454 | version = "0.3.0" 455 | source = "registry+https://github.com/rust-lang/crates.io-index" 456 | checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574" 457 | 458 | [[package]] 459 | name = "hermit-abi" 460 | version = "0.1.19" 461 | source = "registry+https://github.com/rust-lang/crates.io-index" 462 | checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" 463 | dependencies = [ 464 | "libc", 465 | ] 466 | 467 | [[package]] 468 | name = "hex" 469 | version = "0.4.3" 470 | source = "registry+https://github.com/rust-lang/crates.io-index" 471 | checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" 472 | 473 | [[package]] 474 | name = "humantime" 475 | version = "2.1.0" 476 | source = "registry+https://github.com/rust-lang/crates.io-index" 477 | checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" 478 | 479 | [[package]] 480 | name = "itoa" 481 | version = "0.4.8" 482 | source = "registry+https://github.com/rust-lang/crates.io-index" 483 | checksum = "b71991ff56294aa922b450139ee08b3bfc70982c6b2c7562771375cf73542dd4" 484 | 485 | [[package]] 486 | name = "lazy_static" 487 | version = "1.4.0" 488 | source = "registry+https://github.com/rust-lang/crates.io-index" 489 | checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" 490 | 491 | [[package]] 492 | name = "lazycell" 493 | version = "1.3.0" 494 | source = "registry+https://github.com/rust-lang/crates.io-index" 495 | checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" 496 | 497 | [[package]] 498 | name = "libc" 499 | version = "0.2.119" 500 | source = "registry+https://github.com/rust-lang/crates.io-index" 501 | checksum = "1bf2e165bb3457c8e098ea76f3e3bc9db55f87aa90d52d0e6be741470916aaa4" 502 | 503 | [[package]] 504 | name = "libloading" 505 | version = "0.7.3" 506 | source = "registry+https://github.com/rust-lang/crates.io-index" 507 | checksum = "efbc0f03f9a775e9f6aed295c6a1ba2253c5757a9e03d55c6caa46a681abcddd" 508 | dependencies = [ 509 | "cfg-if", 510 | "winapi", 511 | ] 512 | 513 | [[package]] 514 | name = "lock_api" 515 | version = "0.4.6" 516 | source = "registry+https://github.com/rust-lang/crates.io-index" 517 | checksum = "88943dd7ef4a2e5a4bfa2753aaab3013e34ce2533d1996fb18ef591e315e2b3b" 518 | dependencies = [ 519 | "scopeguard", 520 | ] 521 | 522 | [[package]] 523 | name = "log" 524 | version = "0.4.14" 525 | source = "registry+https://github.com/rust-lang/crates.io-index" 526 | checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710" 527 | dependencies = [ 528 | "cfg-if", 529 | ] 530 | 531 | [[package]] 532 | name = "memchr" 533 | version = "2.4.1" 534 | source = "registry+https://github.com/rust-lang/crates.io-index" 535 | checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a" 536 | 537 | [[package]] 538 | name = "memoffset" 539 | version = "0.6.5" 540 | source = "registry+https://github.com/rust-lang/crates.io-index" 541 | checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce" 542 | dependencies = [ 543 | "autocfg", 544 | ] 545 | 546 | [[package]] 547 | name = "minimal-lexical" 548 | version = "0.2.1" 549 | source = "registry+https://github.com/rust-lang/crates.io-index" 550 | checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" 551 | 552 | [[package]] 553 | name = "miniz_oxide" 554 | version = "0.4.4" 555 | source = "registry+https://github.com/rust-lang/crates.io-index" 556 | checksum = "a92518e98c078586bc6c934028adcca4c92a53d6a958196de835170a01d84e4b" 557 | dependencies = [ 558 | "adler", 559 | "autocfg", 560 | ] 561 | 562 | [[package]] 563 | name = "mio" 564 | version = "0.8.0" 565 | source = "registry+https://github.com/rust-lang/crates.io-index" 566 | checksum = "ba272f85fa0b41fc91872be579b3bbe0f56b792aa361a380eb669469f68dafb2" 567 | dependencies = [ 568 | "libc", 569 | "log", 570 | "miow", 571 | "ntapi", 572 | "winapi", 573 | ] 574 | 575 | [[package]] 576 | name = "miow" 577 | version = "0.3.7" 578 | source = "registry+https://github.com/rust-lang/crates.io-index" 579 | checksum = "b9f1c5b025cda876f66ef43a113f91ebc9f4ccef34843000e0adf6ebbab84e21" 580 | dependencies = [ 581 | "winapi", 582 | ] 583 | 584 | [[package]] 585 | name = "nom" 586 | version = "7.1.0" 587 | source = "registry+https://github.com/rust-lang/crates.io-index" 588 | checksum = "1b1d11e1ef389c76fe5b81bcaf2ea32cf88b62bc494e19f493d0b30e7a930109" 589 | dependencies = [ 590 | "memchr", 591 | "minimal-lexical", 592 | "version_check", 593 | ] 594 | 595 | [[package]] 596 | name = "ntapi" 597 | version = "0.3.7" 598 | source = "registry+https://github.com/rust-lang/crates.io-index" 599 | checksum = "c28774a7fd2fbb4f0babd8237ce554b73af68021b5f695a3cebd6c59bac0980f" 600 | dependencies = [ 601 | "winapi", 602 | ] 603 | 604 | [[package]] 605 | name = "num_cpus" 606 | version = "1.13.1" 607 | source = "registry+https://github.com/rust-lang/crates.io-index" 608 | checksum = "19e64526ebdee182341572e50e9ad03965aa510cd94427a4549448f285e957a1" 609 | dependencies = [ 610 | "hermit-abi", 611 | "libc", 612 | ] 613 | 614 | [[package]] 615 | name = "once_cell" 616 | version = "1.9.0" 617 | source = "registry+https://github.com/rust-lang/crates.io-index" 618 | checksum = "da32515d9f6e6e489d7bc9d84c71b060db7247dc035bbe44eac88cf87486d8d5" 619 | 620 | [[package]] 621 | name = "opaque-debug" 622 | version = "0.3.0" 623 | source = "registry+https://github.com/rust-lang/crates.io-index" 624 | checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" 625 | 626 | [[package]] 627 | name = "parking_lot" 628 | version = "0.12.0" 629 | source = "registry+https://github.com/rust-lang/crates.io-index" 630 | checksum = "87f5ec2493a61ac0506c0f4199f99070cbe83857b0337006a30f3e6719b8ef58" 631 | dependencies = [ 632 | "lock_api", 633 | "parking_lot_core", 634 | ] 635 | 636 | [[package]] 637 | name = "parking_lot_core" 638 | version = "0.9.1" 639 | source = "registry+https://github.com/rust-lang/crates.io-index" 640 | checksum = "28141e0cc4143da2443301914478dc976a61ffdb3f043058310c70df2fed8954" 641 | dependencies = [ 642 | "cfg-if", 643 | "libc", 644 | "redox_syscall", 645 | "smallvec", 646 | "windows-sys", 647 | ] 648 | 649 | [[package]] 650 | name = "peeking_take_while" 651 | version = "0.1.2" 652 | source = "registry+https://github.com/rust-lang/crates.io-index" 653 | checksum = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099" 654 | 655 | [[package]] 656 | name = "pin-project-lite" 657 | version = "0.1.12" 658 | source = "registry+https://github.com/rust-lang/crates.io-index" 659 | checksum = "257b64915a082f7811703966789728173279bdebb956b143dbcd23f6f970a777" 660 | 661 | [[package]] 662 | name = "pin-project-lite" 663 | version = "0.2.8" 664 | source = "registry+https://github.com/rust-lang/crates.io-index" 665 | checksum = "e280fbe77cc62c91527259e9442153f4688736748d24660126286329742b4c6c" 666 | 667 | [[package]] 668 | name = "pin-utils" 669 | version = "0.1.0" 670 | source = "registry+https://github.com/rust-lang/crates.io-index" 671 | checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" 672 | 673 | [[package]] 674 | name = "ppv-lite86" 675 | version = "0.2.16" 676 | source = "registry+https://github.com/rust-lang/crates.io-index" 677 | checksum = "eb9f9e6e233e5c4a35559a617bf40a4ec447db2e84c20b55a6f83167b7e57872" 678 | 679 | [[package]] 680 | name = "proc-macro-crate" 681 | version = "0.1.5" 682 | source = "registry+https://github.com/rust-lang/crates.io-index" 683 | checksum = "1d6ea3c4595b96363c13943497db34af4460fb474a95c43f4446ad341b8c9785" 684 | dependencies = [ 685 | "toml", 686 | ] 687 | 688 | [[package]] 689 | name = "proc-macro2" 690 | version = "1.0.36" 691 | source = "registry+https://github.com/rust-lang/crates.io-index" 692 | checksum = "c7342d5883fbccae1cc37a2353b09c87c9b0f3afd73f5fb9bba687a1f733b029" 693 | dependencies = [ 694 | "unicode-xid", 695 | ] 696 | 697 | [[package]] 698 | name = "quote" 699 | version = "1.0.15" 700 | source = "registry+https://github.com/rust-lang/crates.io-index" 701 | checksum = "864d3e96a899863136fc6e99f3d7cae289dafe43bf2c5ac19b70df7210c0a145" 702 | dependencies = [ 703 | "proc-macro2", 704 | ] 705 | 706 | [[package]] 707 | name = "rand" 708 | version = "0.8.5" 709 | source = "registry+https://github.com/rust-lang/crates.io-index" 710 | checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" 711 | dependencies = [ 712 | "libc", 713 | "rand_chacha", 714 | "rand_core", 715 | ] 716 | 717 | [[package]] 718 | name = "rand_chacha" 719 | version = "0.3.1" 720 | source = "registry+https://github.com/rust-lang/crates.io-index" 721 | checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" 722 | dependencies = [ 723 | "ppv-lite86", 724 | "rand_core", 725 | ] 726 | 727 | [[package]] 728 | name = "rand_core" 729 | version = "0.6.3" 730 | source = "registry+https://github.com/rust-lang/crates.io-index" 731 | checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7" 732 | dependencies = [ 733 | "getrandom", 734 | ] 735 | 736 | [[package]] 737 | name = "rayon" 738 | version = "1.5.1" 739 | source = "registry+https://github.com/rust-lang/crates.io-index" 740 | checksum = "c06aca804d41dbc8ba42dfd964f0d01334eceb64314b9ecf7c5fad5188a06d90" 741 | dependencies = [ 742 | "autocfg", 743 | "crossbeam-deque", 744 | "either", 745 | "rayon-core", 746 | ] 747 | 748 | [[package]] 749 | name = "rayon-core" 750 | version = "1.9.1" 751 | source = "registry+https://github.com/rust-lang/crates.io-index" 752 | checksum = "d78120e2c850279833f1dd3582f730c4ab53ed95aeaaaa862a2a5c71b1656d8e" 753 | dependencies = [ 754 | "crossbeam-channel", 755 | "crossbeam-deque", 756 | "crossbeam-utils", 757 | "lazy_static", 758 | "num_cpus", 759 | ] 760 | 761 | [[package]] 762 | name = "redox_syscall" 763 | version = "0.2.10" 764 | source = "registry+https://github.com/rust-lang/crates.io-index" 765 | checksum = "8383f39639269cde97d255a32bdb68c047337295414940c68bdd30c2e13203ff" 766 | dependencies = [ 767 | "bitflags", 768 | ] 769 | 770 | [[package]] 771 | name = "regex" 772 | version = "1.5.4" 773 | source = "registry+https://github.com/rust-lang/crates.io-index" 774 | checksum = "d07a8629359eb56f1e2fb1652bb04212c072a87ba68546a04065d525673ac461" 775 | dependencies = [ 776 | "aho-corasick", 777 | "memchr", 778 | "regex-syntax", 779 | ] 780 | 781 | [[package]] 782 | name = "regex-automata" 783 | version = "0.1.10" 784 | source = "registry+https://github.com/rust-lang/crates.io-index" 785 | checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" 786 | 787 | [[package]] 788 | name = "regex-syntax" 789 | version = "0.6.25" 790 | source = "registry+https://github.com/rust-lang/crates.io-index" 791 | checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b" 792 | 793 | [[package]] 794 | name = "rustc-hash" 795 | version = "1.1.0" 796 | source = "registry+https://github.com/rust-lang/crates.io-index" 797 | checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" 798 | 799 | [[package]] 800 | name = "ryu" 801 | version = "1.0.9" 802 | source = "registry+https://github.com/rust-lang/crates.io-index" 803 | checksum = "73b4b750c782965c211b42f022f59af1fbceabdd026623714f104152f1ec149f" 804 | 805 | [[package]] 806 | name = "scopeguard" 807 | version = "1.1.0" 808 | source = "registry+https://github.com/rust-lang/crates.io-index" 809 | checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" 810 | 811 | [[package]] 812 | name = "serde" 813 | version = "1.0.136" 814 | source = "registry+https://github.com/rust-lang/crates.io-index" 815 | checksum = "ce31e24b01e1e524df96f1c2fdd054405f8d7376249a5110886fb4b658484789" 816 | 817 | [[package]] 818 | name = "sha-1" 819 | version = "0.9.8" 820 | source = "registry+https://github.com/rust-lang/crates.io-index" 821 | checksum = "99cd6713db3cf16b6c84e06321e049a9b9f699826e16096d23bbcc44d15d51a6" 822 | dependencies = [ 823 | "block-buffer", 824 | "cfg-if", 825 | "cpufeatures", 826 | "digest", 827 | "opaque-debug", 828 | ] 829 | 830 | [[package]] 831 | name = "shlex" 832 | version = "1.1.0" 833 | source = "registry+https://github.com/rust-lang/crates.io-index" 834 | checksum = "43b2853a4d09f215c24cc5489c992ce46052d359b5109343cbafbf26bc62f8a3" 835 | 836 | [[package]] 837 | name = "signal-hook-registry" 838 | version = "1.4.0" 839 | source = "registry+https://github.com/rust-lang/crates.io-index" 840 | checksum = "e51e73328dc4ac0c7ccbda3a494dfa03df1de2f46018127f60c693f2648455b0" 841 | dependencies = [ 842 | "libc", 843 | ] 844 | 845 | [[package]] 846 | name = "slab" 847 | version = "0.4.5" 848 | source = "registry+https://github.com/rust-lang/crates.io-index" 849 | checksum = "9def91fd1e018fe007022791f865d0ccc9b3a0d5001e01aabb8b40e46000afb5" 850 | 851 | [[package]] 852 | name = "smallvec" 853 | version = "1.8.0" 854 | source = "registry+https://github.com/rust-lang/crates.io-index" 855 | checksum = "f2dd574626839106c320a323308629dcb1acfc96e32a8cba364ddc61ac23ee83" 856 | 857 | [[package]] 858 | name = "socket2" 859 | version = "0.4.4" 860 | source = "registry+https://github.com/rust-lang/crates.io-index" 861 | checksum = "66d72b759436ae32898a2af0a14218dbf55efde3feeb170eb623637db85ee1e0" 862 | dependencies = [ 863 | "libc", 864 | "winapi", 865 | ] 866 | 867 | [[package]] 868 | name = "strsim" 869 | version = "0.8.0" 870 | source = "registry+https://github.com/rust-lang/crates.io-index" 871 | checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" 872 | 873 | [[package]] 874 | name = "swipl" 875 | version = "0.3.6" 876 | source = "registry+https://github.com/rust-lang/crates.io-index" 877 | checksum = "c2b98b973f28e775f54d07e6db4b78d5605a98fedbe15322af0f51fd4e9ae050" 878 | dependencies = [ 879 | "lazy_static", 880 | "swipl-fli", 881 | "swipl-macros", 882 | "thiserror", 883 | ] 884 | 885 | [[package]] 886 | name = "swipl-fli" 887 | version = "0.3.3" 888 | source = "registry+https://github.com/rust-lang/crates.io-index" 889 | checksum = "97401209985d55fc7513fc9ba5f73e0de3886f42620e6d0d9e945c636dcd4102" 890 | dependencies = [ 891 | "bindgen", 892 | "swipl-info", 893 | ] 894 | 895 | [[package]] 896 | name = "swipl-info" 897 | version = "0.3.2" 898 | source = "registry+https://github.com/rust-lang/crates.io-index" 899 | checksum = "d3c24ee13ef4f59cce23ccaff3006a861c7f8b02984c2a7821e7f1ced54b6c1a" 900 | dependencies = [ 901 | "regex", 902 | ] 903 | 904 | [[package]] 905 | name = "swipl-macros" 906 | version = "0.3.3" 907 | source = "registry+https://github.com/rust-lang/crates.io-index" 908 | checksum = "a575fc11dc12e551e13b1c8e208a0e054bda3bfaeeb1960ecc69bb7847b610a0" 909 | dependencies = [ 910 | "proc-macro-crate", 911 | "proc-macro2", 912 | "quote", 913 | "syn", 914 | ] 915 | 916 | [[package]] 917 | name = "syn" 918 | version = "1.0.86" 919 | source = "registry+https://github.com/rust-lang/crates.io-index" 920 | checksum = "8a65b3f4ffa0092e9887669db0eae07941f023991ab58ea44da8fe8e2d511c6b" 921 | dependencies = [ 922 | "proc-macro2", 923 | "quote", 924 | "unicode-xid", 925 | ] 926 | 927 | [[package]] 928 | name = "tar" 929 | version = "0.4.38" 930 | source = "registry+https://github.com/rust-lang/crates.io-index" 931 | checksum = "4b55807c0344e1e6c04d7c965f5289c39a8d94ae23ed5c0b57aabac549f871c6" 932 | dependencies = [ 933 | "filetime", 934 | "libc", 935 | "xattr", 936 | ] 937 | 938 | [[package]] 939 | name = "termcolor" 940 | version = "1.1.2" 941 | source = "registry+https://github.com/rust-lang/crates.io-index" 942 | checksum = "2dfed899f0eb03f32ee8c6a0aabdb8a7949659e3466561fc0adf54e26d88c5f4" 943 | dependencies = [ 944 | "winapi-util", 945 | ] 946 | 947 | [[package]] 948 | name = "terminus-store" 949 | version = "0.19.6" 950 | source = "registry+https://github.com/rust-lang/crates.io-index" 951 | checksum = "088b651d11c0c36cbd8e941f1086e003d600c52b94221cba772558dd2128875c" 952 | dependencies = [ 953 | "async-trait", 954 | "byteorder", 955 | "bytes 1.1.0", 956 | "flate2", 957 | "fs2", 958 | "futures", 959 | "futures-locks", 960 | "lazy_static", 961 | "rand", 962 | "rayon", 963 | "tar", 964 | "thiserror", 965 | "tokio 1.17.0", 966 | "tokio-util", 967 | ] 968 | 969 | [[package]] 970 | name = "terminus-store-prolog" 971 | version = "0.2.0" 972 | dependencies = [ 973 | "chardetng", 974 | "csv", 975 | "encoding_rs", 976 | "hex", 977 | "sha-1", 978 | "swipl", 979 | "terminus-store", 980 | "urlencoding", 981 | ] 982 | 983 | [[package]] 984 | name = "textwrap" 985 | version = "0.11.0" 986 | source = "registry+https://github.com/rust-lang/crates.io-index" 987 | checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" 988 | dependencies = [ 989 | "unicode-width", 990 | ] 991 | 992 | [[package]] 993 | name = "thiserror" 994 | version = "1.0.30" 995 | source = "registry+https://github.com/rust-lang/crates.io-index" 996 | checksum = "854babe52e4df1653706b98fcfc05843010039b406875930a70e4d9644e5c417" 997 | dependencies = [ 998 | "thiserror-impl", 999 | ] 1000 | 1001 | [[package]] 1002 | name = "thiserror-impl" 1003 | version = "1.0.30" 1004 | source = "registry+https://github.com/rust-lang/crates.io-index" 1005 | checksum = "aa32fd3f627f367fe16f893e2597ae3c05020f8bba2666a4e6ea73d377e5714b" 1006 | dependencies = [ 1007 | "proc-macro2", 1008 | "quote", 1009 | "syn", 1010 | ] 1011 | 1012 | [[package]] 1013 | name = "tokio" 1014 | version = "0.2.25" 1015 | source = "registry+https://github.com/rust-lang/crates.io-index" 1016 | checksum = "6703a273949a90131b290be1fe7b039d0fc884aa1935860dfcbe056f28cd8092" 1017 | dependencies = [ 1018 | "bytes 0.5.6", 1019 | "pin-project-lite 0.1.12", 1020 | "slab", 1021 | ] 1022 | 1023 | [[package]] 1024 | name = "tokio" 1025 | version = "1.17.0" 1026 | source = "registry+https://github.com/rust-lang/crates.io-index" 1027 | checksum = "2af73ac49756f3f7c01172e34a23e5d0216f6c32333757c2c61feb2bbff5a5ee" 1028 | dependencies = [ 1029 | "bytes 1.1.0", 1030 | "libc", 1031 | "memchr", 1032 | "mio", 1033 | "num_cpus", 1034 | "once_cell", 1035 | "parking_lot", 1036 | "pin-project-lite 0.2.8", 1037 | "signal-hook-registry", 1038 | "socket2", 1039 | "tokio-macros", 1040 | "winapi", 1041 | ] 1042 | 1043 | [[package]] 1044 | name = "tokio-macros" 1045 | version = "1.7.0" 1046 | source = "registry+https://github.com/rust-lang/crates.io-index" 1047 | checksum = "b557f72f448c511a979e2564e55d74e6c4432fc96ff4f6241bc6bded342643b7" 1048 | dependencies = [ 1049 | "proc-macro2", 1050 | "quote", 1051 | "syn", 1052 | ] 1053 | 1054 | [[package]] 1055 | name = "tokio-util" 1056 | version = "0.6.9" 1057 | source = "registry+https://github.com/rust-lang/crates.io-index" 1058 | checksum = "9e99e1983e5d376cd8eb4b66604d2e99e79f5bd988c3055891dcd8c9e2604cc0" 1059 | dependencies = [ 1060 | "bytes 1.1.0", 1061 | "futures-core", 1062 | "futures-sink", 1063 | "log", 1064 | "pin-project-lite 0.2.8", 1065 | "tokio 1.17.0", 1066 | ] 1067 | 1068 | [[package]] 1069 | name = "toml" 1070 | version = "0.5.8" 1071 | source = "registry+https://github.com/rust-lang/crates.io-index" 1072 | checksum = "a31142970826733df8241ef35dc040ef98c679ab14d7c3e54d827099b3acecaa" 1073 | dependencies = [ 1074 | "serde", 1075 | ] 1076 | 1077 | [[package]] 1078 | name = "typenum" 1079 | version = "1.15.0" 1080 | source = "registry+https://github.com/rust-lang/crates.io-index" 1081 | checksum = "dcf81ac59edc17cc8697ff311e8f5ef2d99fcbd9817b34cec66f90b6c3dfd987" 1082 | 1083 | [[package]] 1084 | name = "unicode-width" 1085 | version = "0.1.9" 1086 | source = "registry+https://github.com/rust-lang/crates.io-index" 1087 | checksum = "3ed742d4ea2bd1176e236172c8429aaf54486e7ac098db29ffe6529e0ce50973" 1088 | 1089 | [[package]] 1090 | name = "unicode-xid" 1091 | version = "0.2.2" 1092 | source = "registry+https://github.com/rust-lang/crates.io-index" 1093 | checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3" 1094 | 1095 | [[package]] 1096 | name = "urlencoding" 1097 | version = "1.3.3" 1098 | source = "registry+https://github.com/rust-lang/crates.io-index" 1099 | checksum = "5a1f0175e03a0973cf4afd476bef05c26e228520400eb1fd473ad417b1c00ffb" 1100 | 1101 | [[package]] 1102 | name = "vec_map" 1103 | version = "0.8.2" 1104 | source = "registry+https://github.com/rust-lang/crates.io-index" 1105 | checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191" 1106 | 1107 | [[package]] 1108 | name = "version_check" 1109 | version = "0.9.4" 1110 | source = "registry+https://github.com/rust-lang/crates.io-index" 1111 | checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" 1112 | 1113 | [[package]] 1114 | name = "wasi" 1115 | version = "0.10.2+wasi-snapshot-preview1" 1116 | source = "registry+https://github.com/rust-lang/crates.io-index" 1117 | checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" 1118 | 1119 | [[package]] 1120 | name = "which" 1121 | version = "4.2.4" 1122 | source = "registry+https://github.com/rust-lang/crates.io-index" 1123 | checksum = "2a5a7e487e921cf220206864a94a89b6c6905bfc19f1057fa26a4cb360e5c1d2" 1124 | dependencies = [ 1125 | "either", 1126 | "lazy_static", 1127 | "libc", 1128 | ] 1129 | 1130 | [[package]] 1131 | name = "winapi" 1132 | version = "0.3.9" 1133 | source = "registry+https://github.com/rust-lang/crates.io-index" 1134 | checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" 1135 | dependencies = [ 1136 | "winapi-i686-pc-windows-gnu", 1137 | "winapi-x86_64-pc-windows-gnu", 1138 | ] 1139 | 1140 | [[package]] 1141 | name = "winapi-i686-pc-windows-gnu" 1142 | version = "0.4.0" 1143 | source = "registry+https://github.com/rust-lang/crates.io-index" 1144 | checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" 1145 | 1146 | [[package]] 1147 | name = "winapi-util" 1148 | version = "0.1.5" 1149 | source = "registry+https://github.com/rust-lang/crates.io-index" 1150 | checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" 1151 | dependencies = [ 1152 | "winapi", 1153 | ] 1154 | 1155 | [[package]] 1156 | name = "winapi-x86_64-pc-windows-gnu" 1157 | version = "0.4.0" 1158 | source = "registry+https://github.com/rust-lang/crates.io-index" 1159 | checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" 1160 | 1161 | [[package]] 1162 | name = "windows-sys" 1163 | version = "0.32.0" 1164 | source = "registry+https://github.com/rust-lang/crates.io-index" 1165 | checksum = "3df6e476185f92a12c072be4a189a0210dcdcf512a1891d6dff9edb874deadc6" 1166 | dependencies = [ 1167 | "windows_aarch64_msvc", 1168 | "windows_i686_gnu", 1169 | "windows_i686_msvc", 1170 | "windows_x86_64_gnu", 1171 | "windows_x86_64_msvc", 1172 | ] 1173 | 1174 | [[package]] 1175 | name = "windows_aarch64_msvc" 1176 | version = "0.32.0" 1177 | source = "registry+https://github.com/rust-lang/crates.io-index" 1178 | checksum = "d8e92753b1c443191654ec532f14c199742964a061be25d77d7a96f09db20bf5" 1179 | 1180 | [[package]] 1181 | name = "windows_i686_gnu" 1182 | version = "0.32.0" 1183 | source = "registry+https://github.com/rust-lang/crates.io-index" 1184 | checksum = "6a711c68811799e017b6038e0922cb27a5e2f43a2ddb609fe0b6f3eeda9de615" 1185 | 1186 | [[package]] 1187 | name = "windows_i686_msvc" 1188 | version = "0.32.0" 1189 | source = "registry+https://github.com/rust-lang/crates.io-index" 1190 | checksum = "146c11bb1a02615db74680b32a68e2d61f553cc24c4eb5b4ca10311740e44172" 1191 | 1192 | [[package]] 1193 | name = "windows_x86_64_gnu" 1194 | version = "0.32.0" 1195 | source = "registry+https://github.com/rust-lang/crates.io-index" 1196 | checksum = "c912b12f7454c6620635bbff3450962753834be2a594819bd5e945af18ec64bc" 1197 | 1198 | [[package]] 1199 | name = "windows_x86_64_msvc" 1200 | version = "0.32.0" 1201 | source = "registry+https://github.com/rust-lang/crates.io-index" 1202 | checksum = "504a2476202769977a040c6364301a3f65d0cc9e3fb08600b2bda150a0488316" 1203 | 1204 | [[package]] 1205 | name = "xattr" 1206 | version = "0.2.2" 1207 | source = "registry+https://github.com/rust-lang/crates.io-index" 1208 | checksum = "244c3741f4240ef46274860397c7c74e50eb23624996930e484c16679633a54c" 1209 | dependencies = [ 1210 | "libc", 1211 | ] 1212 | -------------------------------------------------------------------------------- /rust/terminus-store-prolog-core/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "terminus-store-prolog" 3 | version = "0.2.0" 4 | authors = ["Matthijs van Otterdijk ", "Robin de Rooij ", "Gavin Mendel-Gleason "] 5 | edition = "2018" 6 | publish = false 7 | 8 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 9 | 10 | [dependencies] 11 | swipl = "0.3.6" 12 | #swipl = {path = "../../swipl-rs/swipl"} 13 | terminus-store = "=0.19.6" 14 | csv = "1.1" 15 | sha-1 = "0.9.1" 16 | hex = "0.4.2" 17 | encoding_rs = "0.8.24" 18 | chardetng = "0.1.9" 19 | urlencoding = "1.1.1" -------------------------------------------------------------------------------- /rust/terminus-store-prolog-core/src/builder.rs: -------------------------------------------------------------------------------- 1 | use crate::layer::*; 2 | use std::io::{self, Write}; 3 | use swipl::prelude::*; 4 | use terminus_store::layer::*; 5 | use terminus_store::storage::name_to_string; 6 | use terminus_store::store::sync::*; 7 | 8 | predicates! { 9 | pub semidet fn nb_add_id_triple(context, builder_term, subject_id_term, predicate_id_term, object_id_term) { 10 | let builder: WrappedBuilder = builder_term.get_ex()?; 11 | let subject_id = subject_id_term.get_ex()?; 12 | let predicate_id = predicate_id_term.get_ex()?; 13 | let object_id = object_id_term.get_ex()?; 14 | 15 | context.try_or_die(builder.add_id_triple(IdTriple::new(subject_id, predicate_id, object_id))) 16 | } 17 | 18 | pub semidet fn nb_add_string_triple(context, builder_term, subject_term, predicate_term, object_term) { 19 | let builder: WrappedBuilder = builder_term.get_ex()?; 20 | let subject: PrologText = subject_term.get_ex()?; 21 | let predicate: PrologText = predicate_term.get_ex()?; 22 | 23 | let inner = context.new_term_ref(); 24 | if attempt(object_term.unify(term!{context: node(#&inner)}?))? { 25 | let object: PrologText = inner.get_ex()?; 26 | context.try_or_die(builder.add_string_triple(StringTriple::new_node(&subject, &predicate, &object))) 27 | } 28 | else if attempt(object_term.unify(term!{context: value(#&inner)}?))? { 29 | let object: PrologText = inner.get_ex()?; 30 | context.try_or_die(builder.add_string_triple(StringTriple::new_value(&subject, &predicate, &object))) 31 | } 32 | else { 33 | context.raise_exception(&term!{context: error(domain_error(oneof([node(), value()]), #object_term), _)}?) 34 | } 35 | } 36 | 37 | pub semidet fn nb_remove_id_triple(context, builder_term, subject_id_term, predicate_id_term, object_id_term) { 38 | let builder: WrappedBuilder = builder_term.get_ex()?; 39 | let subject_id = subject_id_term.get_ex()?; 40 | let predicate_id = predicate_id_term.get_ex()?; 41 | let object_id = object_id_term.get_ex()?; 42 | 43 | context.try_or_die(builder.remove_id_triple(IdTriple::new(subject_id, predicate_id, object_id))) 44 | } 45 | 46 | pub semidet fn nb_remove_string_triple(context, builder_term, subject_term, predicate_term, object_term) { 47 | let builder: WrappedBuilder = builder_term.get_ex()?; 48 | let subject: PrologText = subject_term.get_ex()?; 49 | let predicate: PrologText = predicate_term.get_ex()?; 50 | 51 | let inner = context.new_term_ref(); 52 | if attempt(object_term.unify(term!{context: node(#&inner)}?))? { 53 | let object: PrologText = inner.get_ex()?; 54 | context.try_or_die(builder.remove_string_triple(StringTriple::new_node(&subject, &predicate, &object))) 55 | } 56 | else if attempt(object_term.unify(term!{context: value(#&inner)}?))? { 57 | let object: PrologText = inner.get_ex()?; 58 | context.try_or_die(builder.remove_string_triple(StringTriple::new_value(&subject, &predicate, &object))) 59 | } 60 | else { 61 | context.raise_exception(&term!{context: error(domain_error(oneof([node(), value()]), #object_term), _)}?) 62 | } 63 | } 64 | 65 | pub semidet fn builder_committed(_context, builder_term) { 66 | let builder: WrappedBuilder = builder_term.get_ex()?; 67 | 68 | into_prolog_result(builder.committed()) 69 | } 70 | 71 | pub semidet fn nb_commit(context, builder_term, layer_term) { 72 | let builder: WrappedBuilder = builder_term.get_ex()?; 73 | let layer = context.try_or_die(builder.commit())?; 74 | layer_term.unify(WrappedLayer(layer)) 75 | } 76 | 77 | pub semidet fn nb_apply_delta(context, builder_term, layer_term) { 78 | let builder: WrappedBuilder = builder_term.get_ex()?; 79 | let layer: WrappedLayer = layer_term.get_ex()?; 80 | 81 | context.try_or_die(builder.apply_delta(&layer))?; 82 | 83 | Ok(()) 84 | } 85 | 86 | pub semidet fn nb_apply_diff(context, builder_term, layer_term) { 87 | let builder: WrappedBuilder = builder_term.get_ex()?; 88 | let layer: WrappedLayer = layer_term.get_ex()?; 89 | 90 | context.try_or_die(builder.apply_diff(&layer))?; 91 | 92 | Ok(()) 93 | } 94 | } 95 | 96 | wrapped_clone_blob!("builder", pub WrappedBuilder, SyncStoreLayerBuilder); 97 | 98 | impl CloneBlobImpl for WrappedBuilder { 99 | fn write(&self, stream: &mut PrologStream) -> io::Result<()> { 100 | write!(stream, "", name_to_string(self.name())) 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /rust/terminus-store-prolog-core/src/csv.rs: -------------------------------------------------------------------------------- 1 | use chardetng::*; 2 | use csv::ReaderBuilder; 3 | use encoding_rs::UTF_8; 4 | use hex; 5 | use sha1::{Digest, Sha1}; 6 | use std::fs::File; 7 | use std::io; 8 | use std::io::prelude::*; 9 | use std::path::PathBuf; 10 | use terminus_store::layer::StringTriple; 11 | use terminus_store::store::sync::*; 12 | use urlencoding; 13 | 14 | use swipl::prelude::*; 15 | 16 | use crate::builder::WrappedBuilder; 17 | 18 | predicates! { 19 | pub semidet fn csv_iri(_context, csv_name_term, prefix_term, iri_term) { 20 | let csv_name: String = csv_name_term.get::()?.to_string(); 21 | let prefix: String = prefix_term.get::()?.to_string(); 22 | let (_, node) = csv_name_iri(csv_name, prefix); 23 | 24 | iri_term.unify(&node) 25 | } 26 | 27 | pub semidet fn csv_builder(context, 28 | name_term, 29 | csv_term, 30 | builder_term, 31 | data_prefix_term, 32 | schema_prefix_term, 33 | header_term, 34 | skip_header_term 35 | ) { 36 | let name: PrologText = name_term.get_ex()?; 37 | let csv: PrologText = csv_term.get_ex()?; 38 | let builder: WrappedBuilder = builder_term.get_ex()?; 39 | let data_prefix: PrologText = data_prefix_term.get_ex()?; 40 | let schema_prefix: PrologText = schema_prefix_term.get_ex()?; 41 | 42 | // TODO original throws an exception here if the type does not match 43 | let has_header: bool = header_term.get_ex()?; 44 | let skip_header: bool = skip_header_term.get_ex()?; 45 | 46 | context.try_or_die_generic(import_csv(name.to_string(), 47 | csv.to_string(), 48 | &builder, 49 | None, 50 | data_prefix.to_string(), 51 | schema_prefix.to_string(), 52 | has_header, 53 | skip_header 54 | )) 55 | } 56 | 57 | #[name("csv_builder")] 58 | pub semidet fn csv_builder_with_schema(context, 59 | name_term, 60 | csv_term, 61 | builder_term, 62 | schema_builder_term, 63 | data_prefix_term, 64 | schema_prefix_term, 65 | header_term, 66 | skip_header_term 67 | ) { 68 | let name: PrologText = name_term.get_ex()?; 69 | let csv: PrologText = csv_term.get_ex()?; 70 | let builder: WrappedBuilder = builder_term.get_ex()?; 71 | let schema_builder: WrappedBuilder = schema_builder_term.get_ex()?; 72 | let data_prefix: PrologText = data_prefix_term.get_ex()?; 73 | let schema_prefix: PrologText = schema_prefix_term.get_ex()?; 74 | 75 | // TODO original throws an exception here if the type does not match 76 | let has_header: bool = header_term.get_ex()?; 77 | let skip_header: bool = skip_header_term.get_ex()?; 78 | 79 | context.try_or_die_generic(import_csv(name.to_string(), 80 | csv.to_string(), 81 | &builder, 82 | Some(&schema_builder), 83 | data_prefix.to_string(), 84 | schema_prefix.to_string(), 85 | has_header, 86 | skip_header 87 | )) 88 | } 89 | } 90 | 91 | pub fn csv_name_iri(csv_name: String, data_prefix: String) -> (String, String) { 92 | let csv_name_escaped = urlencoding::encode(&csv_name); 93 | let csv_node = format!("{}CSV_{}", data_prefix, csv_name_escaped); 94 | return (csv_name_escaped, csv_node); 95 | } 96 | 97 | pub fn csv_row_type_info( 98 | csv_name: &str, 99 | column_names: &[String], 100 | schema_prefix: &str, 101 | ) -> (String, String, String) { 102 | let mut column_hasher = Sha1::new(); 103 | let mut sorted_column_names = column_names.to_vec(); 104 | sorted_column_names.sort(); 105 | column_hasher.update(csv_name.clone()); 106 | for field in sorted_column_names.iter() { 107 | // create a Sha1 object 108 | column_hasher.update(field); 109 | } 110 | let column_hash = column_hasher.finalize(); 111 | let column_hash_string = hex::encode(column_hash); 112 | 113 | let row_type = format!("{}CSVRow_{}", schema_prefix, column_hash_string); 114 | // Create Row types 115 | let row_label = format!("\"CSV Row from {}\"@en", csv_name); 116 | let sorted_column_string = format!("CSV Row object for columns {:?}", sorted_column_names); 117 | let row_comment = format!("{:?}@en", sorted_column_string); 118 | 119 | (row_type, row_label, row_comment) 120 | } 121 | 122 | fn check_utf8(csv_path: PathBuf) -> Result { 123 | let csv_path_clone = csv_path.clone(); 124 | let mut f = File::open(csv_path_clone)?; 125 | let mut buffer = [0; 2048]; 126 | // read a chunk 127 | let _n = f.read(&mut buffer); 128 | 129 | let mut enc_detector = EncodingDetector::new(); 130 | 131 | enc_detector.feed(&buffer, true); 132 | 133 | let res = enc_detector.guess(None, true); 134 | 135 | if res == UTF_8 { 136 | return Ok(true); 137 | } else { 138 | return Ok(false); 139 | } 140 | } 141 | 142 | pub fn import_csv( 143 | csv_name: String, 144 | csv_path: String, 145 | builder: &SyncStoreLayerBuilder, 146 | schema_builder_option: Option<&SyncStoreLayerBuilder>, 147 | data_prefix: String, 148 | schema_prefix: String, 149 | has_header: bool, 150 | skip_header: bool, 151 | ) -> Result<(), csv::Error> { 152 | let pathbuf: PathBuf = csv_path.into(); 153 | 154 | if !check_utf8(pathbuf.clone())? { 155 | return Err( 156 | io::Error::new(io::ErrorKind::InvalidData, "Could not convert to utf-8").into(), 157 | ); 158 | } 159 | let file = File::open(pathbuf)?; 160 | 161 | let mut reader = ReaderBuilder::new() 162 | .has_headers(has_header && !skip_header) 163 | .from_reader(file); 164 | 165 | let mut header = Vec::new(); 166 | let mut column_names = Vec::new(); 167 | 168 | let headers = reader.headers(); 169 | // if headers.is_error(){ 170 | // return io::Error::new(io::ErrorKind::UnexpectedEof,"There are no lines in this CSV").into(); 171 | // } 172 | let (csv_name_escaped, csv_node) = csv_name_iri(csv_name.clone(), data_prefix.clone()); 173 | if !has_header || skip_header { 174 | let len = headers 175 | .expect("Expected a Some for headers but headers are empty") 176 | .len(); 177 | for i in 0..len { 178 | header.push(format!( 179 | "{}{}_column_{}", 180 | schema_prefix, csv_name_escaped, i 181 | )); 182 | column_names.push(format!("{}", i)); 183 | } 184 | } else { 185 | for field in headers 186 | .expect("Expected a Some for headers but headers are empty") 187 | .iter() 188 | { 189 | let escaped_field = urlencoding::encode(field); 190 | column_names.push(String::from(field)); 191 | header.push(format!( 192 | "{}{}_column_{}", 193 | schema_prefix, csv_name_escaped, escaped_field 194 | )); 195 | } 196 | } 197 | 198 | // Prefixes 199 | let rdf = "http://www.w3.org/1999/02/22-rdf-syntax-ns#"; 200 | let rdfs = "http://www.w3.org/2000/01/rdf-schema#"; 201 | let xsd = "http://www.w3.org/2001/XMLSchema#"; 202 | 203 | let rdf_type = format!("{}{}", rdf, "type"); 204 | let label = format!("{}{}", rdfs, "label"); 205 | 206 | // Create the csv type 207 | let csv_type = format!("{}CSV", schema_prefix); 208 | let csv_name_value = format!("{:?}@en", csv_name); 209 | 210 | builder.add_string_triple(StringTriple::new_node(&csv_node, &rdf_type, &csv_type))?; 211 | builder.add_string_triple(StringTriple::new_value(&csv_node, &label, &csv_name_value))?; 212 | 213 | // Create the ordered column names metadata for the csv 214 | let mut column_index = 0; 215 | for field in column_names.iter() { 216 | let escaped_field = urlencoding::encode(field); 217 | let column_predicate = format!("{}csv_column", schema_prefix); 218 | let column_node = format!( 219 | "{}ColumnObject_{}_{}", 220 | data_prefix, csv_name_escaped, escaped_field 221 | ); 222 | let column_type = format!("{}Column", schema_prefix); 223 | let column_index_predicate = format!("{}csv_column_index", schema_prefix); 224 | let column_index_value = format!("{}^^'{}{}'", column_index, xsd, "integer"); 225 | let column_name_predicate = format!("{}csv_column_name", schema_prefix); 226 | let column_name_value = format!("{:?}^^'{}{}'", field, xsd, "string"); 227 | 228 | builder.add_string_triple(StringTriple::new_node( 229 | &csv_node, 230 | &column_predicate, 231 | &column_node, 232 | ))?; 233 | 234 | builder.add_string_triple(StringTriple::new_node( 235 | &column_node, 236 | &rdf_type, 237 | &column_type, 238 | ))?; 239 | 240 | builder.add_string_triple(StringTriple::new_value( 241 | &column_node, 242 | &column_index_predicate, 243 | &column_index_value, 244 | ))?; 245 | 246 | builder.add_string_triple(StringTriple::new_value( 247 | &column_node, 248 | &column_name_predicate, 249 | &column_name_value, 250 | ))?; 251 | column_index += 1; 252 | } 253 | 254 | if let Some(schema_builder) = schema_builder_option { 255 | write_schema(&csv_name, schema_builder, &schema_prefix, &column_names)?; 256 | } 257 | 258 | let (row_type, _, _) = csv_row_type_info(&csv_name, &column_names, &schema_prefix); 259 | 260 | for result in reader.records() { 261 | let record = result?; 262 | // create a Sha1 object 263 | let mut hasher = Sha1::new(); 264 | // add csv_name to hasher so we don't overlap CSVs 265 | hasher.update(csv_name.clone()); 266 | // process input message 267 | for (_, field) in record.iter().enumerate() { 268 | hasher.update(field); 269 | } 270 | let hash = hasher.finalize(); 271 | let hash_string = hex::encode(hash); 272 | let node = format!("{}CSVRow_{}", data_prefix, hash_string); 273 | let row_predicate = format!("{}csv_row", schema_prefix); 274 | 275 | // add row type 276 | builder.add_string_triple(StringTriple::new_node(&node, &rdf_type, &row_type))?; 277 | // add row predicate 278 | builder.add_string_triple(StringTriple::new_node(&csv_node, &row_predicate, &node))?; 279 | for (col, field) in record.iter().enumerate() { 280 | let value = format!("{:?}^^'{}{}'", field, xsd, "string"); 281 | let column = &header[col]; 282 | builder.add_string_triple(StringTriple::new_value(&node, &column, &value))?; 283 | } 284 | } 285 | 286 | return Ok(()); 287 | } 288 | 289 | fn write_schema( 290 | csv_name: &str, 291 | schema_builder: &SyncStoreLayerBuilder, 292 | schema_prefix: &str, 293 | column_names: &[String], 294 | ) -> Result<(), csv::Error> { 295 | // Prefixes 296 | let rdf = "http://www.w3.org/1999/02/22-rdf-syntax-ns#"; 297 | let rdfs = "http://www.w3.org/2000/01/rdf-schema#"; 298 | let xsd = "http://www.w3.org/2001/XMLSchema#"; 299 | let owl = "http://www.w3.org/2002/07/owl#"; 300 | 301 | // common predicates 302 | let rdf_type = format!("{}{}", rdf, "type"); 303 | let label = format!("{}{}", rdfs, "label"); 304 | let comment = format!("{}{}", rdfs, "comment"); 305 | let domain = format!("{}{}", rdfs, "domain"); 306 | let range = format!("{}{}", rdfs, "range"); 307 | let owl_class = format!("{}{}", owl, "Class"); 308 | let datatype_property = format!("{}{}", owl, "DatatypeProperty"); 309 | let object_property = format!("{}{}", owl, "ObjectProperty"); 310 | let sub_class_of = format!("{}{}", rdfs, "subClassOf"); 311 | 312 | // common types 313 | let xsd_string = format!("{}{}", xsd, "string"); 314 | let xsd_integer = format!("{}{}", xsd, "integer"); 315 | 316 | // Create the csv object 317 | let csv_type = format!("{}CSV", schema_prefix); 318 | let csv_label = "\"CSV\"@en"; 319 | let csv_comment = "\"CSV object\"@en"; 320 | let document = "http://terminusdb.com/schema/system#Document"; 321 | let (row_type, row_label, row_comment) = 322 | csv_row_type_info(csv_name, column_names, schema_prefix); 323 | 324 | schema_builder.add_string_triple(StringTriple::new_node(&csv_type, &rdf_type, &owl_class))?; 325 | schema_builder.add_string_triple(StringTriple::new_value(&csv_type, &label, &csv_label))?; 326 | schema_builder.add_string_triple(StringTriple::new_value(&csv_type, &comment, &csv_comment))?; 327 | schema_builder.add_string_triple(StringTriple::new_node( 328 | &csv_type, 329 | &sub_class_of, 330 | &document, 331 | ))?; 332 | 333 | // Create column objects and fields 334 | let column_predicate = format!("{}csv_column", schema_prefix); 335 | let column_predicate_label = "\"csv column\"@en"; 336 | let column_predicate_comment = "\"Associates a CSV with a column object\"@en"; 337 | 338 | let column_type = format!("{}Column", schema_prefix); 339 | let column_label = "\"Column\"@en"; 340 | let column_comment = "\"Column information object for a CSV\"@en"; 341 | let column_index_predicate = format!("{}csv_column_index", schema_prefix); 342 | let column_index_label = "\"csv column index\"@en"; 343 | let column_index_comment = "\"The ordering index for a column in a csv\"@en"; 344 | let column_name_predicate = format!("{}csv_column_name", schema_prefix); 345 | let column_name_label = "\"csv column name\"@en"; 346 | let column_name_comment = "\"The name of the column as it was verbatim in the CSV\"@en"; 347 | 348 | schema_builder.add_string_triple(StringTriple::new_node( 349 | &column_type, 350 | &rdf_type, 351 | &owl_class, 352 | ))?; 353 | schema_builder.add_string_triple(StringTriple::new_value( 354 | &column_type, 355 | &label, 356 | &column_label, 357 | ))?; 358 | schema_builder.add_string_triple(StringTriple::new_value( 359 | &column_type, 360 | &comment, 361 | &column_comment, 362 | ))?; 363 | // column 364 | schema_builder.add_string_triple(StringTriple::new_node( 365 | &column_predicate, 366 | &rdf_type, 367 | &object_property, 368 | ))?; 369 | schema_builder.add_string_triple(StringTriple::new_value( 370 | &column_predicate, 371 | &label, 372 | &column_predicate_label, 373 | ))?; 374 | schema_builder.add_string_triple(StringTriple::new_value( 375 | &column_predicate, 376 | &comment, 377 | &column_predicate_comment, 378 | ))?; 379 | schema_builder.add_string_triple(StringTriple::new_node( 380 | &column_predicate, 381 | &domain, 382 | &csv_type, 383 | ))?; 384 | schema_builder.add_string_triple(StringTriple::new_node( 385 | &column_predicate, 386 | &range, 387 | &column_type, 388 | ))?; 389 | 390 | // index 391 | schema_builder.add_string_triple(StringTriple::new_node( 392 | &column_index_predicate, 393 | &rdf_type, 394 | &datatype_property, 395 | ))?; 396 | schema_builder.add_string_triple(StringTriple::new_value( 397 | &column_index_predicate, 398 | &label, 399 | &column_index_label, 400 | ))?; 401 | schema_builder.add_string_triple(StringTriple::new_value( 402 | &column_index_predicate, 403 | &comment, 404 | &column_index_comment, 405 | ))?; 406 | schema_builder.add_string_triple(StringTriple::new_node( 407 | &column_index_predicate, 408 | &domain, 409 | &column_type, 410 | ))?; 411 | schema_builder.add_string_triple(StringTriple::new_node( 412 | &column_index_predicate, 413 | &range, 414 | &xsd_integer, 415 | ))?; 416 | 417 | // name 418 | schema_builder.add_string_triple(StringTriple::new_node( 419 | &column_name_predicate, 420 | &rdf_type, 421 | &datatype_property, 422 | ))?; 423 | schema_builder.add_string_triple(StringTriple::new_value( 424 | &column_name_predicate, 425 | &label, 426 | &column_name_label, 427 | ))?; 428 | schema_builder.add_string_triple(StringTriple::new_value( 429 | &column_name_predicate, 430 | &comment, 431 | &column_name_comment, 432 | ))?; 433 | schema_builder.add_string_triple(StringTriple::new_node( 434 | &column_name_predicate, 435 | &domain, 436 | &column_type, 437 | ))?; 438 | schema_builder.add_string_triple(StringTriple::new_node( 439 | &column_name_predicate, 440 | &range, 441 | &xsd_string, 442 | ))?; 443 | 444 | // Row super class 445 | let row_super = format!("{}CSVRow", schema_prefix); 446 | let row_super_label = "\"CSV Row\"@en"; 447 | let row_super_comment = "\"Generic Row of a CSV file\"@en"; 448 | 449 | schema_builder.add_string_triple(StringTriple::new_node(&row_super, &rdf_type, &owl_class))?; 450 | schema_builder.add_string_triple(StringTriple::new_value( 451 | &row_super, 452 | &label, 453 | &row_super_label, 454 | ))?; 455 | schema_builder.add_string_triple(StringTriple::new_value( 456 | &row_super, 457 | &comment, 458 | &row_super_comment, 459 | ))?; 460 | 461 | schema_builder.add_string_triple(StringTriple::new_node(&row_type, &rdf_type, &owl_class))?; 462 | schema_builder.add_string_triple(StringTriple::new_node( 463 | &row_type, 464 | &sub_class_of, 465 | &row_super, 466 | ))?; 467 | 468 | let system_prefix = "http://terminusdb.com/schema/system#"; 469 | let csv_name_property = format!("{}csv_name", system_prefix); 470 | let csv_name_value = format!("{:?}@en", csv_name); 471 | schema_builder.add_string_triple(StringTriple::new_value(&row_type, &label, &row_label))?; 472 | schema_builder.add_string_triple(StringTriple::new_value(&row_type, &comment, &row_comment))?; 473 | schema_builder.add_string_triple(StringTriple::new_value( 474 | &row_type, 475 | &csv_name_property, 476 | &csv_name_value, 477 | ))?; 478 | // Row predicate 479 | let row_predicate = format!("{}csv_row", schema_prefix); 480 | let row_predicate_label = "\"csv row\"@en"; 481 | let row_predicate_comment = "\"Connects a CSV to its rows\"@en"; 482 | let row_super = format!("{}CSVRow", schema_prefix); 483 | 484 | schema_builder.add_string_triple(StringTriple::new_node( 485 | &row_predicate, 486 | &rdf_type, 487 | &object_property, 488 | ))?; 489 | schema_builder.add_string_triple(StringTriple::new_value( 490 | &row_predicate, 491 | &label, 492 | &row_predicate_label, 493 | ))?; 494 | schema_builder.add_string_triple(StringTriple::new_value( 495 | &row_predicate, 496 | &comment, 497 | &row_predicate_comment, 498 | ))?; 499 | schema_builder.add_string_triple(StringTriple::new_node(&row_predicate, &domain, &csv_type))?; 500 | schema_builder.add_string_triple(StringTriple::new_node(&row_predicate, &range, &row_super))?; 501 | 502 | let (csv_name_escaped, _) = csv_name_iri(csv_name.to_string(), "".to_string()); 503 | 504 | // Create column predicates for each field 505 | for field in column_names { 506 | let escaped_field = urlencoding::encode(field); 507 | let column_p = format!( 508 | "{}{}_column_{}", 509 | schema_prefix, csv_name_escaped, escaped_field 510 | ); 511 | let column_label = format!("\"Column {}\"@en", field); 512 | let column_comment = format!("\"CSV Column for header name {}\"@en", field); 513 | 514 | schema_builder.add_string_triple(StringTriple::new_node( 515 | &column_p, 516 | &rdf_type, 517 | &datatype_property, 518 | ))?; 519 | schema_builder.add_string_triple(StringTriple::new_value( 520 | &column_p, 521 | &label, 522 | &column_label, 523 | ))?; 524 | schema_builder.add_string_triple(StringTriple::new_value( 525 | &column_p, 526 | &comment, 527 | &column_comment, 528 | ))?; 529 | schema_builder.add_string_triple(StringTriple::new_node(&column_p, &domain, &row_type))?; 530 | schema_builder.add_string_triple(StringTriple::new_node(&column_p, &range, &xsd_string))?; 531 | } 532 | return Ok(()); 533 | } 534 | -------------------------------------------------------------------------------- /rust/terminus-store-prolog-core/src/layer.rs: -------------------------------------------------------------------------------- 1 | use crate::store::*; 2 | use std::io::{self, Write}; 3 | use std::iter::Peekable; 4 | use swipl::prelude::*; 5 | use terminus_store::layer::{IdTriple, ObjectType}; 6 | use terminus_store::storage::{name_to_string, string_to_name}; 7 | use terminus_store::store::sync::*; 8 | use terminus_store::Layer; 9 | 10 | predicates! { 11 | pub semidet fn node_and_value_count(_context, layer_term, count_term) { 12 | let layer: WrappedLayer = layer_term.get_ex()?; 13 | let count = layer.node_and_value_count() as u64; 14 | 15 | count_term.unify(count) 16 | } 17 | 18 | pub semidet fn predicate_count(_context, layer_term, count_term) { 19 | let layer: WrappedLayer = layer_term.get_ex()?; 20 | let count = layer.predicate_count() as u64; 21 | 22 | count_term.unify(count) 23 | } 24 | 25 | pub semidet fn subject_to_id(_context, layer_term, subject_term, id_term) { 26 | let layer: WrappedLayer = layer_term.get_ex()?; 27 | let subject: PrologText = subject_term.get_ex()?; 28 | 29 | match layer.subject_id(&subject) { 30 | Some(id) => id_term.unify(id), 31 | None => Err(PrologError::Failure) 32 | } 33 | } 34 | 35 | pub semidet fn id_to_subject(_context, layer_term, id_term, subject_term) { 36 | let layer: WrappedLayer = layer_term.get_ex()?; 37 | let id: u64 = id_term.get_ex()?; 38 | 39 | match layer.id_subject(id) { 40 | Some(subject) => subject_term.unify(subject), 41 | None => Err(PrologError::Failure) 42 | } 43 | } 44 | 45 | pub semidet fn predicate_to_id(_context, layer_term, predicate_term, id_term) { 46 | let layer: WrappedLayer = layer_term.get_ex()?; 47 | let predicate: PrologText = predicate_term.get_ex()?; 48 | 49 | match layer.predicate_id(&predicate) { 50 | Some(id) => id_term.unify(id), 51 | None => Err(PrologError::Failure) 52 | } 53 | } 54 | 55 | pub semidet fn id_to_predicate(_context, layer_term, id_term, predicate_term) { 56 | let layer: WrappedLayer = layer_term.get_ex()?; 57 | let id: u64 = id_term.get_ex()?; 58 | 59 | match layer.id_predicate(id) { 60 | Some(predicate) => predicate_term.unify(predicate), 61 | None => Err(PrologError::Failure) 62 | } 63 | } 64 | 65 | pub semidet fn object_to_id(context, layer_term, object_term, id_term) { 66 | let layer: WrappedLayer = layer_term.get_ex()?; 67 | 68 | let inner = context.new_term_ref(); 69 | let id: Option; 70 | if attempt(object_term.unify(term!{context: node(#&inner)}?))? { 71 | let object: PrologText = inner.get_ex()?; 72 | id = layer.object_node_id(&object); 73 | } 74 | else if attempt(object_term.unify(term!{context: value(#&inner)}?))? { 75 | let object: PrologText = inner.get_ex()?; 76 | id = layer.object_value_id(&object); 77 | } 78 | else { 79 | return context.raise_exception(&term!{context: error(domain_error(oneof([node(), value()]), #object_term), _)}?); 80 | } 81 | 82 | 83 | match id { 84 | Some(id) => id_term.unify(id), 85 | None => Err(PrologError::Failure) 86 | } 87 | } 88 | 89 | pub semidet fn id_to_object(_context, layer_term, id_term, object_term) { 90 | let layer: WrappedLayer = layer_term.get_ex()?; 91 | let id: u64 = id_term.get_ex()?; 92 | 93 | match layer.id_object(id) { 94 | Some(ObjectType::Node(object)) => { 95 | object_term.unify(Functor::new("node", 1))?; 96 | object_term.unify_arg(1, &object) 97 | } 98 | Some(ObjectType::Value(object)) => { 99 | object_term.unify(Functor::new("value", 1))?; 100 | object_term.unify_arg(1, &object) 101 | } 102 | None => Err(PrologError::Failure) 103 | } 104 | } 105 | 106 | pub semidet fn parent(context, layer_term, parent_term) { 107 | let layer: WrappedLayer = layer_term.get_ex()?; 108 | match context.try_or_die(layer.parent())? { 109 | Some(p) => parent_term.unify(WrappedLayer(p)), 110 | None => Err(PrologError::Failure) 111 | } 112 | } 113 | 114 | pub semidet fn squash(context, layer_term, squashed_layer_term) { 115 | let layer: WrappedLayer = layer_term.get_ex()?; 116 | let squashed = context.try_or_die(layer.squash())?; 117 | squashed_layer_term.unify(&WrappedLayer(squashed)) 118 | } 119 | 120 | pub semidet fn rollup(context, layer_term) { 121 | let layer: WrappedLayer = layer_term.get_ex()?; 122 | context.try_or_die(layer.rollup()) 123 | } 124 | 125 | pub semidet fn rollup_upto(context, layer_term, upto_term) { 126 | let layer: WrappedLayer = layer_term.get_ex()?; 127 | let upto: WrappedLayer = upto_term.get_ex()?; 128 | context.try_or_die(layer.rollup_upto(&upto)) 129 | } 130 | 131 | pub semidet fn imprecise_rollup_upto(context, layer_term, upto_term) { 132 | let layer: WrappedLayer = layer_term.get_ex()?; 133 | let upto: WrappedLayer = upto_term.get_ex()?; 134 | context.try_or_die(layer.imprecise_rollup_upto(&upto)) 135 | } 136 | 137 | pub semidet fn layer_addition_count(context, layer_term, count_term) { 138 | let layer: WrappedLayer = layer_term.get_ex()?; 139 | let count = context.try_or_die(layer.triple_layer_addition_count())? as u64; 140 | 141 | count_term.unify(count) 142 | } 143 | 144 | pub semidet fn layer_removal_count(context, layer_term, count_term) { 145 | let layer: WrappedLayer = layer_term.get_ex()?; 146 | let count = context.try_or_die(layer.triple_layer_removal_count())? as u64; 147 | 148 | count_term.unify(count) 149 | } 150 | 151 | pub semidet fn layer_total_addition_count(_context, layer_term, count_term) { 152 | let layer: WrappedLayer = layer_term.get_ex()?; 153 | let count = layer.triple_addition_count() as u64; 154 | 155 | count_term.unify(count) 156 | } 157 | 158 | pub semidet fn layer_total_removal_count(_context, layer_term, count_term) { 159 | let layer: WrappedLayer = layer_term.get_ex()?; 160 | let count = layer.triple_removal_count() as u64; 161 | 162 | count_term.unify(count) 163 | } 164 | 165 | pub semidet fn layer_total_triple_count(_context, layer_term, count_term) { 166 | let layer: WrappedLayer = layer_term.get_ex()?; 167 | let count = layer.triple_count() as u64; 168 | 169 | count_term.unify(count) 170 | } 171 | 172 | pub semidet fn layer_to_id(_context, layer_term, id_term) { 173 | let layer: WrappedLayer = layer_term.get_ex()?; 174 | let name = name_to_string(layer.name()); 175 | 176 | id_term.unify(&name) 177 | } 178 | 179 | pub semidet fn store_id_layer(context, store_term, id_term, layer_term) { 180 | if layer_term.is_var() { 181 | let store: WrappedStore = store_term.get_ex()?; 182 | let id: PrologText = id_term.get_ex()?; 183 | let name = context.try_or_die(string_to_name(&id))?; 184 | 185 | match context.try_or_die(store.get_layer_from_id(name))? { 186 | Some(layer) => layer_term.unify(&WrappedLayer(layer)), 187 | None => Err(PrologError::Failure) 188 | } 189 | } 190 | else { 191 | let layer: WrappedLayer = layer_term.get_ex()?; 192 | let name = name_to_string(layer.name()); 193 | 194 | id_term.unify(&name) 195 | } 196 | } 197 | 198 | pub nondet fn id_triple+Send>>>(context, layer_term, subject_id_term, predicate_id_term, object_id_term) { 199 | setup => { 200 | let layer: WrappedLayer = layer_term.get_ex()?; 201 | 202 | let iter: Box+Send>; 203 | if let Some(subject_id) = attempt_opt(subject_id_term.get::())? { 204 | if let Some(predicate_id) = attempt_opt(predicate_id_term.get::())? { 205 | if let Some(object_id) = attempt_opt(object_id_term.get::())? { 206 | // everything is known 207 | if layer.triple_exists(subject_id, predicate_id, object_id) { 208 | return Ok(None); 209 | } 210 | else { 211 | return Err(PrologError::Failure) 212 | } 213 | } 214 | else { 215 | // subject and predicate are known, object is not 216 | iter = layer.triples_sp(subject_id, predicate_id); 217 | } 218 | } 219 | else { 220 | // subject is known, predicate is not. object may or may not be bound already. 221 | if let Some(object_id) = attempt_opt(object_id_term.get::())? { 222 | // object is known so predicate is the only unknown 223 | iter = Box::new(layer.triples_s(subject_id) 224 | .filter(move |t| t.object == object_id)); 225 | } 226 | else { 227 | // both predicate and object are unknown 228 | iter = layer.triples_s(subject_id); 229 | } 230 | } 231 | } 232 | else if let Some(object_id) = attempt_opt(object_id_term.get::())? { 233 | // subject is unknown 234 | if let Some(predicate_id) = attempt_opt(predicate_id_term.get::())? { 235 | // predicate is known 236 | iter = Box::new(layer.triples_o(object_id) 237 | .filter(move |t| t.predicate == predicate_id)); 238 | } 239 | else { 240 | // predicate is unknown, only object is known 241 | iter = layer.triples_o(object_id) 242 | } 243 | } 244 | else if let Some(predicate_id) = attempt_opt(predicate_id_term.get::())? { 245 | // only predicate is known 246 | iter = layer.triples_p(predicate_id); 247 | } 248 | else { 249 | // nothing is known so return everything 250 | iter = layer.triples(); 251 | } 252 | 253 | // lets make it peekable 254 | let iter = iter.peekable(); 255 | 256 | Ok(Some(iter)) 257 | }, 258 | call(iter) => { 259 | if let Some(triple) = iter.next() { 260 | subject_id_term.unify(triple.subject)?; 261 | predicate_id_term.unify(triple.predicate)?; 262 | object_id_term.unify(triple.object)?; 263 | 264 | Ok(iter.peek().is_some()) 265 | } 266 | else { 267 | return Err(PrologError::Failure); 268 | } 269 | } 270 | } 271 | 272 | pub semidet fn sp_card(_context, layer_term, subject_id_term, predicate_id_term, count_term) { 273 | let layer: WrappedLayer = layer_term.get_ex()?; 274 | let subject_id: u64 = subject_id_term.get_ex()?; 275 | let predicate_id: u64 = predicate_id_term.get_ex()?; 276 | let iter = layer.triples_sp(subject_id, predicate_id); 277 | let count = iter.count() as u64; 278 | count_term.unify(count) 279 | } 280 | 281 | pub nondet fn id_triple_addition+Send>>>(context, layer_term, subject_id_term, predicate_id_term, object_id_term) { 282 | setup => { 283 | let layer: WrappedLayer = layer_term.get_ex()?; 284 | 285 | let iter: Box+Send>; 286 | if let Some(subject_id) = attempt_opt(subject_id_term.get::())? { 287 | if let Some(predicate_id) = attempt_opt(predicate_id_term.get::())? { 288 | if let Some(object_id) = attempt_opt(object_id_term.get::())? { 289 | // everything is known 290 | if context.try_or_die(layer.triple_addition_exists(subject_id, predicate_id, object_id))? { 291 | return Ok(None); 292 | } 293 | else { 294 | return Err(PrologError::Failure) 295 | } 296 | } 297 | else { 298 | // subject and predicate are known, object is not 299 | iter = context.try_or_die(layer.triple_additions_sp(subject_id, predicate_id))?; 300 | } 301 | } 302 | else { 303 | // subject is known, predicate is not. object may or may not be bound already. 304 | if let Some(object_id) = attempt_opt(object_id_term.get::())? { 305 | // object is known so predicate is the only unknown 306 | iter = Box::new(context.try_or_die(layer.triple_additions_s(subject_id))? 307 | .filter(move |t| t.object == object_id)); 308 | } 309 | else { 310 | // both predicate and object are unknown 311 | iter = context.try_or_die(layer.triple_additions_s(subject_id))?; 312 | } 313 | } 314 | } 315 | else if let Some(object_id) = attempt_opt(object_id_term.get::())? { 316 | // subject is unknown 317 | if let Some(predicate_id) = attempt_opt(predicate_id_term.get::())? { 318 | // predicate is known 319 | iter = Box::new(context.try_or_die(layer.triple_additions_o(object_id))? 320 | .filter(move |t| t.predicate == predicate_id)); 321 | } 322 | else { 323 | // predicate is unknown, only object is known 324 | iter = context.try_or_die(layer.triple_additions_o(object_id))? 325 | } 326 | } 327 | else if let Some(predicate_id) = attempt_opt(predicate_id_term.get::())? { 328 | // only predicate is known 329 | iter = context.try_or_die(layer.triple_additions_p(predicate_id))?; 330 | } 331 | else { 332 | // nothing is known so return everything 333 | iter = context.try_or_die(layer.triple_additions())?; 334 | } 335 | 336 | // lets make it peekable 337 | let iter = iter.peekable(); 338 | 339 | Ok(Some(iter)) 340 | }, 341 | call(iter) => { 342 | if let Some(triple) = iter.next() { 343 | subject_id_term.unify(triple.subject)?; 344 | predicate_id_term.unify(triple.predicate)?; 345 | object_id_term.unify(triple.object)?; 346 | 347 | Ok(iter.peek().is_some()) 348 | } 349 | else { 350 | return Err(PrologError::Failure); 351 | } 352 | } 353 | } 354 | 355 | pub nondet fn id_triple_removal+Send>>>(context, layer_term, subject_id_term, predicate_id_term, object_id_term) { 356 | setup => { 357 | let layer: WrappedLayer = layer_term.get_ex()?; 358 | 359 | let iter: Box+Send>; 360 | if let Some(subject_id) = attempt_opt(subject_id_term.get::())? { 361 | if let Some(predicate_id) = attempt_opt(predicate_id_term.get::())? { 362 | if let Some(object_id) = attempt_opt(object_id_term.get::())? { 363 | // everything is known 364 | if context.try_or_die(layer.triple_removal_exists(subject_id, predicate_id, object_id))? { 365 | return Ok(None); 366 | } 367 | else { 368 | return Err(PrologError::Failure) 369 | } 370 | } 371 | else { 372 | // subject and predicate are known, object is not 373 | iter = context.try_or_die(layer.triple_removals_sp(subject_id, predicate_id))?; 374 | } 375 | } 376 | else { 377 | // subject is known, predicate is not. object may or may not be bound already. 378 | if let Some(object_id) = attempt_opt(object_id_term.get::())? { 379 | // object is known so predicate is the only unknown 380 | iter = Box::new(context.try_or_die(layer.triple_removals_s(subject_id))? 381 | .filter(move |t| t.object == object_id)); 382 | } 383 | else { 384 | // both predicate and object are unknown 385 | iter = context.try_or_die(layer.triple_removals_s(subject_id))?; 386 | } 387 | } 388 | } 389 | else if let Some(object_id) = attempt_opt(object_id_term.get::())? { 390 | // subject is unknown 391 | if let Some(predicate_id) = attempt_opt(predicate_id_term.get::())? { 392 | // predicate is known 393 | iter = Box::new(context.try_or_die(layer.triple_removals_o(object_id))? 394 | .filter(move |t| t.predicate == predicate_id)); 395 | } 396 | else { 397 | // predicate is unknown, only object is known 398 | iter = context.try_or_die(layer.triple_removals_o(object_id))? 399 | } 400 | } 401 | else if let Some(predicate_id) = attempt_opt(predicate_id_term.get::())? { 402 | // only predicate is known 403 | iter = context.try_or_die(layer.triple_removals_p(predicate_id))?; 404 | } 405 | else { 406 | // nothing is known so return everything 407 | iter = context.try_or_die(layer.triple_removals())?; 408 | } 409 | 410 | // lets make it peekable 411 | let iter = iter.peekable(); 412 | 413 | Ok(Some(iter)) 414 | }, 415 | call(iter) => { 416 | if let Some(triple) = iter.next() { 417 | subject_id_term.unify(triple.subject)?; 418 | predicate_id_term.unify(triple.predicate)?; 419 | object_id_term.unify(triple.object)?; 420 | 421 | Ok(iter.peek().is_some()) 422 | } 423 | else { 424 | return Err(PrologError::Failure); 425 | } 426 | } 427 | } 428 | 429 | pub semidet fn retrieve_layer_stack_names(context, layer_term, layer_stack_term) { 430 | let layer: WrappedLayer = layer_term.get_ex()?; 431 | 432 | let names = context.try_or_die(layer.retrieve_layer_stack_names())?; 433 | let name_strings: Vec = names.into_iter() 434 | .map(|name| name_to_string(name)) 435 | .collect(); 436 | 437 | layer_stack_term.unify(name_strings.as_slice()) 438 | } 439 | 440 | pub semidet fn layer_equals(_context, layer1_term, layer2_term) { 441 | let layer1: WrappedLayer = layer1_term.get_ex()?; 442 | let layer2: WrappedLayer = layer2_term.get_ex()?; 443 | 444 | into_prolog_result(*layer1 == *layer2) 445 | } 446 | } 447 | 448 | wrapped_clone_blob!("layer", pub WrappedLayer, SyncStoreLayer); 449 | 450 | impl CloneBlobImpl for WrappedLayer { 451 | fn write(&self, stream: &mut PrologStream) -> io::Result<()> { 452 | write!(stream, "", name_to_string(self.name())) 453 | } 454 | } 455 | -------------------------------------------------------------------------------- /rust/terminus-store-prolog-core/src/lib.rs: -------------------------------------------------------------------------------- 1 | mod builder; 2 | mod csv; 3 | mod layer; 4 | mod named_graph; 5 | mod store; 6 | 7 | pub fn install(module: Option<&str>) { 8 | csv::register_csv_iri_in_module(module); 9 | csv::register_csv_builder_in_module(module); 10 | csv::register_csv_builder_with_schema_in_module(module); 11 | store::register_open_memory_store_in_module(module); 12 | store::register_open_directory_store_in_module(module); 13 | named_graph::register_create_named_graph_in_module(module); 14 | named_graph::register_open_named_graph_in_module(module); 15 | named_graph::register_delete_named_graph_in_module(module); 16 | named_graph::register_head2_in_module(module); 17 | named_graph::register_head3_in_module(module); 18 | named_graph::register_nb_set_head_in_module(module); 19 | named_graph::register_nb_force_set_head_in_module(module); 20 | named_graph::register_nb_force_set_head_version_in_module(module); 21 | store::register_open_write_in_module(module); 22 | builder::register_nb_add_id_triple_in_module(module); 23 | builder::register_nb_add_string_triple_in_module(module); 24 | builder::register_nb_remove_id_triple_in_module(module); 25 | builder::register_nb_remove_string_triple_in_module(module); 26 | builder::register_builder_committed_in_module(module); 27 | builder::register_nb_commit_in_module(module); 28 | builder::register_nb_apply_delta_in_module(module); 29 | builder::register_nb_apply_diff_in_module(module); 30 | layer::register_node_and_value_count_in_module(module); 31 | layer::register_predicate_count_in_module(module); 32 | layer::register_subject_to_id_in_module(module); 33 | layer::register_id_to_subject_in_module(module); 34 | layer::register_predicate_to_id_in_module(module); 35 | layer::register_id_to_predicate_in_module(module); 36 | layer::register_object_to_id_in_module(module); 37 | layer::register_id_to_object_in_module(module); 38 | layer::register_parent_in_module(module); 39 | layer::register_squash_in_module(module); 40 | layer::register_rollup_in_module(module); 41 | layer::register_rollup_upto_in_module(module); 42 | layer::register_imprecise_rollup_upto_in_module(module); 43 | layer::register_layer_addition_count_in_module(module); 44 | layer::register_layer_removal_count_in_module(module); 45 | layer::register_layer_total_addition_count_in_module(module); 46 | layer::register_layer_total_removal_count_in_module(module); 47 | layer::register_layer_total_triple_count_in_module(module); 48 | layer::register_retrieve_layer_stack_names_in_module(module); 49 | layer::register_layer_to_id_in_module(module); 50 | layer::register_store_id_layer_in_module(module); 51 | layer::register_layer_equals_in_module(module); 52 | store::register_pack_export_in_module(module); 53 | store::register_pack_layerids_and_parents_in_module(module); 54 | store::register_pack_import_in_module(module); 55 | layer::register_id_triple_in_module(module); 56 | layer::register_id_triple_addition_in_module(module); 57 | layer::register_id_triple_removal_in_module(module); 58 | layer::register_sp_card_in_module(module); 59 | } 60 | -------------------------------------------------------------------------------- /rust/terminus-store-prolog-core/src/named_graph.rs: -------------------------------------------------------------------------------- 1 | use crate::layer::*; 2 | use crate::store::*; 3 | use std::io::{self, Write}; 4 | use swipl::prelude::*; 5 | use terminus_store::store::sync::*; 6 | 7 | predicates! { 8 | pub semidet fn create_named_graph(context, store_term, graph_name_term, graph_term) { 9 | let store: WrappedStore = store_term.get_ex()?; 10 | let graph_name: PrologText = graph_name_term.get_ex()?; 11 | 12 | let graph = context.try_or_die(store.create(&graph_name))?; 13 | graph_term.unify(&WrappedNamedGraph(graph)) 14 | } 15 | 16 | pub semidet fn open_named_graph(context, store_term, graph_name_term, graph_term) { 17 | let store: WrappedStore = store_term.get_ex()?; 18 | let graph_name: PrologText = graph_name_term.get_ex()?; 19 | 20 | match context.try_or_die(store.open(&graph_name))? { 21 | None => Err(PrologError::Failure), 22 | Some(graph) => graph_term.unify(&WrappedNamedGraph(graph)), 23 | } 24 | } 25 | 26 | pub semidet fn delete_named_graph(context, store_term, graph_name_term) { 27 | let store: WrappedStore = store_term.get_ex()?; 28 | let graph_name: PrologText = graph_name_term.get_ex()?; 29 | 30 | into_prolog_result(context.try_or_die(store.delete(&graph_name))?) 31 | } 32 | 33 | #[name("head")] 34 | pub semidet fn head2(context, graph_term, layer_term) { 35 | let graph: WrappedNamedGraph = graph_term.get_ex()?; 36 | match context.try_or_die(graph.head())? { 37 | None => Err(PrologError::Failure), 38 | Some(layer) => layer_term.unify(&WrappedLayer(layer)), 39 | } 40 | } 41 | 42 | #[name("head")] 43 | pub semidet fn head3(context, graph_term, layer_term, version_term) { 44 | let graph: WrappedNamedGraph = graph_term.get_ex()?; 45 | let (layer_opt, version) = context.try_or_die(graph.head_version())?; 46 | version_term.unify(version)?; 47 | 48 | if let Some(layer) = layer_opt { 49 | layer_term.unify(&WrappedLayer(layer))?; 50 | } 51 | 52 | Ok(()) 53 | } 54 | 55 | pub semidet fn nb_set_head(context, graph_term, layer_term) { 56 | let graph: WrappedNamedGraph = graph_term.get_ex()?; 57 | let layer: WrappedLayer = layer_term.get_ex()?; 58 | 59 | into_prolog_result(context.try_or_die(graph.set_head(&layer))?) 60 | } 61 | 62 | pub semidet fn nb_force_set_head(context, graph_term, layer_term) { 63 | let graph: WrappedNamedGraph = graph_term.get_ex()?; 64 | let layer: WrappedLayer = layer_term.get_ex()?; 65 | 66 | context.try_or_die(graph.force_set_head(&layer))?; 67 | 68 | Ok(()) 69 | } 70 | 71 | #[name("nb_force_set_head")] 72 | pub semidet fn nb_force_set_head_version(context, graph_term, layer_term, version_term) { 73 | let graph: WrappedNamedGraph = graph_term.get_ex()?; 74 | let layer: WrappedLayer = layer_term.get_ex()?; 75 | 76 | let version: u64 = version_term.get_ex()?; 77 | 78 | let result = context.try_or_die(graph.force_set_head_version(&layer, version))?; 79 | 80 | into_prolog_result(result) 81 | } 82 | } 83 | 84 | wrapped_clone_blob!("named_graph", pub WrappedNamedGraph, SyncNamedGraph); 85 | 86 | impl CloneBlobImpl for WrappedNamedGraph { 87 | fn write(&self, stream: &mut PrologStream) -> io::Result<()> { 88 | write!(stream, "", self.name()) 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /rust/terminus-store-prolog-core/src/store.rs: -------------------------------------------------------------------------------- 1 | use crate::builder::*; 2 | use crate::layer::*; 3 | use crate::named_graph::*; 4 | use std::io::{self, Cursor}; 5 | use swipl::prelude::*; 6 | use terminus_store::storage::{name_to_string, pack_layer_parents, string_to_name, PackError}; 7 | use terminus_store::store::sync::*; 8 | 9 | predicates! { 10 | pub semidet fn open_memory_store(_context, term) { 11 | let store = open_sync_memory_store(); 12 | term.unify(&WrappedStore(store)) 13 | } 14 | 15 | pub semidet fn open_directory_store(_context, dir_term, out_term) { 16 | let dir: PrologText = dir_term.get_ex()?; 17 | let store = open_sync_directory_store(&*dir); 18 | out_term.unify(&WrappedStore(store)) 19 | } 20 | 21 | pub semidet fn open_write(context, store_or_graph_or_layer_term, builder_term) { 22 | let builder; 23 | if let Some(store) = attempt_opt(store_or_graph_or_layer_term.get::())? { 24 | builder = context.try_or_die(store.create_base_layer())?; 25 | } 26 | else if let Some(graph) = attempt_opt(store_or_graph_or_layer_term.get::())? { 27 | if let Some(layer) = context.try_or_die(graph.head())? { 28 | builder = context.try_or_die(layer.open_write())?; 29 | } 30 | else { 31 | return context.raise_exception(&term!{context: error(cannot_open_named_graph_without_base_layer, _)}?); 32 | } 33 | } 34 | else { 35 | let layer: WrappedLayer = store_or_graph_or_layer_term.get_ex()?; 36 | builder = context.try_or_die(layer.open_write())?; 37 | } 38 | 39 | builder_term.unify(WrappedBuilder(builder)) 40 | } 41 | 42 | pub semidet fn pack_export(context, store_term, layer_ids_term, pack_term) { 43 | let store: WrappedStore = store_term.get_ex()?; 44 | let layer_id_strings_list: Vec = layer_ids_term.get_ex()?; 45 | let mut layer_ids_list = Vec::with_capacity(layer_id_strings_list.len()); 46 | for layer_id_string in layer_id_strings_list { 47 | let layer_id = context.try_or_die(string_to_name(&layer_id_string))?; 48 | layer_ids_list.push(layer_id); 49 | } 50 | 51 | let result = context.try_or_die(store.export_layers( 52 | Box::new(layer_ids_list.into_iter())))?; 53 | 54 | pack_term.unify(result.as_slice()) 55 | } 56 | 57 | pub semidet fn pack_layerids_and_parents(context, pack_term, layer_parents_term) { 58 | let pack: Vec = pack_term.get_ex()?; 59 | let layer_parent_map = context.try_or_die(pack_layer_parents(Cursor::new(pack)) 60 | .map_err(|e| { 61 | // todo we're mapping to io error here for ease but should be something better 62 | match e { 63 | PackError::Io(e) => e, 64 | PackError::LayerNotFound => io::Error::new(io::ErrorKind::NotFound, "a layer from the pack was not found"), 65 | PackError::Utf8Error(e) => io::Error::new(io::ErrorKind::InvalidData, format!("{:?}", e)) 66 | } 67 | }))?; 68 | 69 | let pair_functor = Functor::new("-", 2); 70 | let none_atom = Atom::new("none"); 71 | let some_functor = Functor::new("some", 1); 72 | 73 | let mut result_terms = Vec::with_capacity(layer_parent_map.len()); 74 | for (layer, parent) in layer_parent_map { 75 | let term = context.new_term_ref(); 76 | term.unify(&pair_functor)?; 77 | term.unify_arg(1, &name_to_string(layer))?; 78 | match parent { 79 | Some(parent) => { 80 | let parent_term = context.new_term_ref(); 81 | parent_term.unify(some_functor)?; 82 | parent_term.unify_arg(1, &name_to_string(parent))?; 83 | term.unify_arg(2, &parent_term)?; 84 | }, 85 | None => { 86 | term.unify_arg(2, &none_atom)?; 87 | } 88 | } 89 | 90 | result_terms.push(term); 91 | } 92 | 93 | layer_parents_term.unify(result_terms.as_slice()) 94 | } 95 | 96 | pub semidet fn pack_import(context, store_term, layer_ids_term, pack_term) { 97 | let store: WrappedStore = store_term.get_ex()?; 98 | 99 | let layer_id_strings: Vec = layer_ids_term.get_ex()?; 100 | let mut layer_ids = Vec::with_capacity(layer_id_strings.len()); 101 | for layer_id_string in layer_id_strings { 102 | let name = context.try_or_die(string_to_name(&layer_id_string))?; 103 | layer_ids.push(name); 104 | } 105 | 106 | let pack: Vec = pack_term.get_ex()?; 107 | 108 | context.try_or_die(store.import_layers(pack.as_slice(), Box::new(layer_ids.into_iter()))) 109 | } 110 | } 111 | 112 | wrapped_clone_blob!("store", pub WrappedStore, SyncStore, defaults); 113 | -------------------------------------------------------------------------------- /rust/terminus-store-prolog-dylib/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "terminus-store-prolog-dylib" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | [lib] 8 | crate-type = ["cdylib"] 9 | 10 | [dependencies] 11 | terminus-store-prolog = {path = "../terminus-store-prolog-core"} -------------------------------------------------------------------------------- /rust/terminus-store-prolog-dylib/src/lib.rs: -------------------------------------------------------------------------------- 1 | use terminus_store_prolog; 2 | 3 | #[no_mangle] 4 | pub extern "C" fn install() { 5 | terminus_store_prolog::install(None); 6 | } 7 | -------------------------------------------------------------------------------- /script/swiarch.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env swipl 2 | 3 | %% 4 | %% Print the value of the SWIARCH environment variable. 5 | %% 6 | 7 | :- current_prolog_flag(arch, Arch), 8 | format(Arch), 9 | halt. 10 | -------------------------------------------------------------------------------- /script/swipl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | ## 4 | ## Run `swipl` and load the `terminus_store_prolog` library. 5 | ## 6 | ## - Arguments to this script are passed to `swipl`. 7 | ## - You should run `make` before this. 8 | ## 9 | 10 | # Exit the script on any error 11 | set -e 12 | 13 | # Absolute path of this script allowing it to be run from any directory 14 | SCRIPTDIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" &> /dev/null && pwd)" 15 | 16 | # Get the `swipl` command in $CMD 17 | source "$SCRIPTDIR/swipl-cmd.sh" 18 | 19 | # Run the `swipl` command 20 | "${CMD[@]}" 21 | -------------------------------------------------------------------------------- /script/swipl-cmd.sh: -------------------------------------------------------------------------------- 1 | # 1. Set $SCRIPTDIR. 2 | # 2. `source` this file. 3 | # 3. Use $CMD to run `swipl` with its arguments 4 | 5 | # Pack shared object directory used by `swipl`. 6 | PACKSODIR="lib/$($SCRIPTDIR/swiarch.pl)" 7 | 8 | # Top-level directory 9 | TOPDIR="$SCRIPTDIR/.." 10 | 11 | # Run `swipl`, disable autoloading (to report implicit imports), add the shared 12 | # library to the search path, and `consult/1` the Prolog. 13 | CMD=(swipl 14 | --on-error=status 15 | -g "set_prolog_flag(autoload, false)" 16 | -g "asserta(file_search_path(foreign,'$TOPDIR/$PACKSODIR'))" 17 | -g "['$TOPDIR/prolog/terminus_store.pl']" 18 | -g version 19 | "$@") 20 | 21 | # Note: The --on-error flag requires a SWI-Prolog version >= 8.4. 22 | 23 | # Use the above array by calling "${CMD[@]}". 24 | -------------------------------------------------------------------------------- /script/swipl_callgrind: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | ## 4 | ## Run `swipl` and load the `terminus_store_prolog` library using Valgrind with 5 | ## the Callgrind tool. 6 | ## 7 | ## - Arguments to this script are passed to `swipl`. 8 | ## - You should run `make` before this. 9 | ## 10 | 11 | # Exit the script on any error 12 | set -e 13 | 14 | # Absolute path of this script allowing it to be run from any directory 15 | SCRIPTDIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" &> /dev/null && pwd)" 16 | 17 | # Get the `swipl` command in $CMD 18 | source "$SCRIPTDIR/swipl-cmd.sh" 19 | 20 | # Run `valgrind` with the `callgrind` tool and the `swipl` command. Generate 21 | # assembly code annotation, including jumps. 22 | valgrind \ 23 | --tool=callgrind \ 24 | --dump-instr=yes \ 25 | --collect-jumps=yes \ 26 | "${CMD[@]}" 27 | -------------------------------------------------------------------------------- /script/swipl_gdb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | ## 4 | ## Run `swipl` and load the `terminus_store_prolog` library using GDB. 5 | ## 6 | ## - Arguments to this script are passed to `swipl`. 7 | ## - You should run `make` before this. 8 | ## 9 | 10 | # Exit the script on any error 11 | set -e 12 | 13 | # Absolute path of this script allowing it to be run from any directory 14 | SCRIPTDIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" &> /dev/null && pwd)" 15 | 16 | # Get the `swipl` command in $CMD 17 | source "$SCRIPTDIR/swipl-cmd.sh" 18 | 19 | # Run `gdb` with the `swipl` command 20 | gdb --args "${CMD[@]}" 21 | -------------------------------------------------------------------------------- /script/swipl_valgrind: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | ## 4 | ## Run `swipl` and load the `terminus_store_prolog` library using Valgrind. 5 | ## 6 | ## - Arguments to this script are passed to `swipl`. 7 | ## - You should run `make` before this. 8 | ## 9 | 10 | # Exit the script on any error 11 | set -e 12 | 13 | # Absolute path of this script allowing it to be run from any directory 14 | SCRIPTDIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" &> /dev/null && pwd)" 15 | 16 | # Get the `swipl` command in $CMD 17 | source "$SCRIPTDIR/swipl-cmd.sh" 18 | 19 | # Run `valgrind` the `swipl` command 20 | valgrind "${CMD[@]}" 21 | -------------------------------------------------------------------------------- /script/test: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | ## 4 | ## Run `swipl`, load the `terminus_store_prolog` library, and run the tests. 5 | ## 6 | ## - You should run `make` before this. 7 | ## 8 | 9 | # Exit the script on any error 10 | set -e 11 | 12 | # Absolute path of this script allowing it to be run from any directory. 13 | # 14 | # Use `cygpath` to get a path that `swipl` will recognize on MSYS (Windows). 15 | SCRIPTDIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" &> /dev/null && (cygpath --mixed "$(pwd)" 2> /dev/null || pwd))" 16 | 17 | # Get the `swipl` command in $CMD 18 | source "$SCRIPTDIR/swipl-cmd.sh" 19 | 20 | # Run the `swipl` command with tests 21 | "${CMD[@]}" -g terminus_store:run_tests -g halt 22 | --------------------------------------------------------------------------------