Compare commits
269 Commits
T1813-CL-r
...
project-go
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
662fd6cedc | ||
|
|
362dc95e27 | ||
|
|
eead24a562 | ||
|
|
d79dd69607 | ||
|
|
024bf0c578 | ||
|
|
d7443a5558 | ||
|
|
2df357b012 | ||
|
|
b2b5a6e2a0 | ||
|
|
5e2ee6c817 | ||
|
|
862a1afdf1 | ||
|
|
bbce21e78f | ||
|
|
15c8662023 | ||
|
|
beaba0fc16 | ||
|
|
8f70c5f2a5 | ||
|
|
14c651d3ba | ||
|
|
04efc7a4a6 | ||
|
|
19832b5838 | ||
|
|
e63fae2d5b | ||
|
|
34dd47ef07 | ||
|
|
d3f275b231 | ||
|
|
aad4bcb7a0 | ||
|
|
034b54cb72 | ||
|
|
8cf51d9f68 | ||
|
|
1cd1da84fd | ||
|
|
128a6cd522 | ||
|
|
d9eeedb9ee | ||
|
|
156e2cd095 | ||
|
|
8b834c702c | ||
|
|
eda5213d95 | ||
|
|
1f2a15e7c8 | ||
|
|
d72e7fa38d | ||
|
|
e5e37bc14a | ||
|
|
3ee068bbf9 | ||
|
|
68e846b182 | ||
|
|
310e305cfb | ||
|
|
9d6a23b6bd | ||
|
|
f2d5ab61c4 | ||
|
|
0f77c85824 | ||
|
|
d6d4153fb7 | ||
|
|
7d6a5e5b9c | ||
|
|
c529d52664 | ||
|
|
45451bae3b | ||
|
|
3e11f38548 | ||
|
|
6e4047a847 | ||
|
|
8febdc12fb | ||
|
|
3f23a10f44 | ||
|
|
11300960de | ||
|
|
1d5f387ddd | ||
|
|
c4c3a254bf | ||
|
|
b4beb0fc86 | ||
|
|
58e6097664 | ||
|
|
ff21c0705c | ||
|
|
2a2b99b02a | ||
|
|
3daab6ce97 | ||
|
|
fbd7274c95 | ||
|
|
6efc84f022 | ||
|
|
287c2e94d1 | ||
|
|
417cf4b30b | ||
|
|
68e7fd3d36 | ||
|
|
5261d82063 | ||
|
|
9eb87bcf3e | ||
|
|
a9491d3e68 | ||
|
|
b42e47b0be | ||
|
|
898c894a48 | ||
|
|
a3c2492672 | ||
|
|
a0b8871b36 | ||
|
|
bb6cf35441 | ||
|
|
5bc301d21d | ||
|
|
1b89e679df | ||
|
|
43e0520bc8 | ||
|
|
2c8e45e889 | ||
|
|
0876a8848d | ||
|
|
fb4641a6be | ||
|
|
201f75e809 | ||
|
|
dc8dad9794 | ||
|
|
aa02745915 | ||
|
|
b2d5a8eeca | ||
|
|
c09b175c76 | ||
|
|
f1fe77adfb | ||
|
|
35f8978560 | ||
|
|
9e8fb2516b | ||
|
|
0a66feccff | ||
|
|
d008a2ad8d | ||
|
|
7478300762 | ||
|
|
0bc298c3ad | ||
|
|
05f120b7d4 | ||
|
|
d73d153978 | ||
|
|
b489ac7cff | ||
|
|
e15576f56c | ||
|
|
a98463b0bd | ||
|
|
705631a35d | ||
|
|
d4f0bb0e38 | ||
|
|
531db2d47c | ||
|
|
116262d9a0 | ||
|
|
bbfef45b37 | ||
|
|
05b00edfd4 | ||
|
|
480df4ed69 | ||
|
|
80e0e439b7 | ||
|
|
351258ace8 | ||
|
|
74d3663821 | ||
|
|
eb0b3141d5 | ||
|
|
ff2f8031a9 | ||
|
|
094d4f282d | ||
|
|
3dd2657320 | ||
|
|
6fe474282a | ||
|
|
7fc0fb6520 | ||
|
|
063e297e1e | ||
|
|
86b1688192 | ||
|
|
f629de7e60 | ||
|
|
b737e53456 | ||
|
|
10ca68bb2a | ||
|
|
bfbd8538d4 | ||
|
|
3e0e17d469 | ||
|
|
b57f91fcfc | ||
|
|
066a96c0ae | ||
|
|
1ae6b71c5f | ||
|
|
cbe15e7f44 | ||
|
|
65a7ba01da | ||
|
|
7a2bbd4bb3 | ||
|
|
589e0e098b | ||
|
|
41d4185156 | ||
|
|
599c0a641f | ||
|
|
1fb49c4865 | ||
|
|
df1485aeec | ||
|
|
b2e1056389 | ||
|
|
e4c9411e63 | ||
|
|
a0bc1371dd | ||
|
|
21ad5d4328 | ||
|
|
8e3ab1ad0f | ||
|
|
cccf32e79d | ||
|
|
22bd60c613 | ||
|
|
8059a3e653 | ||
|
|
a7f4c98bea | ||
|
|
483f4d04bd | ||
|
|
3e7aef432f | ||
|
|
10ea9c773e | ||
|
|
b782271be8 | ||
|
|
a8ffcfa046 | ||
|
|
7b78665cd8 | ||
|
|
4abaf27765 | ||
|
|
ea2806bd57 | ||
|
|
c8dbaf5979 | ||
|
|
17049ada09 | ||
|
|
1b619f51b2 | ||
|
|
537855a0b2 | ||
|
|
5822b44b15 | ||
|
|
bf01c58ed9 | ||
|
|
89a5566f3f | ||
|
|
29452f8774 | ||
|
|
60ad05acff | ||
|
|
4f593c7fca | ||
|
|
770ea1189a | ||
|
|
695bb343f1 | ||
|
|
12b4ec1589 | ||
|
|
b33d2c3940 | ||
|
|
477acad1f6 | ||
|
|
ddca2b40f5 | ||
|
|
4817be0add | ||
|
|
3fb7e5378d | ||
|
|
1d88893715 | ||
|
|
bd2c30fddc | ||
|
|
06e6ead4d2 | ||
|
|
728b37080d | ||
|
|
48a531aac1 | ||
|
|
914fc1a656 | ||
|
|
1d1c182c2d | ||
|
|
c6e19ec09f | ||
|
|
693dab78d2 | ||
|
|
69eca9b043 | ||
|
|
5aeaad198b | ||
|
|
b23f88c607 | ||
|
|
4fd8bdce4c | ||
|
|
265b203b00 | ||
|
|
661e5185d8 | ||
|
|
7348ad6800 | ||
|
|
6c00d146f2 | ||
|
|
ced84e17b6 | ||
|
|
834ce5f51a | ||
|
|
bb1308acc7 | ||
|
|
e1f31d3d02 | ||
|
|
339cd9b84e | ||
|
|
7deac4ac8b | ||
|
|
fec887a67c | ||
|
|
f3a3a4ed87 | ||
|
|
ec65187442 | ||
|
|
079c0495c3 | ||
|
|
90cfed2ada | ||
|
|
8716b8e992 | ||
|
|
a277541354 | ||
|
|
b01564f179 | ||
|
|
d9bb4e2e46 | ||
|
|
05d0aee494 | ||
|
|
aabec99a8e | ||
|
|
d277dd49a3 | ||
|
|
18f9d19b18 | ||
|
|
530eed5c6d | ||
|
|
12f4e0068a | ||
|
|
e8976e0f1c | ||
|
|
6eb52581eb | ||
|
|
8606e69fd6 | ||
|
|
c7b045bffc | ||
|
|
b66cc66503 | ||
|
|
0e4719018a | ||
|
|
0ebd52aac3 | ||
|
|
6c971b856e | ||
|
|
6cb293688d | ||
|
|
16709dff6c | ||
|
|
95dd3481c0 | ||
|
|
47c0c629c7 | ||
|
|
636c551047 | ||
|
|
72384b2b71 | ||
|
|
a9b1ff9bea | ||
|
|
e40bc32624 | ||
|
|
bd21bc82b7 | ||
|
|
9c1680e82c | ||
|
|
1a78c3695d | ||
|
|
10196f3d7d | ||
|
|
2c86fefbb5 | ||
|
|
df689dccd5 | ||
|
|
6033fbe9bd | ||
|
|
519a204424 | ||
|
|
3fc5e57fef | ||
|
|
906933d2b3 | ||
|
|
e9a937ad6d | ||
|
|
6dc2cdfae4 | ||
|
|
69ea410406 | ||
|
|
24a576c8e9 | ||
|
|
d417ffee6e | ||
|
|
f868b51483 | ||
|
|
26dc73c809 | ||
|
|
9119c89eba | ||
|
|
4e7ea34ae9 | ||
|
|
d7d291217b | ||
|
|
42facfacbc | ||
|
|
bd1e848363 | ||
|
|
0ffb58b764 | ||
|
|
9551b6973a | ||
|
|
f7ef5f50a4 | ||
|
|
046cd80054 | ||
|
|
9e678f8cbe | ||
|
|
69e4f1784b | ||
|
|
d04e23805d | ||
|
|
7e82cc6550 | ||
|
|
18b801a722 | ||
|
|
7e81a95b81 | ||
|
|
0a23eb11ae | ||
|
|
8ea281649a | ||
|
|
da68f86fc9 | ||
|
|
738b5fb8d8 | ||
|
|
b45ae403e6 | ||
|
|
d744711e5e | ||
|
|
8d87e38c64 | ||
|
|
086fc47769 | ||
|
|
5abcb5081d | ||
|
|
9534dfb6ed | ||
|
|
e2112faff0 | ||
|
|
6913feacc7 | ||
|
|
4e604de9d7 | ||
|
|
e628b5ba6e | ||
|
|
5da32c1bff | ||
|
|
ccca46370d | ||
|
|
e33fa5f9c0 | ||
|
|
721eefe263 | ||
|
|
be9ed7e879 | ||
|
|
482798295e | ||
|
|
d58a1cbb58 | ||
|
|
8dc3153fde | ||
|
|
b94e50bf1c | ||
|
|
9f855676cb |
@@ -1,6 +1,9 @@
|
||||
---
|
||||
Checks: '*,
|
||||
-abseil-string-find-str-contains,
|
||||
-altera-id-dependent-backward-branch,
|
||||
-altera-struct-pack-align,
|
||||
-altera-unroll-loops,
|
||||
-android-*,
|
||||
-cert-err58-cpp,
|
||||
-cppcoreguidelines-avoid-c-arrays,
|
||||
@@ -57,7 +60,10 @@ Checks: '*,
|
||||
-readability-implicit-bool-conversion,
|
||||
-readability-magic-numbers,
|
||||
-readability-named-parameter,
|
||||
-misc-no-recursion'
|
||||
-misc-no-recursion,
|
||||
-concurrency-mt-unsafe,
|
||||
-bugprone-easily-swappable-parameters'
|
||||
|
||||
WarningsAsErrors: ''
|
||||
HeaderFilterRegex: 'src/.*'
|
||||
AnalyzeTemporaryDtors: false
|
||||
@@ -84,4 +90,3 @@ CheckOptions:
|
||||
- key: modernize-use-nullptr.NullMacros
|
||||
value: 'NULL'
|
||||
...
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@ tmpdir=$(mktemp -d repo-XXXXXXXX)
|
||||
trap "rm -rf $tmpdir" EXIT INT
|
||||
|
||||
modified_files=$(git diff --cached --name-only --diff-filter=AM $against | sed -nE "/.*\.(cpp|cc|cxx|c|h|hpp)$/p")
|
||||
FAIL=0
|
||||
for file in $modified_files; do
|
||||
echo "Checking $file..."
|
||||
|
||||
@@ -23,13 +24,13 @@ for file in $modified_files; do
|
||||
|
||||
git checkout-index --prefix="$tmpdir/" -- $file
|
||||
|
||||
echo "Running clang-format..."
|
||||
$project_folder/tools/git-clang-format $tmpdir/$file
|
||||
code=$?
|
||||
|
||||
if [ $code -ne 0 ]; then
|
||||
break
|
||||
# Do not break header checker
|
||||
echo "Running header checker..."
|
||||
$project_folder/tools/header-checker.py $tmpdir/$file $file --amend-year
|
||||
CODE=$?
|
||||
if [ $CODE -ne 0 ]; then
|
||||
FAIL=1
|
||||
fi
|
||||
done;
|
||||
|
||||
return $code
|
||||
return ${FAIL}
|
||||
|
||||
34
.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
34
.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
@@ -0,0 +1,34 @@
|
||||
---
|
||||
name: Bug report
|
||||
about: Create a report to help us improve
|
||||
title: "[BUG] "
|
||||
labels: bug
|
||||
assignees: gitbuda, antonio2368
|
||||
|
||||
---
|
||||
|
||||
|
||||
**Memgraph version**
|
||||
Which version did you use?
|
||||
|
||||
**Environment**
|
||||
Some information about the environment you are using Memgraph on: operating
|
||||
system, how do you connect, with or without docker, which driver etc.
|
||||
|
||||
**Describe the bug**
|
||||
A clear and concise description of what the bug is.
|
||||
|
||||
**To Reproduce**
|
||||
Steps to reproduce the behavior:
|
||||
1. Run the following query '...'
|
||||
2. Click on '....'
|
||||
|
||||
**Expected behavior**
|
||||
A clear and concise description of what you expected to happen.
|
||||
|
||||
**Logs**
|
||||
If applicable, add logs of Memgraph, CLI output or screenshots to help explain
|
||||
your problem.
|
||||
|
||||
**Additional context**
|
||||
Add any other context about the problem here.
|
||||
9
.github/pull_request_template.md
vendored
9
.github/pull_request_template.md
vendored
@@ -1,9 +1,14 @@
|
||||
[master < Epic] PR
|
||||
- [ ] Check, and update documentation if necessary
|
||||
- [ ] Update [changelog](https://docs.memgraph.com/memgraph/changelog)
|
||||
- [ ] Write E2E tests
|
||||
- [ ] Compare the [benchmarking results](https://bench-graph.memgraph.com/) between the master branch and the Epic branch
|
||||
- [ ] Provide the full content or a guide for the final git message
|
||||
|
||||
[master < Task] PR
|
||||
- [ ] Check, and update documentation if necessary
|
||||
- [ ] Update [changelog](https://docs.memgraph.com/memgraph/changelog)
|
||||
- [ ] Provide the full content or a guide for the final git message
|
||||
|
||||
|
||||
To keep docs changelog up to date, one more thing to do:
|
||||
- [ ] Write a release note here
|
||||
- [ ] Tag someone from docs team in the comments
|
||||
|
||||
@@ -3,7 +3,7 @@ name: Daily Benchmark
|
||||
on:
|
||||
workflow_dispatch:
|
||||
schedule:
|
||||
- cron: "0 1 * * *"
|
||||
- cron: "0 22 * * *"
|
||||
|
||||
jobs:
|
||||
release_benchmarks:
|
||||
@@ -11,10 +11,12 @@ jobs:
|
||||
runs-on: [self-hosted, Linux, X64, Diff, Gen7]
|
||||
env:
|
||||
THREADS: 24
|
||||
MEMGRAPH_ENTERPRISE_LICENSE: ${{ secrets.MEMGRAPH_ENTERPRISE_LICENSE }}
|
||||
MEMGRAPH_ORGANIZATION_NAME: ${{ secrets.MEMGRAPH_ORGANIZATION_NAME }}
|
||||
|
||||
steps:
|
||||
- name: Set up repository
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
# Number of commits to fetch. `0` indicates all history for all
|
||||
# branches and tags. (default: 1)
|
||||
@@ -23,7 +25,7 @@ jobs:
|
||||
- name: Build release binaries
|
||||
run: |
|
||||
# Activate toolchain.
|
||||
source /opt/toolchain-v3/activate
|
||||
source /opt/toolchain-v4/activate
|
||||
|
||||
# Initialize dependencies.
|
||||
./init
|
||||
@@ -40,6 +42,16 @@ jobs:
|
||||
--groups aggregation 1000_create unwind_create dense_expand match \
|
||||
--no-strict
|
||||
|
||||
- name: Get branch name (merge)
|
||||
if: github.event_name != 'pull_request'
|
||||
shell: bash
|
||||
run: echo "BRANCH_NAME=$(echo ${GITHUB_REF#refs/heads/} | tr / -)" >> $GITHUB_ENV
|
||||
|
||||
- name: Get branch name (pull request)
|
||||
if: github.event_name == 'pull_request'
|
||||
shell: bash
|
||||
run: echo "BRANCH_NAME=$(echo ${GITHUB_HEAD_REF} | tr / -)" >> $GITHUB_ENV
|
||||
|
||||
- name: Upload macro benchmark results
|
||||
run: |
|
||||
cd tools/bench-graph-client
|
||||
@@ -49,7 +61,8 @@ jobs:
|
||||
./main.py --benchmark-name "macro_benchmark" \
|
||||
--benchmark-results-path "../../tests/macro_benchmark/.harness_summary" \
|
||||
--github-run-id "${{ github.run_id }}" \
|
||||
--github-run-number "${{ github.run_number }}"
|
||||
--github-run-number "${{ github.run_number }}" \
|
||||
--head-branch-name "${{ env.BRANCH_NAME }}"
|
||||
|
||||
- name: Run mgbench
|
||||
run: |
|
||||
@@ -65,4 +78,5 @@ jobs:
|
||||
./main.py --benchmark-name "mgbench" \
|
||||
--benchmark-results-path "../../tests/mgbench/benchmark_result.json" \
|
||||
--github-run-id "${{ github.run_id }}" \
|
||||
--github-run-number "${{ github.run_number }}"
|
||||
--github-run-number "${{ github.run_number }}" \
|
||||
--head-branch-name "${{ env.BRANCH_NAME }}"
|
||||
164
.github/workflows/diff.yaml
vendored
164
.github/workflows/diff.yaml
vendored
@@ -1,12 +1,20 @@
|
||||
name: Diff
|
||||
concurrency:
|
||||
group: ${{ github.head_ref || github.sha }}
|
||||
cancel-in-progress: true
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
workflow_dispatch:
|
||||
pull_request:
|
||||
paths-ignore:
|
||||
- 'docs/**'
|
||||
- '**/*.md'
|
||||
- '.clang-format'
|
||||
- 'CODEOWNERS'
|
||||
- "docs/**"
|
||||
- "**/*.md"
|
||||
- ".clang-format"
|
||||
- "CODEOWNERS"
|
||||
- "licenses/*"
|
||||
|
||||
jobs:
|
||||
community_build:
|
||||
@@ -14,10 +22,12 @@ jobs:
|
||||
runs-on: [self-hosted, Linux, X64, Diff]
|
||||
env:
|
||||
THREADS: 24
|
||||
MEMGRAPH_ENTERPRISE_LICENSE: ${{ secrets.MEMGRAPH_ENTERPRISE_LICENSE }}
|
||||
MEMGRAPH_ORGANIZATION_NAME: ${{ secrets.MEMGRAPH_ORGANIZATION_NAME }}
|
||||
|
||||
steps:
|
||||
- name: Set up repository
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
# Number of commits to fetch. `0` indicates all history for all
|
||||
# branches and tags. (default: 1)
|
||||
@@ -26,7 +36,7 @@ jobs:
|
||||
- name: Build community binaries
|
||||
run: |
|
||||
# Activate toolchain.
|
||||
source /opt/toolchain-v3/activate
|
||||
source /opt/toolchain-v4/activate
|
||||
|
||||
# Initialize dependencies.
|
||||
./init
|
||||
@@ -39,60 +49,67 @@ jobs:
|
||||
- name: Run unit tests
|
||||
run: |
|
||||
# Activate toolchain.
|
||||
source /opt/toolchain-v3/activate
|
||||
source /opt/toolchain-v4/activate
|
||||
|
||||
# Run unit tests.
|
||||
cd build
|
||||
ctest -R memgraph__unit --output-on-failure -j$THREADS
|
||||
|
||||
- name: Run stress test
|
||||
run: |
|
||||
cd tests/stress
|
||||
./continuous_integration
|
||||
|
||||
- name: Create community DEB package
|
||||
run: |
|
||||
# Activate toolchain.
|
||||
source /opt/toolchain-v3/activate
|
||||
|
||||
cd build
|
||||
|
||||
# create mgconsole
|
||||
# we use the -B to force the build
|
||||
make -j$THREADS -B mgconsole
|
||||
|
||||
# Create community DEB package.
|
||||
mkdir output && cd output
|
||||
cpack -G DEB --config ../CPackConfig.cmake
|
||||
|
||||
- name: Save community DEB package
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: "Community DEB package"
|
||||
path: build/output/memgraph*.deb
|
||||
|
||||
code_analysis:
|
||||
name: "Code analysis"
|
||||
runs-on: [self-hosted, Linux, X64, Diff]
|
||||
env:
|
||||
THREADS: 24
|
||||
MEMGRAPH_ENTERPRISE_LICENSE: ${{ secrets.MEMGRAPH_ENTERPRISE_LICENSE }}
|
||||
MEMGRAPH_ORGANIZATION_NAME: ${{ secrets.MEMGRAPH_ORGANIZATION_NAME }}
|
||||
|
||||
steps:
|
||||
- name: Set up repository
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
# Number of commits to fetch. `0` indicates all history for all
|
||||
# branches and tags. (default: 1)
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Build combined ASAN, UBSAN and coverage binaries
|
||||
# This is also needed if we want do to comparison against other branches
|
||||
# See https://github.community/t/checkout-code-fails-when-it-runs-lerna-run-test-since-master/17920
|
||||
- name: Fetch all history for all tags and branches
|
||||
run: git fetch
|
||||
|
||||
- name: Initialize deps
|
||||
run: |
|
||||
# Activate toolchain.
|
||||
source /opt/toolchain-v3/activate
|
||||
source /opt/toolchain-v4/activate
|
||||
|
||||
# Initialize dependencies.
|
||||
./init
|
||||
|
||||
- name: Set base branch
|
||||
if: ${{ github.event_name == 'pull_request' }}
|
||||
run: |
|
||||
echo "BASE_BRANCH=origin/${{ github.base_ref }}" >> $GITHUB_ENV
|
||||
|
||||
- name: Set base branch # if we manually dispatch or push to master
|
||||
if: ${{ github.event_name != 'pull_request' }}
|
||||
run: |
|
||||
echo "BASE_BRANCH=origin/master" >> $GITHUB_ENV
|
||||
|
||||
- name: Python code analysis
|
||||
run: |
|
||||
CHANGED_FILES=$(git diff -U0 ${{ env.BASE_BRANCH }}... --name-only)
|
||||
for file in ${CHANGED_FILES}; do
|
||||
echo ${file}
|
||||
if [[ ${file} == *.py ]]; then
|
||||
python3 -m black --check --diff ${file}
|
||||
python3 -m isort --check-only --diff ${file}
|
||||
fi
|
||||
done
|
||||
|
||||
- name: Build combined ASAN, UBSAN and coverage binaries
|
||||
run: |
|
||||
# Activate toolchain.
|
||||
source /opt/toolchain-v4/activate
|
||||
|
||||
cd build
|
||||
cmake -DTEST_COVERAGE=ON -DASAN=ON -DUBSAN=ON ..
|
||||
make -j$THREADS memgraph__unit
|
||||
@@ -100,7 +117,7 @@ jobs:
|
||||
- name: Run unit tests
|
||||
run: |
|
||||
# Activate toolchain.
|
||||
source /opt/toolchain-v3/activate
|
||||
source /opt/toolchain-v4/activate
|
||||
|
||||
# Run unit tests. It is restricted to 2 threads intentionally, because higher concurrency makes the timing related tests unstable.
|
||||
cd build
|
||||
@@ -109,7 +126,7 @@ jobs:
|
||||
- name: Compute code coverage
|
||||
run: |
|
||||
# Activate toolchain.
|
||||
source /opt/toolchain-v3/activate
|
||||
source /opt/toolchain-v4/activate
|
||||
|
||||
# Compute code coverage.
|
||||
cd tools/github
|
||||
@@ -120,17 +137,17 @@ jobs:
|
||||
tar -czf code_coverage.tar.gz coverage.json html report.json summary.rmu
|
||||
|
||||
- name: Save code coverage
|
||||
uses: actions/upload-artifact@v2
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: "Code coverage"
|
||||
path: tools/github/generated/code_coverage.tar.gz
|
||||
|
||||
- name: Run clang-tidy
|
||||
run: |
|
||||
source /opt/toolchain-v3/activate
|
||||
source /opt/toolchain-v4/activate
|
||||
|
||||
# Restrict clang-tidy results only to the modified parts
|
||||
git diff -U0 master... -- src ':!*.hpp' | ./tools/github/clang-tidy/clang-tidy-diff.py -p 1 -j $THREADS -path build | tee ./build/clang_tidy_output.txt
|
||||
git diff -U0 ${{ env.BASE_BRANCH }}... -- src | ./tools/github/clang-tidy/clang-tidy-diff.py -p 1 -j $THREADS -path build -regex ".+\.cpp" | tee ./build/clang_tidy_output.txt
|
||||
|
||||
# Fail if any warning is reported
|
||||
! cat ./build/clang_tidy_output.txt | ./tools/github/clang-tidy/grep_error_lines.sh > /dev/null
|
||||
@@ -140,10 +157,12 @@ jobs:
|
||||
runs-on: [self-hosted, Linux, X64, Diff]
|
||||
env:
|
||||
THREADS: 24
|
||||
MEMGRAPH_ENTERPRISE_LICENSE: ${{ secrets.MEMGRAPH_ENTERPRISE_LICENSE }}
|
||||
MEMGRAPH_ORGANIZATION_NAME: ${{ secrets.MEMGRAPH_ORGANIZATION_NAME }}
|
||||
|
||||
steps:
|
||||
- name: Set up repository
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
# Number of commits to fetch. `0` indicates all history for all
|
||||
# branches and tags. (default: 1)
|
||||
@@ -152,7 +171,7 @@ jobs:
|
||||
- name: Build debug binaries
|
||||
run: |
|
||||
# Activate toolchain.
|
||||
source /opt/toolchain-v3/activate
|
||||
source /opt/toolchain-v4/activate
|
||||
|
||||
# Initialize dependencies.
|
||||
./init
|
||||
@@ -165,7 +184,7 @@ jobs:
|
||||
- name: Run leftover CTest tests
|
||||
run: |
|
||||
# Activate toolchain.
|
||||
source /opt/toolchain-v3/activate
|
||||
source /opt/toolchain-v4/activate
|
||||
|
||||
# Run leftover CTest tests (all except unit and benchmark tests).
|
||||
cd build
|
||||
@@ -197,14 +216,14 @@ jobs:
|
||||
- name: Run cppcheck and clang-format
|
||||
run: |
|
||||
# Activate toolchain.
|
||||
source /opt/toolchain-v3/activate
|
||||
source /opt/toolchain-v4/activate
|
||||
|
||||
# Run cppcheck and clang-format.
|
||||
cd tools/github
|
||||
./cppcheck_and_clang_format diff
|
||||
|
||||
- name: Save cppcheck and clang-format errors
|
||||
uses: actions/upload-artifact@v2
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: "Code coverage"
|
||||
path: tools/github/cppcheck_and_clang_format.txt
|
||||
@@ -214,10 +233,12 @@ jobs:
|
||||
runs-on: [self-hosted, Linux, X64, Diff]
|
||||
env:
|
||||
THREADS: 24
|
||||
MEMGRAPH_ENTERPRISE_LICENSE: ${{ secrets.MEMGRAPH_ENTERPRISE_LICENSE }}
|
||||
MEMGRAPH_ORGANIZATION_NAME: ${{ secrets.MEMGRAPH_ORGANIZATION_NAME }}
|
||||
|
||||
steps:
|
||||
- name: Set up repository
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
# Number of commits to fetch. `0` indicates all history for all
|
||||
# branches and tags. (default: 1)
|
||||
@@ -226,7 +247,7 @@ jobs:
|
||||
- name: Build release binaries
|
||||
run: |
|
||||
# Activate toolchain.
|
||||
source /opt/toolchain-v3/activate
|
||||
source /opt/toolchain-v4/activate
|
||||
|
||||
# Initialize dependencies.
|
||||
./init
|
||||
@@ -242,13 +263,22 @@ jobs:
|
||||
./continuous_integration
|
||||
|
||||
- name: Save quality assurance status
|
||||
uses: actions/upload-artifact@v2
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: "GQL Behave Status"
|
||||
path: |
|
||||
tests/gql_behave/gql_behave_status.csv
|
||||
tests/gql_behave/gql_behave_status.html
|
||||
|
||||
- name: Run unit tests
|
||||
run: |
|
||||
# Activate toolchain.
|
||||
source /opt/toolchain-v4/activate
|
||||
|
||||
# Run unit tests.
|
||||
cd build
|
||||
ctest -R memgraph__unit --output-on-failure -j$THREADS
|
||||
|
||||
- name: Run e2e tests
|
||||
run: |
|
||||
# TODO(gitbuda): Setup mgclient and pymgclient properly.
|
||||
@@ -277,7 +307,7 @@ jobs:
|
||||
- name: Create enterprise DEB package
|
||||
run: |
|
||||
# Activate toolchain.
|
||||
source /opt/toolchain-v3/activate
|
||||
source /opt/toolchain-v4/activate
|
||||
|
||||
cd build
|
||||
|
||||
@@ -290,13 +320,13 @@ jobs:
|
||||
cpack -G DEB --config ../CPackConfig.cmake
|
||||
|
||||
- name: Save enterprise DEB package
|
||||
uses: actions/upload-artifact@v2
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: "Enterprise DEB package"
|
||||
path: build/output/memgraph*.deb
|
||||
|
||||
- name: Save test data
|
||||
uses: actions/upload-artifact@v2
|
||||
uses: actions/upload-artifact@v3
|
||||
if: always()
|
||||
with:
|
||||
name: "Test data"
|
||||
@@ -310,10 +340,12 @@ jobs:
|
||||
#continue-on-error: true
|
||||
env:
|
||||
THREADS: 24
|
||||
MEMGRAPH_ENTERPRISE_LICENSE: ${{ secrets.MEMGRAPH_ENTERPRISE_LICENSE }}
|
||||
MEMGRAPH_ORGANIZATION_NAME: ${{ secrets.MEMGRAPH_ORGANIZATION_NAME }}
|
||||
|
||||
steps:
|
||||
- name: Set up repository
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
# Number of commits to fetch. `0` indicates all history for all
|
||||
# branches and tags. (default: 1)
|
||||
@@ -322,7 +354,7 @@ jobs:
|
||||
- name: Build release binaries
|
||||
run: |
|
||||
# Activate toolchain.
|
||||
source /opt/toolchain-v3/activate
|
||||
source /opt/toolchain-v4/activate
|
||||
|
||||
# Initialize dependencies.
|
||||
./init
|
||||
@@ -338,7 +370,7 @@ jobs:
|
||||
./run.sh test --binary ../../build/memgraph --run-args "test-all --node-configs resources/node-config.edn" --ignore-run-stdout-logs --ignore-run-stderr-logs
|
||||
|
||||
- name: Save Jepsen report
|
||||
uses: actions/upload-artifact@v2
|
||||
uses: actions/upload-artifact@v3
|
||||
if: ${{ always() }}
|
||||
with:
|
||||
name: "Jepsen Report"
|
||||
@@ -349,10 +381,12 @@ jobs:
|
||||
runs-on: [self-hosted, Linux, X64, Diff, Gen7]
|
||||
env:
|
||||
THREADS: 24
|
||||
MEMGRAPH_ENTERPRISE_LICENSE: ${{ secrets.MEMGRAPH_ENTERPRISE_LICENSE }}
|
||||
MEMGRAPH_ORGANIZATION_NAME: ${{ secrets.MEMGRAPH_ORGANIZATION_NAME }}
|
||||
|
||||
steps:
|
||||
- name: Set up repository
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
# Number of commits to fetch. `0` indicates all history for all
|
||||
# branches and tags. (default: 1)
|
||||
@@ -361,7 +395,7 @@ jobs:
|
||||
- name: Build release binaries
|
||||
run: |
|
||||
# Activate toolchain.
|
||||
source /opt/toolchain-v3/activate
|
||||
source /opt/toolchain-v4/activate
|
||||
|
||||
# Initialize dependencies.
|
||||
./init
|
||||
@@ -378,6 +412,16 @@ jobs:
|
||||
--groups aggregation 1000_create unwind_create dense_expand match \
|
||||
--no-strict
|
||||
|
||||
- name: Get branch name (merge)
|
||||
if: github.event_name != 'pull_request'
|
||||
shell: bash
|
||||
run: echo "BRANCH_NAME=$(echo ${GITHUB_REF#refs/heads/} | tr / -)" >> $GITHUB_ENV
|
||||
|
||||
- name: Get branch name (pull request)
|
||||
if: github.event_name == 'pull_request'
|
||||
shell: bash
|
||||
run: echo "BRANCH_NAME=$(echo ${GITHUB_HEAD_REF} | tr / -)" >> $GITHUB_ENV
|
||||
|
||||
- name: Upload macro benchmark results
|
||||
run: |
|
||||
cd tools/bench-graph-client
|
||||
@@ -387,7 +431,8 @@ jobs:
|
||||
./main.py --benchmark-name "macro_benchmark" \
|
||||
--benchmark-results-path "../../tests/macro_benchmark/.harness_summary" \
|
||||
--github-run-id "${{ github.run_id }}" \
|
||||
--github-run-number "${{ github.run_number }}"
|
||||
--github-run-number "${{ github.run_number }}" \
|
||||
--head-branch-name "${{ env.BRANCH_NAME }}"
|
||||
|
||||
- name: Run mgbench
|
||||
run: |
|
||||
@@ -403,4 +448,5 @@ jobs:
|
||||
./main.py --benchmark-name "mgbench" \
|
||||
--benchmark-results-path "../../tests/mgbench/benchmark_result.json" \
|
||||
--github-run-id "${{ github.run_id }}" \
|
||||
--github-run-number "${{ github.run_number }}"
|
||||
--github-run-number "${{ github.run_number }}" \
|
||||
--head-branch-name "${{ env.BRANCH_NAME }}"
|
||||
|
||||
10
.github/workflows/full_clang_tidy.yaml
vendored
10
.github/workflows/full_clang_tidy.yaml
vendored
@@ -9,10 +9,12 @@ jobs:
|
||||
runs-on: [self-hosted, Linux, X64, Ubuntu20.04]
|
||||
env:
|
||||
THREADS: 24
|
||||
MEMGRAPH_ENTERPRISE_LICENSE: ${{ secrets.MEMGRAPH_ENTERPRISE_LICENSE }}
|
||||
MEMGRAPH_ORGANIZATION_NAME: ${{ secrets.MEMGRAPH_ORGANIZATION_NAME }}
|
||||
|
||||
steps:
|
||||
- name: Set up repository
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
# Number of commits to fetch. `0` indicates all history for all
|
||||
# branches and tags. (default: 1)
|
||||
@@ -21,7 +23,7 @@ jobs:
|
||||
- name: Build debug binaries
|
||||
run: |
|
||||
# Activate toolchain.
|
||||
source /opt/toolchain-v3/activate
|
||||
source /opt/toolchain-v4/activate
|
||||
|
||||
# Initialize dependencies.
|
||||
./init
|
||||
@@ -34,10 +36,10 @@ jobs:
|
||||
|
||||
- name: Run clang-tidy
|
||||
run: |
|
||||
source /opt/toolchain-v3/activate
|
||||
source /opt/toolchain-v4/activate
|
||||
|
||||
# The results are also written to standard output in order to retain them in the logs
|
||||
./tools/github/clang-tidy/run-clang-tidy.py -p build -j $THREADS -clang-tidy-binary=/opt/toolchain-v3/bin/clang-tidy "$PWD/src/*" |
|
||||
./tools/github/clang-tidy/run-clang-tidy.py -p build -j $THREADS -clang-tidy-binary=/opt/toolchain-v4/bin/clang-tidy "$PWD/src/*" |
|
||||
tee ./build/full_clang_tidy_output.txt
|
||||
|
||||
- name: Summarize clang-tidy results
|
||||
|
||||
214
.github/workflows/package_all.yaml
vendored
214
.github/workflows/package_all.yaml
vendored
@@ -5,244 +5,208 @@ name: Package All
|
||||
on: workflow_dispatch
|
||||
|
||||
jobs:
|
||||
centos-7_community:
|
||||
runs-on: [self-hosted, DockerMgBuild]
|
||||
centos-7:
|
||||
runs-on: [self-hosted, DockerMgBuild, X64]
|
||||
timeout-minutes: 60
|
||||
steps:
|
||||
- name: "Set up repository"
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0 # Required because of release/get_version.py
|
||||
- name: "Build package"
|
||||
run: |
|
||||
./release/package/run.sh package community centos-7
|
||||
./release/package/run.sh package centos-7
|
||||
- name: "Upload package"
|
||||
uses: actions/upload-artifact@v2
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: centos-7_community
|
||||
name: centos-7
|
||||
path: build/output/centos-7/memgraph*.rpm
|
||||
|
||||
centos-8_community:
|
||||
runs-on: [self-hosted, DockerMgBuild]
|
||||
centos-9:
|
||||
runs-on: [self-hosted, DockerMgBuild, X64]
|
||||
timeout-minutes: 60
|
||||
steps:
|
||||
- name: "Set up repository"
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0 # Required because of release/get_version.py
|
||||
- name: "Build package"
|
||||
run: |
|
||||
./release/package/run.sh package community centos-8
|
||||
./release/package/run.sh package centos-9
|
||||
- name: "Upload package"
|
||||
uses: actions/upload-artifact@v2
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: centos-8_community
|
||||
path: build/output/centos-8/memgraph*.rpm
|
||||
name: centos-9
|
||||
path: build/output/centos-9/memgraph*.rpm
|
||||
|
||||
debian-9_community:
|
||||
runs-on: [self-hosted, DockerMgBuild]
|
||||
debian-10:
|
||||
runs-on: [self-hosted, DockerMgBuild, X64]
|
||||
timeout-minutes: 60
|
||||
steps:
|
||||
- name: "Set up repository"
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0 # Required because of release/get_version.py
|
||||
- name: "Build package"
|
||||
run: |
|
||||
./release/package/run.sh package community debian-9
|
||||
./release/package/run.sh package debian-10
|
||||
- name: "Upload package"
|
||||
uses: actions/upload-artifact@v2
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: debian-9_community
|
||||
path: build/output/debian-9/memgraph*.deb
|
||||
|
||||
debian-10_community:
|
||||
runs-on: [self-hosted, DockerMgBuild]
|
||||
timeout-minutes: 60
|
||||
steps:
|
||||
- name: "Set up repository"
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
fetch-depth: 0 # Required because of release/get_version.py
|
||||
- name: "Build package"
|
||||
run: |
|
||||
./release/package/run.sh package community debian-10
|
||||
- name: "Upload package"
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: debian-10_community
|
||||
name: debian-10
|
||||
path: build/output/debian-10/memgraph*.deb
|
||||
|
||||
docker_community:
|
||||
runs-on: [self-hosted, DockerMgBuild]
|
||||
debian-11:
|
||||
runs-on: [self-hosted, DockerMgBuild, X64]
|
||||
timeout-minutes: 60
|
||||
steps:
|
||||
- name: "Set up repository"
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0 # Required because of release/get_version.py
|
||||
- name: "Build package"
|
||||
run: |
|
||||
./release/package/run.sh package debian-11
|
||||
- name: "Upload package"
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: debian-11
|
||||
path: build/output/debian-11/memgraph*.deb
|
||||
|
||||
docker:
|
||||
runs-on: [self-hosted, DockerMgBuild, X64]
|
||||
timeout-minutes: 60
|
||||
steps:
|
||||
- name: "Set up repository"
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0 # Required because of release/get_version.py
|
||||
- name: "Build package"
|
||||
run: |
|
||||
cd release/package
|
||||
./run.sh package community debian-10 --for-docker
|
||||
./run.sh package debian-11 --for-docker
|
||||
./run.sh docker
|
||||
- name: "Upload package"
|
||||
uses: actions/upload-artifact@v2
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: docker_community
|
||||
name: docker
|
||||
path: build/output/docker/memgraph*.tar.gz
|
||||
|
||||
ubuntu-1804_community:
|
||||
runs-on: [self-hosted, DockerMgBuild]
|
||||
ubuntu-1804:
|
||||
runs-on: [self-hosted, DockerMgBuild, X64]
|
||||
timeout-minutes: 60
|
||||
steps:
|
||||
- name: "Set up repository"
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0 # Required because of release/get_version.py
|
||||
- name: "Build package"
|
||||
run: |
|
||||
./release/package/run.sh package community ubuntu-18.04
|
||||
./release/package/run.sh package ubuntu-18.04
|
||||
- name: "Upload package"
|
||||
uses: actions/upload-artifact@v2
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: ubuntu-1804_community
|
||||
name: ubuntu-1804
|
||||
path: build/output/ubuntu-18.04/memgraph*.deb
|
||||
|
||||
ubuntu-2004_community:
|
||||
runs-on: [self-hosted, DockerMgBuild]
|
||||
ubuntu-2004:
|
||||
runs-on: [self-hosted, DockerMgBuild, X64]
|
||||
timeout-minutes: 60
|
||||
steps:
|
||||
- name: "Set up repository"
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0 # Required because of release/get_version.py
|
||||
- name: "Build package"
|
||||
run: |
|
||||
./release/package/run.sh package community ubuntu-20.04
|
||||
./release/package/run.sh package ubuntu-20.04
|
||||
- name: "Upload package"
|
||||
uses: actions/upload-artifact@v2
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: ubuntu-2004_community
|
||||
name: ubuntu-2004
|
||||
path: build/output/ubuntu-20.04/memgraph*.deb
|
||||
|
||||
centos-7_enterprise:
|
||||
runs-on: [self-hosted, DockerMgBuild]
|
||||
ubuntu-2204:
|
||||
runs-on: [self-hosted, DockerMgBuild, X64]
|
||||
timeout-minutes: 60
|
||||
steps:
|
||||
- name: "Set up repository"
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0 # Required because of release/get_version.py
|
||||
- name: "Build package"
|
||||
run: |
|
||||
./release/package/run.sh package enterprise centos-7
|
||||
./release/package/run.sh package ubuntu-22.04
|
||||
- name: "Upload package"
|
||||
uses: actions/upload-artifact@v2
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: centos-7_enterprise
|
||||
path: build/output/centos-7/memgraph*.rpm
|
||||
name: ubuntu-2204
|
||||
path: build/output/ubuntu-22.04/memgraph*.deb
|
||||
|
||||
centos-8_enterprise:
|
||||
runs-on: [self-hosted, DockerMgBuild]
|
||||
debian-11-platform:
|
||||
runs-on: [self-hosted, DockerMgBuild, X64]
|
||||
timeout-minutes: 60
|
||||
steps:
|
||||
- name: "Set up repository"
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0 # Required because of release/get_version.py
|
||||
- name: "Build package"
|
||||
run: |
|
||||
./release/package/run.sh package enterprise centos-8
|
||||
./release/package/run.sh package debian-11 --for-platform
|
||||
- name: "Upload package"
|
||||
uses: actions/upload-artifact@v2
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: centos-8_enterprise
|
||||
path: build/output/centos-8/memgraph*.rpm
|
||||
name: debian-11-platform
|
||||
path: build/output/debian-11/memgraph*.deb
|
||||
|
||||
debian-9_enterprise:
|
||||
runs-on: [self-hosted, DockerMgBuild]
|
||||
fedora-36:
|
||||
runs-on: [self-hosted, DockerMgBuild, X64]
|
||||
timeout-minutes: 60
|
||||
steps:
|
||||
- name: "Set up repository"
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0 # Required because of release/get_version.py
|
||||
- name: "Build package"
|
||||
run: |
|
||||
./release/package/run.sh package enterprise debian-9
|
||||
./release/package/run.sh package fedora-36
|
||||
- name: "Upload package"
|
||||
uses: actions/upload-artifact@v2
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: debian-9_enterprise
|
||||
path: build/output/debian-9/memgraph*.deb
|
||||
name: fedora-36
|
||||
path: build/output/fedora-36/memgraph*.rpm
|
||||
|
||||
debian-10_enterprise:
|
||||
runs-on: [self-hosted, DockerMgBuild]
|
||||
debian-11-arm:
|
||||
runs-on: [self-hosted, DockerMgBuild, ARM64, strange]
|
||||
timeout-minutes: 60
|
||||
steps:
|
||||
- name: "Set up repository"
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0 # Required because of release/get_version.py
|
||||
- name: "Build package"
|
||||
run: |
|
||||
./release/package/run.sh package enterprise debian-10
|
||||
./release/package/run.sh package debian-11-arm
|
||||
- name: "Upload package"
|
||||
uses: actions/upload-artifact@v2
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: debian-10_enterprise
|
||||
path: build/output/debian-10/memgraph*.deb
|
||||
name: debian-11-arm
|
||||
path: build/output/debian-11-arm/memgraph*.deb
|
||||
|
||||
docker_enterprise:
|
||||
runs-on: [self-hosted, DockerMgBuild]
|
||||
ubuntu-2204-arm:
|
||||
runs-on: [self-hosted, DockerMgBuild, ARM64, strange]
|
||||
timeout-minutes: 60
|
||||
steps:
|
||||
- name: "Set up repository"
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0 # Required because of release/get_version.py
|
||||
- name: "Build package"
|
||||
run: |
|
||||
cd release/package
|
||||
./run.sh package enterprise debian-10 --for-docker
|
||||
./run.sh docker
|
||||
./release/package/run.sh package ubuntu-22.04-arm
|
||||
- name: "Upload package"
|
||||
uses: actions/upload-artifact@v2
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: docker_enterprise
|
||||
path: build/output/docker/memgraph*.tar.gz
|
||||
|
||||
ubuntu-1804_enterprise:
|
||||
runs-on: [self-hosted, DockerMgBuild]
|
||||
timeout-minutes: 60
|
||||
steps:
|
||||
- name: "Set up repository"
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
fetch-depth: 0 # Required because of release/get_version.py
|
||||
- name: "Build package"
|
||||
run: |
|
||||
./release/package/run.sh package enterprise ubuntu-18.04
|
||||
- name: "Upload package"
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: ubuntu-1804_enterprise
|
||||
path: build/output/ubuntu-18.04/memgraph*.deb
|
||||
|
||||
ubuntu-2004_enterprise:
|
||||
runs-on: [self-hosted, DockerMgBuild]
|
||||
timeout-minutes: 60
|
||||
steps:
|
||||
- name: "Set up repository"
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
fetch-depth: 0 # Required because of release/get_version.py
|
||||
- name: "Build package"
|
||||
run: |
|
||||
./release/package/run.sh package enterprise ubuntu-20.04
|
||||
- name: "Upload package"
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: ubuntu-2004_enterprise
|
||||
path: build/output/ubuntu-20.04/memgraph*.deb
|
||||
name: ubuntu-22.04-arm
|
||||
path: build/output/ubuntu-22.04-arm/memgraph*.deb
|
||||
|
||||
89
.github/workflows/release_centos8.yaml
vendored
89
.github/workflows/release_centos8.yaml
vendored
@@ -3,7 +3,7 @@ name: Release CentOS 8
|
||||
on:
|
||||
workflow_dispatch:
|
||||
schedule:
|
||||
- cron: "0 1 * * *"
|
||||
- cron: "0 22 * * *"
|
||||
|
||||
jobs:
|
||||
community_build:
|
||||
@@ -11,11 +11,13 @@ jobs:
|
||||
runs-on: [self-hosted, Linux, X64, CentOS8]
|
||||
env:
|
||||
THREADS: 24
|
||||
MEMGRAPH_ENTERPRISE_LICENSE: ${{ secrets.MEMGRAPH_ENTERPRISE_LICENSE }}
|
||||
MEMGRAPH_ORGANIZATION_NAME: ${{ secrets.MEMGRAPH_ORGANIZATION_NAME }}
|
||||
timeout-minutes: 960
|
||||
|
||||
steps:
|
||||
- name: Set up repository
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
# Number of commits to fetch. `0` indicates all history for all
|
||||
# branches and tags. (default: 1)
|
||||
@@ -24,7 +26,7 @@ jobs:
|
||||
- name: Build community binaries
|
||||
run: |
|
||||
# Activate toolchain.
|
||||
source /opt/toolchain-v3/activate
|
||||
source /opt/toolchain-v4/activate
|
||||
|
||||
# Initialize dependencies.
|
||||
./init
|
||||
@@ -34,56 +36,26 @@ jobs:
|
||||
cmake -DCMAKE_BUILD_TYPE=release -DMG_ENTERPRISE=OFF ..
|
||||
make -j$THREADS
|
||||
|
||||
- name: Create community RPM package
|
||||
run: |
|
||||
# Activate toolchain.
|
||||
source /opt/toolchain-v3/activate
|
||||
|
||||
cd build
|
||||
|
||||
# create mgconsole
|
||||
# we use the -B to force the build
|
||||
make -j$THREADS -B mgconsole
|
||||
|
||||
# Create community RPM package.
|
||||
mkdir output && cd output
|
||||
cpack -G RPM --config ../CPackConfig.cmake
|
||||
rpmlint memgraph*.rpm
|
||||
|
||||
- name: Save community RPM package
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: "Community RPM package"
|
||||
path: build/output/memgraph*.rpm
|
||||
|
||||
- name: Run unit tests
|
||||
run: |
|
||||
# Activate toolchain.
|
||||
source /opt/toolchain-v3/activate
|
||||
source /opt/toolchain-v4/activate
|
||||
|
||||
# Run unit tests.
|
||||
cd build
|
||||
ctest -R memgraph__unit --output-on-failure
|
||||
|
||||
- name: Run stress test (plain)
|
||||
run: |
|
||||
cd tests/stress
|
||||
./continuous_integration
|
||||
|
||||
- name: Run stress test (large)
|
||||
run: |
|
||||
cd tests/stress
|
||||
./continuous_integration --large-dataset
|
||||
|
||||
coverage_build:
|
||||
name: "Coverage build"
|
||||
runs-on: [self-hosted, Linux, X64, CentOS8]
|
||||
env:
|
||||
THREADS: 24
|
||||
MEMGRAPH_ENTERPRISE_LICENSE: ${{ secrets.MEMGRAPH_ENTERPRISE_LICENSE }}
|
||||
MEMGRAPH_ORGANIZATION_NAME: ${{ secrets.MEMGRAPH_ORGANIZATION_NAME }}
|
||||
|
||||
steps:
|
||||
- name: Set up repository
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
# Number of commits to fetch. `0` indicates all history for all
|
||||
# branches and tags. (default: 1)
|
||||
@@ -92,7 +64,7 @@ jobs:
|
||||
- name: Build coverage binaries
|
||||
run: |
|
||||
# Activate toolchain.
|
||||
source /opt/toolchain-v3/activate
|
||||
source /opt/toolchain-v4/activate
|
||||
|
||||
# Initialize dependencies.
|
||||
./init
|
||||
@@ -105,7 +77,7 @@ jobs:
|
||||
- name: Run unit tests
|
||||
run: |
|
||||
# Activate toolchain.
|
||||
source /opt/toolchain-v3/activate
|
||||
source /opt/toolchain-v4/activate
|
||||
|
||||
# Run unit tests.
|
||||
cd build
|
||||
@@ -114,7 +86,7 @@ jobs:
|
||||
- name: Compute code coverage
|
||||
run: |
|
||||
# Activate toolchain.
|
||||
source /opt/toolchain-v3/activate
|
||||
source /opt/toolchain-v4/activate
|
||||
|
||||
# Compute code coverage.
|
||||
cd tools/github
|
||||
@@ -125,7 +97,7 @@ jobs:
|
||||
tar -czf code_coverage.tar.gz coverage.json html report.json summary.rmu
|
||||
|
||||
- name: Save code coverage
|
||||
uses: actions/upload-artifact@v2
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: "Code coverage"
|
||||
path: tools/github/generated/code_coverage.tar.gz
|
||||
@@ -135,10 +107,12 @@ jobs:
|
||||
runs-on: [self-hosted, Linux, X64, CentOS8]
|
||||
env:
|
||||
THREADS: 24
|
||||
MEMGRAPH_ENTERPRISE_LICENSE: ${{ secrets.MEMGRAPH_ENTERPRISE_LICENSE }}
|
||||
MEMGRAPH_ORGANIZATION_NAME: ${{ secrets.MEMGRAPH_ORGANIZATION_NAME }}
|
||||
|
||||
steps:
|
||||
- name: Set up repository
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
# Number of commits to fetch. `0` indicates all history for all
|
||||
# branches and tags. (default: 1)
|
||||
@@ -147,7 +121,7 @@ jobs:
|
||||
- name: Build debug binaries
|
||||
run: |
|
||||
# Activate toolchain.
|
||||
source /opt/toolchain-v3/activate
|
||||
source /opt/toolchain-v4/activate
|
||||
|
||||
# Initialize dependencies.
|
||||
./init
|
||||
@@ -160,7 +134,7 @@ jobs:
|
||||
- name: Run leftover CTest tests
|
||||
run: |
|
||||
# Activate toolchain.
|
||||
source /opt/toolchain-v3/activate
|
||||
source /opt/toolchain-v4/activate
|
||||
|
||||
# Run leftover CTest tests (all except unit and benchmark tests).
|
||||
cd build
|
||||
@@ -192,14 +166,14 @@ jobs:
|
||||
- name: Run cppcheck and clang-format
|
||||
run: |
|
||||
# Activate toolchain.
|
||||
source /opt/toolchain-v3/activate
|
||||
source /opt/toolchain-v4/activate
|
||||
|
||||
# Run cppcheck and clang-format.
|
||||
cd tools/github
|
||||
./cppcheck_and_clang_format diff
|
||||
|
||||
- name: Save cppcheck and clang-format errors
|
||||
uses: actions/upload-artifact@v2
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: "Code coverage"
|
||||
path: tools/github/cppcheck_and_clang_format.txt
|
||||
@@ -209,11 +183,13 @@ jobs:
|
||||
runs-on: [self-hosted, Linux, X64, CentOS8]
|
||||
env:
|
||||
THREADS: 24
|
||||
MEMGRAPH_ENTERPRISE_LICENSE: ${{ secrets.MEMGRAPH_ENTERPRISE_LICENSE }}
|
||||
MEMGRAPH_ORGANIZATION_NAME: ${{ secrets.MEMGRAPH_ORGANIZATION_NAME }}
|
||||
timeout-minutes: 960
|
||||
|
||||
steps:
|
||||
- name: Set up repository
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
# Number of commits to fetch. `0` indicates all history for all
|
||||
# branches and tags. (default: 1)
|
||||
@@ -222,7 +198,7 @@ jobs:
|
||||
- name: Build release binaries
|
||||
run: |
|
||||
# Activate toolchain.
|
||||
source /opt/toolchain-v3/activate
|
||||
source /opt/toolchain-v4/activate
|
||||
|
||||
# Initialize dependencies.
|
||||
./init
|
||||
@@ -235,7 +211,7 @@ jobs:
|
||||
- name: Create enterprise RPM package
|
||||
run: |
|
||||
# Activate toolchain.
|
||||
source /opt/toolchain-v3/activate
|
||||
source /opt/toolchain-v4/activate
|
||||
|
||||
cd build
|
||||
|
||||
@@ -249,7 +225,7 @@ jobs:
|
||||
rpmlint memgraph*.rpm
|
||||
|
||||
- name: Save enterprise RPM package
|
||||
uses: actions/upload-artifact@v2
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: "Enterprise RPM package"
|
||||
path: build/output/memgraph*.rpm
|
||||
@@ -257,7 +233,7 @@ jobs:
|
||||
- name: Run micro benchmark tests
|
||||
run: |
|
||||
# Activate toolchain.
|
||||
source /opt/toolchain-v3/activate
|
||||
source /opt/toolchain-v4/activate
|
||||
|
||||
# Run micro benchmark tests.
|
||||
cd build
|
||||
@@ -286,13 +262,22 @@ jobs:
|
||||
./continuous_integration
|
||||
|
||||
- name: Save quality assurance status
|
||||
uses: actions/upload-artifact@v2
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: "GQL Behave Status"
|
||||
path: |
|
||||
tests/gql_behave/gql_behave_status.csv
|
||||
tests/gql_behave/gql_behave_status.html
|
||||
|
||||
- name: Run unit tests
|
||||
run: |
|
||||
# Activate toolchain.
|
||||
source /opt/toolchain-v4/activate
|
||||
|
||||
# Run unit tests.
|
||||
cd build
|
||||
ctest -R memgraph__unit --output-on-failure
|
||||
|
||||
- name: Run e2e tests
|
||||
run: |
|
||||
# TODO(gitbuda): Setup mgclient and pymgclient properly.
|
||||
|
||||
96
.github/workflows/release_debian10.yaml
vendored
96
.github/workflows/release_debian10.yaml
vendored
@@ -3,7 +3,7 @@ name: Release Debian 10
|
||||
on:
|
||||
workflow_dispatch:
|
||||
schedule:
|
||||
- cron: "0 1 * * *"
|
||||
- cron: "0 22 * * *"
|
||||
|
||||
jobs:
|
||||
community_build:
|
||||
@@ -11,11 +11,13 @@ jobs:
|
||||
runs-on: [self-hosted, Linux, X64, Debian10]
|
||||
env:
|
||||
THREADS: 24
|
||||
MEMGRAPH_ENTERPRISE_LICENSE: ${{ secrets.MEMGRAPH_ENTERPRISE_LICENSE }}
|
||||
MEMGRAPH_ORGANIZATION_NAME: ${{ secrets.MEMGRAPH_ORGANIZATION_NAME }}
|
||||
timeout-minutes: 960
|
||||
|
||||
steps:
|
||||
- name: Set up repository
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
# Number of commits to fetch. `0` indicates all history for all
|
||||
# branches and tags. (default: 1)
|
||||
@@ -24,7 +26,7 @@ jobs:
|
||||
- name: Build community binaries
|
||||
run: |
|
||||
# Activate toolchain.
|
||||
source /opt/toolchain-v3/activate
|
||||
source /opt/toolchain-v4/activate
|
||||
|
||||
# Initialize dependencies.
|
||||
./init
|
||||
@@ -34,55 +36,26 @@ jobs:
|
||||
cmake -DCMAKE_BUILD_TYPE=release -DMG_ENTERPRISE=OFF ..
|
||||
make -j$THREADS
|
||||
|
||||
- name: Create community DEB package
|
||||
run: |
|
||||
# Activate toolchain.
|
||||
source /opt/toolchain-v3/activate
|
||||
|
||||
cd build
|
||||
|
||||
# create mgconsole
|
||||
# we use the -B to force the build
|
||||
make -j$THREADS -B mgconsole
|
||||
|
||||
# Create community DEB package.
|
||||
mkdir output && cd output
|
||||
cpack -G DEB --config ../CPackConfig.cmake
|
||||
|
||||
- name: Save community DEB package
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: "Community DEB package"
|
||||
path: build/output/memgraph*.deb
|
||||
|
||||
- name: Run unit tests
|
||||
run: |
|
||||
# Activate toolchain.
|
||||
source /opt/toolchain-v3/activate
|
||||
source /opt/toolchain-v4/activate
|
||||
|
||||
# Run unit tests.
|
||||
cd build
|
||||
ctest -R memgraph__unit --output-on-failure
|
||||
|
||||
- name: Run stress test (plain)
|
||||
run: |
|
||||
cd tests/stress
|
||||
./continuous_integration
|
||||
|
||||
- name: Run stress test (large)
|
||||
run: |
|
||||
cd tests/stress
|
||||
./continuous_integration --large-dataset
|
||||
|
||||
coverage_build:
|
||||
name: "Coverage build"
|
||||
runs-on: [self-hosted, Linux, X64, Debian10]
|
||||
env:
|
||||
THREADS: 24
|
||||
MEMGRAPH_ENTERPRISE_LICENSE: ${{ secrets.MEMGRAPH_ENTERPRISE_LICENSE }}
|
||||
MEMGRAPH_ORGANIZATION_NAME: ${{ secrets.MEMGRAPH_ORGANIZATION_NAME }}
|
||||
|
||||
steps:
|
||||
- name: Set up repository
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
# Number of commits to fetch. `0` indicates all history for all
|
||||
# branches and tags. (default: 1)
|
||||
@@ -91,7 +64,7 @@ jobs:
|
||||
- name: Build coverage binaries
|
||||
run: |
|
||||
# Activate toolchain.
|
||||
source /opt/toolchain-v3/activate
|
||||
source /opt/toolchain-v4/activate
|
||||
|
||||
# Initialize dependencies.
|
||||
./init
|
||||
@@ -104,7 +77,7 @@ jobs:
|
||||
- name: Run unit tests
|
||||
run: |
|
||||
# Activate toolchain.
|
||||
source /opt/toolchain-v3/activate
|
||||
source /opt/toolchain-v4/activate
|
||||
|
||||
# Run unit tests.
|
||||
cd build
|
||||
@@ -113,7 +86,7 @@ jobs:
|
||||
- name: Compute code coverage
|
||||
run: |
|
||||
# Activate toolchain.
|
||||
source /opt/toolchain-v3/activate
|
||||
source /opt/toolchain-v4/activate
|
||||
|
||||
# Compute code coverage.
|
||||
cd tools/github
|
||||
@@ -124,7 +97,7 @@ jobs:
|
||||
tar -czf code_coverage.tar.gz coverage.json html report.json summary.rmu
|
||||
|
||||
- name: Save code coverage
|
||||
uses: actions/upload-artifact@v2
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: "Code coverage"
|
||||
path: tools/github/generated/code_coverage.tar.gz
|
||||
@@ -134,10 +107,12 @@ jobs:
|
||||
runs-on: [self-hosted, Linux, X64, Debian10]
|
||||
env:
|
||||
THREADS: 24
|
||||
MEMGRAPH_ENTERPRISE_LICENSE: ${{ secrets.MEMGRAPH_ENTERPRISE_LICENSE }}
|
||||
MEMGRAPH_ORGANIZATION_NAME: ${{ secrets.MEMGRAPH_ORGANIZATION_NAME }}
|
||||
|
||||
steps:
|
||||
- name: Set up repository
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
# Number of commits to fetch. `0` indicates all history for all
|
||||
# branches and tags. (default: 1)
|
||||
@@ -146,7 +121,7 @@ jobs:
|
||||
- name: Build debug binaries
|
||||
run: |
|
||||
# Activate toolchain.
|
||||
source /opt/toolchain-v3/activate
|
||||
source /opt/toolchain-v4/activate
|
||||
|
||||
# Initialize dependencies.
|
||||
./init
|
||||
@@ -159,7 +134,7 @@ jobs:
|
||||
- name: Run leftover CTest tests
|
||||
run: |
|
||||
# Activate toolchain.
|
||||
source /opt/toolchain-v3/activate
|
||||
source /opt/toolchain-v4/activate
|
||||
|
||||
# Run leftover CTest tests (all except unit and benchmark tests).
|
||||
cd build
|
||||
@@ -191,14 +166,14 @@ jobs:
|
||||
- name: Run cppcheck and clang-format
|
||||
run: |
|
||||
# Activate toolchain.
|
||||
source /opt/toolchain-v3/activate
|
||||
source /opt/toolchain-v4/activate
|
||||
|
||||
# Run cppcheck and clang-format.
|
||||
cd tools/github
|
||||
./cppcheck_and_clang_format diff
|
||||
|
||||
- name: Save cppcheck and clang-format errors
|
||||
uses: actions/upload-artifact@v2
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: "Code coverage"
|
||||
path: tools/github/cppcheck_and_clang_format.txt
|
||||
@@ -208,11 +183,13 @@ jobs:
|
||||
runs-on: [self-hosted, Linux, X64, Debian10]
|
||||
env:
|
||||
THREADS: 24
|
||||
MEMGRAPH_ENTERPRISE_LICENSE: ${{ secrets.MEMGRAPH_ENTERPRISE_LICENSE }}
|
||||
MEMGRAPH_ORGANIZATION_NAME: ${{ secrets.MEMGRAPH_ORGANIZATION_NAME }}
|
||||
timeout-minutes: 960
|
||||
|
||||
steps:
|
||||
- name: Set up repository
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
# Number of commits to fetch. `0` indicates all history for all
|
||||
# branches and tags. (default: 1)
|
||||
@@ -221,7 +198,7 @@ jobs:
|
||||
- name: Build release binaries
|
||||
run: |
|
||||
# Activate toolchain.
|
||||
source /opt/toolchain-v3/activate
|
||||
source /opt/toolchain-v4/activate
|
||||
|
||||
# Initialize dependencies.
|
||||
./init
|
||||
@@ -234,7 +211,7 @@ jobs:
|
||||
- name: Create enterprise DEB package
|
||||
run: |
|
||||
# Activate toolchain.
|
||||
source /opt/toolchain-v3/activate
|
||||
source /opt/toolchain-v4/activate
|
||||
|
||||
cd build
|
||||
|
||||
@@ -247,7 +224,7 @@ jobs:
|
||||
cpack -G DEB --config ../CPackConfig.cmake
|
||||
|
||||
- name: Save enterprise DEB package
|
||||
uses: actions/upload-artifact@v2
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: "Enterprise DEB package"
|
||||
path: build/output/memgraph*.deb
|
||||
@@ -255,7 +232,7 @@ jobs:
|
||||
- name: Run micro benchmark tests
|
||||
run: |
|
||||
# Activate toolchain.
|
||||
source /opt/toolchain-v3/activate
|
||||
source /opt/toolchain-v4/activate
|
||||
|
||||
# Run micro benchmark tests.
|
||||
cd build
|
||||
@@ -284,13 +261,22 @@ jobs:
|
||||
./continuous_integration
|
||||
|
||||
- name: Save quality assurance status
|
||||
uses: actions/upload-artifact@v2
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: "GQL Behave Status"
|
||||
path: |
|
||||
tests/gql_behave/gql_behave_status.csv
|
||||
tests/gql_behave/gql_behave_status.html
|
||||
|
||||
- name: Run unit tests
|
||||
run: |
|
||||
# Activate toolchain.
|
||||
source /opt/toolchain-v4/activate
|
||||
|
||||
# Run unit tests.
|
||||
cd build
|
||||
ctest -R memgraph__unit --output-on-failure
|
||||
|
||||
- name: Run e2e tests
|
||||
run: |
|
||||
# TODO(gitbuda): Setup mgclient and pymgclient properly.
|
||||
@@ -332,11 +318,13 @@ jobs:
|
||||
runs-on: [self-hosted, Linux, X64, Debian10, JepsenControl]
|
||||
env:
|
||||
THREADS: 24
|
||||
MEMGRAPH_ENTERPRISE_LICENSE: ${{ secrets.MEMGRAPH_ENTERPRISE_LICENSE }}
|
||||
MEMGRAPH_ORGANIZATION_NAME: ${{ secrets.MEMGRAPH_ORGANIZATION_NAME }}
|
||||
timeout-minutes: 60
|
||||
|
||||
steps:
|
||||
- name: Set up repository
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
# Number of commits to fetch. `0` indicates all history for all
|
||||
# branches and tags. (default: 1)
|
||||
@@ -345,7 +333,7 @@ jobs:
|
||||
- name: Build release binaries
|
||||
run: |
|
||||
# Activate toolchain.
|
||||
source /opt/toolchain-v3/activate
|
||||
source /opt/toolchain-v4/activate
|
||||
|
||||
# Initialize dependencies.
|
||||
./init
|
||||
@@ -361,7 +349,7 @@ jobs:
|
||||
./run.sh test --binary ../../build/memgraph --run-args "test-all --node-configs resources/node-config.edn" --ignore-run-stdout-logs --ignore-run-stderr-logs
|
||||
|
||||
- name: Save Jepsen report
|
||||
uses: actions/upload-artifact@v2
|
||||
uses: actions/upload-artifact@v3
|
||||
if: ${{ always() }}
|
||||
with:
|
||||
name: "Jepsen Report"
|
||||
|
||||
69
.github/workflows/release_docker.yaml
vendored
Normal file
69
.github/workflows/release_docker.yaml
vendored
Normal file
@@ -0,0 +1,69 @@
|
||||
name: Publish Docker images
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
version:
|
||||
description: "Memgraph binary version to publish on DockerHub."
|
||||
required: true
|
||||
force_release:
|
||||
type: boolean
|
||||
required: false
|
||||
default: false
|
||||
|
||||
jobs:
|
||||
docker_publish:
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
DOCKER_ORGANIZATION_NAME: memgraph
|
||||
DOCKER_REPOSITORY_NAME: memgraph
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v2
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
id: buildx
|
||||
uses: docker/setup-buildx-action@v2
|
||||
|
||||
- name: Log in to Docker Hub
|
||||
uses: docker/login-action@v2
|
||||
with:
|
||||
username: ${{ secrets.DOCKER_USERNAME }}
|
||||
password: ${{ secrets.DOCKER_PASSWORD }}
|
||||
|
||||
- name: Download memgraph binary
|
||||
run: |
|
||||
cd release/docker
|
||||
curl -L https://download.memgraph.com/memgraph/v${{ github.event.inputs.version }}/debian-11/memgraph_${{ github.event.inputs.version }}-1_amd64.deb > memgraph-amd64.deb
|
||||
curl -L https://download.memgraph.com/memgraph/v${{ github.event.inputs.version }}/debian-11-aarch64/memgraph_${{ github.event.inputs.version }}-1_arm64.deb > memgraph-arm64.deb
|
||||
|
||||
- name: Check if specified version is already pushed
|
||||
run: |
|
||||
EXISTS=$(docker manifest inspect $DOCKER_ORGANIZATION_NAME/$DOCKER_REPOSITORY_NAME:${{ github.event.inputs.version }} > /dev/null; echo $?)
|
||||
echo $EXISTS
|
||||
if [[ ${EXISTS} -eq 0 ]]; then
|
||||
echo 'The specified version has been already released to DockerHub.'
|
||||
if [[ ${{ github.event.inputs.force_release }} = true ]]; then
|
||||
echo 'Forcing the release!'
|
||||
else
|
||||
echo 'Stopping the release!'
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
echo 'All good the specified version has not been release to DockerHub.'
|
||||
fi
|
||||
|
||||
- name: Build & push docker images
|
||||
run: |
|
||||
cd release/docker
|
||||
docker buildx build \
|
||||
--build-arg BINARY_NAME="memgraph-" \
|
||||
--build-arg EXTENSION="deb" \
|
||||
--platform linux/amd64,linux/arm64 \
|
||||
--tag $DOCKER_ORGANIZATION_NAME/$DOCKER_REPOSITORY_NAME:${{ github.event.inputs.version }} \
|
||||
--tag $DOCKER_ORGANIZATION_NAME/$DOCKER_REPOSITORY_NAME:latest \
|
||||
--file memgraph_deb.dockerfile \
|
||||
--push .
|
||||
88
.github/workflows/release_ubuntu2004.yaml
vendored
88
.github/workflows/release_ubuntu2004.yaml
vendored
@@ -3,7 +3,7 @@ name: Release Ubuntu 20.04
|
||||
on:
|
||||
workflow_dispatch:
|
||||
schedule:
|
||||
- cron: "0 1 * * *"
|
||||
- cron: "0 22 * * *"
|
||||
|
||||
jobs:
|
||||
community_build:
|
||||
@@ -11,11 +11,13 @@ jobs:
|
||||
runs-on: [self-hosted, Linux, X64, Ubuntu20.04]
|
||||
env:
|
||||
THREADS: 24
|
||||
MEMGRAPH_ENTERPRISE_LICENSE: ${{ secrets.MEMGRAPH_ENTERPRISE_LICENSE }}
|
||||
MEMGRAPH_ORGANIZATION_NAME: ${{ secrets.MEMGRAPH_ORGANIZATION_NAME }}
|
||||
timeout-minutes: 960
|
||||
|
||||
steps:
|
||||
- name: Set up repository
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
# Number of commits to fetch. `0` indicates all history for all
|
||||
# branches and tags. (default: 1)
|
||||
@@ -24,7 +26,7 @@ jobs:
|
||||
- name: Build community binaries
|
||||
run: |
|
||||
# Activate toolchain.
|
||||
source /opt/toolchain-v3/activate
|
||||
source /opt/toolchain-v4/activate
|
||||
|
||||
# Initialize dependencies.
|
||||
./init
|
||||
@@ -34,55 +36,26 @@ jobs:
|
||||
cmake -DCMAKE_BUILD_TYPE=release -DMG_ENTERPRISE=OFF ..
|
||||
make -j$THREADS
|
||||
|
||||
- name: Create community DEB package
|
||||
run: |
|
||||
# Activate toolchain.
|
||||
source /opt/toolchain-v3/activate
|
||||
|
||||
cd build
|
||||
|
||||
# create mgconsole
|
||||
# we use the -B to force the build
|
||||
make -j$THREADS -B mgconsole
|
||||
|
||||
# Create community DEB package.
|
||||
mkdir output && cd output
|
||||
cpack -G DEB --config ../CPackConfig.cmake
|
||||
|
||||
- name: Save community DEB package
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: "Community DEB package"
|
||||
path: build/output/memgraph*.deb
|
||||
|
||||
- name: Run unit tests
|
||||
run: |
|
||||
# Activate toolchain.
|
||||
source /opt/toolchain-v3/activate
|
||||
source /opt/toolchain-v4/activate
|
||||
|
||||
# Run unit tests.
|
||||
cd build
|
||||
ctest -R memgraph__unit --output-on-failure
|
||||
|
||||
- name: Run stress test (plain)
|
||||
run: |
|
||||
cd tests/stress
|
||||
./continuous_integration
|
||||
|
||||
- name: Run stress test (large)
|
||||
run: |
|
||||
cd tests/stress
|
||||
./continuous_integration --large-dataset
|
||||
|
||||
coverage_build:
|
||||
name: "Coverage build"
|
||||
runs-on: [self-hosted, Linux, X64, Ubuntu20.04]
|
||||
env:
|
||||
THREADS: 24
|
||||
MEMGRAPH_ENTERPRISE_LICENSE: ${{ secrets.MEMGRAPH_ENTERPRISE_LICENSE }}
|
||||
MEMGRAPH_ORGANIZATION_NAME: ${{ secrets.MEMGRAPH_ORGANIZATION_NAME }}
|
||||
|
||||
steps:
|
||||
- name: Set up repository
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
# Number of commits to fetch. `0` indicates all history for all
|
||||
# branches and tags. (default: 1)
|
||||
@@ -91,7 +64,7 @@ jobs:
|
||||
- name: Build coverage binaries
|
||||
run: |
|
||||
# Activate toolchain.
|
||||
source /opt/toolchain-v3/activate
|
||||
source /opt/toolchain-v4/activate
|
||||
|
||||
# Initialize dependencies.
|
||||
./init
|
||||
@@ -104,7 +77,7 @@ jobs:
|
||||
- name: Run unit tests
|
||||
run: |
|
||||
# Activate toolchain.
|
||||
source /opt/toolchain-v3/activate
|
||||
source /opt/toolchain-v4/activate
|
||||
|
||||
# Run unit tests.
|
||||
cd build
|
||||
@@ -113,7 +86,7 @@ jobs:
|
||||
- name: Compute code coverage
|
||||
run: |
|
||||
# Activate toolchain.
|
||||
source /opt/toolchain-v3/activate
|
||||
source /opt/toolchain-v4/activate
|
||||
|
||||
# Compute code coverage.
|
||||
cd tools/github
|
||||
@@ -124,7 +97,7 @@ jobs:
|
||||
tar -czf code_coverage.tar.gz coverage.json html report.json summary.rmu
|
||||
|
||||
- name: Save code coverage
|
||||
uses: actions/upload-artifact@v2
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: "Code coverage"
|
||||
path: tools/github/generated/code_coverage.tar.gz
|
||||
@@ -134,10 +107,12 @@ jobs:
|
||||
runs-on: [self-hosted, Linux, X64, Ubuntu20.04]
|
||||
env:
|
||||
THREADS: 24
|
||||
MEMGRAPH_ENTERPRISE_LICENSE: ${{ secrets.MEMGRAPH_ENTERPRISE_LICENSE }}
|
||||
MEMGRAPH_ORGANIZATION_NAME: ${{ secrets.MEMGRAPH_ORGANIZATION_NAME }}
|
||||
|
||||
steps:
|
||||
- name: Set up repository
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
# Number of commits to fetch. `0` indicates all history for all
|
||||
# branches and tags. (default: 1)
|
||||
@@ -146,7 +121,7 @@ jobs:
|
||||
- name: Build debug binaries
|
||||
run: |
|
||||
# Activate toolchain.
|
||||
source /opt/toolchain-v3/activate
|
||||
source /opt/toolchain-v4/activate
|
||||
|
||||
# Initialize dependencies.
|
||||
./init
|
||||
@@ -159,7 +134,7 @@ jobs:
|
||||
- name: Run leftover CTest tests
|
||||
run: |
|
||||
# Activate toolchain.
|
||||
source /opt/toolchain-v3/activate
|
||||
source /opt/toolchain-v4/activate
|
||||
|
||||
# Run leftover CTest tests (all except unit and benchmark tests).
|
||||
cd build
|
||||
@@ -191,14 +166,14 @@ jobs:
|
||||
- name: Run cppcheck and clang-format
|
||||
run: |
|
||||
# Activate toolchain.
|
||||
source /opt/toolchain-v3/activate
|
||||
source /opt/toolchain-v4/activate
|
||||
|
||||
# Run cppcheck and clang-format.
|
||||
cd tools/github
|
||||
./cppcheck_and_clang_format diff
|
||||
|
||||
- name: Save cppcheck and clang-format errors
|
||||
uses: actions/upload-artifact@v2
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: "Code coverage"
|
||||
path: tools/github/cppcheck_and_clang_format.txt
|
||||
@@ -208,11 +183,13 @@ jobs:
|
||||
runs-on: [self-hosted, Linux, X64, Ubuntu20.04]
|
||||
env:
|
||||
THREADS: 24
|
||||
MEMGRAPH_ENTERPRISE_LICENSE: ${{ secrets.MEMGRAPH_ENTERPRISE_LICENSE }}
|
||||
MEMGRAPH_ORGANIZATION_NAME: ${{ secrets.MEMGRAPH_ORGANIZATION_NAME }}
|
||||
timeout-minutes: 960
|
||||
|
||||
steps:
|
||||
- name: Set up repository
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
# Number of commits to fetch. `0` indicates all history for all
|
||||
# branches and tags. (default: 1)
|
||||
@@ -221,7 +198,7 @@ jobs:
|
||||
- name: Build release binaries
|
||||
run: |
|
||||
# Activate toolchain.
|
||||
source /opt/toolchain-v3/activate
|
||||
source /opt/toolchain-v4/activate
|
||||
|
||||
# Initialize dependencies.
|
||||
./init
|
||||
@@ -234,7 +211,7 @@ jobs:
|
||||
- name: Create enterprise DEB package
|
||||
run: |
|
||||
# Activate toolchain.
|
||||
source /opt/toolchain-v3/activate
|
||||
source /opt/toolchain-v4/activate
|
||||
|
||||
cd build
|
||||
|
||||
@@ -247,7 +224,7 @@ jobs:
|
||||
cpack -G DEB --config ../CPackConfig.cmake
|
||||
|
||||
- name: Save enterprise DEB package
|
||||
uses: actions/upload-artifact@v2
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: "Enterprise DEB package"
|
||||
path: build/output/memgraph*.deb
|
||||
@@ -255,7 +232,7 @@ jobs:
|
||||
- name: Run micro benchmark tests
|
||||
run: |
|
||||
# Activate toolchain.
|
||||
source /opt/toolchain-v3/activate
|
||||
source /opt/toolchain-v4/activate
|
||||
|
||||
# Run micro benchmark tests.
|
||||
cd build
|
||||
@@ -284,13 +261,22 @@ jobs:
|
||||
./continuous_integration
|
||||
|
||||
- name: Save quality assurance status
|
||||
uses: actions/upload-artifact@v2
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: "GQL Behave Status"
|
||||
path: |
|
||||
tests/gql_behave/gql_behave_status.csv
|
||||
tests/gql_behave/gql_behave_status.html
|
||||
|
||||
- name: Run unit tests
|
||||
run: |
|
||||
# Activate toolchain.
|
||||
source /opt/toolchain-v4/activate
|
||||
|
||||
# Run unit tests.
|
||||
cd build
|
||||
ctest -R memgraph__unit --output-on-failure
|
||||
|
||||
- name: Run e2e tests
|
||||
run: |
|
||||
# TODO(gitbuda): Setup mgclient and pymgclient properly.
|
||||
|
||||
20
.pre-commit-config.yaml
Normal file
20
.pre-commit-config.yaml
Normal file
@@ -0,0 +1,20 @@
|
||||
repos:
|
||||
- repo: https://github.com/pre-commit/pre-commit-hooks
|
||||
rev: v2.3.0
|
||||
hooks:
|
||||
- id: check-yaml
|
||||
- id: end-of-file-fixer
|
||||
- id: trailing-whitespace
|
||||
- repo: https://github.com/psf/black
|
||||
rev: 22.8.0
|
||||
hooks:
|
||||
- id: black
|
||||
- repo: https://github.com/pycqa/isort
|
||||
rev: 5.10.1
|
||||
hooks:
|
||||
- id: isort
|
||||
name: isort (python)
|
||||
- repo: https://github.com/pre-commit/mirrors-clang-format
|
||||
rev: v13.0.0
|
||||
hooks:
|
||||
- id: clang-format
|
||||
342
CMakeLists.txt
342
CMakeLists.txt
@@ -1,342 +0,0 @@
|
||||
# MemGraph CMake configuration
|
||||
|
||||
cmake_minimum_required(VERSION 3.8)
|
||||
|
||||
# !! IMPORTANT !! run ./project_root/init.sh before cmake command
|
||||
# to download dependencies
|
||||
|
||||
if(NOT UNIX)
|
||||
message(FATAL_ERROR "Unsupported operating system.")
|
||||
endif()
|
||||
|
||||
# Set `make clean` to ignore outputs of add_custom_command. If generated files
|
||||
# need to be cleaned, set ADDITIONAL_MAKE_CLEAN_FILES property.
|
||||
set_directory_properties(PROPERTIES CLEAN_NO_CUSTOM TRUE)
|
||||
|
||||
# ccache setup
|
||||
# ccache isn't enabled all the time because it makes some problem
|
||||
# during the code coverage process
|
||||
find_program(CCACHE_FOUND ccache)
|
||||
option(USE_CCACHE "ccache:" ON)
|
||||
message(STATUS "CCache: ${USE_CCACHE}")
|
||||
if(CCACHE_FOUND AND USE_CCACHE)
|
||||
set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE ccache)
|
||||
set_property(GLOBAL PROPERTY RULE_LAUNCH_LINK ccache)
|
||||
endif(CCACHE_FOUND AND USE_CCACHE)
|
||||
|
||||
# choose a compiler
|
||||
# NOTE: must be choosen before use of project() or enable_language()
|
||||
find_program(CLANG_FOUND clang)
|
||||
find_program(CLANGXX_FOUND clang++)
|
||||
if (CLANG_FOUND AND CLANGXX_FOUND)
|
||||
set(CMAKE_C_COMPILER ${CLANG_FOUND})
|
||||
set(CMAKE_CXX_COMPILER ${CLANGXX_FOUND})
|
||||
else()
|
||||
message(FATAL_ERROR "Couldn't find clang and/or clang++!")
|
||||
endif()
|
||||
|
||||
option(BUILD_FOR_DOCKER "Build Memgraph binary for docker." OFF)
|
||||
message(STATUS "BUILD_FOR_DOCKER: ${BUILD_FOR_DOCKER}")
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
project(memgraph)
|
||||
|
||||
# For more information about how to release a new version of Memgraph, see
|
||||
# `release/README.md`.
|
||||
|
||||
# Option that is used to specify which version of Memgraph should be built. The
|
||||
# default is `ON` which causes the build system to build Memgraph Enterprise.
|
||||
# Memgraph Community is built if explicitly set to `OFF`.
|
||||
option(MG_ENTERPRISE "Build Memgraph Enterprise Edition" ON)
|
||||
|
||||
# Set the current version here to override the automatic version detection. The
|
||||
# version must be specified as `X.Y.Z`. Primarily used when building new patch
|
||||
# versions.
|
||||
set(MEMGRAPH_OVERRIDE_VERSION "")
|
||||
|
||||
# Custom suffix that this version should have. The suffix can be any arbitrary
|
||||
# string. Primarily used when building a version for a specific customer.
|
||||
set(MEMGRAPH_OVERRIDE_VERSION_SUFFIX "")
|
||||
|
||||
# Variables used to generate the versions.
|
||||
if (MG_ENTERPRISE)
|
||||
set(get_version_enterprise "--enterprise")
|
||||
else()
|
||||
set(get_version_enterprise "")
|
||||
endif()
|
||||
set(get_version_script "${CMAKE_SOURCE_DIR}/release/get_version.py")
|
||||
|
||||
# Get version that should be used in the binary.
|
||||
execute_process(
|
||||
OUTPUT_VARIABLE MEMGRAPH_VERSION
|
||||
RESULT_VARIABLE MEMGRAPH_VERSION_RESULT
|
||||
COMMAND "${get_version_script}" ${get_version_enterprise}
|
||||
"${MEMGRAPH_OVERRIDE_VERSION}"
|
||||
"${MEMGRAPH_OVERRIDE_VERSION_SUFFIX}"
|
||||
"--memgraph-root-dir"
|
||||
"${CMAKE_SOURCE_DIR}"
|
||||
)
|
||||
if(MEMGRAPH_VERSION_RESULT AND NOT MEMGRAPH_VERSION_RESULT EQUAL 0)
|
||||
message(FATAL_ERROR "Unable to get Memgraph version.")
|
||||
else()
|
||||
MESSAGE(STATUS "Memgraph version: ${MEMGRAPH_VERSION}")
|
||||
endif()
|
||||
|
||||
# Get version that should be used in the DEB package.
|
||||
execute_process(
|
||||
OUTPUT_VARIABLE MEMGRAPH_VERSION_DEB
|
||||
RESULT_VARIABLE MEMGRAPH_VERSION_DEB_RESULT
|
||||
COMMAND "${get_version_script}" ${get_version_enterprise}
|
||||
--variant deb
|
||||
"${MEMGRAPH_OVERRIDE_VERSION}"
|
||||
"${MEMGRAPH_OVERRIDE_VERSION_SUFFIX}"
|
||||
"--memgraph-root-dir"
|
||||
"${CMAKE_SOURCE_DIR}"
|
||||
)
|
||||
if(MEMGRAPH_VERSION_DEB_RESULT AND NOT MEMGRAPH_VERSION_DEB_RESULT EQUAL 0)
|
||||
message(FATAL_ERROR "Unable to get Memgraph DEB version.")
|
||||
else()
|
||||
MESSAGE(STATUS "Memgraph DEB version: ${MEMGRAPH_VERSION_DEB}")
|
||||
endif()
|
||||
|
||||
# Get version that should be used in the RPM package.
|
||||
execute_process(
|
||||
OUTPUT_VARIABLE MEMGRAPH_VERSION_RPM
|
||||
RESULT_VARIABLE MEMGRAPH_VERSION_RPM_RESULT
|
||||
COMMAND "${get_version_script}" ${get_version_enterprise}
|
||||
--variant rpm
|
||||
"${MEMGRAPH_OVERRIDE_VERSION}"
|
||||
"${MEMGRAPH_OVERRIDE_VERSION_SUFFIX}"
|
||||
"--memgraph-root-dir"
|
||||
"${CMAKE_SOURCE_DIR}"
|
||||
)
|
||||
if(MEMGRAPH_VERSION_RPM_RESULT AND NOT MEMGRAPH_VERSION_RPM_RESULT EQUAL 0)
|
||||
message(FATAL_ERROR "Unable to get Memgraph RPM version.")
|
||||
else()
|
||||
MESSAGE(STATUS "Memgraph RPM version: ${MEMGRAPH_VERSION_RPM}")
|
||||
endif()
|
||||
|
||||
# We want the above variables to be updated each time something is committed to
|
||||
# the repository. That is why we include a dependency on the current git HEAD
|
||||
# to trigger a new CMake run when the git repository state changes. This is a
|
||||
# hack, as CMake doesn't have a mechanism to regenerate variables when
|
||||
# something changes (only files can be regenerated).
|
||||
# https://cmake.org/pipermail/cmake/2018-October/068389.html
|
||||
#
|
||||
# The hack in the above link is nearly correct but it has a fatal flaw. The
|
||||
# `CMAKE_CONFIGURE_DEPENDS` isn't a `GLOBAL` property, it is instead a
|
||||
# `DIRECTORY` property and as such must be set in the `DIRECTORY` scope.
|
||||
# https://cmake.org/cmake/help/v3.14/manual/cmake-properties.7.html
|
||||
#
|
||||
# Unlike the above mentioned hack, we don't use the `.git/index` file. That
|
||||
# file changes on every `git add` (even on `git status`) so it triggers
|
||||
# unnecessary recalculations of the release version. The release version only
|
||||
# changes on every `git commit` or `git checkout`. That is why we watch the
|
||||
# following files for changes:
|
||||
# - `.git/HEAD` -> changes each time a `git checkout` is issued
|
||||
# - `.git/refs/heads/...` -> the value in `.git/HEAD` is a branch name (when
|
||||
# you are on a branch) and you have to monitor the file of the specific
|
||||
# branch to detect when a `git commit` was issued
|
||||
# More details about the contents of the `.git` directory and the specific
|
||||
# files used can be seen here:
|
||||
# https://git-scm.com/book/en/v2/Git-Internals-Git-References
|
||||
set(git_directory "${CMAKE_SOURCE_DIR}/.git")
|
||||
if (EXISTS "${git_directory}")
|
||||
set_property(DIRECTORY APPEND PROPERTY
|
||||
CMAKE_CONFIGURE_DEPENDS "${git_directory}/HEAD")
|
||||
file(STRINGS "${git_directory}/HEAD" git_head_data)
|
||||
if (git_head_data MATCHES "^ref: ")
|
||||
string(SUBSTRING "${git_head_data}" 5 -1 git_head_ref)
|
||||
set_property(DIRECTORY APPEND PROPERTY
|
||||
CMAKE_CONFIGURE_DEPENDS "${git_directory}/${git_head_ref}")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
# setup CMake module path, defines path for include() and find_package()
|
||||
# https://cmake.org/cmake/help/latest/variable/CMAKE_MODULE_PATH.html
|
||||
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${PROJECT_SOURCE_DIR}/cmake)
|
||||
# custom function definitions
|
||||
include(functions)
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
# We want out of source builds, so that cmake generated files don't get mixed
|
||||
# with source files. This allows for easier clean up.
|
||||
disallow_in_source_build()
|
||||
add_custom_target(clean_all
|
||||
COMMAND ${CMAKE_COMMAND} -P ${PROJECT_SOURCE_DIR}/cmake/clean_all.cmake
|
||||
COMMENT "Removing all files in ${CMAKE_BINARY_DIR}")
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
# build flags -----------------------------------------------------------------
|
||||
|
||||
# Export the compile commands so that we can use clang-tidy. Additional benefit
|
||||
# is easier debugging of compilation and linker flags.
|
||||
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
||||
|
||||
set(CMAKE_CXX_STANDARD 20)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
# c99-designator is disabled because of required mixture of designated and
|
||||
# non-designated initializers in Python Query Module code (`py_module.cpp`).
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall \
|
||||
-Werror=switch -Werror=switch-bool -Werror=return-type \
|
||||
-Werror=return-stack-address \
|
||||
-Wno-c99-designator")
|
||||
|
||||
# Don't omit frame pointer in RelWithDebInfo, for additional callchain debug.
|
||||
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO
|
||||
"${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -fno-omit-frame-pointer")
|
||||
|
||||
# Statically link libgcc and libstdc++, the GCC allows this according to:
|
||||
# https://gcc.gnu.org/onlinedocs/gcc-10.2.0/libstdc++/manual/manual/license.html
|
||||
# https://www.gnu.org/licenses/gcc-exception-faq.html
|
||||
# Last checked for gcc-10.2 which we are using on the build machines.
|
||||
# ** If we change versions, recheck this! **
|
||||
# ** Static linking is allowed only for executables! **
|
||||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static-libgcc -static-libstdc++")
|
||||
|
||||
# Use gold linker to speedup build
|
||||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fuse-ld=gold")
|
||||
|
||||
# release flags
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "-O2 -DNDEBUG")
|
||||
|
||||
#debug flags
|
||||
set(PREFERRED_DEBUGGER "gdb" CACHE STRING
|
||||
"Tunes the debug output for your preferred debugger (gdb or lldb).")
|
||||
if ("${PREFERRED_DEBUGGER}" STREQUAL "gdb" AND
|
||||
"${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang|GNU")
|
||||
set(CMAKE_CXX_FLAGS_DEBUG "-ggdb")
|
||||
elseif ("${PREFERRED_DEBUGGER}" STREQUAL "lldb" AND
|
||||
"${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
|
||||
set(CMAKE_CXX_FLAGS_DEBUG "-glldb")
|
||||
else()
|
||||
message(WARNING "Unable to tune for PREFERRED_DEBUGGER: "
|
||||
"'${PREFERRED_DEBUGGER}' with compiler: '${CMAKE_CXX_COMPILER_ID}'")
|
||||
set(CMAKE_CXX_FLAGS_DEBUG "-g")
|
||||
endif()
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
# default build type is debug
|
||||
if (NOT CMAKE_BUILD_TYPE)
|
||||
set(CMAKE_BUILD_TYPE "Debug")
|
||||
endif()
|
||||
message(STATUS "CMake build type: ${CMAKE_BUILD_TYPE}")
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
# setup external dependencies -------------------------------------------------
|
||||
|
||||
# threading
|
||||
find_package(Threads REQUIRED)
|
||||
# optional readline
|
||||
option(USE_READLINE "Use GNU Readline library if available (default ON). \
|
||||
Set this to OFF to prevent linking with Readline even if it is available." ON)
|
||||
if (USE_READLINE)
|
||||
find_package(Readline)
|
||||
if (READLINE_FOUND)
|
||||
add_definitions(-DHAS_READLINE)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
set(libs_dir ${CMAKE_SOURCE_DIR}/libs)
|
||||
add_subdirectory(libs EXCLUDE_FROM_ALL)
|
||||
|
||||
# Optional subproject configuration -------------------------------------------
|
||||
option(TEST_COVERAGE "Generate coverage reports from running memgraph" OFF)
|
||||
option(TOOLS "Build tools binaries" ON)
|
||||
option(QUERY_MODULES "Build query modules containing custom procedures" ON)
|
||||
option(ASAN "Build with Address Sanitizer. To get a reasonable performance option should be used only in Release or RelWithDebInfo build " OFF)
|
||||
option(TSAN "Build with Thread Sanitizer. To get a reasonable performance option should be used only in Release or RelWithDebInfo build " OFF)
|
||||
option(UBSAN "Build with Undefined Behaviour Sanitizer" OFF)
|
||||
|
||||
if (TEST_COVERAGE)
|
||||
string(TOLOWER ${CMAKE_BUILD_TYPE} lower_build_type)
|
||||
if (NOT lower_build_type STREQUAL "debug")
|
||||
message(FATAL_ERROR "Generating test coverage unsupported in non Debug builds. Current build type is '${CMAKE_BUILD_TYPE}'")
|
||||
endif()
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fprofile-instr-generate -fcoverage-mapping")
|
||||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fprofile-instr-generate -fcoverage-mapping")
|
||||
endif()
|
||||
|
||||
if (MG_ENTERPRISE)
|
||||
add_definitions(-DMG_ENTERPRISE)
|
||||
endif()
|
||||
|
||||
if (ASAN)
|
||||
# Enable Addres sanitizer and get nicer stack traces in error messages.
|
||||
# NOTE: AddressSanitizer uses llvm-symbolizer binary from the Clang
|
||||
# distribution to symbolize the stack traces (note that ideally the
|
||||
# llvm-symbolizer version must match the version of ASan runtime library).
|
||||
# Just make sure llvm-symbolizer is in PATH before running the binary or
|
||||
# provide it in separate ASAN_SYMBOLIZER_PATH environment variable.
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address -fno-omit-frame-pointer")
|
||||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fsanitize=address")
|
||||
# To detect Stack-use-after-return bugs set run-time flag:
|
||||
# ASAN_OPTIONS=detect_stack_use_after_return=1
|
||||
# To check initialization order bugs set run-time flag:
|
||||
# ASAN_OPTIONS=check_initialization_order=true
|
||||
# This mode reports an error if initializer for a global variable accesses
|
||||
# dynamically initialized global from another translation unit, which is
|
||||
# not yet initialized
|
||||
# ASAN_OPTIONS=strict_init_order=true
|
||||
# This mode reports an error if initializer for a global variable accesses
|
||||
# any dynamically initialized global from another translation unit.
|
||||
endif()
|
||||
|
||||
if (TSAN)
|
||||
# ThreadSanitizer generally requires all code to be compiled with -fsanitize=thread.
|
||||
# If some code (e.g. dynamic libraries) is not compiled with the flag, it can
|
||||
# lead to false positive race reports, false negative race reports and/or
|
||||
# missed stack frames in reports depending on the nature of non-instrumented
|
||||
# code. To not produce false positive reports ThreadSanitizer has to see all
|
||||
# synchronization in the program, some synchronization operations (namely,
|
||||
# atomic operations and thread-safe static initialization) are intercepted
|
||||
# during compilation (and can only be intercepted during compilation).
|
||||
# ThreadSanitizer stack trace collection also relies on compiler instrumentation
|
||||
# (unwinding stack on each memory access is too expensive).
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=thread")
|
||||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fsanitize=thread")
|
||||
# By default ThreadSanitizer uses addr2line utility to symbolize reports.
|
||||
# llvm-symbolizer is faster, consumes less memory and produces much better
|
||||
# reports. To use it set runtime flag:
|
||||
# TSAN_OPTIONS="extern-symbolizer-path=~/llvm-symbolizer"
|
||||
# For more runtime flags see: https://github.com/google/sanitizers/wiki/ThreadSanitizerFlags
|
||||
endif()
|
||||
|
||||
if (UBSAN)
|
||||
# Compile with UBSAN but disable vptr check. This is disabled because it
|
||||
# requires linking with clang++ to make sure C++ specific parts of the
|
||||
# runtime library and c++ standard libraries are present.
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=undefined -fno-omit-frame-pointer -fno-sanitize=vptr")
|
||||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fsanitize=undefined -fno-sanitize=vptr")
|
||||
# Run program with environment variable UBSAN_OPTIONS=print_stacktrace=1.
|
||||
# Make sure llvm-symbolizer binary is in path.
|
||||
# To make the program abort on undefined behavior, use UBSAN_OPTIONS=halt_on_error=1.
|
||||
endif()
|
||||
|
||||
set(MG_PYTHON_VERSION "" CACHE STRING "Specify the exact python version used by the query modules")
|
||||
|
||||
# Add subprojects
|
||||
include_directories(src)
|
||||
add_subdirectory(src)
|
||||
|
||||
# Release configuration
|
||||
add_subdirectory(release)
|
||||
|
||||
enable_testing()
|
||||
add_subdirectory(tests)
|
||||
|
||||
if(TOOLS)
|
||||
add_subdirectory(tools)
|
||||
endif()
|
||||
|
||||
if(QUERY_MODULES)
|
||||
add_subdirectory(query_modules)
|
||||
endif()
|
||||
|
||||
install(FILES ${CMAKE_BINARY_DIR}/bin/mgconsole
|
||||
PERMISSIONS OWNER_EXECUTE OWNER_READ OWNER_WRITE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE
|
||||
TYPE BIN)
|
||||
@@ -1 +0,0 @@
|
||||
* @gitbuda @antonio2368 @antaljanosbenjamin @kostasrim @jbajic
|
||||
127
CODE_OF_CONDUCT.md
Normal file
127
CODE_OF_CONDUCT.md
Normal file
@@ -0,0 +1,127 @@
|
||||
# Contributor Covenant Code of Conduct
|
||||
|
||||
## Our Pledge
|
||||
|
||||
We as members, contributors, and leaders pledge to make participation in our
|
||||
community a harassment-free experience for everyone, regardless of age, body
|
||||
size, visible or invisible disability, ethnicity, sex characteristics, gender
|
||||
identity and expression, level of experience, education, socio-economic status,
|
||||
nationality, personal appearance, race, caste, color, religion, or sexual
|
||||
identity and orientation.
|
||||
|
||||
We pledge to act and interact in ways that contribute to an open, welcoming,
|
||||
diverse, inclusive, and healthy community.
|
||||
|
||||
## Our Standards
|
||||
|
||||
Examples of behavior that contributes to a positive environment for our
|
||||
community include:
|
||||
|
||||
- Demonstrating empathy and kindness toward other people
|
||||
- Being respectful of differing opinions, viewpoints, and experiences
|
||||
- Giving and gracefully accepting constructive feedback
|
||||
- Accepting responsibility and apologizing to those affected by our mistakes,
|
||||
and learning from the experience
|
||||
- Focusing on what is best not just for us as individuals, but for the overall
|
||||
community
|
||||
|
||||
Examples of unacceptable behavior include:
|
||||
|
||||
- The use of sexualized language or imagery, and sexual attention or advances of
|
||||
any kind
|
||||
- Trolling, insulting or derogatory comments, and personal or political attacks
|
||||
- Public or private harassment
|
||||
- Publishing other's private information, such as a physical or email address,
|
||||
without their explicit permission
|
||||
- Other conduct which could reasonably be considered inappropriate in a
|
||||
professional setting
|
||||
|
||||
## Enforcement Responsibilities
|
||||
|
||||
Community leaders are responsible for clarifying and enforcing our standards of
|
||||
acceptable behavior and will take appropriate and fair corrective action in
|
||||
response to any behavior that they deem inappropriate, threatening, offensive,
|
||||
or harmful.
|
||||
|
||||
Community leaders have the right and responsibility to remove, edit, or reject
|
||||
comments, commits, code, wiki edits, issues, and other contributions that are
|
||||
not aligned to this Code of Conduct, and will communicate reasons for moderation
|
||||
decisions when appropriate.
|
||||
|
||||
## Scope
|
||||
|
||||
This Code of Conduct applies within all community spaces, and also applies when
|
||||
an individual is officially representing the community in public spaces.
|
||||
Examples of representing our community include using an official e-mail address,
|
||||
posting via an official social media account, or acting as an appointed
|
||||
representative at an online or offline event.
|
||||
|
||||
## Enforcement
|
||||
|
||||
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
||||
reported to the community leaders responsible for enforcement at
|
||||
[contact@memgraph.com](contact@memgraph.com). All complaints will be reviewed
|
||||
and investigated promptly and fairly.
|
||||
|
||||
All community leaders are obligated to respect the privacy and security of the
|
||||
reporter of any incident.
|
||||
|
||||
## Enforcement Guidelines
|
||||
|
||||
Community leaders will follow these Community Impact Guidelines in determining
|
||||
the consequences for any action they deem in violation of this Code of Conduct:
|
||||
|
||||
### 1. Correction
|
||||
|
||||
**Community Impact**: Use of inappropriate language or other behavior deemed
|
||||
unprofessional or unwelcome in the community.
|
||||
|
||||
**Consequence**: A private, written warning from community leaders, providing
|
||||
clarity around the nature of the violation and an explanation of why the
|
||||
behavior was inappropriate. A public apology may be requested.
|
||||
|
||||
### 2. Warning
|
||||
|
||||
**Community Impact**: A violation through a single incident or series of
|
||||
actions.
|
||||
|
||||
**Consequence**: A warning with consequences for continued behavior. No
|
||||
interaction with the people involved, including unsolicited interaction with
|
||||
those enforcing the Code of Conduct, for a specified period of time. This
|
||||
includes avoiding interactions in community spaces as well as external channels
|
||||
like social media. Violating these terms may lead to a temporary or permanent
|
||||
ban.
|
||||
|
||||
### 3. Temporary Ban
|
||||
|
||||
**Community Impact**: A serious violation of community standards, including
|
||||
sustained inappropriate behavior.
|
||||
|
||||
**Consequence**: A temporary ban from any sort of interaction or public
|
||||
communication with the community for a specified period of time. No public or
|
||||
private interaction with the people involved, including unsolicited interaction
|
||||
with those enforcing the Code of Conduct, is allowed during this period.
|
||||
Violating these terms may lead to a permanent ban.
|
||||
|
||||
### 4. Permanent Ban
|
||||
|
||||
**Community Impact**: Demonstrating a pattern of violation of community
|
||||
standards, including sustained inappropriate behavior, harassment of an
|
||||
individual, or aggression toward or disparagement of classes of individuals.
|
||||
|
||||
**Consequence**: A permanent ban from any sort of public interaction within the
|
||||
community.
|
||||
|
||||
## Attribution
|
||||
|
||||
This Code of Conduct is adapted from the Contributor Covenant, version 2.1,
|
||||
available at
|
||||
[https://www.contributor-covenant.org/version/2/1/code_of_conduct.html](https://www.contributor-covenant.org/version/2/1/code_of_conduct.html).
|
||||
|
||||
Community Impact Guidelines were inspired by [Mozilla's code of conduct
|
||||
enforcement ladder][mozilla coc].
|
||||
|
||||
For answers to common questions about this code of conduct, see the FAQ at
|
||||
[https://www.contributor-covenant.org/faq](https://www.contributor-covenant.org/faq).
|
||||
Translations are available at
|
||||
[https://www.contributor-covenant.org/translations](https://www.contributor-covenant.org/translations).
|
||||
121
CONTRIBUTING.md
Normal file
121
CONTRIBUTING.md
Normal file
@@ -0,0 +1,121 @@
|
||||
# How to contribute?
|
||||
|
||||
This is a general purpose guide for contributing to Memgraph. We're still
|
||||
working out the kinks to make contributing to this project as easy and
|
||||
transparent as possible, but we're not quite there yet. Hopefully, this document
|
||||
makes the process for contributing clear and answers some questions that you may
|
||||
have.
|
||||
|
||||
- [How to contribute?](#how-to-contribute)
|
||||
- [Open development](#open-development)
|
||||
- [Branch organization](#branch-organization)
|
||||
- [Bugs & changes](#bugs--changes)
|
||||
- [Where to find known issues?](#where-to-find-known-issues)
|
||||
- [Proposing a change](#proposing-a-change)
|
||||
- [Your first pull request](#your-first-pull-request)
|
||||
- [Sending a pull request](#sending-a-pull-request)
|
||||
- [Style guide](#style-guide)
|
||||
- [How to get in touch?](#how-to-get-in-touch)
|
||||
- [Code of Conduct](#code-of-conduct)
|
||||
- [License](#license)
|
||||
- [Attribution](#attribution)
|
||||
|
||||
## Open development
|
||||
|
||||
All work on Memgraph is done via [GitHub](https://github.com/memgraph/memgraph).
|
||||
Both core team members and external contributors send pull requests which go
|
||||
through the same review process.
|
||||
|
||||
## Branch organization
|
||||
|
||||
Most pull requests should target the [`master
|
||||
branch`](https://github.com/memgraph/memgraph/tree/master). We only use separate
|
||||
branches for developing new features and fixing bugs before they are merged with
|
||||
`master`. We do our best to keep `master` in good shape, with all tests passing.
|
||||
|
||||
Code that lands in `master` must be compatible with the latest stable release.
|
||||
It may contain additional features but no breaking changes if it's not
|
||||
absolutely necessary. We should be able to release a new minor version from the
|
||||
tip of `master` at any time.
|
||||
|
||||
## Bugs & changes
|
||||
|
||||
### Where to find known issues?
|
||||
|
||||
We are using [GitHub Issues](https://github.com/memgraph/memgraph/issues) for
|
||||
our public bugs. We keep a close eye on this and try to make it clear when we
|
||||
have an internal fix in progress. Before filing a new task, try to make sure
|
||||
your problem doesn't already exist.
|
||||
|
||||
### Proposing a change
|
||||
|
||||
If you intend to change the public API, or make any non-trivial changes to the
|
||||
implementation, we recommend [filing an
|
||||
issue](https://github.com/memgraph/memgraph/issues/new). This lets us reach an
|
||||
agreement on your proposal before you put significant effort into it.
|
||||
|
||||
If you're only fixing a bug, it's fine to submit a pull request right away but
|
||||
we still recommend to file an issue detailing what you're fixing. This is
|
||||
helpful in case we don't accept that specific fix but want to keep track of the
|
||||
issue.
|
||||
|
||||
### Your first pull request
|
||||
|
||||
Working on your first Pull Request? You can learn how from this free video
|
||||
series:
|
||||
|
||||
**[How to Contribute to an Open Source Project on
|
||||
GitHub](https://app.egghead.io/courses/how-to-contribute-to-an-open-source-project-on-github)**
|
||||
|
||||
If you decide to fix an issue, please be sure to check the comment thread in
|
||||
case somebody is already working on a fix. If nobody is working on it at the
|
||||
moment, please leave a comment stating that you intend to work on it so other
|
||||
people don't accidentally duplicate your effort.
|
||||
|
||||
If somebody claims an issue but doesn't follow up for more than two weeks, it's
|
||||
fine to take it over but you should still leave a comment.
|
||||
|
||||
### Sending a pull request
|
||||
|
||||
The core team is monitoring for pull requests. We will review your pull request
|
||||
and either merge it, request changes to it, or close it with an explanation.
|
||||
**Before submitting a pull request,** please make sure the following is done:
|
||||
|
||||
1. Fork [the repository](https://github.com/memgraph/memgraph) and create your
|
||||
branch from `master`.
|
||||
2. If you've fixed a bug or added code that should be tested, add tests!
|
||||
3. Use the formatter `clang-format` for C/C++ code and `flake8` for Python code.
|
||||
`clang-format` will automatically detect the `.clang-format` file in the root
|
||||
directory while `flake8` can be used with the default configuration.
|
||||
|
||||
### Style guide
|
||||
|
||||
Memgraph uses the [Google Style
|
||||
Guide](https://google.github.io/styleguide/cppguide.html) for C++ in most of its
|
||||
code. You should follow them whenever writing new code.
|
||||
|
||||
## How to get in touch?
|
||||
|
||||
Aside from communicating directly via Pull Requests and Issues, the Memgraph
|
||||
Community [Discord Server](https://discord.gg/memgraph) is the best place for
|
||||
conversing with project maintainers and other community members.
|
||||
|
||||
## [Code of Conduct](https://github.com/memgraph/memgraph/blob/master/CODE_OF_CONDUCT.md)
|
||||
|
||||
Memgraph has adopted the [Contributor
|
||||
Covenant](https://www.contributor-covenant.org/) as its Code of Conduct, and we
|
||||
expect project participants to adhere to it. Please read [the full
|
||||
text](https://github.com/memgraph/memgraph/blob/master/CODE_OF_CONDUCT.md) so
|
||||
that you can understand what actions will and will not be tolerated.
|
||||
|
||||
## License
|
||||
|
||||
By contributing to Memgraph, you agree that your contributions will be licensed
|
||||
under the [Memgraph licensing
|
||||
scheme](https://github.com/memgraph/memgraph/blob/master/LICENSE).
|
||||
|
||||
## Attribution
|
||||
|
||||
This Contributing guide is adapted from the **React.js Contributing guide**
|
||||
available at
|
||||
[https://reactjs.org/docs/how-to-contribute.html](https://reactjs.org/docs/how-to-contribute.html).
|
||||
5
LICENSE
Normal file
5
LICENSE
Normal file
@@ -0,0 +1,5 @@
|
||||
Source code in this repository is variously licensed under the Business Source
|
||||
License 1.1 (BSL), the Memgraph Enterprise License (MEL). A copy of each licence
|
||||
can be found in the licences directory. Source code in a given file is licensed
|
||||
under the BSL and the copyright belongs to The Memgraph Authors unless
|
||||
otherwise noted at th beginning of the file.
|
||||
194
README.md
194
README.md
@@ -1,21 +1,187 @@
|
||||
# Memgraph
|
||||
<p align="center">
|
||||
<img width="400px" src="https://uploads-ssl.webflow.com/5e7ceb09657a69bdab054b3a/5e7ceb09657a6937ab054bba_Black_Original%20_Logo.png">
|
||||
</p>
|
||||
|
||||
Memgraph is an ACID compliant high performance transactional distributed
|
||||
in-memory graph database featuring runtime native query compiling, lock free
|
||||
data structures, multi-version concurrency control and asynchronous IO.
|
||||
---
|
||||
|
||||
## Development Documentation
|
||||
<p align="center">
|
||||
<a href="https://github.com/memgraph/memgraph/blob/master/licenses/APL.txt">
|
||||
<img src="https://img.shields.io/badge/license-APL-green" alt="license" title="license"/>
|
||||
</a>
|
||||
<a href="https://github.com/memgraph/memgraph/blob/master/licenses/BSL.txt">
|
||||
<img src="https://img.shields.io/badge/license-BSL-yellowgreen" alt="license" title="license"/>
|
||||
</a>
|
||||
<a href="https://github.com/memgraph/memgraph/blob/master/licenses/MEL.txt" alt="Documentation">
|
||||
<img src="https://img.shields.io/badge/license-MEL-yellow" alt="license" title="license"/>
|
||||
</a>
|
||||
</p>
|
||||
|
||||
Please continue in
|
||||
[Notion](https://www.notion.so/memgraph/memgraph-0428591638604c8385550e214ea9f3e6).
|
||||
<p align="center">
|
||||
<a href="https://github.com/memgraph/memgraph">
|
||||
<img src="https://img.shields.io/github/actions/workflow/status/memgraph/memgraph/release_debian10.yaml?branch=master&label=build%20and%20test&logo=github"/>
|
||||
</a>
|
||||
<a href="https://memgraph.com/docs/" alt="Documentation">
|
||||
<img src="https://img.shields.io/badge/documentation-Memgraph-orange" />
|
||||
</a>
|
||||
</p>
|
||||
|
||||
## User Documentation
|
||||
<p align="center">
|
||||
<a href="https://memgr.ph/join-discord">
|
||||
<img src="https://img.shields.io/badge/Discord-7289DA?style=for-the-badge&logo=discord&logoColor=white" alt="Discord"/>
|
||||
</a>
|
||||
</p>
|
||||
|
||||
Memgraph user documentation is maintained within
|
||||
[docs](https://github.com/memgraph/docs) repository. The documentation is also
|
||||
available on [GitBook](https://docs.memgraph.com).
|
||||
## :clipboard: Description
|
||||
|
||||
## Licences
|
||||
Memgraph is an open source graph database built for real-time streaming and
|
||||
compatible with Neo4j. Whether you're a developer or a data scientist with
|
||||
interconnected data, Memgraph will get you the immediate actionable insights
|
||||
fast.
|
||||
|
||||
* [Community](release/LICENSE_COMMUNITY.md)
|
||||
* [Enterprise](release/LICENSE_ENTERPRISE.md)
|
||||
Memgraph directly connects to your streaming infrastructure. You can ingest data
|
||||
from sources like Kafka, SQL, or plain CSV files. Memgraph provides a standard
|
||||
interface to query your data with Cypher, a widely-used and declarative query
|
||||
language that is easy to write, understand and optimize for performance. This is
|
||||
achieved by using the property graph data model, which stores data in terms of
|
||||
objects, their attributes, and the relationships that connect them. This is a
|
||||
natural and effective way to model many real-world problems without relying on
|
||||
complex SQL schemas.
|
||||
|
||||
Memgraph is implemented in C/C++ and leverages an in-memory first architecture
|
||||
to ensure that you’re getting the [best possible
|
||||
performance](http://memgraph.com/benchgraph) consistently and without surprises.
|
||||
It’s also ACID-compliant and highly available.
|
||||
|
||||
## :zap: Features
|
||||
|
||||
- Run Python, Rust, and C/C++ code natively, check out the
|
||||
[MAGE](https://github.com/memgraph/mage) graph algorithm library
|
||||
- Native support for machine learning
|
||||
- Streaming support
|
||||
- Replication
|
||||
- Authentication and authorization
|
||||
- ACID compliance
|
||||
|
||||
|
||||
## :video_game: Memgraph Playground
|
||||
|
||||
You don't need to install anything to try out Memgraph. Check out
|
||||
our **[Memgraph Playground](https://playground.memgraph.com/)** sandboxes in
|
||||
your browser.
|
||||
|
||||
<p align="left">
|
||||
<a href="https://playground.memgraph.com/">
|
||||
<img width="450px" alt="Memgraph Playground" src="https://download.memgraph.com/asset/github/memgraph/memgraph-playground.png">
|
||||
</a>
|
||||
</p>
|
||||
|
||||
## :floppy_disk: Download & Install
|
||||
|
||||
### Windows
|
||||
|
||||
[](https://memgraph.com/docs/memgraph/install-memgraph-on-windows-docker)
|
||||
[](https://memgraph.com/docs/memgraph/install-memgraph-on-windows-wsl)
|
||||
|
||||
### macOS
|
||||
|
||||
[](https://memgraph.com/docs/memgraph/install-memgraph-on-macos-docker)
|
||||
[](https://memgraph.com/docs/memgraph/install-memgraph-on-ubuntu)
|
||||
|
||||
### Linux
|
||||
|
||||
[](https://memgraph.com/docs/memgraph/install-memgraph-on-linux-docker)
|
||||
[](https://memgraph.com/docs/memgraph/install-memgraph-on-debian)
|
||||
[](https://memgraph.com/docs/memgraph/install-memgraph-on-ubuntu)
|
||||
[](https://memgraph.com/docs/memgraph/install-memgraph-from-rpm)
|
||||
[](https://memgraph.com/docs/memgraph/install-memgraph-from-rpm)
|
||||
[](https://memgraph.com/docs/memgraph/install-memgraph-from-rpm)
|
||||
|
||||
You can find the binaries and Docker images on the [Download
|
||||
Hub](https://memgraph.com/download) and the installation instructions in the
|
||||
[official documentation](https://memgraph.com/docs/memgraph/installation).
|
||||
|
||||
|
||||
## :cloud: Memgraph Cloud
|
||||
|
||||
Check out [Memgraph Cloud](https://memgraph.com/docs/memgraph-cloud) - a cloud service fully managed on AWS and available in 6 geographic regions around the world. Memgraph Cloud allows you to create projects with Enterprise instances of MemgraphDB from your browser.
|
||||
|
||||
<p align="left">
|
||||
<a href="https://memgraph.com/docs/memgraph-cloud">
|
||||
<img width="450px" alt="Memgraph Cloud" src="https://public-assets.memgraph.com/memgraph-gifs%2Fcloud.gif">
|
||||
</a>
|
||||
</p>
|
||||
|
||||
## :link: Connect to Memgraph
|
||||
|
||||
[Connect to the database](https://memgraph.com/docs/memgraph/connect-to-memgraph) using Memgraph Lab, mgconsole, various drivers (Python, C/C++ and others) and WebSocket.
|
||||
|
||||
### :microscope: Memgraph Lab
|
||||
|
||||
Visualize graphs and play with queries to understand your data. [Memgraph Lab](https://memgraph.com/docs/memgraph-lab) is a user interface that helps you explore and manipulate the data stored in Memgraph. Visualize graphs, execute ad hoc queries, and optimize their performance.
|
||||
|
||||
<p align="left">
|
||||
<a href="https://memgraph.com/docs/memgraph-lab">
|
||||
<img width="450px" alt="Memgraph Cloud" src="https://public-assets.memgraph.com/memgraph-gifs%2Flab.gif">
|
||||
</a>
|
||||
</p>
|
||||
|
||||
## :file_folder: Import data
|
||||
|
||||
[Import data](https://memgraph.com/docs/memgraph/import-data) into Memgraph using Kafka, RedPanda or Pulsar streams, CSV and JSON files, or Cypher commands.
|
||||
|
||||
## :bookmark_tabs: Documentation
|
||||
|
||||
The Memgraph documentation is available at
|
||||
[memgraph.com/docs](https://memgraph.com/docs).
|
||||
|
||||
## :question: Configuration
|
||||
|
||||
Command line options that Memgraph accepts are available in the [reference
|
||||
guide](https://memgraph.com/docs/memgraph/reference-guide/configuration).
|
||||
|
||||
## :trophy: Contributing
|
||||
|
||||
The main purpose of this repository is to continue evolving Memgraph, making it
|
||||
faster and easier to use. Development of Memgraph happens in the open on GitHub,
|
||||
and we are grateful to the community for contributing bug fixes and
|
||||
improvements. Read below to learn how you can take part in improving Memgraph.
|
||||
|
||||
### Code of Conduct
|
||||
|
||||
Memgraph has adopted a Code of Conduct that we expect project participants to
|
||||
adhere to. Please read [the full text](CODE_OF_CONDUCT.md) so that you can
|
||||
understand what actions will and will not be tolerated.
|
||||
|
||||
### Contributing Guide
|
||||
|
||||
Read our [contributing guide](CONTRIBUTING.md) to learn about our development
|
||||
process and how to propose bug fixes and improvements.
|
||||
|
||||
### Internals
|
||||
|
||||
Read our
|
||||
[internal](https://memgraph.notion.site/Memgraph-Internals-12b69132d67a417898972927d6870bd2)
|
||||
docs to learn more about Memgraph's architecture, how to build the project from
|
||||
source and how to start contributing. All information related to the database,
|
||||
can be found in the aforementioned docs.
|
||||
|
||||
### :scroll: License
|
||||
|
||||
Memgraph Community is available under the [BSL
|
||||
license](./licenses/BSL.txt).</br> Memgraph Enterprise is available under the
|
||||
[MEL license](./licenses/MEL.txt).
|
||||
|
||||
## :busts_in_silhouette: Community
|
||||
|
||||
- :purple_heart: [**Discord**](https://discord.gg/memgraph)
|
||||
- :ocean: [**Stack Overflow**](https://stackoverflow.com/questions/tagged/memgraphdb)
|
||||
- :busts_in_silhouette: [**Discourse forum**](https://discourse.memgraph.com/)
|
||||
- :bird: [**Twitter**](https://twitter.com/memgraphdb)
|
||||
- :movie_camera:
|
||||
[**YouTube**](https://www.youtube.com/channel/UCZ3HOJvHGxtQ_JHxOselBYg)
|
||||
|
||||
<p align="center">
|
||||
<a href="#">
|
||||
<img src="https://img.shields.io/badge/⬆️ back_to_top_⬆️-white" alt="Back to top" title="Back to top"/>
|
||||
</a>
|
||||
</p>
|
||||
|
||||
@@ -1,35 +0,0 @@
|
||||
# Find the GNU Readline library.
|
||||
# This module plugs into CMake's `find_package` so the example usage is:
|
||||
# `find_package(Readline REQUIRED)`
|
||||
# Options to `find_package` are as documented in CMake documentation.
|
||||
# READLINE_LIBRARY will be a path to the library.
|
||||
# READLINE_INCLUDE_DIR will be a path to the include directory.
|
||||
# READLINE_FOUND will be TRUE if the library is found.
|
||||
#
|
||||
# If the library is found, an imported target `readline` will be provided. This
|
||||
# can be used for linking via `target_link_libraries`, without the need to
|
||||
# explicitly include READLINE_INCLUDE_DIR and link with READLINE_LIBRARY. For
|
||||
# example: `target_link_libraries(my_executable readline)`.
|
||||
if (READLINE_LIBRARY AND READLINE_INCLUDE_DIR)
|
||||
set(READLINE_FOUND TRUE)
|
||||
else()
|
||||
find_library(READLINE_LIBRARY readline)
|
||||
find_path(READLINE_INCLUDE_DIR readline/readline.h)
|
||||
if (READLINE_LIBRARY AND READLINE_INCLUDE_DIR)
|
||||
set(READLINE_FOUND TRUE)
|
||||
if (NOT READLINE_FIND_QUIETLY)
|
||||
message(STATUS "Found Readline: ${READLINE_LIBRARY} ${READLINE_INCLUDE_DIR}")
|
||||
endif()
|
||||
else()
|
||||
set(READLINE_FOUND FALSE)
|
||||
if (READLINE_FIND_REQUIRED)
|
||||
message(FATAL_ERROR "Could not find Readline")
|
||||
elseif (NOT READLINE_FIND_QUIETLY)
|
||||
message(STATUS "Could not find Readline")
|
||||
endif()
|
||||
endif()
|
||||
mark_as_advanced(READLINE_LIBRARY READLINE_INCLUDE_DIR)
|
||||
add_library(readline SHARED IMPORTED)
|
||||
set_property(TARGET readline PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${READLINE_INCLUDE_DIR})
|
||||
set_property(TARGET readline PROPERTY IMPORTED_LOCATION ${READLINE_LIBRARY})
|
||||
endif()
|
||||
@@ -1,90 +0,0 @@
|
||||
#.rst:
|
||||
# FindSeccomp
|
||||
# -----------
|
||||
#
|
||||
# Try to locate the libseccomp library.
|
||||
# If found, this will define the following variables:
|
||||
#
|
||||
# ``Seccomp_FOUND``
|
||||
# True if the seccomp library is available
|
||||
# ``Seccomp_INCLUDE_DIRS``
|
||||
# The seccomp include directories
|
||||
# ``Seccomp_LIBRARIES``
|
||||
# The seccomp libraries for linking
|
||||
#
|
||||
# If ``Seccomp_FOUND`` is TRUE, it will also define the following
|
||||
# imported target:
|
||||
#
|
||||
# ``Seccomp::Seccomp``
|
||||
# The Seccomp library
|
||||
#
|
||||
# Since 5.44.0.
|
||||
|
||||
#=============================================================================
|
||||
# Copyright (c) 2017 Martin Flöser <mgraesslin@kde.org>
|
||||
# Copyright (c) 2017 David Kahles <david.kahles96@gmail.com>
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions
|
||||
# are met:
|
||||
#
|
||||
# 1. Redistributions of source code must retain the copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
# 2. Redistributions in binary form must reproduce the copyright
|
||||
# notice, this list of conditions and the following disclaimer in the
|
||||
# documentation and/or other materials provided with the distribution.
|
||||
# 3. The name of the author may not be used to endorse or promote products
|
||||
# derived from this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#=============================================================================
|
||||
|
||||
find_package(PkgConfig QUIET)
|
||||
pkg_check_modules(PKG_Libseccomp QUIET libseccomp)
|
||||
|
||||
find_path(Seccomp_INCLUDE_DIRS
|
||||
NAMES
|
||||
seccomp.h
|
||||
HINTS
|
||||
${PKG_Libseccomp_INCLUDE_DIRS}
|
||||
)
|
||||
find_library(Seccomp_LIBRARIES
|
||||
NAMES
|
||||
seccomp
|
||||
HINTS
|
||||
${PKG_Libseccomp_LIBRARY_DIRS}
|
||||
)
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
find_package_handle_standard_args(Seccomp
|
||||
FOUND_VAR
|
||||
Seccomp_FOUND
|
||||
REQUIRED_VARS
|
||||
Seccomp_LIBRARIES
|
||||
Seccomp_INCLUDE_DIRS
|
||||
)
|
||||
|
||||
if (Seccomp_FOUND AND NOT TARGET Seccomp::Seccomp)
|
||||
add_library(Seccomp::Seccomp UNKNOWN IMPORTED)
|
||||
set_target_properties(Seccomp::Seccomp PROPERTIES
|
||||
IMPORTED_LOCATION "${Seccomp_LIBRARIES}"
|
||||
INTERFACE_INCLUDE_DIRECTORIES "${Seccomp_INCLUDE_DIRS}"
|
||||
)
|
||||
endif()
|
||||
|
||||
mark_as_advanced(Seccomp_LIBRARIES Seccomp_INCLUDE_DIRS)
|
||||
|
||||
include(FeatureSummary)
|
||||
set_package_properties(Seccomp PROPERTIES
|
||||
URL "https://github.com/seccomp/libseccomp"
|
||||
DESCRIPTION "The enhanced seccomp library."
|
||||
)
|
||||
@@ -1,2 +0,0 @@
|
||||
file(GLOB build_contents "${CMAKE_BINARY_DIR}/*")
|
||||
file(REMOVE_RECURSE ${build_contents})
|
||||
@@ -1,87 +0,0 @@
|
||||
# prints all included directories
|
||||
function(list_includes)
|
||||
get_property(dirs DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
|
||||
PROPERTY INCLUDE_DIRECTORIES)
|
||||
foreach(dir ${dirs})
|
||||
message(STATUS "dir='${dir}'")
|
||||
endforeach()
|
||||
endfunction(list_includes)
|
||||
|
||||
# get file names from list of file paths
|
||||
function(get_file_names file_paths file_names)
|
||||
set(file_names "")
|
||||
foreach(file_path ${file_paths})
|
||||
get_filename_component (file_name ${file_path} NAME_WE)
|
||||
list(APPEND file_names ${file_name})
|
||||
endforeach()
|
||||
set(file_names "${file_names}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
MACRO(SUBDIRLIST result curdir)
|
||||
FILE(GLOB children RELATIVE ${curdir} ${curdir}/*)
|
||||
SET(dirlist "")
|
||||
FOREACH(child ${children})
|
||||
IF(IS_DIRECTORY ${curdir}/${child})
|
||||
LIST(APPEND dirlist ${child})
|
||||
ENDIF()
|
||||
ENDFOREACH()
|
||||
SET(${result} ${dirlist})
|
||||
ENDMACRO()
|
||||
|
||||
function(disallow_in_source_build)
|
||||
get_filename_component(src_dir ${CMAKE_SOURCE_DIR} REALPATH)
|
||||
get_filename_component(bin_dir ${CMAKE_BINARY_DIR} REALPATH)
|
||||
message(STATUS "SOURCE_DIR" ${src_dir})
|
||||
message(STATUS "BINARY_DIR" ${bin_dir})
|
||||
# Do we maybe want to limit out-of-source builds to be only inside a
|
||||
# directory which contains 'build' in name?
|
||||
if("${src_dir}" STREQUAL "${bin_dir}")
|
||||
# Unfortunately, we cannot remove CMakeCache.txt and CMakeFiles here
|
||||
# because they are written after cmake is done.
|
||||
message(FATAL_ERROR "In source build is not supported! "
|
||||
"Remove CMakeCache.txt and CMakeFiles and then create a separate "
|
||||
"directory, e.g. 'build' and run cmake there.")
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
# Takes a string of ';' separated VALUES and stores a new string in RESULT,
|
||||
# where ';' is replaced with given SEP.
|
||||
function(join values sep result)
|
||||
# Match non escaped ';' and replace it with separator. This doesn't handle
|
||||
# the case when backslash is escaped, e.g: "a\\\\;b" will produce "a;b".
|
||||
string(REGEX REPLACE "([^\\]|^);" "\\1${sep}" tmp "${values}")
|
||||
# Fix-up escapes by matching backslashes and removing them.
|
||||
string(REGEX REPLACE "[\\](.)" "\\1" tmp "${tmp}")
|
||||
set(${result} "${tmp}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
# Returns a list of compile flags ready for gcc or clang.
|
||||
function(get_target_cxx_flags target result)
|
||||
# First set the CMAKE_CXX_FLAGS variables, then append directory and target
|
||||
# options in that order. Definitions come last, directory then target.
|
||||
string(TOUPPER ${CMAKE_BUILD_TYPE} build_type)
|
||||
set(flags "${CMAKE_CXX_FLAGS} ${CMAKE_CXX_FLAGS_${build_type}}")
|
||||
get_directory_property(dir_opts DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
|
||||
COMPILE_OPTIONS)
|
||||
if(dir_opts)
|
||||
join("${dir_opts}" " " dir_opts)
|
||||
string(APPEND flags " " ${dir_opts})
|
||||
endif()
|
||||
get_target_property(opts ${target} COMPILE_OPTIONS)
|
||||
if(opts)
|
||||
join("${opts}" " " opts)
|
||||
string(APPEND flags " " ${opts})
|
||||
endif()
|
||||
get_directory_property(dir_defs DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
|
||||
COMPILE_DEFINITIONS)
|
||||
if(dir_defs)
|
||||
join("${dir_defs}" " -D" dir_defs)
|
||||
string(APPEND flags " -D" ${dir_defs})
|
||||
endif()
|
||||
get_target_property(defs ${target} COMPILE_DEFINITIONS)
|
||||
if(defs)
|
||||
join("${defs}" " -D" defs)
|
||||
string(APPEND flags " -D" ${defs})
|
||||
endif()
|
||||
set(${result} ${flags} PARENT_SCOPE)
|
||||
endfunction()
|
||||
@@ -1,103 +0,0 @@
|
||||
header: >-
|
||||
Memgraph Configuration
|
||||
|
||||
This is the main configuration file for Memgraph. You can modify this file to
|
||||
suit your specific needs. Additional configuration can be specified by
|
||||
including another configuration file, in a file pointed to by the
|
||||
'MEMGRAPH_CONFIG' environment variable or by passing arguments on the command
|
||||
line.
|
||||
|
||||
Each configuration setting is in the form: '--setting-name=value'.
|
||||
|
||||
footer: >-
|
||||
Additional Configuration Inclusion
|
||||
|
||||
You can include additional configuration files from this file. Additional
|
||||
files are processed after this file. Settings that are set in the additional
|
||||
files will override previously set values. Additional configuration files are
|
||||
specified with the '--flag-file' flag.
|
||||
|
||||
Example:
|
||||
|
||||
--flag-file=another.conf
|
||||
|
||||
modifications:
|
||||
|
||||
# Each modification should consist of the following parameters:
|
||||
# * name: the name of the flag that should be modified (with underscores)
|
||||
# [string]
|
||||
# * value: the value that should be set instead of the binary provided
|
||||
# default value [string]
|
||||
# * override: set to `true` to uncomment the config option by default
|
||||
# [boolean]
|
||||
|
||||
- name: "data_directory"
|
||||
value: "/var/lib/memgraph"
|
||||
override: true
|
||||
|
||||
- name: "log_file"
|
||||
value: "/var/log/memgraph/memgraph.log"
|
||||
override: true
|
||||
|
||||
- name: "log_level"
|
||||
value: "WARNING"
|
||||
override: true
|
||||
|
||||
- name: "bolt_num_workers"
|
||||
value: ""
|
||||
override: false
|
||||
|
||||
- name: "storage_properties_on_edges"
|
||||
value: "true"
|
||||
override: true
|
||||
|
||||
- name: "storage_recover_on_startup"
|
||||
value: "true"
|
||||
override: true
|
||||
|
||||
- name: "storage_snapshot_interval_sec"
|
||||
value: "300"
|
||||
override: true
|
||||
|
||||
- name: "storage_snapshot_on_exit"
|
||||
value: "true"
|
||||
override: true
|
||||
|
||||
- name: "storage_snapshot_retention_count"
|
||||
value: "3"
|
||||
override: true
|
||||
|
||||
- name: "storage_wal_enabled"
|
||||
value: "true"
|
||||
override: true
|
||||
|
||||
- name: "telemetry_enabled"
|
||||
value: "true"
|
||||
override: true
|
||||
|
||||
- name: "query_modules_directory"
|
||||
value: "/usr/lib/memgraph/query_modules"
|
||||
override: true
|
||||
|
||||
- name: "auth_module_executable"
|
||||
value: "/usr/lib/memgraph/auth_module/example.py"
|
||||
override: false
|
||||
|
||||
- name: "memory_limit"
|
||||
value: "0"
|
||||
override: true
|
||||
|
||||
- name: "isolation_level"
|
||||
value: "SNAPSHOT_ISOLATION"
|
||||
override: true
|
||||
|
||||
- name: "allow_load_csv"
|
||||
value: "true"
|
||||
override: false
|
||||
|
||||
undocumented:
|
||||
- "flag_file"
|
||||
- "also_log_to_stderr"
|
||||
- "help"
|
||||
- "help_xml"
|
||||
- "version"
|
||||
@@ -1,124 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
import argparse
|
||||
import copy
|
||||
import os
|
||||
import subprocess
|
||||
import sys
|
||||
import textwrap
|
||||
|
||||
import xml.etree.ElementTree as ET
|
||||
|
||||
import yaml
|
||||
|
||||
|
||||
SCRIPT_DIR = os.path.dirname(os.path.realpath(__file__))
|
||||
CONFIG_FILE = os.path.join(SCRIPT_DIR, "flags.yaml")
|
||||
WIDTH = 80
|
||||
|
||||
|
||||
def wrap_text(s, initial_indent="# "):
|
||||
return "\n#\n".join(
|
||||
map(lambda x: textwrap.fill(x, WIDTH, initial_indent=initial_indent,
|
||||
subsequent_indent="# "), s.split("\n")))
|
||||
|
||||
|
||||
def extract_flags(binary_path):
|
||||
ret = {}
|
||||
data = subprocess.run([binary_path, "--help-xml"],
|
||||
stdout=subprocess.PIPE).stdout.decode("utf-8")
|
||||
root = ET.fromstring(data)
|
||||
for child in root:
|
||||
if child.tag == "usage" and child.text.lower().count("warning"):
|
||||
raise Exception("You should set the usage message!")
|
||||
if child.tag == "flag":
|
||||
flag = {}
|
||||
for elem in child:
|
||||
flag[elem.tag] = elem.text if elem.text is not None else ""
|
||||
flag["override"] = False
|
||||
ret[flag["name"]] = flag
|
||||
return ret
|
||||
|
||||
|
||||
def apply_config_to_flags(config, flags):
|
||||
flags = copy.deepcopy(flags)
|
||||
for name in config["undocumented"]:
|
||||
flags.pop(name)
|
||||
for modification in config["modifications"]:
|
||||
name = modification["name"]
|
||||
if name not in flags:
|
||||
print("WARNING: Flag '" + name + "' missing from binary!",
|
||||
file=sys.stderr)
|
||||
continue
|
||||
flags[name]["default"] = modification["value"]
|
||||
flags[name]["override"] = modification["override"]
|
||||
return flags
|
||||
|
||||
|
||||
def extract_sections(flags):
|
||||
sections = []
|
||||
other = []
|
||||
current_section = ""
|
||||
current_flags = []
|
||||
for name in sorted(flags.keys()):
|
||||
section = name.split("_")[0]
|
||||
if section == current_section:
|
||||
current_flags.append(name)
|
||||
else:
|
||||
if len(current_flags) < 2:
|
||||
other.extend(current_flags)
|
||||
else:
|
||||
sections.append((current_section, current_flags))
|
||||
current_section = section
|
||||
current_flags = [name]
|
||||
if len(current_flags) < 2:
|
||||
other.extend(current_flags)
|
||||
else:
|
||||
sections.append((current_section, current_flags))
|
||||
sections.append(("other", other))
|
||||
assert set(sum(map(lambda x: x[1], sections), [])) == set(flags.keys()), \
|
||||
"The section extraction algorithm lost some flags!"
|
||||
return sections
|
||||
|
||||
|
||||
def generate_config_file(sections, flags):
|
||||
ret = wrap_text(config["header"]) + "\n\n\n"
|
||||
for section, section_flags in sections:
|
||||
ret += wrap_text(section.capitalize(), initial_indent="## ") + "\n\n"
|
||||
for name in section_flags:
|
||||
flag = flags[name]
|
||||
helpstr = flag["meaning"] + " [" + flag["type"] + "]"
|
||||
ret += wrap_text(helpstr) + "\n"
|
||||
prefix = "# " if not flag["override"] else ""
|
||||
ret += prefix + "--" + flag["name"].replace("_", "-") + \
|
||||
"=" + flag["default"] + "\n\n"
|
||||
ret += "\n"
|
||||
ret += wrap_text(config["footer"])
|
||||
return ret.strip() + "\n"
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument("memgraph_binary",
|
||||
help="path to Memgraph binary")
|
||||
parser.add_argument("output_file",
|
||||
help="path where to store the generated Memgraph "
|
||||
"configuration file")
|
||||
parser.add_argument("--config-file", default=CONFIG_FILE,
|
||||
help="path to generator configuration file")
|
||||
|
||||
args = parser.parse_args()
|
||||
flags = extract_flags(args.memgraph_binary)
|
||||
|
||||
with open(args.config_file) as f:
|
||||
config = yaml.safe_load(f)
|
||||
|
||||
flags = apply_config_to_flags(config, flags)
|
||||
sections = extract_sections(flags)
|
||||
data = generate_config_file(sections, flags)
|
||||
|
||||
dirname = os.path.dirname(args.output_file)
|
||||
if dirname and not os.path.exists(dirname):
|
||||
os.makedirs(dirname)
|
||||
|
||||
with open(args.output_file, "w") as f:
|
||||
f.write(data)
|
||||
@@ -172,7 +172,7 @@ relationshipDetail : '[' ( name=variable )? ( relationshipTypes )? ( variableExp
|
||||
|
||||
relationshipLambda: '(' traversed_edge=variable ',' traversed_node=variable '|' expression ')';
|
||||
|
||||
variableExpansion : '*' (BFS | WSHORTEST)? ( expression )? ( '..' ( expression )? )? ;
|
||||
variableExpansion : '*' (BFS | WSHORTEST | ALLSHORTEST)? ( expression )? ( '..' ( expression )? )? ;
|
||||
|
||||
properties : mapLiteral
|
||||
| parameter
|
||||
@@ -279,7 +279,7 @@ idInColl : variable IN expression ;
|
||||
|
||||
functionInvocation : functionName '(' ( DISTINCT )? ( expression ( ',' expression )* )? ')' ;
|
||||
|
||||
functionName : symbolicName ;
|
||||
functionName : symbolicName ( '.' symbolicName )* ;
|
||||
|
||||
listComprehension : '[' filterExpression ( '|' expression )? ']' ;
|
||||
|
||||
@@ -381,6 +381,7 @@ cypherKeyword : ALL
|
||||
| WHERE
|
||||
| WITH
|
||||
| WSHORTEST
|
||||
| ALLSHORTEST
|
||||
| XOR
|
||||
| YIELD
|
||||
;
|
||||
@@ -139,6 +139,7 @@ WHEN : W H E N ;
|
||||
WHERE : W H E R E ;
|
||||
WITH : W I T H ;
|
||||
WSHORTEST : W S H O R T E S T ;
|
||||
ALLSHORTEST : A L L S H O R T E S T ;
|
||||
XOR : X O R ;
|
||||
YIELD : Y I E L D ;
|
||||
|
||||
@@ -1,3 +1,16 @@
|
||||
/*
|
||||
* Copyright 2021 Memgraph Ltd.
|
||||
*
|
||||
* Use of this software is governed by the Business Source License
|
||||
* included in the file licenses/BSL.txt; by using this file, you agree to be bound by the terms of the Business Source
|
||||
* License, and you may not use this file except in compliance with the Business Source License.
|
||||
*
|
||||
* As of the Change Date specified in that file, in accordance with
|
||||
* the Business Source License, use of this software will be governed
|
||||
* by the Apache License, Version 2.0, included in the file
|
||||
* licenses/APL.txt.
|
||||
*/
|
||||
|
||||
/* Memgraph specific part of Cypher grammar with enterprise features. */
|
||||
|
||||
parser grammar MemgraphCypher ;
|
||||
@@ -16,12 +29,16 @@ memgraphCypherKeyword : cypherKeyword
|
||||
| BATCH_LIMIT
|
||||
| BATCH_SIZE
|
||||
| BEFORE
|
||||
| BOOTSTRAP_SERVERS
|
||||
| CHECK
|
||||
| CLEAR
|
||||
| COMMIT
|
||||
| COMMITTED
|
||||
| CONFIG
|
||||
| CONFIGS
|
||||
| CONSUMER_GROUP
|
||||
| CREATE_DELETE
|
||||
| CREDENTIALS
|
||||
| CSV
|
||||
| DATA
|
||||
| DELIMITER
|
||||
@@ -29,8 +46,10 @@ memgraphCypherKeyword : cypherKeyword
|
||||
| DENY
|
||||
| DROP
|
||||
| DUMP
|
||||
| EDGE_TYPES
|
||||
| EXECUTE
|
||||
| FOR
|
||||
| FOREACH
|
||||
| FREE
|
||||
| FROM
|
||||
| GLOBAL
|
||||
@@ -38,6 +57,8 @@ memgraphCypherKeyword : cypherKeyword
|
||||
| HEADER
|
||||
| IDENTIFIED
|
||||
| ISOLATION
|
||||
| KAFKA
|
||||
| LABELS
|
||||
| LEVEL
|
||||
| LOAD
|
||||
| LOCK
|
||||
@@ -45,7 +66,9 @@ memgraphCypherKeyword : cypherKeyword
|
||||
| MODE
|
||||
| NEXT
|
||||
| NO
|
||||
| NOTHING
|
||||
| PASSWORD
|
||||
| PULSAR
|
||||
| PORT
|
||||
| PRIVILEGES
|
||||
| READ
|
||||
@@ -58,6 +81,8 @@ memgraphCypherKeyword : cypherKeyword
|
||||
| ROLES
|
||||
| QUOTE
|
||||
| SESSION
|
||||
| SETTING
|
||||
| SETTINGS
|
||||
| SNAPSHOT
|
||||
| START
|
||||
| STATS
|
||||
@@ -76,6 +101,7 @@ memgraphCypherKeyword : cypherKeyword
|
||||
| UPDATE
|
||||
| USER
|
||||
| USERS
|
||||
| VERSION
|
||||
;
|
||||
|
||||
symbolicName : UnescapedSymbolicName
|
||||
@@ -98,6 +124,9 @@ query : cypherQuery
|
||||
| isolationLevelQuery
|
||||
| createSnapshotQuery
|
||||
| streamQuery
|
||||
| settingQuery
|
||||
| versionQuery
|
||||
| showConfigQuery
|
||||
;
|
||||
|
||||
authQuery : createRole
|
||||
@@ -140,8 +169,19 @@ clause : cypherMatch
|
||||
| cypherReturn
|
||||
| callProcedure
|
||||
| loadCsv
|
||||
| foreach
|
||||
;
|
||||
|
||||
updateClause : set
|
||||
| remove
|
||||
| create
|
||||
| merge
|
||||
| cypherDelete
|
||||
| foreach
|
||||
;
|
||||
|
||||
foreach : FOREACH '(' variable IN expression '|' updateClause+ ')' ;
|
||||
|
||||
streamQuery : checkStream
|
||||
| createStream
|
||||
| dropStream
|
||||
@@ -152,6 +192,11 @@ streamQuery : checkStream
|
||||
| showStreams
|
||||
;
|
||||
|
||||
settingQuery : setSetting
|
||||
| showSetting
|
||||
| showSettings
|
||||
;
|
||||
|
||||
loadCsv : LOAD CSV FROM csvFile ( WITH | NO ) HEADER
|
||||
( IGNORE BAD ) ?
|
||||
( DELIMITER delimiter ) ?
|
||||
@@ -187,11 +232,11 @@ setRole : SET ROLE FOR user=userOrRoleName TO role=userOrRoleName;
|
||||
|
||||
clearRole : CLEAR ROLE FOR user=userOrRoleName ;
|
||||
|
||||
grantPrivilege : GRANT ( ALL PRIVILEGES | privileges=privilegeList ) TO userOrRole=userOrRoleName ;
|
||||
grantPrivilege : GRANT ( ALL PRIVILEGES | privileges=grantPrivilegesList ) TO userOrRole=userOrRoleName ;
|
||||
|
||||
denyPrivilege : DENY ( ALL PRIVILEGES | privileges=privilegeList ) TO userOrRole=userOrRoleName ;
|
||||
denyPrivilege : DENY ( ALL PRIVILEGES | privileges=privilegesList ) TO userOrRole=userOrRoleName ;
|
||||
|
||||
revokePrivilege : REVOKE ( ALL PRIVILEGES | privileges=privilegeList ) FROM userOrRole=userOrRoleName ;
|
||||
revokePrivilege : REVOKE ( ALL PRIVILEGES | privileges=revokePrivilegesList ) FROM userOrRole=userOrRoleName ;
|
||||
|
||||
privilege : CREATE
|
||||
| DELETE
|
||||
@@ -211,9 +256,34 @@ privilege : CREATE
|
||||
| CONFIG
|
||||
| DURABILITY
|
||||
| STREAM
|
||||
| MODULE_READ
|
||||
| MODULE_WRITE
|
||||
| WEBSOCKET
|
||||
;
|
||||
|
||||
privilegeList : privilege ( ',' privilege )* ;
|
||||
granularPrivilege : NOTHING | READ | UPDATE | CREATE_DELETE ;
|
||||
|
||||
entityType : LABELS | EDGE_TYPES ;
|
||||
|
||||
privilegeOrEntityPrivileges : privilege | entityPrivileges=entityPrivilegeList ;
|
||||
|
||||
grantPrivilegesList : privilegeOrEntityPrivileges ( ',' privilegeOrEntityPrivileges )* ;
|
||||
|
||||
entityPrivilegeList : entityPrivilege ( ',' entityPrivilege )* ;
|
||||
|
||||
entityPrivilege : granularPrivilege ON entityType entities=entitiesList ;
|
||||
|
||||
privilegeOrEntities : privilege | entityType entities=entitiesList ;
|
||||
|
||||
revokePrivilegesList : privilegeOrEntities ( ',' privilegeOrEntities )* ;
|
||||
|
||||
privilegesList : privilege ( ',' privilege )* ;
|
||||
|
||||
entitiesList : ASTERISK | listOfEntities ;
|
||||
|
||||
listOfEntities : entity ( ',' entity )* ;
|
||||
|
||||
entity : COLON symbolicName ;
|
||||
|
||||
showPrivileges : SHOW PRIVILEGES FOR userOrRole=userOrRoleName ;
|
||||
|
||||
@@ -233,7 +303,6 @@ replicaName : symbolicName ;
|
||||
socketAddress : literal ;
|
||||
|
||||
registerReplica : REGISTER REPLICA replicaName ( SYNC | ASYNC )
|
||||
( WITH TIMEOUT timeout=literal ) ?
|
||||
TO socketAddress ;
|
||||
|
||||
dropReplica : DROP REPLICA replicaName ;
|
||||
@@ -273,18 +342,42 @@ symbolicNameWithMinus : symbolicName ( MINUS symbolicName )* ;
|
||||
|
||||
symbolicNameWithDotsAndMinus: symbolicNameWithMinus ( DOT symbolicNameWithMinus )* ;
|
||||
|
||||
topicNames : symbolicNameWithDotsAndMinus ( COMMA symbolicNameWithDotsAndMinus )* ;
|
||||
symbolicTopicNames : symbolicNameWithDotsAndMinus ( COMMA symbolicNameWithDotsAndMinus )* ;
|
||||
|
||||
createStream : CREATE STREAM streamName
|
||||
TOPICS topicNames
|
||||
TRANSFORM transformationName=procedureName
|
||||
( CONSUMER_GROUP consumerGroup=symbolicNameWithDotsAndMinus ) ?
|
||||
( BATCH_INTERVAL batchInterval=literal ) ?
|
||||
( BATCH_SIZE batchSize=literal ) ? ;
|
||||
topicNames : symbolicTopicNames | literal ;
|
||||
|
||||
commonCreateStreamConfig : TRANSFORM transformationName=procedureName
|
||||
| BATCH_INTERVAL batchInterval=literal
|
||||
| BATCH_SIZE batchSize=literal
|
||||
;
|
||||
|
||||
createStream : kafkaCreateStream | pulsarCreateStream ;
|
||||
|
||||
configKeyValuePair : literal ':' literal ;
|
||||
|
||||
configMap : '{' ( configKeyValuePair ( ',' configKeyValuePair )* )? '}' ;
|
||||
|
||||
kafkaCreateStreamConfig : TOPICS topicNames
|
||||
| CONSUMER_GROUP consumerGroup=symbolicNameWithDotsAndMinus
|
||||
| BOOTSTRAP_SERVERS bootstrapServers=literal
|
||||
| CONFIGS configsMap=configMap
|
||||
| CREDENTIALS credentialsMap=configMap
|
||||
| commonCreateStreamConfig
|
||||
;
|
||||
|
||||
kafkaCreateStream : CREATE KAFKA STREAM streamName ( kafkaCreateStreamConfig ) * ;
|
||||
|
||||
|
||||
pulsarCreateStreamConfig : TOPICS topicNames
|
||||
| SERVICE_URL serviceUrl=literal
|
||||
| commonCreateStreamConfig
|
||||
;
|
||||
|
||||
pulsarCreateStream : CREATE PULSAR STREAM streamName ( pulsarCreateStreamConfig ) * ;
|
||||
|
||||
dropStream : DROP STREAM streamName ;
|
||||
|
||||
startStream : START STREAM streamName ;
|
||||
startStream : START STREAM streamName ( BATCH_LIMIT batchLimit=literal ) ? ( TIMEOUT timeout=literal ) ? ;
|
||||
|
||||
startAllStreams : START ALL STREAMS ;
|
||||
|
||||
@@ -295,3 +388,17 @@ stopAllStreams : STOP ALL STREAMS ;
|
||||
showStreams : SHOW STREAMS ;
|
||||
|
||||
checkStream : CHECK STREAM streamName ( BATCH_LIMIT batchLimit=literal ) ? ( TIMEOUT timeout=literal ) ? ;
|
||||
|
||||
settingName : literal ;
|
||||
|
||||
settingValue : literal ;
|
||||
|
||||
setSetting : SET DATABASE SETTING settingName TO settingValue ;
|
||||
|
||||
showSetting : SHOW DATABASE SETTING settingName ;
|
||||
|
||||
showSettings : SHOW DATABASE SETTINGS ;
|
||||
|
||||
showConfigQuery : SHOW CONFIG ;
|
||||
|
||||
versionQuery : SHOW VERSION ;
|
||||
120
cypher_grammar/MemgraphCypherLexer.g4
Normal file
120
cypher_grammar/MemgraphCypherLexer.g4
Normal file
@@ -0,0 +1,120 @@
|
||||
/*
|
||||
* Copyright 2021 Memgraph Ltd.
|
||||
*
|
||||
* Use of this software is governed by the Business Source License
|
||||
* included in the file licenses/BSL.txt; by using this file, you agree to be bound by the terms of the Business Source
|
||||
* License, and you may not use this file except in compliance with the Business Source License.
|
||||
*
|
||||
* As of the Change Date specified in that file, in accordance with
|
||||
* the Business Source License, use of this software will be governed
|
||||
* by the Apache License, Version 2.0, included in the file
|
||||
* licenses/APL.txt.
|
||||
*/
|
||||
|
||||
/* Memgraph specific Cypher reserved words used for enterprise features. */
|
||||
|
||||
/*
|
||||
* When changing this grammar make sure to update constants in
|
||||
* src/query/frontend/stripped_lexer_constants.hpp (kKeywords, kSpecialTokens
|
||||
* and bitsets) if needed.
|
||||
*/
|
||||
|
||||
lexer grammar MemgraphCypherLexer ;
|
||||
|
||||
import CypherLexer ;
|
||||
|
||||
UNDERSCORE : '_' ;
|
||||
|
||||
AFTER : A F T E R ;
|
||||
ALTER : A L T E R ;
|
||||
ASYNC : A S Y N C ;
|
||||
AUTH : A U T H ;
|
||||
BAD : B A D ;
|
||||
BATCH_INTERVAL : B A T C H UNDERSCORE I N T E R V A L ;
|
||||
BATCH_LIMIT : B A T C H UNDERSCORE L I M I T ;
|
||||
BATCH_SIZE : B A T C H UNDERSCORE S I Z E ;
|
||||
BEFORE : B E F O R E ;
|
||||
BOOTSTRAP_SERVERS : B O O T S T R A P UNDERSCORE S E R V E R S ;
|
||||
CHECK : C H E C K ;
|
||||
CLEAR : C L E A R ;
|
||||
COMMIT : C O M M I T ;
|
||||
COMMITTED : C O M M I T T E D ;
|
||||
CONFIG : C O N F I G ;
|
||||
CONFIGS : C O N F I G S;
|
||||
CONSUMER_GROUP : C O N S U M E R UNDERSCORE G R O U P ;
|
||||
CREATE_DELETE : C R E A T E UNDERSCORE D E L E T E ;
|
||||
CREDENTIALS : C R E D E N T I A L S ;
|
||||
CSV : C S V ;
|
||||
DATA : D A T A ;
|
||||
DELIMITER : D E L I M I T E R ;
|
||||
DATABASE : D A T A B A S E ;
|
||||
DENY : D E N Y ;
|
||||
DIRECTORY : D I R E C T O R Y ;
|
||||
DROP : D R O P ;
|
||||
DUMP : D U M P ;
|
||||
DURABILITY : D U R A B I L I T Y ;
|
||||
EXECUTE : E X E C U T E ;
|
||||
FOR : F O R ;
|
||||
FOREACH : F O R E A C H;
|
||||
FREE : F R E E ;
|
||||
FREE_MEMORY : F R E E UNDERSCORE M E M O R Y ;
|
||||
FROM : F R O M ;
|
||||
GLOBAL : G L O B A L ;
|
||||
GRANT : G R A N T ;
|
||||
GRANTS : G R A N T S ;
|
||||
HEADER : H E A D E R ;
|
||||
IDENTIFIED : I D E N T I F I E D ;
|
||||
IGNORE : I G N O R E ;
|
||||
ISOLATION : I S O L A T I O N ;
|
||||
KAFKA : K A F K A ;
|
||||
LABELS : L A B E L S ;
|
||||
LEVEL : L E V E L ;
|
||||
LOAD : L O A D ;
|
||||
LOCK : L O C K ;
|
||||
MAIN : M A I N ;
|
||||
MODE : M O D E ;
|
||||
MODULE_READ : M O D U L E UNDERSCORE R E A D ;
|
||||
MODULE_WRITE : M O D U L E UNDERSCORE W R I T E ;
|
||||
NEXT : N E X T ;
|
||||
NO : N O ;
|
||||
NOTHING : N O T H I N G ;
|
||||
PASSWORD : P A S S W O R D ;
|
||||
PORT : P O R T ;
|
||||
PRIVILEGES : P R I V I L E G E S ;
|
||||
PULSAR : P U L S A R ;
|
||||
READ : R E A D ;
|
||||
READ_FILE : R E A D UNDERSCORE F I L E ;
|
||||
REGISTER : R E G I S T E R ;
|
||||
REPLICA : R E P L I C A ;
|
||||
REPLICAS : R E P L I C A S ;
|
||||
REPLICATION : R E P L I C A T I O N ;
|
||||
REVOKE : R E V O K E ;
|
||||
ROLE : R O L E ;
|
||||
ROLES : R O L E S ;
|
||||
QUOTE : Q U O T E ;
|
||||
SERVICE_URL : S E R V I C E UNDERSCORE U R L ;
|
||||
SESSION : S E S S I O N ;
|
||||
SETTING : S E T T I N G ;
|
||||
SETTINGS : S E T T I N G S ;
|
||||
SNAPSHOT : S N A P S H O T ;
|
||||
START : S T A R T ;
|
||||
STATS : S T A T S ;
|
||||
STOP : S T O P ;
|
||||
STREAM : S T R E A M ;
|
||||
STREAMS : S T R E A M S ;
|
||||
SYNC : S Y N C ;
|
||||
TIMEOUT : T I M E O U T ;
|
||||
TO : T O ;
|
||||
TOPICS : T O P I C S;
|
||||
TRANSACTION : T R A N S A C T I O N ;
|
||||
TRANSFORM : T R A N S F O R M ;
|
||||
TRIGGER : T R I G G E R ;
|
||||
TRIGGERS : T R I G G E R S ;
|
||||
UNCOMMITTED : U N C O M M I T T E D ;
|
||||
UNLOCK : U N L O C K ;
|
||||
UPDATE : U P D A T E ;
|
||||
USER : U S E R ;
|
||||
USERS : U S E R S ;
|
||||
VERSION : V E R S I O N ;
|
||||
WEBSOCKET : W E B S O C K E T ;
|
||||
EDGE_TYPES : E D G E UNDERSCORE T Y P E S ;
|
||||
204
docs/csv-import-tool/README.md
Normal file
204
docs/csv-import-tool/README.md
Normal file
@@ -0,0 +1,204 @@
|
||||
# CSV Import Tool Documentation
|
||||
|
||||
CSV is a universal and very versatile data format used to store large quantities
|
||||
of data. Each Memgraph database instance has a CSV import tool installed called
|
||||
`mg_import_csv`. The CSV import tool should be used for initial bulk ingestion
|
||||
of data into the database. Upon ingestion, the CSV importer creates a snapshot
|
||||
that will be used by the database to recover its state on its next startup.
|
||||
|
||||
If you are already familiar with the Neo4j bulk import tool, then using the
|
||||
`mg_import_csv` tool should be easy. The CSV import tool is fully compatible
|
||||
with the [Neo4j CSV
|
||||
format](https://neo4j.com/docs/operations-manual/current/tools/import/). If you
|
||||
already have a pipeline set-up for Neo4j, you should only replace `neo4j-admin
|
||||
import` with `mg_import_csv`.
|
||||
|
||||
## CSV File Format
|
||||
|
||||
Each row of a CSV file represents a single entry that should be imported into
|
||||
the database. Both nodes and relationships can be imported into the database
|
||||
using CSV files.
|
||||
|
||||
Each set of CSV files must have a header that describes the data that is stored
|
||||
in the CSV files. Each field in the CSV header is in the format
|
||||
`<name>[:<type>]` which identifies the name that should be used for that column
|
||||
and the type that should be used for that column. The type is optional and
|
||||
defaults to `string` (see the following chapter).
|
||||
|
||||
Each CSV field must be divided using the delimiter and each CSV field can either
|
||||
be quoted or unquoted. When the field is quoted, the first and last character in
|
||||
the field *must* be the quote character. If the field isn't quoted, and a quote
|
||||
character appears in it, it is treated as a regular character. If a quote
|
||||
character appears inside a quoted string then the quote character must be
|
||||
doubled in order to escape it. Line feeds and carriage returns are ignored in
|
||||
the CSV file, also, the file can't contain a NULL character.
|
||||
|
||||
## Properties
|
||||
|
||||
Both nodes and relationships can have properties added to them. When importing
|
||||
properties, the CSV importer uses the name specified in the header of the
|
||||
corresponding CSV column for the name of the property. A property is designated
|
||||
by specifying one of the following types in the header:
|
||||
- `integer`, `int`, `long`, `byte`, `short`: creates an integer property
|
||||
- `float`, `double`: creates a float property
|
||||
- `boolean`, `bool`: creates a boolean property
|
||||
- `string`, `char`: creates a string property
|
||||
|
||||
When importing a boolean value, the CSV field should contain exactly the text
|
||||
`true` to import a `True` boolean value. All other text values are treated as a
|
||||
boolean value `False`.
|
||||
|
||||
If you want to import an array of values, you can do so by appending `[]` to any
|
||||
of the above types. The values of the array are then determined by splitting
|
||||
the raw CSV value using the array delimiter character.
|
||||
|
||||
Assuming that the array delimiter is `;`, the following example:
|
||||
```plaintext
|
||||
first_name,last_name:string,number:integer,aliases:string[]
|
||||
John,Doe,1,Johnny;Jo;J-man
|
||||
Melissa,Doe,2,Mel
|
||||
```
|
||||
|
||||
Will yield these results:
|
||||
```plaintext
|
||||
CREATE ({first_name: "John", last_name: "Doe", number: 1, aliases: ["Johnny", "Jo", "J-man"]});
|
||||
CREATE ({first_name: "Melissa", last_name: "Doe", number: 2, aliases: ["Mel"]});
|
||||
```
|
||||
### Nodes
|
||||
|
||||
When importing nodes, several more types can be specified in the header of the
|
||||
CSV file (along with all property types):
|
||||
- `ID`: id of the node that should be used as the node ID when importing
|
||||
relationships
|
||||
- `LABEL`: designates that the field contains additional labels for the node
|
||||
- `IGNORE`: designates that the field should be ignored
|
||||
|
||||
The `ID` field type sets the internal ID that will be used for the node when
|
||||
creating relationships. It is optional and nodes that don't have an ID value
|
||||
specified will be imported, but can't be connected to any relationships. If you
|
||||
want to save the ID value as a property in the database, just specify a name for
|
||||
the ID (`user_id:ID`). If you just want to use the ID during the import, leave
|
||||
out the name of the field (`:ID`). The `ID` field also supports creating
|
||||
separate ID spaces. The ID space is specified with the ID space name appended
|
||||
to the `ID` type in parentheses (`ID(user)`). That allows you to have the same
|
||||
IDs (by value) for multiple different node files (for example, numbers from 1 to
|
||||
N). The IDs in each ID space will be treated as an independent set of IDs that
|
||||
don't interfere with IDs in another ID space.
|
||||
|
||||
The `LABEL` field type adds additional labels to the node. The value is treated
|
||||
as an array type so that multiple additional labels can be specified for each
|
||||
node. The value is split using the array delimiter (`--array-delimiter` flag).
|
||||
|
||||
### Relationships
|
||||
|
||||
In order to be able to import relationships, you must import the nodes in the
|
||||
same invocation of `mg_import_csv` that is used to import the relationships.
|
||||
|
||||
When importing relationships, several more types can be specified in the header
|
||||
of the CSV file (along with all property types):
|
||||
- `START_ID`: id of the start node that should be connected with the
|
||||
relationship
|
||||
- `END_ID`: id of the end node that should be connected with the relationship
|
||||
- `TYPE`: designates the type of the relationship
|
||||
- `IGNORE`: designates that the field should be ignored
|
||||
|
||||
The `START_ID` field type sets the start node that should be connected with the
|
||||
relationship to the end node. The field *must* be specified and the node ID
|
||||
must be one of the node IDs that were specified in the node CSV files. The name
|
||||
of this field is ignored. If the node ID is in an ID space, you can specify the
|
||||
ID space for the in the same way as for the node ID (`START_ID(user)`).
|
||||
|
||||
The `END_ID` field type sets the end node that should be connected with the
|
||||
relationship to the start node. The field *must* be specified and the node ID
|
||||
must be one of the node IDs that were specified in the node CSV files. The name
|
||||
of this field is ignored. If the node ID is in an ID space, you can specify the
|
||||
ID space for the in the same way as for the node ID (`END_ID(user)`).
|
||||
|
||||
The `TYPE` field type sets the type of the relationship. Each relationship
|
||||
*must* have a relationship type, but it doesn't necessarily need to be specified
|
||||
in the CSV file, it can also be set externally for the whole CSV file. The name
|
||||
of this field is ignored.
|
||||
|
||||
## CSV Importer Flags
|
||||
|
||||
The importer has many command line options that allow you to customize the way
|
||||
the importer loads your data.
|
||||
|
||||
The two main flags that are used to specify the input CSV files are `--nodes`
|
||||
and `--relationships`. Basic description of these flags is provided in the table
|
||||
and more detailed explainion can be found further down bellow.
|
||||
|
||||
|
||||
| Flag | Description |
|
||||
|-----------------------| -------------- |
|
||||
|`--nodes` | Used to specify CSV files that contain the nodes to the importer. |
|
||||
|`--relationships` | Used to specify CSV files that contain the relationships to the importer.|
|
||||
|`--delimiter` | Sets the delimiter that should be used when splitting the CSV fields (default `,`)|
|
||||
|`--quote` | Sets the quote character that should be used to quote a CSV field (default `"`)|
|
||||
|`--array-delimiter` | Sets the delimiter that should be used when splitting array values (default `;`)|
|
||||
|`--id-type` | Specifies which data type should be used to store the supplied <br /> node IDs when storing them as properties (if the field name is supplied). <br /> The supported values are either `STRING` or `INTEGER`. (default `STRING`)|
|
||||
|`--ignore-empty-strings` | Instructs the importer to treat all empty strings as `Null` values <br /> instead of an empty string value (default `false`)|
|
||||
|`--ignore-extra-columns` | Instructs the importer to ignore all columns (instead of raising an error) <br /> that aren't specified after the last specified column in the CSV header. (default `false`) |
|
||||
| `--skip-bad-relationships`| Instructs the importer to ignore all relationships (instead of raising an error) <br /> that refer to nodes that don't exist in the node files. (default `false`) |
|
||||
|`--skip-duplicate-nodes` | Instructs the importer to ignore all duplicate nodes (instead of raising an error). <br /> Duplicate nodes are nodes that have an ID that is the same as another node that was already imported. (default `false`) |
|
||||
| `--trim-strings`| Instructs the importer to trim all of the loaded CSV field values before processing them further. <br /> Trimming the fields removes all leading and trailing whitespace from them. (default `false`) |
|
||||
|
||||
The `--nodes` and `--relationships` flags are used to specify CSV files that
|
||||
contain the nodes and relationships to the importer. Multiple files can be
|
||||
specified in each supplied `--nodes` or `--relationships` flag. Files that are
|
||||
supplied in one `--nodes` or `--relationships` flag are treated by the CSV
|
||||
parser as one big CSV file. Only the first line of the first file is parsed for
|
||||
the CSV header, all other files (and rows) are treated as data. This is useful
|
||||
when you have a very large CSV file and don't want to edit its first line just
|
||||
to add a CSV header. Instead, you can specify the header in a separate file
|
||||
(e.g. `users_header.csv` or `friendships_header.csv`) and have the data intact
|
||||
in the large file (e.g. `users.csv` or `friendships.csv`). Also, you can supply
|
||||
additional labels for each set of node files.
|
||||
|
||||
The format of `--nodes` flag is:
|
||||
`[<label>[:<label>]...=]<file>[,<file>][,<file>]...`. Take note that only the
|
||||
first `<file>` part is mandatory, all other parts of the flag value are
|
||||
optional. Multiple `--nodes` flags can be supplied to describe multiple sets of
|
||||
different node files. For the importer to work, at least one `--nodes` flag
|
||||
*must* be supplied.
|
||||
|
||||
The format of `--relationships` flag is: `[<type>=]<file>[,<file>][,<file>]...`.
|
||||
Take note that only the first `<file>` part is mandatory, all other parts of the
|
||||
flag value are optional. Multiple `--relationships` flags can be supplied to
|
||||
describe multiple sets of different relationship files. The `--relationships`
|
||||
flag isn't mandatory.
|
||||
|
||||
## CSV Parser Logic
|
||||
|
||||
The CSV parser uses the same logic as the standard Python CSV parser. The data
|
||||
is parsed in the same way as the following snippet:
|
||||
|
||||
```python
|
||||
import csv
|
||||
for row in csv.reader(stream, strict=True):
|
||||
# process 'row'
|
||||
```
|
||||
|
||||
Python uses 'excel' as the default dialect when parsing CSV files and the
|
||||
default settings for the CSV parser are:
|
||||
- delimiter: `','`
|
||||
- doublequote: `True`
|
||||
- escapechar: `None`
|
||||
- lineterminator: `'\r\n'`
|
||||
- quotechar: `'"'`
|
||||
- skipinitialspace: `False`
|
||||
|
||||
The above snippet can be expanded to:
|
||||
|
||||
```python
|
||||
import csv
|
||||
for row in csv.reader(stream, delimiter=',', doublequote=True,
|
||||
escapechar=None, lineterminator='\r\n',
|
||||
quotechar='"', skipinitialspace=False,
|
||||
strict=True):
|
||||
# process 'row'
|
||||
```
|
||||
|
||||
For more information about the meaning of the above values, see:
|
||||
https://docs.python.org/3/library/csv.html#csv.Dialect
|
||||
|
||||
2
environment/.gitignore
vendored
2
environment/.gitignore
vendored
@@ -1,2 +0,0 @@
|
||||
archives
|
||||
build
|
||||
@@ -1,4 +0,0 @@
|
||||
# Memgraph Build and Run Environments
|
||||
|
||||
Please continue in
|
||||
[Notion](https://www.notion.so/memgraph/Tools-05e0baafb78a49b386e0063b4833d23d).
|
||||
3
environment/os/.gitignore
vendored
3
environment/os/.gitignore
vendored
@@ -1,3 +0,0 @@
|
||||
*.deb
|
||||
*.rpm
|
||||
*.tar.gz
|
||||
@@ -1,134 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -Eeuo pipefail
|
||||
|
||||
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
|
||||
source "$DIR/../util.sh"
|
||||
|
||||
TOOLCHAIN_BUILD_DEPS=(
|
||||
coreutils gcc gcc-c++ make # generic build tools
|
||||
wget # used for archive download
|
||||
gnupg2 # used for archive signature verification
|
||||
tar gzip bzip2 xz unzip # used for archive unpacking
|
||||
zlib-devel # zlib library used for all builds
|
||||
expat-devel libipt-devel libbabeltrace-devel xz-devel python3-devel # gdb
|
||||
texinfo # gdb
|
||||
libcurl-devel # cmake
|
||||
readline-devel # cmake and llvm
|
||||
libffi-devel libxml2-devel perl-Digest-MD5 # llvm
|
||||
libedit-devel pcre-devel automake bison # swig
|
||||
)
|
||||
|
||||
TOOLCHAIN_RUN_DEPS=(
|
||||
make # generic build tools
|
||||
tar gzip bzip2 xz # used for archive unpacking
|
||||
zlib # zlib library used for all builds
|
||||
expat libipt libbabeltrace xz-libs python3 # for gdb
|
||||
readline # for cmake and llvm
|
||||
libffi libxml2 # for llvm
|
||||
)
|
||||
|
||||
MEMGRAPH_BUILD_DEPS=(
|
||||
git # source code control
|
||||
make pkgconfig # build system
|
||||
curl wget # for downloading libs
|
||||
libuuid-devel java-11-openjdk # required by antlr
|
||||
readline-devel # for memgraph console
|
||||
python3-devel # for query modules
|
||||
openssl-devel
|
||||
libseccomp-devel
|
||||
python3 python-virtualenv python3-pip nmap-ncat # for qa, macro_benchmark and stress tests
|
||||
#
|
||||
# IMPORTANT: python3-yaml does NOT exist on CentOS
|
||||
# Install it using `pip3 install PyYAML`
|
||||
#
|
||||
PyYAML # Package name here does not correspond to the yum package!
|
||||
libcurl-devel # mg-requests
|
||||
sbcl # for custom Lisp C++ preprocessing
|
||||
rpm-build rpmlint # for RPM package building
|
||||
doxygen graphviz # source documentation generators
|
||||
which mono-complete dotnet-sdk-3.1 golang nodejs zip unzip java-11-openjdk-devel # for driver tests
|
||||
autoconf # for jemalloc code generation
|
||||
)
|
||||
|
||||
list() {
|
||||
echo "$1"
|
||||
}
|
||||
|
||||
check() {
|
||||
local missing=""
|
||||
for pkg in $1; do
|
||||
if [ "$pkg" == git ]; then
|
||||
if ! which "git" >/dev/null; then
|
||||
missing="git $missing"
|
||||
fi
|
||||
continue
|
||||
fi
|
||||
if [ "$pkg" == "PyYAML" ]; then
|
||||
if ! python3 -c "import yaml" >/dev/null 2>/dev/null; then
|
||||
missing="$pkg $missing"
|
||||
fi
|
||||
continue
|
||||
fi
|
||||
if ! yum list installed "$pkg" >/dev/null 2>/dev/null; then
|
||||
missing="$pkg $missing"
|
||||
fi
|
||||
done
|
||||
if [ "$missing" != "" ]; then
|
||||
echo "MISSING PACKAGES: $missing"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
install() {
|
||||
cd "$DIR"
|
||||
if [ "$EUID" -ne 0 ]; then
|
||||
echo "Please run as root."
|
||||
exit 1
|
||||
fi
|
||||
# If GitHub Actions runner is installed, append LANG to the environment.
|
||||
# Python related tests doesn't work the LANG export.
|
||||
if [ -d "/home/gh/actions-runner" ]; then
|
||||
echo "LANG=en_US.utf8" >> /home/gh/actions-runner/.env
|
||||
else
|
||||
echo "NOTE: export LANG=en_US.utf8"
|
||||
fi
|
||||
yum install -y epel-release
|
||||
yum update -y
|
||||
yum install -y wget git python3 python3-pip
|
||||
for pkg in $1; do
|
||||
if [ "$pkg" == libipt ]; then
|
||||
if ! yum list installed libipt >/dev/null 2>/dev/null; then
|
||||
yum install -y http://repo.okay.com.mx/centos/8/x86_64/release/libipt-1.6.1-8.el8.x86_64.rpm
|
||||
fi
|
||||
continue
|
||||
fi
|
||||
if [ "$pkg" == libipt-devel ]; then
|
||||
if ! yum list installed libipt-devel >/dev/null 2>/dev/null; then
|
||||
yum install -y http://repo.okay.com.mx/centos/8/x86_64/release/libipt-devel-1.6.1-8.el8.x86_64.rpm
|
||||
fi
|
||||
continue
|
||||
fi
|
||||
if [ "$pkg" == dotnet-sdk-3.1 ]; then
|
||||
if ! yum list installed dotnet-sdk-3.1 >/dev/null 2>/dev/null; then
|
||||
wget -nv https://packages.microsoft.com/config/centos/7/packages-microsoft-prod.rpm -O packages-microsoft-prod.rpm
|
||||
rpm -Uvh https://packages.microsoft.com/config/centos/7/packages-microsoft-prod.rpm
|
||||
yum update -y
|
||||
yum install -y dotnet-sdk-3.1
|
||||
fi
|
||||
continue
|
||||
fi
|
||||
if [ "$pkg" == PyYAML ]; then
|
||||
if [ -z ${SUDO_USER+x} ]; then # Running as root (e.g. Docker).
|
||||
pip3 install --user PyYAML
|
||||
else # Running using sudo.
|
||||
sudo -H -u "$SUDO_USER" bash -c "pip3 install --user PyYAML"
|
||||
fi
|
||||
continue
|
||||
fi
|
||||
yum install -y "$pkg"
|
||||
done
|
||||
}
|
||||
|
||||
deps=$2"[*]"
|
||||
"$1" "${!deps}"
|
||||
@@ -1,152 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -Eeuo pipefail
|
||||
|
||||
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
|
||||
source "$DIR/../util.sh"
|
||||
|
||||
TOOLCHAIN_BUILD_DEPS=(
|
||||
coreutils gcc gcc-c++ make # generic build tools
|
||||
wget # used for archive download
|
||||
gnupg2 # used for archive signature verification
|
||||
tar gzip bzip2 xz unzip # used for archive unpacking
|
||||
zlib-devel # zlib library used for all builds
|
||||
expat-devel libipt-devel libbabeltrace-devel xz-devel python36-devel texinfo # for gdb
|
||||
libcurl-devel # for cmake
|
||||
readline-devel # for cmake and llvm
|
||||
libffi-devel libxml2-devel # for llvm
|
||||
libedit-devel pcre-devel automake bison # for swig
|
||||
)
|
||||
|
||||
TOOLCHAIN_RUN_DEPS=(
|
||||
make # generic build tools
|
||||
tar gzip bzip2 xz # used for archive unpacking
|
||||
zlib # zlib library used for all builds
|
||||
expat libipt libbabeltrace xz-libs python36 # for gdb
|
||||
readline # for cmake and llvm
|
||||
libffi libxml2 # for llvm
|
||||
)
|
||||
|
||||
MEMGRAPH_BUILD_DEPS=(
|
||||
git # source code control
|
||||
make pkgconf-pkg-config # build system
|
||||
curl wget # for downloading libs
|
||||
libuuid-devel java-11-openjdk # required by antlr
|
||||
readline-devel # for memgraph console
|
||||
python36-devel # for query modules
|
||||
openssl-devel
|
||||
libseccomp-devel
|
||||
python36 python3-virtualenv python3-pip nmap-ncat # for qa, macro_benchmark and stress tests
|
||||
#
|
||||
# IMPORTANT: python3-yaml does NOT exist on CentOS
|
||||
# Install it manually using `pip3 install PyYAML`
|
||||
#
|
||||
PyYAML # Package name here does not correspond to the yum package!
|
||||
libcurl-devel # mg-requests
|
||||
rpm-build rpmlint # for RPM package building
|
||||
doxygen graphviz # source documentation generators
|
||||
which mono-complete dotnet-sdk-3.1 nodejs golang zip unzip java-11-openjdk-devel # for driver tests
|
||||
sbcl # for custom Lisp C++ preprocessing
|
||||
autoconf # for jemalloc code generation
|
||||
)
|
||||
|
||||
list() {
|
||||
echo "$1"
|
||||
}
|
||||
|
||||
check() {
|
||||
local missing=""
|
||||
for pkg in $1; do
|
||||
if [ "$pkg" == "PyYAML" ]; then
|
||||
if ! python3 -c "import yaml" >/dev/null 2>/dev/null; then
|
||||
missing="$pkg $missing"
|
||||
fi
|
||||
continue
|
||||
fi
|
||||
if ! yum list installed "$pkg" >/dev/null 2>/dev/null; then
|
||||
missing="$pkg $missing"
|
||||
fi
|
||||
done
|
||||
if [ "$missing" != "" ]; then
|
||||
echo "MISSING PACKAGES: $missing"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
install() {
|
||||
cd "$DIR"
|
||||
if [ "$EUID" -ne 0 ]; then
|
||||
echo "Please run as root."
|
||||
exit 1
|
||||
fi
|
||||
# If GitHub Actions runner is installed, append LANG to the environment.
|
||||
# Python related tests doesn't work the LANG export.
|
||||
if [ -d "/home/gh/actions-runner" ]; then
|
||||
echo "LANG=en_US.utf8" >> /home/gh/actions-runner/.env
|
||||
else
|
||||
echo "NOTE: export LANG=en_US.utf8"
|
||||
fi
|
||||
dnf install -y epel-release
|
||||
dnf install -y 'dnf-command(config-manager)'
|
||||
dnf config-manager --set-enabled powertools # Required to install texinfo.
|
||||
dnf update -y
|
||||
dnf install -y wget git python36 python3-pip
|
||||
for pkg in $1; do
|
||||
if [ "$pkg" == libipt ]; then
|
||||
if ! dnf list installed libipt >/dev/null 2>/dev/null; then
|
||||
dnf install -y http://repo.okay.com.mx/centos/8/x86_64/release/libipt-1.6.1-8.el8.x86_64.rpm
|
||||
fi
|
||||
continue
|
||||
fi
|
||||
if [ "$pkg" == libipt-devel ]; then
|
||||
if ! yum list installed libipt-devel >/dev/null 2>/dev/null; then
|
||||
dnf install -y http://repo.okay.com.mx/centos/8/x86_64/release/libipt-devel-1.6.1-8.el8.x86_64.rpm
|
||||
fi
|
||||
continue
|
||||
fi
|
||||
# Install GDB dependencies not present in the standard repos.
|
||||
# https://bugs.centos.org/view.php?id=17068
|
||||
# https://centos.pkgs.org
|
||||
# Since 2020, there is Babeltrace2 (https://babeltrace.org). Not used
|
||||
# within GDB yet (an assumption).
|
||||
if [ "$pkg" == libbabeltrace-devel ]; then
|
||||
if ! dnf list installed libbabeltrace-devel >/dev/null 2>/dev/null; then
|
||||
dnf install -y http://mirror.centos.org/centos/8/PowerTools/x86_64/os/Packages/libbabeltrace-devel-1.5.4-3.el8.x86_64.rpm
|
||||
fi
|
||||
continue
|
||||
fi
|
||||
if [ "$pkg" == sbcl ]; then
|
||||
if ! dnf list installed cl-asdf >/dev/null 2>/dev/null; then
|
||||
dnf install -y https://pkgs.dyn.su/el8/base/x86_64/cl-asdf-20101028-18.el8.noarch.rpm
|
||||
fi
|
||||
if ! dnf list installed common-lisp-controller >/dev/null 2>/dev/null; then
|
||||
dnf install -y https://pkgs.dyn.su/el8/base/x86_64/common-lisp-controller-7.4-20.el8.noarch.rpm
|
||||
fi
|
||||
if ! dnf list installed sbcl >/dev/null 2>/dev/null; then
|
||||
dnf install -y https://pkgs.dyn.su/el8/base/x86_64/sbcl-2.0.1-4.el8.x86_64.rpm
|
||||
fi
|
||||
continue
|
||||
fi
|
||||
if [ "$pkg" == dotnet-sdk-3.1 ]; then
|
||||
if ! dnf list installed dotnet-sdk-3.1 >/dev/null 2>/dev/null; then
|
||||
wget -nv https://packages.microsoft.com/config/centos/8/packages-microsoft-prod.rpm -O packages-microsoft-prod.rpm
|
||||
rpm -Uvh https://packages.microsoft.com/config/centos/8/packages-microsoft-prod.rpm
|
||||
dnf update -y
|
||||
dnf install -y dotnet-sdk-3.1
|
||||
fi
|
||||
continue
|
||||
fi
|
||||
if [ "$pkg" == PyYAML ]; then
|
||||
if [ -z ${SUDO_USER+x} ]; then # Running as root (e.g. Docker).
|
||||
pip3 install --user PyYAML
|
||||
else # Running using sudo.
|
||||
sudo -H -u "$SUDO_USER" bash -c "pip3 install --user PyYAML"
|
||||
fi
|
||||
continue
|
||||
fi
|
||||
dnf install -y "$pkg"
|
||||
done
|
||||
}
|
||||
|
||||
deps=$2"[*]"
|
||||
"$1" "${!deps}"
|
||||
@@ -1,93 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -Eeuo pipefail
|
||||
|
||||
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
|
||||
source "$DIR/../util.sh"
|
||||
|
||||
TOOLCHAIN_BUILD_DEPS=(
|
||||
coreutils gcc g++ build-essential make # generic build tools
|
||||
wget # used for archive download
|
||||
gnupg # used for archive signature verification
|
||||
tar gzip bzip2 xz-utils unzip # used for archive unpacking
|
||||
zlib1g-dev # zlib library used for all builds
|
||||
libexpat1-dev libipt-dev libbabeltrace-dev liblzma-dev python3-dev texinfo # for gdb
|
||||
libcurl4-openssl-dev # for cmake
|
||||
libreadline-dev # for cmake and llvm
|
||||
libffi-dev libxml2-dev # for llvm
|
||||
libedit-dev libpcre3-dev automake bison # for swig
|
||||
)
|
||||
|
||||
TOOLCHAIN_RUN_DEPS=(
|
||||
make # generic build tools
|
||||
tar gzip bzip2 xz-utils # used for archive unpacking
|
||||
zlib1g # zlib library used for all builds
|
||||
libexpat1 libipt2 libbabeltrace1 liblzma5 python3 # for gdb
|
||||
libcurl4 # for cmake
|
||||
libreadline7 # for cmake and llvm
|
||||
libffi6 libxml2 # for llvm
|
||||
)
|
||||
|
||||
MEMGRAPH_BUILD_DEPS=(
|
||||
git # source code control
|
||||
make pkg-config # build system
|
||||
curl wget # for downloading libs
|
||||
uuid-dev default-jre-headless # required by antlr
|
||||
libreadline-dev # for memgraph console
|
||||
libpython3-dev python3-dev # for query modules
|
||||
libssl-dev
|
||||
libseccomp-dev
|
||||
netcat # tests are using nc to wait for memgraph
|
||||
python3 virtualenv python3-virtualenv python3-pip # for qa, macro_benchmark and stress tests
|
||||
python3-yaml # for the configuration generator
|
||||
libcurl4-openssl-dev # mg-requests
|
||||
sbcl # for custom Lisp C++ preprocessing
|
||||
doxygen graphviz # source documentation generators
|
||||
mono-runtime mono-mcs zip unzip default-jdk-headless # for driver tests
|
||||
dotnet-sdk-3.1 golang nodejs npm
|
||||
autoconf # for jemalloc code generation
|
||||
)
|
||||
|
||||
list() {
|
||||
echo "$1"
|
||||
}
|
||||
|
||||
check() {
|
||||
check_all_dpkg "$1"
|
||||
}
|
||||
|
||||
install() {
|
||||
cat >/etc/apt/sources.list <<EOF
|
||||
deb http://deb.debian.org/debian/ buster main non-free contrib
|
||||
deb-src http://deb.debian.org/debian/ buster main non-free contrib
|
||||
deb http://deb.debian.org/debian/ buster-updates main contrib non-free
|
||||
deb-src http://deb.debian.org/debian/ buster-updates main contrib non-free
|
||||
deb http://security.debian.org/debian-security buster/updates main contrib non-free
|
||||
deb-src http://security.debian.org/debian-security buster/updates main contrib non-free
|
||||
EOF
|
||||
cd "$DIR"
|
||||
apt update
|
||||
# If GitHub Actions runner is installed, append LANG to the environment.
|
||||
# Python related tests doesn't work the LANG export.
|
||||
if [ -d "/home/gh/actions-runner" ]; then
|
||||
echo "LANG=en_US.utf8" >> /home/gh/actions-runner/.env
|
||||
else
|
||||
echo "NOTE: export LANG=en_US.utf8"
|
||||
fi
|
||||
apt install -y wget
|
||||
for pkg in $1; do
|
||||
if [ "$pkg" == dotnet-sdk-3.1 ]; then
|
||||
if ! dpkg -s "$pkg" 2>/dev/null >/dev/null; then
|
||||
wget -nv https://packages.microsoft.com/config/debian/10/packages-microsoft-prod.deb -O packages-microsoft-prod.deb
|
||||
dpkg -i packages-microsoft-prod.deb
|
||||
apt-get update
|
||||
apt-get install -y apt-transport-https dotnet-sdk-3.1
|
||||
fi
|
||||
continue
|
||||
fi
|
||||
apt install -y "$pkg"
|
||||
done
|
||||
}
|
||||
|
||||
deps=$2"[*]"
|
||||
"$1" "${!deps}"
|
||||
@@ -1,62 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -Eeuo pipefail
|
||||
|
||||
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
|
||||
source "$DIR/../util.sh"
|
||||
|
||||
TOOLCHAIN_BUILD_DEPS=(
|
||||
coreutils gcc g++ build-essential make # generic build tools
|
||||
wget # used for archive download
|
||||
gnupg # used for archive signature verification
|
||||
tar gzip bzip2 xz-utils unzip # used for archive unpacking
|
||||
zlib1g-dev # zlib library used for all builds
|
||||
libexpat1-dev libipt-dev libbabeltrace-dev libbabeltrace-ctf-dev liblzma-dev python3-dev texinfo # for gdb
|
||||
libcurl4-openssl-dev # for cmake
|
||||
libreadline-dev # for cmake and llvm
|
||||
libffi-dev libxml2-dev # for llvm
|
||||
libedit-dev libpcre3-dev automake bison # for swig
|
||||
)
|
||||
|
||||
TOOLCHAIN_RUN_DEPS=(
|
||||
make # generic build tools
|
||||
tar gzip bzip2 xz-utils # used for archive unpacking
|
||||
zlib1g # zlib library used for all builds
|
||||
libexpat1 libipt1 libbabeltrace1 libbabeltrace-ctf1 liblzma5 python3 # for gdb
|
||||
libcurl3 # for cmake
|
||||
libreadline7 # for cmake and llvm
|
||||
libffi6 libxml2 # for llvm
|
||||
)
|
||||
|
||||
MEMGRAPH_BUILD_DEPS=(
|
||||
git # source code control
|
||||
make pkg-config # build system
|
||||
curl wget # for downloading libs
|
||||
uuid-dev default-jre-headless # required by antlr
|
||||
libreadline-dev # for memgraph console
|
||||
libpython3-dev python3-dev # for query modules
|
||||
libssl-dev
|
||||
libseccomp-dev
|
||||
python3 python-virtualenv python3-pip # for qa, macro_benchmark and stress tests
|
||||
python3-yaml # for the configuration generator
|
||||
libcurl4-openssl-dev # mg-requests
|
||||
sbcl # for custom Lisp C++ preprocessing
|
||||
doxygen graphviz # source documentation generators
|
||||
mono-runtime mono-mcs nodejs zip unzip default-jdk-headless # for driver tests
|
||||
autoconf # for jemalloc code generation
|
||||
)
|
||||
|
||||
list() {
|
||||
echo "$1"
|
||||
}
|
||||
|
||||
check() {
|
||||
check_all_dpkg "$1"
|
||||
}
|
||||
|
||||
install() {
|
||||
install_all_apt "$1"
|
||||
}
|
||||
|
||||
deps=$2"[*]"
|
||||
"$1" "${!deps}"
|
||||
@@ -1,36 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -Eeuo pipefail
|
||||
|
||||
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
|
||||
source "$DIR/../util.sh"
|
||||
|
||||
TOOLCHAIN_BUILD_DEPS=(
|
||||
pkg
|
||||
)
|
||||
|
||||
TOOLCHAIN_RUN_DEPS=(
|
||||
pkg
|
||||
)
|
||||
|
||||
MEMGRAPH_BUILD_DEPS=(
|
||||
pkg
|
||||
)
|
||||
|
||||
list() {
|
||||
echo "$1"
|
||||
}
|
||||
|
||||
check() {
|
||||
echo "TODO: Implement ${FUNCNAME[0]}."
|
||||
exit 1
|
||||
}
|
||||
|
||||
install() {
|
||||
echo "TODO: Implement ${FUNCNAME[0]}."
|
||||
exit 1
|
||||
}
|
||||
|
||||
# http://ahmed.amayem.com/bash-indirect-expansion-exploration
|
||||
deps=$2"[*]"
|
||||
"$1" "${!deps}"
|
||||
@@ -1,63 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -Eeuo pipefail
|
||||
|
||||
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
|
||||
source "$DIR/../util.sh"
|
||||
|
||||
TOOLCHAIN_BUILD_DEPS=(
|
||||
coreutils gcc g++ build-essential make # generic build tools
|
||||
wget # archive download
|
||||
gnupg # archive signature verification
|
||||
tar gzip bzip2 xz-utils unzip # archive unpacking
|
||||
zlib1g-dev # zlib library used for all builds
|
||||
libexpat1-dev libipt-dev libbabeltrace-dev liblzma-dev python3-dev # gdb
|
||||
texinfo # gdb
|
||||
libcurl4-openssl-dev # cmake
|
||||
libreadline-dev # cmake and llvm
|
||||
libffi-dev libxml2-dev # llvm
|
||||
libedit-dev libpcre3-dev automake bison # swig
|
||||
)
|
||||
|
||||
TOOLCHAIN_RUN_DEPS=(
|
||||
make # generic build tools
|
||||
tar gzip bzip2 xz-utils # used for archive unpacking
|
||||
zlib1g # zlib library used for all builds
|
||||
libexpat1 libipt1 libbabeltrace1 liblzma5 python3 # for gdb
|
||||
libcurl4 # for cmake
|
||||
libreadline7 # for cmake and llvm
|
||||
libffi6 libxml2 # for llvm
|
||||
)
|
||||
|
||||
MEMGRAPH_BUILD_DEPS=(
|
||||
git # source code control
|
||||
make pkg-config # build system
|
||||
curl wget # downloading libs
|
||||
uuid-dev default-jre-headless # required by antlr
|
||||
libreadline-dev # memgraph console
|
||||
libpython3-dev python3-dev # for query modules
|
||||
libssl-dev
|
||||
libseccomp-dev
|
||||
python3 virtualenv python3-virtualenv python3-pip # qa, macro bench and stress tests
|
||||
python3-yaml # the configuration generator
|
||||
libcurl4-openssl-dev # mg-requests
|
||||
sbcl # custom Lisp C++ preprocessing
|
||||
doxygen graphviz # source documentation generators
|
||||
mono-runtime mono-mcs nodejs zip unzip default-jdk-headless # driver tests
|
||||
autoconf # for jemalloc code generation
|
||||
)
|
||||
|
||||
list() {
|
||||
echo "$1"
|
||||
}
|
||||
|
||||
check() {
|
||||
check_all_dpkg "$1"
|
||||
}
|
||||
|
||||
install() {
|
||||
apt install -y $1
|
||||
}
|
||||
|
||||
deps=$2"[*]"
|
||||
"$1" "${!deps}"
|
||||
@@ -1,85 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -Eeuo pipefail
|
||||
|
||||
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
|
||||
source "$DIR/../util.sh"
|
||||
|
||||
TOOLCHAIN_BUILD_DEPS=(
|
||||
coreutils gcc g++ build-essential make # generic build tools
|
||||
wget # used for archive download
|
||||
gnupg # used for archive signature verification
|
||||
tar gzip bzip2 xz-utils unzip # used for archive unpacking
|
||||
zlib1g-dev # zlib library used for all builds
|
||||
libexpat1-dev libipt-dev libbabeltrace-dev liblzma-dev python3-dev texinfo # for gdb
|
||||
libcurl4-openssl-dev # for cmake
|
||||
libreadline-dev # for cmake and llvm
|
||||
libffi-dev libxml2-dev # for llvm
|
||||
libedit-dev libpcre3-dev automake bison # for swig
|
||||
)
|
||||
|
||||
TOOLCHAIN_RUN_DEPS=(
|
||||
make # generic build tools
|
||||
tar gzip bzip2 xz-utils # used for archive unpacking
|
||||
zlib1g # zlib library used for all builds
|
||||
libexpat1 libipt2 libbabeltrace1 liblzma5 python3 # for gdb
|
||||
libcurl4 # for cmake
|
||||
libreadline8 # for cmake and llvm
|
||||
libffi7 libxml2 # for llvm
|
||||
)
|
||||
|
||||
MEMGRAPH_BUILD_DEPS=(
|
||||
git # source code control
|
||||
make pkg-config # build system
|
||||
curl wget # for downloading libs
|
||||
uuid-dev default-jre-headless # required by antlr
|
||||
libreadline-dev # for memgraph console
|
||||
libpython3-dev python3-dev # for query modules
|
||||
libssl-dev
|
||||
libseccomp-dev
|
||||
netcat # tests are using nc to wait for memgraph
|
||||
python3 python3-virtualenv python3-pip # for qa, macro_benchmark and stress tests
|
||||
python3-yaml # for the configuration generator
|
||||
libcurl4-openssl-dev # mg-requests
|
||||
sbcl # for custom Lisp C++ preprocessing
|
||||
doxygen graphviz # source documentation generators
|
||||
mono-runtime mono-mcs zip unzip default-jdk-headless # for driver tests
|
||||
dotnet-sdk-3.1 golang nodejs npm
|
||||
autoconf # for jemalloc code generation
|
||||
)
|
||||
|
||||
list() {
|
||||
echo "$1"
|
||||
}
|
||||
|
||||
check() {
|
||||
check_all_dpkg "$1"
|
||||
}
|
||||
|
||||
install() {
|
||||
cd "$DIR"
|
||||
apt update
|
||||
# If GitHub Actions runner is installed, append LANG to the environment.
|
||||
# Python related tests doesn't work the LANG export.
|
||||
if [ -d "/home/gh/actions-runner" ]; then
|
||||
echo "LANG=en_US.utf8" >> /home/gh/actions-runner/.env
|
||||
else
|
||||
echo "NOTE: export LANG=en_US.utf8"
|
||||
fi
|
||||
apt install -y wget
|
||||
for pkg in $1; do
|
||||
if [ "$pkg" == dotnet-sdk-3.1 ]; then
|
||||
if ! dpkg -s dotnet-sdk-3.1 2>/dev/null >/dev/null; then
|
||||
wget -nv https://packages.microsoft.com/config/ubuntu/20.04/packages-microsoft-prod.deb -O packages-microsoft-prod.deb
|
||||
dpkg -i packages-microsoft-prod.deb
|
||||
apt-get update
|
||||
apt-get install -y apt-transport-https dotnet-sdk-3.1
|
||||
fi
|
||||
continue
|
||||
fi
|
||||
apt install -y "$pkg"
|
||||
done
|
||||
}
|
||||
|
||||
deps=$2"[*]"
|
||||
"$1" "${!deps}"
|
||||
@@ -1,651 +0,0 @@
|
||||
#!/bin/bash -e
|
||||
|
||||
# helpers
|
||||
pushd () { command pushd "$@" > /dev/null; }
|
||||
popd () { command popd "$@" > /dev/null; }
|
||||
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
|
||||
CPUS=$( cat /proc/cpuinfo | grep processor | wc -l )
|
||||
cd "$DIR"
|
||||
|
||||
# toolchain version
|
||||
TOOLCHAIN_VERSION=1
|
||||
|
||||
# package versions used
|
||||
GCC_VERSION=8.3.0
|
||||
BINUTILS_VERSION=2.32
|
||||
GDB_VERSION=8.2.1
|
||||
CMAKE_VERSION=3.14.2
|
||||
CPPCHECK_VERSION=1.87
|
||||
LLVM_VERSION=8.0.0
|
||||
SWIG_VERSION=3.0.12 # used only for LLVM compilation
|
||||
|
||||
# check for installed dependencies
|
||||
DISTRO="$( egrep '^(VERSION_)?ID=' /etc/os-release | sort | cut -d '=' -f 2- | sed 's/"//g' | paste -s -d '-' )"
|
||||
case "$DISTRO" in
|
||||
debian-9)
|
||||
DEPS_MANAGER=apt-get
|
||||
DEPS_COMPILE=(
|
||||
coreutils gcc g++ build-essential make # generic build tools
|
||||
wget # used for archive download
|
||||
gnupg # used for archive signature verification
|
||||
tar gzip bzip2 xz-utils unzip # used for archive unpacking
|
||||
zlib1g-dev # zlib library used for all builds
|
||||
libexpat1-dev libipt-dev libbabeltrace-dev libbabeltrace-ctf-dev liblzma-dev python3-dev texinfo # for gdb
|
||||
libcurl4-openssl-dev # for cmake
|
||||
libreadline-dev # for cmake and llvm
|
||||
libffi-dev libxml2-dev # for llvm
|
||||
libedit-dev libpcre3-dev automake bison # for swig
|
||||
)
|
||||
DEPS_RUN=(
|
||||
make # generic build tools
|
||||
tar gzip bzip2 xz-utils # used for archive unpacking
|
||||
zlib1g # zlib library used for all builds
|
||||
libexpat1 libipt1 libbabeltrace1 libbabeltrace-ctf1 liblzma5 python3 # for gdb
|
||||
libcurl3 # for cmake
|
||||
libreadline7 # for cmake and llvm
|
||||
libffi6 libxml2 # for llvm
|
||||
)
|
||||
;;
|
||||
|
||||
debian-10)
|
||||
DEPS_MANAGER=apt-get
|
||||
DEPS_COMPILE=(
|
||||
coreutils gcc g++ build-essential make # generic build tools
|
||||
wget # used for archive download
|
||||
gnupg # used for archive signature verification
|
||||
tar gzip bzip2 xz-utils unzip # used for archive unpacking
|
||||
zlib1g-dev # zlib library used for all builds
|
||||
libexpat1-dev libipt-dev libbabeltrace-dev liblzma-dev python3-dev texinfo # for gdb
|
||||
libcurl4-openssl-dev # for cmake
|
||||
libreadline-dev # for cmake and llvm
|
||||
libffi-dev libxml2-dev # for llvm
|
||||
libedit-dev libpcre3-dev automake bison # for swig
|
||||
)
|
||||
DEPS_RUN=(
|
||||
make # generic build tools
|
||||
tar gzip bzip2 xz-utils # used for archive unpacking
|
||||
zlib1g # zlib library used for all builds
|
||||
libexpat1 libipt2 libbabeltrace1 liblzma5 python3 # for gdb
|
||||
libcurl4 # for cmake
|
||||
libreadline7 # for cmake and llvm
|
||||
libffi6 libxml2 # for llvm
|
||||
)
|
||||
;;
|
||||
|
||||
ubuntu-18.04)
|
||||
DEPS_MANAGER=apt-get
|
||||
DEPS_COMPILE=(
|
||||
coreutils gcc g++ build-essential make # generic build tools
|
||||
wget # used for archive download
|
||||
gnupg # used for archive signature verification
|
||||
tar gzip bzip2 xz-utils unzip # used for archive unpacking
|
||||
zlib1g-dev # zlib library used for all builds
|
||||
libexpat1-dev libipt-dev libbabeltrace-dev liblzma-dev python3-dev texinfo # for gdb
|
||||
libcurl4-openssl-dev # for cmake
|
||||
libreadline-dev # for cmake and llvm
|
||||
libffi-dev libxml2-dev # for llvm
|
||||
libedit-dev libpcre3-dev automake bison # for swig
|
||||
)
|
||||
DEPS_RUN=(
|
||||
make # generic build tools
|
||||
tar gzip bzip2 xz-utils # used for archive unpacking
|
||||
zlib1g # zlib library used for all builds
|
||||
libexpat1 libipt1 libbabeltrace1 liblzma5 python3 # for gdb
|
||||
libcurl4 # for cmake
|
||||
libreadline7 # for cmake and llvm
|
||||
libffi6 libxml2 # for llvm
|
||||
)
|
||||
;;
|
||||
|
||||
centos-7)
|
||||
DEPS_MANAGER=yum
|
||||
DEPS_COMPILE=(
|
||||
coreutils gcc gcc-c++ make # generic build tools
|
||||
wget # used for archive download
|
||||
gnupg2 # used for archive signature verification
|
||||
tar gzip bzip2 xz unzip # used for archive unpacking
|
||||
zlib-devel # zlib library used for all builds
|
||||
expat-devel libipt-devel libbabeltrace-devel xz-devel python3-devel texinfo # for gdb
|
||||
libcurl-devel # for cmake
|
||||
readline-devel # for cmake and llvm
|
||||
libffi-devel libxml2-devel # for llvm
|
||||
libedit-devel pcre-devel automake bison # for swig
|
||||
)
|
||||
DEPS_RUN=(
|
||||
make # generic build tools
|
||||
tar gzip bzip2 xz # used for archive unpacking
|
||||
zlib # zlib library used for all builds
|
||||
expat libipt libbabeltrace xz-libs python3 # for gdb
|
||||
readline # for cmake and llvm
|
||||
libffi libxml2 # for llvm
|
||||
)
|
||||
;;
|
||||
|
||||
*)
|
||||
echo "Unknown distribution: $DISTRO!"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
find_missing_dependencies () {
|
||||
local message="$1"; shift
|
||||
local missing=""
|
||||
while [ "$1" != "" ]; do
|
||||
if [ "$DEPS_MANAGER" == "apt-get" ]; then
|
||||
if ! dpkg -s $1 >/dev/null 2>/dev/null; then
|
||||
missing="$1 $missing"
|
||||
fi
|
||||
elif [ "$DEPS_MANAGER" == "yum" ]; then
|
||||
if ! yum list installed $1 >/dev/null 2>/dev/null; then
|
||||
missing="$1 $missing"
|
||||
fi
|
||||
else
|
||||
echo "Invalid package manager: $DEPS_MANAGER!"
|
||||
exit 1
|
||||
fi
|
||||
shift
|
||||
done
|
||||
if [ "$missing" != "" ]; then
|
||||
echo "$message: $missing"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
find_missing_dependencies "Missing dependencies" ${DEPS_COMPILE[@]}
|
||||
find_missing_dependencies "All dependencies are installed, but the following runtime libraries were not found (they are probably invalid)" ${DEPS_RUN[@]}
|
||||
|
||||
# check installation directory
|
||||
NAME=toolchain-v$TOOLCHAIN_VERSION
|
||||
PREFIX=/opt/$NAME
|
||||
mkdir -p $PREFIX >/dev/null 2>/dev/null || true
|
||||
if [ ! -d $PREFIX ] || [ ! -w $PREFIX ]; then
|
||||
echo "Please make sure that the directory '$PREFIX' exists and is writable by the current user!"
|
||||
echo
|
||||
echo "If unsure, execute these commands as root:"
|
||||
echo " mkdir $PREFIX && chown $USER:$USER $PREFIX"
|
||||
echo
|
||||
echo "Press <return> when you have created the directory and granted permissions."
|
||||
# wait for the directory to be created
|
||||
while true; do
|
||||
read
|
||||
if [ ! -d $PREFIX ] || [ ! -w $PREFIX ]; then
|
||||
echo
|
||||
echo "You can't continue before you have created the directory and granted permissions!"
|
||||
echo
|
||||
echo "Press <return> when you have created the directory and granted permissions."
|
||||
else
|
||||
break
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
# create archives directory
|
||||
mkdir -p archives
|
||||
|
||||
# download all archives
|
||||
pushd archives
|
||||
if [ ! -f gcc-$GCC_VERSION.tar.gz ]; then
|
||||
wget https://ftp.gnu.org/gnu/gcc/gcc-$GCC_VERSION/gcc-$GCC_VERSION.tar.gz
|
||||
fi
|
||||
if [ ! -f binutils-$BINUTILS_VERSION.tar.gz ]; then
|
||||
wget https://ftp.gnu.org/gnu/binutils/binutils-$BINUTILS_VERSION.tar.gz
|
||||
fi
|
||||
if [ ! -f gdb-$GDB_VERSION.tar.gz ]; then
|
||||
wget https://ftp.gnu.org/gnu/gdb/gdb-$GDB_VERSION.tar.gz
|
||||
fi
|
||||
if [ ! -f cmake-$CMAKE_VERSION.tar.gz ]; then
|
||||
wget https://github.com/Kitware/CMake/releases/download/v$CMAKE_VERSION/cmake-$CMAKE_VERSION.tar.gz
|
||||
fi
|
||||
if [ ! -f swig-$SWIG_VERSION.tar.gz ]; then
|
||||
wget https://github.com/swig/swig/archive/rel-$SWIG_VERSION.tar.gz -O swig-$SWIG_VERSION.tar.gz
|
||||
fi
|
||||
if [ ! -f cppcheck-$CPPCHECK_VERSION.tar.gz ]; then
|
||||
wget https://github.com/danmar/cppcheck/archive/$CPPCHECK_VERSION.tar.gz -O cppcheck-$CPPCHECK_VERSION.tar.gz
|
||||
fi
|
||||
if [ ! -f llvm-$LLVM_VERSION.src.tar.xz ]; then
|
||||
wget https://releases.llvm.org/$LLVM_VERSION/llvm-$LLVM_VERSION.src.tar.xz
|
||||
wget https://releases.llvm.org/$LLVM_VERSION/cfe-$LLVM_VERSION.src.tar.xz
|
||||
wget https://releases.llvm.org/$LLVM_VERSION/lld-$LLVM_VERSION.src.tar.xz
|
||||
wget https://releases.llvm.org/$LLVM_VERSION/compiler-rt-$LLVM_VERSION.src.tar.xz
|
||||
wget https://releases.llvm.org/$LLVM_VERSION/clang-tools-extra-$LLVM_VERSION.src.tar.xz
|
||||
fi
|
||||
if [ ! -f pahole-gdb-master.zip ]; then
|
||||
wget https://github.com/PhilArmstrong/pahole-gdb/archive/master.zip -O pahole-gdb-master.zip
|
||||
fi
|
||||
|
||||
# verify all archives
|
||||
# NOTE: Verification can fail if the archive is signed by another developer. I
|
||||
# haven't added commands to download all developer GnuPG keys because the
|
||||
# download is very slow. If the verification fails for you, figure out who has
|
||||
# signed the archive and download their public key instead.
|
||||
GPG="gpg --homedir .gnupg"
|
||||
KEYSERVER="hkp://keyserver.ubuntu.com"
|
||||
mkdir -p .gnupg
|
||||
chmod 700 .gnupg
|
||||
# verify gcc
|
||||
if [ ! -f gcc-$GCC_VERSION.tar.gz.sig ]; then
|
||||
wget https://ftp.gnu.org/gnu/gcc/gcc-$GCC_VERSION/gcc-$GCC_VERSION.tar.gz.sig
|
||||
fi
|
||||
# list of valid gcc gnupg keys: https://gcc.gnu.org/mirrors.html
|
||||
$GPG --keyserver $KEYSERVER --recv-keys 0xA328C3A2C3C45C06
|
||||
$GPG --verify gcc-$GCC_VERSION.tar.gz.sig gcc-$GCC_VERSION.tar.gz
|
||||
# verify binutils
|
||||
if [ ! -f binutils-$BINUTILS_VERSION.tar.gz.sig ]; then
|
||||
wget https://ftp.gnu.org/gnu/binutils/binutils-$BINUTILS_VERSION.tar.gz.sig
|
||||
fi
|
||||
$GPG --keyserver $KEYSERVER --recv-keys 0xDD9E3C4F
|
||||
$GPG --verify binutils-$BINUTILS_VERSION.tar.gz.sig binutils-$BINUTILS_VERSION.tar.gz
|
||||
# verify gdb
|
||||
if [ ! -f gdb-$GDB_VERSION.tar.gz.sig ]; then
|
||||
wget https://ftp.gnu.org/gnu/gdb/gdb-$GDB_VERSION.tar.gz.sig
|
||||
fi
|
||||
$GPG --keyserver $KEYSERVER --recv-keys 0xFF325CF3
|
||||
$GPG --verify gdb-$GDB_VERSION.tar.gz.sig gdb-$GDB_VERSION.tar.gz
|
||||
# verify cmake
|
||||
if [ ! -f cmake-$CMAKE_VERSION-SHA-256.txt ] || [ ! -f cmake-$CMAKE_VERSION-SHA-256.txt.asc ]; then
|
||||
wget https://github.com/Kitware/CMake/releases/download/v$CMAKE_VERSION/cmake-$CMAKE_VERSION-SHA-256.txt
|
||||
wget https://github.com/Kitware/CMake/releases/download/v$CMAKE_VERSION/cmake-$CMAKE_VERSION-SHA-256.txt.asc
|
||||
# Because CentOS 7 doesn't have the `--ignore-missing` flag for `sha256sum`
|
||||
# we filter out the missing files from the sums here manually.
|
||||
cat cmake-$CMAKE_VERSION-SHA-256.txt | grep "cmake-$CMAKE_VERSION.tar.gz" > cmake-$CMAKE_VERSION-SHA-256-filtered.txt
|
||||
fi
|
||||
$GPG --keyserver $KEYSERVER --recv-keys 0xC6C265324BBEBDC350B513D02D2CEF1034921684
|
||||
sha256sum -c cmake-$CMAKE_VERSION-SHA-256-filtered.txt
|
||||
$GPG --verify cmake-$CMAKE_VERSION-SHA-256.txt.asc cmake-$CMAKE_VERSION-SHA-256.txt
|
||||
# verify llvm, cfe, lld, clang-tools-extra
|
||||
if [ ! -f llvm-$LLVM_VERSION.src.tar.xz.sig ]; then
|
||||
wget https://releases.llvm.org/$LLVM_VERSION/llvm-$LLVM_VERSION.src.tar.xz.sig
|
||||
wget https://releases.llvm.org/$LLVM_VERSION/cfe-$LLVM_VERSION.src.tar.xz.sig
|
||||
wget https://releases.llvm.org/$LLVM_VERSION/lld-$LLVM_VERSION.src.tar.xz.sig
|
||||
wget https://releases.llvm.org/$LLVM_VERSION/compiler-rt-$LLVM_VERSION.src.tar.xz.sig
|
||||
wget https://releases.llvm.org/$LLVM_VERSION/clang-tools-extra-$LLVM_VERSION.src.tar.xz.sig
|
||||
fi
|
||||
# list of valid llvm gnupg keys: https://releases.llvm.org/download.html
|
||||
$GPG --keyserver $KEYSERVER --recv-keys 0x345AD05D
|
||||
$GPG --verify llvm-$LLVM_VERSION.src.tar.xz.sig llvm-$LLVM_VERSION.src.tar.xz
|
||||
$GPG --verify cfe-$LLVM_VERSION.src.tar.xz.sig cfe-$LLVM_VERSION.src.tar.xz
|
||||
$GPG --verify lld-$LLVM_VERSION.src.tar.xz.sig lld-$LLVM_VERSION.src.tar.xz
|
||||
$GPG --verify compiler-rt-$LLVM_VERSION.src.tar.xz.sig compiler-rt-$LLVM_VERSION.src.tar.xz
|
||||
$GPG --verify clang-tools-extra-$LLVM_VERSION.src.tar.xz.sig clang-tools-extra-$LLVM_VERSION.src.tar.xz
|
||||
popd
|
||||
|
||||
# create build directory
|
||||
mkdir -p build
|
||||
pushd build
|
||||
|
||||
# compile gcc
|
||||
if [ ! -f $PREFIX/bin/gcc ]; then
|
||||
if [ -d gcc-$GCC_VERSION ]; then
|
||||
rm -rf gcc-$GCC_VERSION
|
||||
fi
|
||||
tar -xvf ../archives/gcc-$GCC_VERSION.tar.gz
|
||||
pushd gcc-$GCC_VERSION
|
||||
./contrib/download_prerequisites
|
||||
mkdir build && pushd build
|
||||
# influenced by: https://buildd.debian.org/status/fetch.php?pkg=gcc-8&arch=amd64&ver=8.3.0-6&stamp=1554588545
|
||||
../configure -v \
|
||||
--build=x86_64-linux-gnu \
|
||||
--host=x86_64-linux-gnu \
|
||||
--target=x86_64-linux-gnu \
|
||||
--prefix=$PREFIX \
|
||||
--disable-multilib \
|
||||
--with-system-zlib \
|
||||
--enable-checking=release \
|
||||
--enable-languages=c,c++,fortran \
|
||||
--enable-gold=yes \
|
||||
--enable-ld=yes \
|
||||
--enable-lto \
|
||||
--enable-bootstrap \
|
||||
--disable-vtable-verify \
|
||||
--disable-werror \
|
||||
--without-included-gettext \
|
||||
--enable-threads=posix \
|
||||
--enable-nls \
|
||||
--enable-clocale=gnu \
|
||||
--enable-libstdcxx-debug \
|
||||
--enable-libstdcxx-time=yes \
|
||||
--enable-gnu-unique-object \
|
||||
--enable-libmpx \
|
||||
--enable-plugin \
|
||||
--enable-default-pie \
|
||||
--with-target-system-zlib \
|
||||
--with-tune=generic \
|
||||
--without-cuda-driver
|
||||
#--program-suffix=$( printf "$GCC_VERSION" | cut -d '.' -f 1,2 ) \
|
||||
make -j$CPUS
|
||||
# make -k check # run test suite
|
||||
make install
|
||||
popd && popd
|
||||
fi
|
||||
|
||||
# activate toolchain
|
||||
export PATH=$PREFIX/bin:$PATH
|
||||
export LD_LIBRARY_PATH=$PREFIX/lib64
|
||||
|
||||
# compile binutils
|
||||
if [ ! -f $PREFIX/bin/ld.gold ]; then
|
||||
if [ -d binutils-$BINUTILS_VERSION ]; then
|
||||
rm -rf binutils-$BINUTILS_VERSION
|
||||
fi
|
||||
tar -xvf ../archives/binutils-$BINUTILS_VERSION.tar.gz
|
||||
pushd binutils-$BINUTILS_VERSION
|
||||
mkdir build && pushd build
|
||||
# influenced by: https://buildd.debian.org/status/fetch.php?pkg=binutils&arch=amd64&ver=2.32-7&stamp=1553247092
|
||||
env \
|
||||
CC=gcc \
|
||||
CXX=g++ \
|
||||
CFLAGS="-g -O2" \
|
||||
CXXFLAGS="-g -O2" \
|
||||
LDFLAGS="" \
|
||||
../configure \
|
||||
--build=x86_64-linux-gnu \
|
||||
--host=x86_64-linux-gnu \
|
||||
--prefix=$PREFIX \
|
||||
--enable-ld=default \
|
||||
--enable-gold \
|
||||
--enable-lto \
|
||||
--enable-plugins \
|
||||
--enable-shared \
|
||||
--enable-threads \
|
||||
--with-system-zlib \
|
||||
--enable-deterministic-archives \
|
||||
--disable-compressed-debug-sections \
|
||||
--enable-new-dtags \
|
||||
--disable-werror
|
||||
make -j$CPUS
|
||||
# make -k check # run test suite
|
||||
make install
|
||||
popd && popd
|
||||
fi
|
||||
|
||||
# compile gdb
|
||||
if [ ! -f $PREFIX/bin/gdb ]; then
|
||||
if [ -d gdb-$GDB_VERSION ]; then
|
||||
rm -rf gdb-$GDB_VERSION
|
||||
fi
|
||||
tar -xvf ../archives/gdb-$GDB_VERSION.tar.gz
|
||||
pushd gdb-$GDB_VERSION
|
||||
mkdir build && pushd build
|
||||
# https://buildd.debian.org/status/fetch.php?pkg=gdb&arch=amd64&ver=8.2.1-2&stamp=1550831554&raw=0
|
||||
env \
|
||||
CC=gcc \
|
||||
CXX=g++ \
|
||||
CFLAGS="-g -O2 -fstack-protector-strong -Wformat -Werror=format-security" \
|
||||
CXXFLAGS="-g -O2 -fstack-protector-strong -Wformat -Werror=format-security" \
|
||||
CPPFLAGS="-Wdate-time -D_FORTIFY_SOURCE=2 -fPIC" \
|
||||
LDFLAGS="-Wl,-z,relro" \
|
||||
PYTHON="" \
|
||||
../configure \
|
||||
--build=x86_64-linux-gnu \
|
||||
--host=x86_64-linux-gnu \
|
||||
--prefix=$PREFIX \
|
||||
--disable-maintainer-mode \
|
||||
--disable-dependency-tracking \
|
||||
--disable-silent-rules \
|
||||
--disable-gdbtk \
|
||||
--disable-shared \
|
||||
--without-guile \
|
||||
--with-system-gdbinit=$PREFIX/etc/gdb/gdbinit \
|
||||
--with-system-readline \
|
||||
--with-expat \
|
||||
--with-system-zlib \
|
||||
--with-lzma \
|
||||
--with-babeltrace \
|
||||
--with-intel-pt \
|
||||
--enable-tui \
|
||||
--with-python=python3
|
||||
make -j$CPUS
|
||||
make install
|
||||
popd && popd
|
||||
fi
|
||||
|
||||
# install pahole
|
||||
if [ ! -d $PREFIX/share/pahole-gdb ]; then
|
||||
unzip ../archives/pahole-gdb-master.zip
|
||||
mv pahole-gdb-master $PREFIX/share/pahole-gdb
|
||||
fi
|
||||
|
||||
# setup system gdbinit
|
||||
if [ ! -f $PREFIX/etc/gdb/gdbinit ]; then
|
||||
mkdir -p $PREFIX/etc/gdb
|
||||
cat >$PREFIX/etc/gdb/gdbinit <<EOF
|
||||
# improve formatting
|
||||
set print pretty on
|
||||
set print object on
|
||||
set print static-members on
|
||||
set print vtbl on
|
||||
set print demangle on
|
||||
set demangle-style gnu-v3
|
||||
set print sevenbit-strings off
|
||||
|
||||
# load libstdc++ pretty printers
|
||||
add-auto-load-scripts-directory $PREFIX/lib64
|
||||
add-auto-load-safe-path $PREFIX
|
||||
|
||||
# load pahole
|
||||
python
|
||||
sys.path.insert(0, "$PREFIX/share/pahole-gdb")
|
||||
import offsets
|
||||
import pahole
|
||||
end
|
||||
EOF
|
||||
fi
|
||||
|
||||
# compile cmake
|
||||
if [ ! -f $PREFIX/bin/cmake ]; then
|
||||
if [ -d cmake-$CMAKE_VERSION ]; then
|
||||
rm -rf cmake-$CMAKE_VERSION
|
||||
fi
|
||||
tar -xvf ../archives/cmake-$CMAKE_VERSION.tar.gz
|
||||
pushd cmake-$CMAKE_VERSION
|
||||
# influenced by: https://buildd.debian.org/status/fetch.php?pkg=cmake&arch=amd64&ver=3.13.4-1&stamp=1549799837
|
||||
echo 'set(CMAKE_SKIP_RPATH ON CACHE BOOL "Skip rpath" FORCE)' >> build-flags.cmake
|
||||
echo 'set(CMAKE_USE_RELATIVE_PATHS ON CACHE BOOL "Use relative paths" FORCE)' >> build-flags.cmake
|
||||
echo 'set(CMAKE_C_FLAGS "-g -O2 -fstack-protector-strong -Wformat -Werror=format-security -Wdate-time -D_FORTIFY_SOURCE=2" CACHE STRING "C flags" FORCE)' >> build-flags.cmake
|
||||
echo 'set(CMAKE_CXX_FLAGS "-g -O2 -fstack-protector-strong -Wformat -Werror=format-security -Wdate-time -D_FORTIFY_SOURCE=2" CACHE STRING "C++ flags" FORCE)' >> build-flags.cmake
|
||||
echo 'set(CMAKE_SKIP_BOOTSTRAP_TEST ON CACHE BOOL "Skip BootstrapTest" FORCE)' >> build-flags.cmake
|
||||
echo 'set(BUILD_CursesDialog ON CACHE BOOL "Build curses GUI" FORCE)' >> build-flags.cmake
|
||||
mkdir build && pushd build
|
||||
../bootstrap \
|
||||
--prefix=$PREFIX \
|
||||
--init=../build-flags.cmake \
|
||||
--parallel=$CPUS \
|
||||
--system-curl
|
||||
make -j$CPUS
|
||||
# make test # run test suite
|
||||
make install
|
||||
popd && popd
|
||||
fi
|
||||
|
||||
# compile cppcheck
|
||||
if [ ! -f $PREFIX/bin/cppcheck ]; then
|
||||
if [ -d cppcheck-$CPPCHECK_VERSION ]; then
|
||||
rm -rf cppcheck-$CPPCHECK_VERSION
|
||||
fi
|
||||
tar -xvf ../archives/cppcheck-$CPPCHECK_VERSION.tar.gz
|
||||
pushd cppcheck-$CPPCHECK_VERSION
|
||||
env \
|
||||
CC=gcc \
|
||||
CXX=g++ \
|
||||
PREFIX=$PREFIX \
|
||||
CFGDIR=$PREFIX/share/cppcheck/cfg \
|
||||
make -j$CPUS
|
||||
env \
|
||||
CC=gcc \
|
||||
CXX=g++ \
|
||||
PREFIX=$PREFIX \
|
||||
CFGDIR=$PREFIX/share/cppcheck/cfg \
|
||||
make install
|
||||
popd
|
||||
fi
|
||||
|
||||
# compile swig
|
||||
if [ ! -d swig-$SWIG_VERSION/install ]; then
|
||||
if [ -d swig-$SWIG_VERSION ]; then
|
||||
rm -rf swig-$SWIG_VERSION
|
||||
fi
|
||||
tar -xvf ../archives/swig-$SWIG_VERSION.tar.gz
|
||||
mv swig-rel-$SWIG_VERSION swig-$SWIG_VERSION
|
||||
pushd swig-$SWIG_VERSION
|
||||
./autogen.sh
|
||||
mkdir build && pushd build
|
||||
../configure --prefix=$DIR/build/swig-$SWIG_VERSION/install
|
||||
make -j$CPUS
|
||||
make install
|
||||
popd && popd
|
||||
fi
|
||||
|
||||
# compile llvm
|
||||
if [ ! -f $PREFIX/bin/clang ]; then
|
||||
if [ -d llvm-$LLVM_VERSION ]; then
|
||||
rm -rf llvm-$LLVM_VERSION
|
||||
fi
|
||||
tar -xvf ../archives/llvm-$LLVM_VERSION.src.tar.xz
|
||||
mv llvm-$LLVM_VERSION.src llvm-$LLVM_VERSION
|
||||
tar -xvf ../archives/cfe-$LLVM_VERSION.src.tar.xz
|
||||
mv cfe-$LLVM_VERSION.src llvm-$LLVM_VERSION/tools/clang
|
||||
tar -xvf ../archives/lld-$LLVM_VERSION.src.tar.xz
|
||||
mv lld-$LLVM_VERSION.src/ llvm-$LLVM_VERSION/tools/lld
|
||||
tar -xvf ../archives/compiler-rt-$LLVM_VERSION.src.tar.xz
|
||||
mv compiler-rt-$LLVM_VERSION.src/ llvm-$LLVM_VERSION/projects/compiler-rt
|
||||
tar -xvf ../archives/clang-tools-extra-$LLVM_VERSION.src.tar.xz
|
||||
mv clang-tools-extra-$LLVM_VERSION.src/ llvm-$LLVM_VERSION/tools/clang/tools/extra
|
||||
pushd llvm-$LLVM_VERSION
|
||||
mkdir build && pushd build
|
||||
# activate swig
|
||||
export PATH=$DIR/build/swig-$SWIG_VERSION/install/bin:$PATH
|
||||
# influenced by: https://buildd.debian.org/status/fetch.php?pkg=llvm-toolchain-7&arch=amd64&ver=1%3A7.0.1%7E%2Brc2-1%7Eexp1&stamp=1541506173&raw=0
|
||||
cmake .. \
|
||||
-DGCC_INSTALL_PREFIX=$PREFIX \
|
||||
-DCMAKE_C_COMPILER=$PREFIX/bin/gcc \
|
||||
-DCMAKE_CXX_COMPILER=$PREFIX/bin/g++ \
|
||||
-DCMAKE_CXX_LINK_FLAGS="-L$PREFIX/lib64 -Wl,-rpath,$PREFIX/lib64" \
|
||||
-DCMAKE_INSTALL_PREFIX=$PREFIX \
|
||||
-DCMAKE_BUILD_TYPE=RelWithDebInfo \
|
||||
-DCMAKE_CXX_FLAGS_RELWITHDEBINFO="-O2 -DNDEBUG" \
|
||||
-DCMAKE_CXX_FLAGS=' -fuse-ld=gold -fPIC -Wno-unused-command-line-argument -Wno-unknown-warning-option' \
|
||||
-DCMAKE_C_FLAGS=' -fuse-ld=gold -fPIC -Wno-unused-command-line-argument -Wno-unknown-warning-option' \
|
||||
-DLLVM_LINK_LLVM_DYLIB=ON \
|
||||
-DLLVM_INSTALL_UTILS=ON \
|
||||
-DLLVM_VERSION_SUFFIX= \
|
||||
-DLLVM_BUILD_LLVM_DYLIB=ON \
|
||||
-DLLVM_ENABLE_RTTI=ON \
|
||||
-DLLVM_ENABLE_FFI=ON \
|
||||
-DLLVM_BINUTILS_INCDIR=$PREFIX/include/ \
|
||||
-DLLVM_USE_PERF=yes \
|
||||
-DLIBCLANG_LIBRARY_VERSION=1 \
|
||||
-DCLANG_ENABLE_BOOTSTRAP=ON
|
||||
make -j$CPUS
|
||||
make -j$CPUS check-clang # run clang test suite
|
||||
make -j$CPUS check-lld # run lld test suite
|
||||
make install
|
||||
popd && popd
|
||||
fi
|
||||
|
||||
# create README
|
||||
if [ ! -f $PREFIX/README.md ]; then
|
||||
cat >$PREFIX/README.md <<EOF
|
||||
# Memgraph Toolchain v$TOOLCHAIN_VERSION
|
||||
|
||||
## Included tools
|
||||
|
||||
- GCC $GCC_VERSION
|
||||
- Binutils $BINUTILS_VERSION
|
||||
- GDB $GDB_VERSION
|
||||
- CMake $CMAKE_VERSION
|
||||
- Cppcheck $CPPCHECK_VERSION
|
||||
- LLVM (Clang, LLD, compiler-rt, Clang tools extra) $LLVM_VERSION
|
||||
|
||||
## Required libraries
|
||||
|
||||
In order to be able to run all of these tools you should install the following
|
||||
packages:
|
||||
|
||||
\`\`\`
|
||||
$DEPS_MANAGER install ${DEPS_RUN[@]}
|
||||
\`\`\`
|
||||
|
||||
## Usage
|
||||
|
||||
In order to use the toolchain you just have to source the activation script:
|
||||
|
||||
\`\`\`
|
||||
source $PREFIX/activate
|
||||
\`\`\`
|
||||
EOF
|
||||
fi
|
||||
|
||||
# create activation script
|
||||
if [ ! -f $PREFIX/activate ]; then
|
||||
cat >$PREFIX/activate <<EOF
|
||||
# This file must be used with "source $PREFIX/activate" *from bash*
|
||||
# You can't run it directly!
|
||||
|
||||
# check for active virtual environments
|
||||
if [ "\$( type -t deactivate )" != "" ]; then
|
||||
echo "You already have an active virtual environment!"
|
||||
return 0
|
||||
fi
|
||||
|
||||
# check that we aren't root
|
||||
if [ "\$USER" == "root" ]; then
|
||||
echo "You shouldn't use the toolchan as root!"
|
||||
return 0
|
||||
fi
|
||||
|
||||
# save original environment
|
||||
export ORIG_PATH=\$PATH
|
||||
export ORIG_PS1=\$PS1
|
||||
export ORIG_LD_LIBRARY_PATH=\$LD_LIBRARY_PATH
|
||||
|
||||
# activate new environment
|
||||
export PATH=$PREFIX/bin:\$PATH
|
||||
export PS1="(TOOLCHAIN) \$PS1"
|
||||
export LD_LIBRARY_PATH=$PREFIX/lib:$PREFIX/lib64
|
||||
|
||||
# disable root
|
||||
function su () {
|
||||
echo "You don't want to use root functions while using the toolchain!"
|
||||
return 1
|
||||
}
|
||||
function sudo () {
|
||||
echo "You don't want to use root functions while using the toolchain!"
|
||||
return 1
|
||||
}
|
||||
|
||||
# create deactivation function
|
||||
function deactivate() {
|
||||
export PATH=\$ORIG_PATH
|
||||
export PS1=\$ORIG_PS1
|
||||
export LD_LIBRARY_PATH=\$ORIG_LD_LIBRARY_PATH
|
||||
unset ORIG_PATH ORIG_PS1 ORIG_LD_LIBRARY_PATH
|
||||
unset -f su sudo deactivate
|
||||
}
|
||||
EOF
|
||||
fi
|
||||
|
||||
# create toolchain archive
|
||||
if [ ! -f $NAME-binaries-$DISTRO.tar.gz ]; then
|
||||
tar --owner=root --group=root -cpvzf $NAME-binaries-$DISTRO.tar.gz -C /opt $NAME
|
||||
fi
|
||||
|
||||
# output final instructions
|
||||
echo -e "\n\n"
|
||||
echo "All tools have been built. They are installed in '$PREFIX'."
|
||||
echo "In order to distribute the tools to someone else, an archive with the toolchain was created in the 'build' directory."
|
||||
echo "If you want to install the packed tools you should execute the following command:"
|
||||
echo
|
||||
echo " tar -xvzf build/$NAME-binaries.tar.gz -C /opt"
|
||||
echo
|
||||
echo "Because the tools were built on this machine, you should probably change the permissions of the installation directory using:"
|
||||
echo
|
||||
echo " OPTIONAL: chown -R root:root $PREFIX"
|
||||
echo
|
||||
echo "In order to use all of the newly compiled tools you should use the prepared activation script:"
|
||||
echo
|
||||
echo " source $PREFIX/activate"
|
||||
echo
|
||||
echo "Or, for more advanced uses, you can add the following lines to your script:"
|
||||
echo
|
||||
echo " export PATH=$PREFIX/bin:\$PATH"
|
||||
echo " export LD_LIBRARY_PATH=$PREFIX/lib:$PREFIX/lib64"
|
||||
echo
|
||||
echo "Enjoy!"
|
||||
@@ -1,533 +0,0 @@
|
||||
#!/bin/bash -e
|
||||
|
||||
# helpers
|
||||
pushd () { command pushd "$@" > /dev/null; }
|
||||
popd () { command popd "$@" > /dev/null; }
|
||||
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
|
||||
CPUS=$( grep -c processor < /proc/cpuinfo )
|
||||
cd "$DIR"
|
||||
|
||||
source "$DIR/../util.sh"
|
||||
DISTRO="$(operating_system)"
|
||||
|
||||
# toolchain version
|
||||
TOOLCHAIN_VERSION=2
|
||||
|
||||
# package versions used
|
||||
GCC_VERSION=10.2.0
|
||||
BINUTILS_VERSION=2.35.1
|
||||
case "$DISTRO" in
|
||||
centos-7) # because GDB >= 9 does NOT compile with readline6.
|
||||
GDB_VERSION=8.3
|
||||
;;
|
||||
*)
|
||||
GDB_VERSION=10.1
|
||||
;;
|
||||
esac
|
||||
CMAKE_VERSION=3.18.4
|
||||
CPPCHECK_VERSION=2.2
|
||||
LLVM_VERSION=11.0.0
|
||||
SWIG_VERSION=4.0.2 # used only for LLVM compilation
|
||||
|
||||
# Check for the dependencies.
|
||||
echo "ALL BUILD PACKAGES: $($DIR/../os/$DISTRO.sh list TOOLCHAIN_BUILD_DEPS)"
|
||||
$DIR/../os/$DISTRO.sh check TOOLCHAIN_BUILD_DEPS
|
||||
echo "ALL RUN PACKAGES: $($DIR/../os/$DISTRO.sh list TOOLCHAIN_RUN_DEPS)"
|
||||
$DIR/../os/$DISTRO.sh check TOOLCHAIN_RUN_DEPS
|
||||
|
||||
# check installation directory
|
||||
NAME=toolchain-v$TOOLCHAIN_VERSION
|
||||
PREFIX=/opt/$NAME
|
||||
mkdir -p $PREFIX >/dev/null 2>/dev/null || true
|
||||
if [ ! -d $PREFIX ] || [ ! -w $PREFIX ]; then
|
||||
echo "Please make sure that the directory '$PREFIX' exists and is writable by the current user!"
|
||||
echo
|
||||
echo "If unsure, execute these commands as root:"
|
||||
echo " mkdir $PREFIX && chown $USER:$USER $PREFIX"
|
||||
echo
|
||||
echo "Press <return> when you have created the directory and granted permissions."
|
||||
# wait for the directory to be created
|
||||
while true; do
|
||||
read
|
||||
if [ ! -d $PREFIX ] || [ ! -w $PREFIX ]; then
|
||||
echo
|
||||
echo "You can't continue before you have created the directory and granted permissions!"
|
||||
echo
|
||||
echo "Press <return> when you have created the directory and granted permissions."
|
||||
else
|
||||
break
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
# create archives directory
|
||||
mkdir -p archives
|
||||
|
||||
# download all archives
|
||||
pushd archives
|
||||
if [ ! -f gcc-$GCC_VERSION.tar.gz ]; then
|
||||
wget https://ftp.gnu.org/gnu/gcc/gcc-$GCC_VERSION/gcc-$GCC_VERSION.tar.gz
|
||||
fi
|
||||
if [ ! -f binutils-$BINUTILS_VERSION.tar.gz ]; then
|
||||
wget https://ftp.gnu.org/gnu/binutils/binutils-$BINUTILS_VERSION.tar.gz
|
||||
fi
|
||||
if [ ! -f gdb-$GDB_VERSION.tar.gz ]; then
|
||||
wget https://ftp.gnu.org/gnu/gdb/gdb-$GDB_VERSION.tar.gz
|
||||
fi
|
||||
if [ ! -f cmake-$CMAKE_VERSION.tar.gz ]; then
|
||||
wget https://github.com/Kitware/CMake/releases/download/v$CMAKE_VERSION/cmake-$CMAKE_VERSION.tar.gz
|
||||
fi
|
||||
if [ ! -f swig-$SWIG_VERSION.tar.gz ]; then
|
||||
wget https://github.com/swig/swig/archive/rel-$SWIG_VERSION.tar.gz -O swig-$SWIG_VERSION.tar.gz
|
||||
fi
|
||||
if [ ! -f cppcheck-$CPPCHECK_VERSION.tar.gz ]; then
|
||||
wget https://github.com/danmar/cppcheck/archive/$CPPCHECK_VERSION.tar.gz -O cppcheck-$CPPCHECK_VERSION.tar.gz
|
||||
fi
|
||||
if [ ! -f llvm-$LLVM_VERSION.src.tar.xz ]; then
|
||||
wget https://github.com/llvm/llvm-project/releases/download/llvmorg-$LLVM_VERSION/llvm-$LLVM_VERSION.src.tar.xz
|
||||
wget https://github.com/llvm/llvm-project/releases/download/llvmorg-$LLVM_VERSION/clang-$LLVM_VERSION.src.tar.xz
|
||||
wget https://github.com/llvm/llvm-project/releases/download/llvmorg-$LLVM_VERSION/lld-$LLVM_VERSION.src.tar.xz
|
||||
wget https://github.com/llvm/llvm-project/releases/download/llvmorg-$LLVM_VERSION/clang-tools-extra-$LLVM_VERSION.src.tar.xz
|
||||
wget https://github.com/llvm/llvm-project/releases/download/llvmorg-$LLVM_VERSION/compiler-rt-$LLVM_VERSION.src.tar.xz
|
||||
fi
|
||||
if [ ! -f pahole-gdb-master.zip ]; then
|
||||
wget https://github.com/PhilArmstrong/pahole-gdb/archive/master.zip -O pahole-gdb-master.zip
|
||||
fi
|
||||
|
||||
# verify all archives
|
||||
# NOTE: Verification can fail if the archive is signed by another developer. I
|
||||
# haven't added commands to download all developer GnuPG keys because the
|
||||
# download is very slow. If the verification fails for you, figure out who has
|
||||
# signed the archive and download their public key instead.
|
||||
GPG="gpg --homedir .gnupg"
|
||||
KEYSERVER="hkp://keyserver.ubuntu.com"
|
||||
mkdir -p .gnupg
|
||||
chmod 700 .gnupg
|
||||
# verify gcc
|
||||
if [ ! -f gcc-$GCC_VERSION.tar.gz.sig ]; then
|
||||
wget https://ftp.gnu.org/gnu/gcc/gcc-$GCC_VERSION/gcc-$GCC_VERSION.tar.gz.sig
|
||||
fi
|
||||
# list of valid gcc gnupg keys: https://gcc.gnu.org/mirrors.html
|
||||
$GPG --keyserver $KEYSERVER --recv-keys 0x3AB00996FC26A641
|
||||
$GPG --verify gcc-$GCC_VERSION.tar.gz.sig gcc-$GCC_VERSION.tar.gz
|
||||
# verify binutils
|
||||
if [ ! -f binutils-$BINUTILS_VERSION.tar.gz.sig ]; then
|
||||
wget https://ftp.gnu.org/gnu/binutils/binutils-$BINUTILS_VERSION.tar.gz.sig
|
||||
fi
|
||||
$GPG --keyserver $KEYSERVER --recv-keys 0xDD9E3C4F
|
||||
$GPG --verify binutils-$BINUTILS_VERSION.tar.gz.sig binutils-$BINUTILS_VERSION.tar.gz
|
||||
# verify gdb
|
||||
if [ ! -f gdb-$GDB_VERSION.tar.gz.sig ]; then
|
||||
wget https://ftp.gnu.org/gnu/gdb/gdb-$GDB_VERSION.tar.gz.sig
|
||||
fi
|
||||
$GPG --keyserver $KEYSERVER --recv-keys 0xFF325CF3
|
||||
$GPG --verify gdb-$GDB_VERSION.tar.gz.sig gdb-$GDB_VERSION.tar.gz
|
||||
# verify cmake
|
||||
if [ ! -f cmake-$CMAKE_VERSION-SHA-256.txt ] || [ ! -f cmake-$CMAKE_VERSION-SHA-256.txt.asc ]; then
|
||||
wget https://github.com/Kitware/CMake/releases/download/v$CMAKE_VERSION/cmake-$CMAKE_VERSION-SHA-256.txt
|
||||
wget https://github.com/Kitware/CMake/releases/download/v$CMAKE_VERSION/cmake-$CMAKE_VERSION-SHA-256.txt.asc
|
||||
# Because CentOS 7 doesn't have the `--ignore-missing` flag for `sha256sum`
|
||||
# we filter out the missing files from the sums here manually.
|
||||
cat cmake-$CMAKE_VERSION-SHA-256.txt | grep "cmake-$CMAKE_VERSION.tar.gz" > cmake-$CMAKE_VERSION-SHA-256-filtered.txt
|
||||
fi
|
||||
$GPG --keyserver $KEYSERVER --recv-keys 0xC6C265324BBEBDC350B513D02D2CEF1034921684
|
||||
sha256sum -c cmake-$CMAKE_VERSION-SHA-256-filtered.txt
|
||||
$GPG --verify cmake-$CMAKE_VERSION-SHA-256.txt.asc cmake-$CMAKE_VERSION-SHA-256.txt
|
||||
# verify llvm, cfe, lld, clang-tools-extra
|
||||
if [ ! -f llvm-$LLVM_VERSION.src.tar.xz.sig ]; then
|
||||
wget https://github.com/llvm/llvm-project/releases/download/llvmorg-$LLVM_VERSION/llvm-$LLVM_VERSION.src.tar.xz.sig
|
||||
wget https://github.com/llvm/llvm-project/releases/download/llvmorg-$LLVM_VERSION/clang-$LLVM_VERSION.src.tar.xz.sig
|
||||
wget https://github.com/llvm/llvm-project/releases/download/llvmorg-$LLVM_VERSION/lld-$LLVM_VERSION.src.tar.xz.sig
|
||||
wget https://github.com/llvm/llvm-project/releases/download/llvmorg-$LLVM_VERSION/clang-tools-extra-$LLVM_VERSION.src.tar.xz.sig
|
||||
wget https://github.com/llvm/llvm-project/releases/download/llvmorg-$LLVM_VERSION/compiler-rt-$LLVM_VERSION.src.tar.xz.sig
|
||||
fi
|
||||
# list of valid llvm gnupg keys: https://releases.llvm.org/download.html
|
||||
$GPG --keyserver $KEYSERVER --recv-keys 0x345AD05D
|
||||
$GPG --verify llvm-$LLVM_VERSION.src.tar.xz.sig llvm-$LLVM_VERSION.src.tar.xz
|
||||
$GPG --verify clang-$LLVM_VERSION.src.tar.xz.sig clang-$LLVM_VERSION.src.tar.xz
|
||||
$GPG --verify lld-$LLVM_VERSION.src.tar.xz.sig lld-$LLVM_VERSION.src.tar.xz
|
||||
$GPG --verify clang-tools-extra-$LLVM_VERSION.src.tar.xz.sig clang-tools-extra-$LLVM_VERSION.src.tar.xz
|
||||
$GPG --verify compiler-rt-$LLVM_VERSION.src.tar.xz.sig compiler-rt-$LLVM_VERSION.src.tar.xz
|
||||
popd
|
||||
|
||||
# create build directory
|
||||
mkdir -p build
|
||||
pushd build
|
||||
|
||||
# compile gcc
|
||||
if [ ! -f $PREFIX/bin/gcc ]; then
|
||||
if [ -d gcc-$GCC_VERSION ]; then
|
||||
rm -rf gcc-$GCC_VERSION
|
||||
fi
|
||||
tar -xvf ../archives/gcc-$GCC_VERSION.tar.gz
|
||||
pushd gcc-$GCC_VERSION
|
||||
./contrib/download_prerequisites
|
||||
mkdir build && pushd build
|
||||
# influenced by: https://buildd.debian.org/status/fetch.php?pkg=gcc-8&arch=amd64&ver=8.3.0-6&stamp=1554588545
|
||||
../configure -v \
|
||||
--build=x86_64-linux-gnu \
|
||||
--host=x86_64-linux-gnu \
|
||||
--target=x86_64-linux-gnu \
|
||||
--prefix=$PREFIX \
|
||||
--disable-multilib \
|
||||
--with-system-zlib \
|
||||
--enable-checking=release \
|
||||
--enable-languages=c,c++,fortran \
|
||||
--enable-gold=yes \
|
||||
--enable-ld=yes \
|
||||
--enable-lto \
|
||||
--enable-bootstrap \
|
||||
--disable-vtable-verify \
|
||||
--disable-werror \
|
||||
--without-included-gettext \
|
||||
--enable-threads=posix \
|
||||
--enable-nls \
|
||||
--enable-clocale=gnu \
|
||||
--enable-libstdcxx-debug \
|
||||
--enable-libstdcxx-time=yes \
|
||||
--enable-gnu-unique-object \
|
||||
--enable-libmpx \
|
||||
--enable-plugin \
|
||||
--enable-default-pie \
|
||||
--with-target-system-zlib \
|
||||
--with-tune=generic \
|
||||
--without-cuda-driver
|
||||
#--program-suffix=$( printf "$GCC_VERSION" | cut -d '.' -f 1,2 ) \
|
||||
make -j$CPUS
|
||||
# make -k check # run test suite
|
||||
make install
|
||||
popd && popd
|
||||
fi
|
||||
|
||||
# activate toolchain
|
||||
export PATH=$PREFIX/bin:$PATH
|
||||
export LD_LIBRARY_PATH=$PREFIX/lib64
|
||||
|
||||
# compile binutils
|
||||
if [ ! -f $PREFIX/bin/ld.gold ]; then
|
||||
if [ -d binutils-$BINUTILS_VERSION ]; then
|
||||
rm -rf binutils-$BINUTILS_VERSION
|
||||
fi
|
||||
tar -xvf ../archives/binutils-$BINUTILS_VERSION.tar.gz
|
||||
pushd binutils-$BINUTILS_VERSION
|
||||
mkdir build && pushd build
|
||||
# influenced by: https://buildd.debian.org/status/fetch.php?pkg=binutils&arch=amd64&ver=2.32-7&stamp=1553247092
|
||||
env \
|
||||
CC=gcc \
|
||||
CXX=g++ \
|
||||
CFLAGS="-g -O2" \
|
||||
CXXFLAGS="-g -O2" \
|
||||
LDFLAGS="" \
|
||||
../configure \
|
||||
--build=x86_64-linux-gnu \
|
||||
--host=x86_64-linux-gnu \
|
||||
--prefix=$PREFIX \
|
||||
--enable-ld=default \
|
||||
--enable-gold \
|
||||
--enable-lto \
|
||||
--enable-plugins \
|
||||
--enable-shared \
|
||||
--enable-threads \
|
||||
--with-system-zlib \
|
||||
--enable-deterministic-archives \
|
||||
--disable-compressed-debug-sections \
|
||||
--enable-new-dtags \
|
||||
--disable-werror
|
||||
make -j$CPUS
|
||||
# make -k check # run test suite
|
||||
make install
|
||||
popd && popd
|
||||
fi
|
||||
|
||||
# compile gdb
|
||||
if [ ! -f $PREFIX/bin/gdb ]; then
|
||||
if [ -d gdb-$GDB_VERSION ]; then
|
||||
rm -rf gdb-$GDB_VERSION
|
||||
fi
|
||||
tar -xvf ../archives/gdb-$GDB_VERSION.tar.gz
|
||||
pushd gdb-$GDB_VERSION
|
||||
mkdir build && pushd build
|
||||
# https://buildd.debian.org/status/fetch.php?pkg=gdb&arch=amd64&ver=8.2.1-2&stamp=1550831554&raw=0
|
||||
env \
|
||||
CC=gcc \
|
||||
CXX=g++ \
|
||||
CFLAGS="-g -O2 -fstack-protector-strong -Wformat -Werror=format-security" \
|
||||
CXXFLAGS="-g -O2 -fstack-protector-strong -Wformat -Werror=format-security" \
|
||||
CPPFLAGS="-Wdate-time -D_FORTIFY_SOURCE=2 -fPIC" \
|
||||
LDFLAGS="-Wl,-z,relro" \
|
||||
PYTHON="" \
|
||||
../configure \
|
||||
--build=x86_64-linux-gnu \
|
||||
--host=x86_64-linux-gnu \
|
||||
--prefix=$PREFIX \
|
||||
--disable-maintainer-mode \
|
||||
--disable-dependency-tracking \
|
||||
--disable-silent-rules \
|
||||
--disable-gdbtk \
|
||||
--disable-shared \
|
||||
--without-guile \
|
||||
--with-system-gdbinit=$PREFIX/etc/gdb/gdbinit \
|
||||
--with-system-readline \
|
||||
--with-expat \
|
||||
--with-system-zlib \
|
||||
--with-lzma \
|
||||
--with-babeltrace \
|
||||
--with-intel-pt \
|
||||
--enable-tui \
|
||||
--with-python=python3
|
||||
make -j$CPUS
|
||||
make install
|
||||
popd && popd
|
||||
fi
|
||||
|
||||
# install pahole
|
||||
if [ ! -d $PREFIX/share/pahole-gdb ]; then
|
||||
unzip ../archives/pahole-gdb-master.zip
|
||||
mv pahole-gdb-master $PREFIX/share/pahole-gdb
|
||||
fi
|
||||
|
||||
# setup system gdbinit
|
||||
if [ ! -f $PREFIX/etc/gdb/gdbinit ]; then
|
||||
mkdir -p $PREFIX/etc/gdb
|
||||
cat >$PREFIX/etc/gdb/gdbinit <<EOF
|
||||
# improve formatting
|
||||
set print pretty on
|
||||
set print object on
|
||||
set print static-members on
|
||||
set print vtbl on
|
||||
set print demangle on
|
||||
set demangle-style gnu-v3
|
||||
set print sevenbit-strings off
|
||||
|
||||
# load libstdc++ pretty printers
|
||||
add-auto-load-scripts-directory $PREFIX/lib64
|
||||
add-auto-load-safe-path $PREFIX
|
||||
|
||||
# load pahole
|
||||
python
|
||||
sys.path.insert(0, "$PREFIX/share/pahole-gdb")
|
||||
import offsets
|
||||
import pahole
|
||||
end
|
||||
EOF
|
||||
fi
|
||||
|
||||
# compile cmake
|
||||
if [ ! -f $PREFIX/bin/cmake ]; then
|
||||
if [ -d cmake-$CMAKE_VERSION ]; then
|
||||
rm -rf cmake-$CMAKE_VERSION
|
||||
fi
|
||||
tar -xvf ../archives/cmake-$CMAKE_VERSION.tar.gz
|
||||
pushd cmake-$CMAKE_VERSION
|
||||
# influenced by: https://buildd.debian.org/status/fetch.php?pkg=cmake&arch=amd64&ver=3.13.4-1&stamp=1549799837
|
||||
echo 'set(CMAKE_SKIP_RPATH ON CACHE BOOL "Skip rpath" FORCE)' >> build-flags.cmake
|
||||
echo 'set(CMAKE_USE_RELATIVE_PATHS ON CACHE BOOL "Use relative paths" FORCE)' >> build-flags.cmake
|
||||
echo 'set(CMAKE_C_FLAGS "-g -O2 -fstack-protector-strong -Wformat -Werror=format-security -Wdate-time -D_FORTIFY_SOURCE=2" CACHE STRING "C flags" FORCE)' >> build-flags.cmake
|
||||
echo 'set(CMAKE_CXX_FLAGS "-g -O2 -fstack-protector-strong -Wformat -Werror=format-security -Wdate-time -D_FORTIFY_SOURCE=2" CACHE STRING "C++ flags" FORCE)' >> build-flags.cmake
|
||||
echo 'set(CMAKE_SKIP_BOOTSTRAP_TEST ON CACHE BOOL "Skip BootstrapTest" FORCE)' >> build-flags.cmake
|
||||
echo 'set(BUILD_CursesDialog ON CACHE BOOL "Build curses GUI" FORCE)' >> build-flags.cmake
|
||||
mkdir build && pushd build
|
||||
../bootstrap \
|
||||
--prefix=$PREFIX \
|
||||
--init=../build-flags.cmake \
|
||||
--parallel=$CPUS \
|
||||
--system-curl
|
||||
make -j$CPUS
|
||||
# make test # run test suite
|
||||
make install
|
||||
popd && popd
|
||||
fi
|
||||
|
||||
# compile cppcheck
|
||||
if [ ! -f $PREFIX/bin/cppcheck ]; then
|
||||
if [ -d cppcheck-$CPPCHECK_VERSION ]; then
|
||||
rm -rf cppcheck-$CPPCHECK_VERSION
|
||||
fi
|
||||
tar -xvf ../archives/cppcheck-$CPPCHECK_VERSION.tar.gz
|
||||
pushd cppcheck-$CPPCHECK_VERSION
|
||||
env \
|
||||
CC=gcc \
|
||||
CXX=g++ \
|
||||
PREFIX=$PREFIX \
|
||||
FILESDIR=$PREFIX/share/cppcheck \
|
||||
CFGDIR=$PREFIX/share/cppcheck/cfg \
|
||||
make -j$CPUS
|
||||
env \
|
||||
CC=gcc \
|
||||
CXX=g++ \
|
||||
PREFIX=$PREFIX \
|
||||
FILESDIR=$PREFIX/share/cppcheck \
|
||||
CFGDIR=$PREFIX/share/cppcheck/cfg \
|
||||
make install
|
||||
popd
|
||||
fi
|
||||
|
||||
# compile swig
|
||||
if [ ! -d swig-$SWIG_VERSION/install ]; then
|
||||
if [ -d swig-$SWIG_VERSION ]; then
|
||||
rm -rf swig-$SWIG_VERSION
|
||||
fi
|
||||
tar -xvf ../archives/swig-$SWIG_VERSION.tar.gz
|
||||
mv swig-rel-$SWIG_VERSION swig-$SWIG_VERSION
|
||||
pushd swig-$SWIG_VERSION
|
||||
./autogen.sh
|
||||
mkdir build && pushd build
|
||||
../configure --prefix=$DIR/build/swig-$SWIG_VERSION/install
|
||||
make -j$CPUS
|
||||
make install
|
||||
popd && popd
|
||||
fi
|
||||
|
||||
# compile llvm
|
||||
if [ ! -f $PREFIX/bin/clang ]; then
|
||||
if [ -d llvm-$LLVM_VERSION ]; then
|
||||
rm -rf llvm-$LLVM_VERSION
|
||||
fi
|
||||
tar -xvf ../archives/llvm-$LLVM_VERSION.src.tar.xz
|
||||
mv llvm-$LLVM_VERSION.src llvm-$LLVM_VERSION
|
||||
tar -xvf ../archives/clang-$LLVM_VERSION.src.tar.xz
|
||||
mv clang-$LLVM_VERSION.src llvm-$LLVM_VERSION/tools/clang
|
||||
tar -xvf ../archives/lld-$LLVM_VERSION.src.tar.xz
|
||||
mv lld-$LLVM_VERSION.src/ llvm-$LLVM_VERSION/tools/lld
|
||||
tar -xvf ../archives/clang-tools-extra-$LLVM_VERSION.src.tar.xz
|
||||
mv clang-tools-extra-$LLVM_VERSION.src/ llvm-$LLVM_VERSION/tools/clang/tools/extra
|
||||
tar -xvf ../archives/compiler-rt-$LLVM_VERSION.src.tar.xz
|
||||
mv compiler-rt-$LLVM_VERSION.src/ llvm-$LLVM_VERSION/projects/compiler-rt
|
||||
pushd llvm-$LLVM_VERSION
|
||||
mkdir build && pushd build
|
||||
# activate swig
|
||||
export PATH=$DIR/build/swig-$SWIG_VERSION/install/bin:$PATH
|
||||
# influenced by: https://buildd.debian.org/status/fetch.php?pkg=llvm-toolchain-7&arch=amd64&ver=1%3A7.0.1%7E%2Brc2-1%7Eexp1&stamp=1541506173&raw=0
|
||||
cmake .. \
|
||||
-DCMAKE_C_COMPILER=$PREFIX/bin/gcc \
|
||||
-DCMAKE_CXX_COMPILER=$PREFIX/bin/g++ \
|
||||
-DCMAKE_CXX_LINK_FLAGS="-L$PREFIX/lib64 -Wl,-rpath,$PREFIX/lib64" \
|
||||
-DCMAKE_INSTALL_PREFIX=$PREFIX \
|
||||
-DCMAKE_BUILD_TYPE=RelWithDebInfo \
|
||||
-DCMAKE_CXX_FLAGS_RELWITHDEBINFO="-O2 -DNDEBUG" \
|
||||
-DCMAKE_CXX_FLAGS=' -fuse-ld=gold -fPIC -Wno-unused-command-line-argument -Wno-unknown-warning-option' \
|
||||
-DCMAKE_C_FLAGS=' -fuse-ld=gold -fPIC -Wno-unused-command-line-argument -Wno-unknown-warning-option' \
|
||||
-DLLVM_LINK_LLVM_DYLIB=ON \
|
||||
-DLLVM_INSTALL_UTILS=ON \
|
||||
-DLLVM_VERSION_SUFFIX= \
|
||||
-DLLVM_BUILD_LLVM_DYLIB=ON \
|
||||
-DLLVM_ENABLE_RTTI=ON \
|
||||
-DLLVM_ENABLE_FFI=ON \
|
||||
-DLLVM_BINUTILS_INCDIR=$PREFIX/include/ \
|
||||
-DLLVM_USE_PERF=yes
|
||||
make -j$CPUS
|
||||
make -j$CPUS check-clang # run clang test suite
|
||||
make -j$CPUS check-lld # run lld test suite
|
||||
make install
|
||||
popd && popd
|
||||
fi
|
||||
|
||||
# create README
|
||||
if [ ! -f $PREFIX/README.md ]; then
|
||||
cat >$PREFIX/README.md <<EOF
|
||||
# Memgraph Toolchain v$TOOLCHAIN_VERSION
|
||||
|
||||
## Included tools
|
||||
|
||||
- GCC $GCC_VERSION
|
||||
- Binutils $BINUTILS_VERSION
|
||||
- GDB $GDB_VERSION
|
||||
- CMake $CMAKE_VERSION
|
||||
- Cppcheck $CPPCHECK_VERSION
|
||||
- LLVM (Clang, LLD, compiler-rt, Clang tools extra) $LLVM_VERSION
|
||||
|
||||
## Required libraries
|
||||
|
||||
In order to be able to run all of these tools you should install the following
|
||||
packages:
|
||||
|
||||
\`\`\`
|
||||
$($DIR/../os/$DISTRO.sh list TOOLCHAIN_RUN_DEPS)
|
||||
\`\`\`
|
||||
|
||||
## Usage
|
||||
|
||||
In order to use the toolchain you just have to source the activation script:
|
||||
|
||||
\`\`\`
|
||||
source $PREFIX/activate
|
||||
\`\`\`
|
||||
EOF
|
||||
fi
|
||||
|
||||
# create activation script
|
||||
if [ ! -f $PREFIX/activate ]; then
|
||||
cat >$PREFIX/activate <<EOF
|
||||
# This file must be used with "source $PREFIX/activate" *from bash*
|
||||
# You can't run it directly!
|
||||
|
||||
# check for active virtual environments
|
||||
if [ "\$( type -t deactivate )" != "" ]; then
|
||||
echo "You already have an active virtual environment!"
|
||||
return 0
|
||||
fi
|
||||
|
||||
# check that we aren't root
|
||||
if [ "\$USER" == "root" ]; then
|
||||
echo "You shouldn't use the toolchan as root!"
|
||||
return 0
|
||||
fi
|
||||
|
||||
# save original environment
|
||||
export ORIG_PATH=\$PATH
|
||||
export ORIG_PS1=\$PS1
|
||||
export ORIG_LD_LIBRARY_PATH=\$LD_LIBRARY_PATH
|
||||
|
||||
# activate new environment
|
||||
export PATH=$PREFIX/bin:\$PATH
|
||||
export PS1="($NAME) \$PS1"
|
||||
export LD_LIBRARY_PATH=$PREFIX/lib:$PREFIX/lib64
|
||||
|
||||
# disable root
|
||||
function su () {
|
||||
echo "You don't want to use root functions while using the toolchain!"
|
||||
return 1
|
||||
}
|
||||
function sudo () {
|
||||
echo "You don't want to use root functions while using the toolchain!"
|
||||
return 1
|
||||
}
|
||||
|
||||
# create deactivation function
|
||||
function deactivate() {
|
||||
export PATH=\$ORIG_PATH
|
||||
export PS1=\$ORIG_PS1
|
||||
export LD_LIBRARY_PATH=\$ORIG_LD_LIBRARY_PATH
|
||||
unset ORIG_PATH ORIG_PS1 ORIG_LD_LIBRARY_PATH
|
||||
unset -f su sudo deactivate
|
||||
}
|
||||
EOF
|
||||
fi
|
||||
|
||||
# create toolchain archive
|
||||
if [ ! -f $NAME-binaries-$DISTRO.tar.gz ]; then
|
||||
tar --owner=root --group=root -cpvzf $NAME-binaries-$DISTRO.tar.gz -C /opt $NAME
|
||||
fi
|
||||
|
||||
# output final instructions
|
||||
echo -e "\n\n"
|
||||
echo "All tools have been built. They are installed in '$PREFIX'."
|
||||
echo "In order to distribute the tools to someone else, an archive with the toolchain was created in the 'build' directory."
|
||||
echo "If you want to install the packed tools you should execute the following command:"
|
||||
echo
|
||||
echo " tar -xvzf build/$NAME-binaries.tar.gz -C /opt"
|
||||
echo
|
||||
echo "Because the tools were built on this machine, you should probably change the permissions of the installation directory using:"
|
||||
echo
|
||||
echo " OPTIONAL: chown -R root:root $PREFIX"
|
||||
echo
|
||||
echo "In order to use all of the newly compiled tools you should use the prepared activation script:"
|
||||
echo
|
||||
echo " source $PREFIX/activate"
|
||||
echo
|
||||
echo "Or, for more advanced uses, you can add the following lines to your script:"
|
||||
echo
|
||||
echo " export PATH=$PREFIX/bin:\$PATH"
|
||||
echo " export LD_LIBRARY_PATH=$PREFIX/lib:$PREFIX/lib64"
|
||||
echo
|
||||
echo "Enjoy!"
|
||||
@@ -1,556 +0,0 @@
|
||||
#!/bin/bash -e
|
||||
|
||||
# helpers
|
||||
pushd () { command pushd "$@" > /dev/null; }
|
||||
popd () { command popd "$@" > /dev/null; }
|
||||
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
|
||||
CPUS=$( grep -c processor < /proc/cpuinfo )
|
||||
cd "$DIR"
|
||||
|
||||
source "$DIR/../util.sh"
|
||||
DISTRO="$(operating_system)"
|
||||
|
||||
# toolchain version
|
||||
TOOLCHAIN_VERSION=3
|
||||
|
||||
# package versions used
|
||||
GCC_VERSION=11.1.0
|
||||
BINUTILS_VERSION=2.36.1
|
||||
case "$DISTRO" in
|
||||
centos-7) # because GDB >= 9 does NOT compile with readline6.
|
||||
GDB_VERSION=8.3
|
||||
;;
|
||||
*)
|
||||
GDB_VERSION=10.2
|
||||
;;
|
||||
esac
|
||||
CMAKE_VERSION=3.20.5
|
||||
CPPCHECK_VERSION=2.4.1
|
||||
LLVM_VERSION=12.0.1rc4
|
||||
LLVM_VERSION_LONG=12.0.1-rc4
|
||||
SWIG_VERSION=4.0.2 # used only for LLVM compilation
|
||||
|
||||
# Check for the dependencies.
|
||||
echo "ALL BUILD PACKAGES: $($DIR/../os/$DISTRO.sh list TOOLCHAIN_BUILD_DEPS)"
|
||||
$DIR/../os/$DISTRO.sh check TOOLCHAIN_BUILD_DEPS
|
||||
echo "ALL RUN PACKAGES: $($DIR/../os/$DISTRO.sh list TOOLCHAIN_RUN_DEPS)"
|
||||
$DIR/../os/$DISTRO.sh check TOOLCHAIN_RUN_DEPS
|
||||
|
||||
# check installation directory
|
||||
NAME=toolchain-v$TOOLCHAIN_VERSION
|
||||
PREFIX=/opt/$NAME
|
||||
mkdir -p $PREFIX >/dev/null 2>/dev/null || true
|
||||
if [ ! -d $PREFIX ] || [ ! -w $PREFIX ]; then
|
||||
echo "Please make sure that the directory '$PREFIX' exists and is writable by the current user!"
|
||||
echo
|
||||
echo "If unsure, execute these commands as root:"
|
||||
echo " mkdir $PREFIX && chown $USER:$USER $PREFIX"
|
||||
echo
|
||||
echo "Press <return> when you have created the directory and granted permissions."
|
||||
# wait for the directory to be created
|
||||
while true; do
|
||||
read
|
||||
if [ ! -d $PREFIX ] || [ ! -w $PREFIX ]; then
|
||||
echo
|
||||
echo "You can't continue before you have created the directory and granted permissions!"
|
||||
echo
|
||||
echo "Press <return> when you have created the directory and granted permissions."
|
||||
else
|
||||
break
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
# create archives directory
|
||||
mkdir -p archives
|
||||
|
||||
# download all archives
|
||||
pushd archives
|
||||
if [ ! -f gcc-$GCC_VERSION.tar.gz ]; then
|
||||
wget https://ftp.gnu.org/gnu/gcc/gcc-$GCC_VERSION/gcc-$GCC_VERSION.tar.gz
|
||||
fi
|
||||
if [ ! -f binutils-$BINUTILS_VERSION.tar.gz ]; then
|
||||
wget https://ftp.gnu.org/gnu/binutils/binutils-$BINUTILS_VERSION.tar.gz
|
||||
fi
|
||||
if [ ! -f gdb-$GDB_VERSION.tar.gz ]; then
|
||||
wget https://ftp.gnu.org/gnu/gdb/gdb-$GDB_VERSION.tar.gz
|
||||
fi
|
||||
if [ ! -f cmake-$CMAKE_VERSION.tar.gz ]; then
|
||||
wget https://github.com/Kitware/CMake/releases/download/v$CMAKE_VERSION/cmake-$CMAKE_VERSION.tar.gz
|
||||
fi
|
||||
if [ ! -f swig-$SWIG_VERSION.tar.gz ]; then
|
||||
wget https://github.com/swig/swig/archive/rel-$SWIG_VERSION.tar.gz -O swig-$SWIG_VERSION.tar.gz
|
||||
fi
|
||||
if [ ! -f cppcheck-$CPPCHECK_VERSION.tar.gz ]; then
|
||||
wget https://github.com/danmar/cppcheck/archive/$CPPCHECK_VERSION.tar.gz -O cppcheck-$CPPCHECK_VERSION.tar.gz
|
||||
fi
|
||||
if [ ! -f llvm-$LLVM_VERSION.src.tar.xz ]; then
|
||||
wget https://github.com/llvm/llvm-project/releases/download/llvmorg-$LLVM_VERSION_LONG/llvm-$LLVM_VERSION.src.tar.xz
|
||||
wget https://github.com/llvm/llvm-project/releases/download/llvmorg-$LLVM_VERSION_LONG/clang-$LLVM_VERSION.src.tar.xz
|
||||
wget https://github.com/llvm/llvm-project/releases/download/llvmorg-$LLVM_VERSION_LONG/lld-$LLVM_VERSION.src.tar.xz
|
||||
wget https://github.com/llvm/llvm-project/releases/download/llvmorg-$LLVM_VERSION_LONG/clang-tools-extra-$LLVM_VERSION.src.tar.xz
|
||||
wget https://github.com/llvm/llvm-project/releases/download/llvmorg-$LLVM_VERSION_LONG/compiler-rt-$LLVM_VERSION.src.tar.xz
|
||||
wget https://github.com/llvm/llvm-project/releases/download/llvmorg-$LLVM_VERSION_LONG/libunwind-$LLVM_VERSION.src.tar.xz
|
||||
fi
|
||||
if [ ! -f pahole-gdb-master.zip ]; then
|
||||
wget https://github.com/PhilArmstrong/pahole-gdb/archive/master.zip -O pahole-gdb-master.zip
|
||||
fi
|
||||
|
||||
# verify all archives
|
||||
# NOTE: Verification can fail if the archive is signed by another developer. I
|
||||
# haven't added commands to download all developer GnuPG keys because the
|
||||
# download is very slow. If the verification fails for you, figure out who has
|
||||
# signed the archive and download their public key instead.
|
||||
GPG="gpg --homedir .gnupg"
|
||||
KEYSERVER="hkp://keyserver.ubuntu.com"
|
||||
|
||||
mkdir -p .gnupg
|
||||
chmod 700 .gnupg
|
||||
# verify gcc
|
||||
if [ ! -f gcc-$GCC_VERSION.tar.gz.sig ]; then
|
||||
wget https://ftp.gnu.org/gnu/gcc/gcc-$GCC_VERSION/gcc-$GCC_VERSION.tar.gz.sig
|
||||
fi
|
||||
# list of valid gcc gnupg keys: https://gcc.gnu.org/mirrors.html
|
||||
$GPG --keyserver $KEYSERVER --recv-keys 0x6C35B99309B5FA62
|
||||
$GPG --verify gcc-$GCC_VERSION.tar.gz.sig gcc-$GCC_VERSION.tar.gz
|
||||
# verify binutils
|
||||
if [ ! -f binutils-$BINUTILS_VERSION.tar.gz.sig ]; then
|
||||
wget https://ftp.gnu.org/gnu/binutils/binutils-$BINUTILS_VERSION.tar.gz.sig
|
||||
fi
|
||||
$GPG --keyserver $KEYSERVER --recv-keys 0xDD9E3C4F
|
||||
$GPG --verify binutils-$BINUTILS_VERSION.tar.gz.sig binutils-$BINUTILS_VERSION.tar.gz
|
||||
# verify gdb
|
||||
if [ ! -f gdb-$GDB_VERSION.tar.gz.sig ]; then
|
||||
wget https://ftp.gnu.org/gnu/gdb/gdb-$GDB_VERSION.tar.gz.sig
|
||||
fi
|
||||
$GPG --keyserver $KEYSERVER --recv-keys 0xFF325CF3
|
||||
$GPG --verify gdb-$GDB_VERSION.tar.gz.sig gdb-$GDB_VERSION.tar.gz
|
||||
# verify cmake
|
||||
if [ ! -f cmake-$CMAKE_VERSION-SHA-256.txt ] || [ ! -f cmake-$CMAKE_VERSION-SHA-256.txt.asc ]; then
|
||||
wget https://github.com/Kitware/CMake/releases/download/v$CMAKE_VERSION/cmake-$CMAKE_VERSION-SHA-256.txt
|
||||
wget https://github.com/Kitware/CMake/releases/download/v$CMAKE_VERSION/cmake-$CMAKE_VERSION-SHA-256.txt.asc
|
||||
# Because CentOS 7 doesn't have the `--ignore-missing` flag for `sha256sum`
|
||||
# we filter out the missing files from the sums here manually.
|
||||
cat cmake-$CMAKE_VERSION-SHA-256.txt | grep "cmake-$CMAKE_VERSION.tar.gz" > cmake-$CMAKE_VERSION-SHA-256-filtered.txt
|
||||
fi
|
||||
$GPG --keyserver $KEYSERVER --recv-keys 0xC6C265324BBEBDC350B513D02D2CEF1034921684
|
||||
sha256sum -c cmake-$CMAKE_VERSION-SHA-256-filtered.txt
|
||||
$GPG --verify cmake-$CMAKE_VERSION-SHA-256.txt.asc cmake-$CMAKE_VERSION-SHA-256.txt
|
||||
# verify llvm, cfe, lld, clang-tools-extra
|
||||
if [ ! -f llvm-$LLVM_VERSION.src.tar.xz.sig ]; then
|
||||
wget https://github.com/llvm/llvm-project/releases/download/llvmorg-$LLVM_VERSION_LONG/llvm-$LLVM_VERSION.src.tar.xz.sig
|
||||
wget https://github.com/llvm/llvm-project/releases/download/llvmorg-$LLVM_VERSION_LONG/clang-$LLVM_VERSION.src.tar.xz.sig
|
||||
wget https://github.com/llvm/llvm-project/releases/download/llvmorg-$LLVM_VERSION_LONG/lld-$LLVM_VERSION.src.tar.xz.sig
|
||||
wget https://github.com/llvm/llvm-project/releases/download/llvmorg-$LLVM_VERSION_LONG/clang-tools-extra-$LLVM_VERSION.src.tar.xz.sig
|
||||
wget https://github.com/llvm/llvm-project/releases/download/llvmorg-$LLVM_VERSION_LONG/compiler-rt-$LLVM_VERSION.src.tar.xz.sig
|
||||
wget https://github.com/llvm/llvm-project/releases/download/llvmorg-$LLVM_VERSION_LONG/libunwind-$LLVM_VERSION.src.tar.xz.sig
|
||||
fi
|
||||
# list of valid llvm gnupg keys: https://releases.llvm.org/download.html
|
||||
$GPG --keyserver $KEYSERVER --recv-keys 0x474E22316ABF4785A88C6E8EA2C794A986419D8A
|
||||
$GPG --verify llvm-$LLVM_VERSION.src.tar.xz.sig llvm-$LLVM_VERSION.src.tar.xz
|
||||
$GPG --verify clang-$LLVM_VERSION.src.tar.xz.sig clang-$LLVM_VERSION.src.tar.xz
|
||||
$GPG --verify lld-$LLVM_VERSION.src.tar.xz.sig lld-$LLVM_VERSION.src.tar.xz
|
||||
$GPG --verify clang-tools-extra-$LLVM_VERSION.src.tar.xz.sig clang-tools-extra-$LLVM_VERSION.src.tar.xz
|
||||
$GPG --verify compiler-rt-$LLVM_VERSION.src.tar.xz.sig compiler-rt-$LLVM_VERSION.src.tar.xz
|
||||
$GPG --verify libunwind-$LLVM_VERSION.src.tar.xz.sig libunwind-$LLVM_VERSION.src.tar.xz
|
||||
popd
|
||||
|
||||
# create build directory
|
||||
mkdir -p build
|
||||
pushd build
|
||||
|
||||
# compile gcc
|
||||
if [ ! -f $PREFIX/bin/gcc ]; then
|
||||
if [ -d gcc-$GCC_VERSION ]; then
|
||||
rm -rf gcc-$GCC_VERSION
|
||||
fi
|
||||
tar -xvf ../archives/gcc-$GCC_VERSION.tar.gz
|
||||
pushd gcc-$GCC_VERSION
|
||||
./contrib/download_prerequisites
|
||||
mkdir build && pushd build
|
||||
# influenced by: https://buildd.debian.org/status/fetch.php?pkg=gcc-8&arch=amd64&ver=8.3.0-6&stamp=1554588545
|
||||
../configure -v \
|
||||
--build=x86_64-linux-gnu \
|
||||
--host=x86_64-linux-gnu \
|
||||
--target=x86_64-linux-gnu \
|
||||
--prefix=$PREFIX \
|
||||
--disable-multilib \
|
||||
--with-system-zlib \
|
||||
--enable-checking=release \
|
||||
--enable-languages=c,c++,fortran \
|
||||
--enable-gold=yes \
|
||||
--enable-ld=yes \
|
||||
--enable-lto \
|
||||
--enable-bootstrap \
|
||||
--disable-vtable-verify \
|
||||
--disable-werror \
|
||||
--without-included-gettext \
|
||||
--enable-threads=posix \
|
||||
--enable-nls \
|
||||
--enable-clocale=gnu \
|
||||
--enable-libstdcxx-debug \
|
||||
--enable-libstdcxx-time=yes \
|
||||
--enable-gnu-unique-object \
|
||||
--enable-libmpx \
|
||||
--enable-plugin \
|
||||
--enable-default-pie \
|
||||
--with-target-system-zlib \
|
||||
--with-tune=generic \
|
||||
--without-cuda-driver
|
||||
#--program-suffix=$( printf "$GCC_VERSION" | cut -d '.' -f 1,2 ) \
|
||||
make -j$CPUS
|
||||
# make -k check # run test suite
|
||||
make install
|
||||
popd && popd
|
||||
fi
|
||||
|
||||
# activate toolchain
|
||||
export PATH=$PREFIX/bin:$PATH
|
||||
export LD_LIBRARY_PATH=$PREFIX/lib64
|
||||
|
||||
# compile binutils
|
||||
if [ ! -f $PREFIX/bin/ld.gold ]; then
|
||||
if [ -d binutils-$BINUTILS_VERSION ]; then
|
||||
rm -rf binutils-$BINUTILS_VERSION
|
||||
fi
|
||||
tar -xvf ../archives/binutils-$BINUTILS_VERSION.tar.gz
|
||||
pushd binutils-$BINUTILS_VERSION
|
||||
mkdir build && pushd build
|
||||
# influenced by: https://buildd.debian.org/status/fetch.php?pkg=binutils&arch=amd64&ver=2.32-7&stamp=1553247092
|
||||
env \
|
||||
CC=gcc \
|
||||
CXX=g++ \
|
||||
CFLAGS="-g -O2" \
|
||||
CXXFLAGS="-g -O2" \
|
||||
LDFLAGS="" \
|
||||
../configure \
|
||||
--build=x86_64-linux-gnu \
|
||||
--host=x86_64-linux-gnu \
|
||||
--prefix=$PREFIX \
|
||||
--enable-ld=default \
|
||||
--enable-gold \
|
||||
--enable-lto \
|
||||
--enable-plugins \
|
||||
--enable-shared \
|
||||
--enable-threads \
|
||||
--with-system-zlib \
|
||||
--enable-deterministic-archives \
|
||||
--disable-compressed-debug-sections \
|
||||
--enable-new-dtags \
|
||||
--disable-werror
|
||||
make -j$CPUS
|
||||
# make -k check # run test suite
|
||||
make install
|
||||
popd && popd
|
||||
fi
|
||||
|
||||
# compile gdb
|
||||
if [ ! -f $PREFIX/bin/gdb ]; then
|
||||
if [ -d gdb-$GDB_VERSION ]; then
|
||||
rm -rf gdb-$GDB_VERSION
|
||||
fi
|
||||
tar -xvf ../archives/gdb-$GDB_VERSION.tar.gz
|
||||
pushd gdb-$GDB_VERSION
|
||||
mkdir build && pushd build
|
||||
# https://buildd.debian.org/status/fetch.php?pkg=gdb&arch=amd64&ver=8.2.1-2&stamp=1550831554&raw=0
|
||||
env \
|
||||
CC=gcc \
|
||||
CXX=g++ \
|
||||
CFLAGS="-g -O2 -fstack-protector-strong -Wformat -Werror=format-security" \
|
||||
CXXFLAGS="-g -O2 -fstack-protector-strong -Wformat -Werror=format-security" \
|
||||
CPPFLAGS="-Wdate-time -D_FORTIFY_SOURCE=2 -fPIC" \
|
||||
LDFLAGS="-Wl,-z,relro" \
|
||||
PYTHON="" \
|
||||
../configure \
|
||||
--build=x86_64-linux-gnu \
|
||||
--host=x86_64-linux-gnu \
|
||||
--prefix=$PREFIX \
|
||||
--disable-maintainer-mode \
|
||||
--disable-dependency-tracking \
|
||||
--disable-silent-rules \
|
||||
--disable-gdbtk \
|
||||
--disable-shared \
|
||||
--without-guile \
|
||||
--with-system-gdbinit=$PREFIX/etc/gdb/gdbinit \
|
||||
--with-system-readline \
|
||||
--with-expat \
|
||||
--with-system-zlib \
|
||||
--with-lzma \
|
||||
--with-babeltrace \
|
||||
--with-intel-pt \
|
||||
--enable-tui \
|
||||
--with-python=python3
|
||||
make -j$CPUS
|
||||
make install
|
||||
popd && popd
|
||||
fi
|
||||
|
||||
# install pahole
|
||||
if [ ! -d $PREFIX/share/pahole-gdb ]; then
|
||||
unzip ../archives/pahole-gdb-master.zip
|
||||
mv pahole-gdb-master $PREFIX/share/pahole-gdb
|
||||
fi
|
||||
|
||||
# setup system gdbinit
|
||||
if [ ! -f $PREFIX/etc/gdb/gdbinit ]; then
|
||||
mkdir -p $PREFIX/etc/gdb
|
||||
cat >$PREFIX/etc/gdb/gdbinit <<EOF
|
||||
# improve formatting
|
||||
set print pretty on
|
||||
set print object on
|
||||
set print static-members on
|
||||
set print vtbl on
|
||||
set print demangle on
|
||||
set demangle-style gnu-v3
|
||||
set print sevenbit-strings off
|
||||
|
||||
# load libstdc++ pretty printers
|
||||
add-auto-load-scripts-directory $PREFIX/lib64
|
||||
add-auto-load-safe-path $PREFIX
|
||||
|
||||
# load pahole
|
||||
python
|
||||
sys.path.insert(0, "$PREFIX/share/pahole-gdb")
|
||||
import offsets
|
||||
import pahole
|
||||
end
|
||||
EOF
|
||||
fi
|
||||
|
||||
# compile cmake
|
||||
if [ ! -f $PREFIX/bin/cmake ]; then
|
||||
if [ -d cmake-$CMAKE_VERSION ]; then
|
||||
rm -rf cmake-$CMAKE_VERSION
|
||||
fi
|
||||
tar -xvf ../archives/cmake-$CMAKE_VERSION.tar.gz
|
||||
pushd cmake-$CMAKE_VERSION
|
||||
# influenced by: https://buildd.debian.org/status/fetch.php?pkg=cmake&arch=amd64&ver=3.13.4-1&stamp=1549799837
|
||||
echo 'set(CMAKE_SKIP_RPATH ON CACHE BOOL "Skip rpath" FORCE)' >> build-flags.cmake
|
||||
echo 'set(CMAKE_USE_RELATIVE_PATHS ON CACHE BOOL "Use relative paths" FORCE)' >> build-flags.cmake
|
||||
echo 'set(CMAKE_C_FLAGS "-g -O2 -fstack-protector-strong -Wformat -Werror=format-security -Wdate-time -D_FORTIFY_SOURCE=2" CACHE STRING "C flags" FORCE)' >> build-flags.cmake
|
||||
echo 'set(CMAKE_CXX_FLAGS "-g -O2 -fstack-protector-strong -Wformat -Werror=format-security -Wdate-time -D_FORTIFY_SOURCE=2" CACHE STRING "C++ flags" FORCE)' >> build-flags.cmake
|
||||
echo 'set(CMAKE_SKIP_BOOTSTRAP_TEST ON CACHE BOOL "Skip BootstrapTest" FORCE)' >> build-flags.cmake
|
||||
echo 'set(BUILD_CursesDialog ON CACHE BOOL "Build curses GUI" FORCE)' >> build-flags.cmake
|
||||
mkdir build && pushd build
|
||||
../bootstrap \
|
||||
--prefix=$PREFIX \
|
||||
--init=../build-flags.cmake \
|
||||
--parallel=$CPUS \
|
||||
--system-curl
|
||||
make -j$CPUS
|
||||
# make test # run test suite
|
||||
make install
|
||||
popd && popd
|
||||
fi
|
||||
|
||||
# compile cppcheck
|
||||
if [ ! -f $PREFIX/bin/cppcheck ]; then
|
||||
if [ -d cppcheck-$CPPCHECK_VERSION ]; then
|
||||
rm -rf cppcheck-$CPPCHECK_VERSION
|
||||
fi
|
||||
tar -xvf ../archives/cppcheck-$CPPCHECK_VERSION.tar.gz
|
||||
pushd cppcheck-$CPPCHECK_VERSION
|
||||
# this was fixed in cppcheck 2.5, remove this in toolchain-v4 after the lib is updated
|
||||
# to 2.5+ version.
|
||||
sed -i '/#include <iostream>/ a #include <limits>' lib/symboldatabase.cpp
|
||||
env \
|
||||
CC=gcc \
|
||||
CXX=g++ \
|
||||
PREFIX=$PREFIX \
|
||||
FILESDIR=$PREFIX/share/cppcheck \
|
||||
CFGDIR=$PREFIX/share/cppcheck/cfg \
|
||||
make -j$CPUS
|
||||
env \
|
||||
CC=gcc \
|
||||
CXX=g++ \
|
||||
PREFIX=$PREFIX \
|
||||
FILESDIR=$PREFIX/share/cppcheck \
|
||||
CFGDIR=$PREFIX/share/cppcheck/cfg \
|
||||
make install
|
||||
popd
|
||||
fi
|
||||
|
||||
# compile swig
|
||||
if [ ! -d swig-$SWIG_VERSION/install ]; then
|
||||
if [ -d swig-$SWIG_VERSION ]; then
|
||||
rm -rf swig-$SWIG_VERSION
|
||||
fi
|
||||
tar -xvf ../archives/swig-$SWIG_VERSION.tar.gz
|
||||
mv swig-rel-$SWIG_VERSION swig-$SWIG_VERSION
|
||||
pushd swig-$SWIG_VERSION
|
||||
./autogen.sh
|
||||
mkdir build && pushd build
|
||||
../configure --prefix=$DIR/build/swig-$SWIG_VERSION/install
|
||||
make -j$CPUS
|
||||
make install
|
||||
popd && popd
|
||||
fi
|
||||
|
||||
# compile llvm
|
||||
if [ ! -f $PREFIX/bin/clang ]; then
|
||||
if [ -d llvm-$LLVM_VERSION ]; then
|
||||
rm -rf llvm-$LLVM_VERSION
|
||||
fi
|
||||
tar -xvf ../archives/llvm-$LLVM_VERSION.src.tar.xz
|
||||
mv llvm-$LLVM_VERSION.src llvm-$LLVM_VERSION
|
||||
tar -xvf ../archives/clang-$LLVM_VERSION.src.tar.xz
|
||||
mv clang-$LLVM_VERSION.src llvm-$LLVM_VERSION/tools/clang
|
||||
tar -xvf ../archives/lld-$LLVM_VERSION.src.tar.xz
|
||||
mv lld-$LLVM_VERSION.src/ llvm-$LLVM_VERSION/tools/lld
|
||||
tar -xvf ../archives/clang-tools-extra-$LLVM_VERSION.src.tar.xz
|
||||
mv clang-tools-extra-$LLVM_VERSION.src/ llvm-$LLVM_VERSION/tools/clang/tools/extra
|
||||
tar -xvf ../archives/compiler-rt-$LLVM_VERSION.src.tar.xz
|
||||
mv compiler-rt-$LLVM_VERSION.src/ llvm-$LLVM_VERSION/projects/compiler-rt
|
||||
tar -xvf ../archives/libunwind-$LLVM_VERSION.src.tar.xz
|
||||
mv libunwind-$LLVM_VERSION.src/include/mach-o llvm-$LLVM_VERSION/tools/lld/include
|
||||
pushd llvm-$LLVM_VERSION
|
||||
mkdir build && pushd build
|
||||
# activate swig
|
||||
export PATH=$DIR/build/swig-$SWIG_VERSION/install/bin:$PATH
|
||||
# influenced by: https://buildd.debian.org/status/fetch.php?pkg=llvm-toolchain-7&arch=amd64&ver=1%3A7.0.1%7E%2Brc2-1%7Eexp1&stamp=1541506173&raw=0
|
||||
cmake .. \
|
||||
-DCMAKE_C_COMPILER=$PREFIX/bin/gcc \
|
||||
-DCMAKE_CXX_COMPILER=$PREFIX/bin/g++ \
|
||||
-DCMAKE_CXX_LINK_FLAGS="-L$PREFIX/lib64 -Wl,-rpath,$PREFIX/lib64" \
|
||||
-DCMAKE_INSTALL_PREFIX=$PREFIX \
|
||||
-DCMAKE_BUILD_TYPE=RelWithDebInfo \
|
||||
-DCMAKE_CXX_FLAGS_RELWITHDEBINFO="-O2 -DNDEBUG" \
|
||||
-DCMAKE_CXX_FLAGS=' -fuse-ld=gold -fPIC -Wno-unused-command-line-argument -Wno-unknown-warning-option' \
|
||||
-DCMAKE_C_FLAGS=' -fuse-ld=gold -fPIC -Wno-unused-command-line-argument -Wno-unknown-warning-option' \
|
||||
-DLLVM_LINK_LLVM_DYLIB=ON \
|
||||
-DLLVM_INSTALL_UTILS=ON \
|
||||
-DLLVM_VERSION_SUFFIX= \
|
||||
-DLLVM_BUILD_LLVM_DYLIB=ON \
|
||||
-DLLVM_ENABLE_RTTI=ON \
|
||||
-DLLVM_ENABLE_FFI=ON \
|
||||
-DLLVM_BINUTILS_INCDIR=$PREFIX/include/ \
|
||||
-DLLVM_USE_PERF=yes
|
||||
make -j$CPUS
|
||||
make -j$CPUS check-clang # run clang test suite
|
||||
make -j$CPUS check-lld # run lld test suite
|
||||
make install
|
||||
popd && popd
|
||||
fi
|
||||
|
||||
# create README
|
||||
if [ ! -f $PREFIX/README.md ]; then
|
||||
cat >$PREFIX/README.md <<EOF
|
||||
# Memgraph Toolchain v$TOOLCHAIN_VERSION
|
||||
|
||||
## Included tools
|
||||
|
||||
- GCC $GCC_VERSION
|
||||
- Binutils $BINUTILS_VERSION
|
||||
- GDB $GDB_VERSION
|
||||
- CMake $CMAKE_VERSION
|
||||
- Cppcheck $CPPCHECK_VERSION
|
||||
- LLVM (Clang, LLD, compiler-rt, Clang tools extra) $LLVM_VERSION
|
||||
|
||||
## Required libraries
|
||||
|
||||
In order to be able to run all of these tools you should install the following
|
||||
packages:
|
||||
|
||||
\`\`\`
|
||||
$($DIR/../os/$DISTRO.sh list TOOLCHAIN_RUN_DEPS)
|
||||
\`\`\`
|
||||
|
||||
## Usage
|
||||
|
||||
In order to use the toolchain you just have to source the activation script:
|
||||
|
||||
\`\`\`
|
||||
source $PREFIX/activate
|
||||
\`\`\`
|
||||
EOF
|
||||
fi
|
||||
|
||||
# create activation script
|
||||
if [ ! -f $PREFIX/activate ]; then
|
||||
cat >$PREFIX/activate <<EOF
|
||||
# This file must be used with "source $PREFIX/activate" *from bash*
|
||||
# You can't run it directly!
|
||||
|
||||
env_error="You already have an active virtual environment!"
|
||||
|
||||
# zsh does not recognize the option -t of the command type
|
||||
# therefore we use the alternative whence -w
|
||||
if [[ "\$ZSH_NAME" == "zsh" ]]; then
|
||||
# check for active virtual environments
|
||||
if [ "\$( whence -w deactivate )" != "deactivate: none" ]; then
|
||||
echo \$env_error
|
||||
return 0;
|
||||
fi
|
||||
# any other shell
|
||||
else
|
||||
# check for active virtual environments
|
||||
if [ "\$( type -t deactivate )" != "" ]; then
|
||||
echo \$env_error
|
||||
return 0
|
||||
fi
|
||||
fi
|
||||
|
||||
# check that we aren't root
|
||||
if [[ "\$USER" == "root" ]]; then
|
||||
echo "You shouldn't use the toolchain as root!"
|
||||
return 0
|
||||
fi
|
||||
|
||||
# save original environment
|
||||
export ORIG_PATH=\$PATH
|
||||
export ORIG_PS1=\$PS1
|
||||
export ORIG_LD_LIBRARY_PATH=\$LD_LIBRARY_PATH
|
||||
|
||||
# activate new environment
|
||||
export PATH=$PREFIX/bin:\$PATH
|
||||
export PS1="($NAME) \$PS1"
|
||||
export LD_LIBRARY_PATH=$PREFIX/lib:$PREFIX/lib64
|
||||
|
||||
# disable root
|
||||
function su () {
|
||||
echo "You don't want to use root functions while using the toolchain!"
|
||||
return 1
|
||||
}
|
||||
function sudo () {
|
||||
echo "You don't want to use root functions while using the toolchain!"
|
||||
return 1
|
||||
}
|
||||
|
||||
# create deactivation function
|
||||
function deactivate() {
|
||||
export PATH=\$ORIG_PATH
|
||||
export PS1=\$ORIG_PS1
|
||||
export LD_LIBRARY_PATH=\$ORIG_LD_LIBRARY_PATH
|
||||
unset ORIG_PATH ORIG_PS1 ORIG_LD_LIBRARY_PATH
|
||||
unset -f su sudo deactivate
|
||||
}
|
||||
EOF
|
||||
fi
|
||||
|
||||
# create toolchain archive
|
||||
if [ ! -f $NAME-binaries-$DISTRO.tar.gz ]; then
|
||||
tar --owner=root --group=root -cpvzf $NAME-binaries-$DISTRO.tar.gz -C /opt $NAME
|
||||
fi
|
||||
|
||||
# output final instructions
|
||||
echo -e "\n\n"
|
||||
echo "All tools have been built. They are installed in '$PREFIX'."
|
||||
echo "In order to distribute the tools to someone else, an archive with the toolchain was created in the 'build' directory."
|
||||
echo "If you want to install the packed tools you should execute the following command:"
|
||||
echo
|
||||
echo " tar -xvzf build/$NAME-binaries.tar.gz -C /opt"
|
||||
echo
|
||||
echo "Because the tools were built on this machine, you should probably change the permissions of the installation directory using:"
|
||||
echo
|
||||
echo " OPTIONAL: chown -R root:root $PREFIX"
|
||||
echo
|
||||
echo "In order to use all of the newly compiled tools you should use the prepared activation script:"
|
||||
echo
|
||||
echo " source $PREFIX/activate"
|
||||
echo
|
||||
echo "Or, for more advanced uses, you can add the following lines to your script:"
|
||||
echo
|
||||
echo " export PATH=$PREFIX/bin:\$PATH"
|
||||
echo " export LD_LIBRARY_PATH=$PREFIX/lib:$PREFIX/lib64"
|
||||
echo
|
||||
echo "Enjoy!"
|
||||
@@ -1,50 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
operating_system() {
|
||||
grep -E '^(VERSION_)?ID=' /etc/os-release | \
|
||||
sort | cut -d '=' -f 2- | sed 's/"//g' | paste -s -d '-'
|
||||
}
|
||||
|
||||
check_all_yum() {
|
||||
local missing=""
|
||||
for pkg in $1; do
|
||||
if ! yum list installed "$pkg" >/dev/null 2>/dev/null; then
|
||||
missing="$pkg $missing"
|
||||
fi
|
||||
done
|
||||
if [ "$missing" != "" ]; then
|
||||
echo "MISSING PACKAGES: $missing"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
check_all_dpkg() {
|
||||
local missing=""
|
||||
for pkg in $1; do
|
||||
if ! dpkg -s "$pkg" >/dev/null 2>/dev/null; then
|
||||
missing="$pkg $missing"
|
||||
fi
|
||||
done
|
||||
if [ "$missing" != "" ]; then
|
||||
echo "MISSING PACKAGES: $missing"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
check_all_dnf() {
|
||||
local missing=""
|
||||
for pkg in $1; do
|
||||
if ! dnf list installed "$pkg" >/dev/null 2>/dev/null; then
|
||||
missing="$pkg $missing"
|
||||
fi
|
||||
done
|
||||
if [ "$missing" != "" ]; then
|
||||
echo "MISSING PACKAGES: $missing"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
install_all_apt() {
|
||||
for pkg in $1; do
|
||||
apt install -y "$pkg"
|
||||
done
|
||||
}
|
||||
@@ -1,944 +0,0 @@
|
||||
/// @file
|
||||
/// Provides API for usage in custom openCypher procedures
|
||||
#ifndef MG_PROCEDURE_H
|
||||
#define MG_PROCEDURE_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if __cplusplus >= 201703L
|
||||
#define MGP_NODISCARD [[nodiscard]]
|
||||
#else
|
||||
#define MGP_NODISCARD
|
||||
#endif
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
/// @name Error Codes
|
||||
///
|
||||
///@{
|
||||
|
||||
/// All functions return an error code that can be used to figure out whether the API call was successful or not. In
|
||||
/// case of failure, the specific error code can be used to identify the reason of the failure.
|
||||
enum MGP_NODISCARD mgp_error {
|
||||
MGP_ERROR_NO_ERROR = 0,
|
||||
MGP_ERROR_UNKNOWN_ERROR,
|
||||
MGP_ERROR_UNABLE_TO_ALLOCATE,
|
||||
MGP_ERROR_INSUFFICIENT_BUFFER,
|
||||
MGP_ERROR_OUT_OF_RANGE,
|
||||
MGP_ERROR_LOGIC_ERROR,
|
||||
MGP_ERROR_NON_EXISTENT_OBJECT,
|
||||
MGP_ERROR_INVALID_ARGUMENT,
|
||||
MGP_ERROR_KEY_ALREADY_EXISTS,
|
||||
};
|
||||
///@}
|
||||
|
||||
/// @name Memory Allocation
|
||||
///
|
||||
/// These should be preferred compared to plain malloc calls as Memgraph's
|
||||
/// execution will handle allocation and deallocation more efficiently. In
|
||||
/// addition to efficiency, Memgraph can set the limit on allowed allocations
|
||||
/// thus providing some safety with regards to memory usage. The allocated
|
||||
/// memory is only valid during the execution of mgp_main. You must not allocate
|
||||
/// global resources with these functions and none of the functions are
|
||||
/// thread-safe, because we provide a single thread of execution when invoking a
|
||||
/// custom procedure. For allocating global resources, you can use the _global
|
||||
/// variations of the aforementioned allocators. This allows Memgraph to be
|
||||
/// more efficient as explained before.
|
||||
///@{
|
||||
|
||||
/// Provides memory managament access and state.
|
||||
struct mgp_memory;
|
||||
|
||||
/// Allocate a block of memory with given size in bytes.
|
||||
/// Unlike malloc, this function is not thread-safe.
|
||||
/// `size_in_bytes` must be greater than 0.
|
||||
/// The resulting pointer must be freed with mgp_free.
|
||||
/// MGP_ERROR_UNABLE_TO_ALLOCATE is returned if unable to serve the requested allocation.
|
||||
enum mgp_error mgp_alloc(struct mgp_memory *memory, size_t size_in_bytes, void **result);
|
||||
|
||||
/// Allocate an aligned block of memory with given size in bytes.
|
||||
/// Unlike malloc and aligned_alloc, this function is not thread-safe.
|
||||
/// `size_in_bytes` must be greater than 0.
|
||||
/// `alignment` must be a power of 2 value.
|
||||
/// The resulting pointer must be freed with mgp_free.
|
||||
/// MGP_ERROR_UNABLE_TO_ALLOCATE is returned if unable to serve the requested allocation.
|
||||
enum mgp_error mgp_aligned_alloc(struct mgp_memory *memory, size_t size_in_bytes, size_t alignment, void **result);
|
||||
|
||||
/// Deallocate an allocation from mgp_alloc or mgp_aligned_alloc.
|
||||
/// Unlike free, this function is not thread-safe.
|
||||
/// If `ptr` is NULL, this function does nothing.
|
||||
/// The behavior is undefined if `ptr` is not a value returned from a prior
|
||||
/// mgp_alloc or mgp_aligned_alloc call with the corresponding `memory`.
|
||||
void mgp_free(struct mgp_memory *memory, void *ptr);
|
||||
|
||||
/// Allocate a global block of memory with given size in bytes.
|
||||
/// This function can be used to allocate global memory that persists
|
||||
/// beyond a single invocation of mgp_main.
|
||||
/// The resulting pointer must be freed with mgp_global_free.
|
||||
/// MGP_ERROR_UNABLE_TO_ALLOCATE is returned if unable to serve the requested allocation.
|
||||
enum mgp_error mgp_global_alloc(size_t size_in_bytes, void **result);
|
||||
|
||||
/// Allocate an aligned global block of memory with given size in bytes.
|
||||
/// This function can be used to allocate global memory that persists
|
||||
/// beyond a single invocation of mgp_main.
|
||||
/// The resulting pointer must be freed with mgp_global_free.
|
||||
/// MGP_ERROR_UNABLE_TO_ALLOCATE is returned if unable to serve the requested allocation.
|
||||
enum mgp_error mgp_global_aligned_alloc(size_t size_in_bytes, size_t alignment, void **result);
|
||||
|
||||
/// Deallocate an allocation from mgp_global_alloc or mgp_global_aligned_alloc.
|
||||
/// If `ptr` is NULL, this function does nothing.
|
||||
/// The behavior is undefined if `ptr` is not a value returned from a prior
|
||||
/// mgp_global_alloc() or mgp_global_aligned_alloc().
|
||||
void mgp_global_free(void *p);
|
||||
///@}
|
||||
|
||||
/// @name Operations on mgp_value
|
||||
///
|
||||
/// struct mgp_value is an immutable container of various values that may appear
|
||||
/// as arguments and results of a custom procedure. The following functions and
|
||||
/// types are used to work with mgp_value. Each function returning a non-const
|
||||
/// mgp_value has allocated a new instance of the result, therefore such
|
||||
/// mgp_value instances need to be deallocated using mgp_value_destroy.
|
||||
///@{
|
||||
|
||||
/// Immutable container of various values that appear in the query language.
|
||||
struct mgp_value;
|
||||
|
||||
/// List of mgp_value instances
|
||||
struct mgp_list;
|
||||
|
||||
/// Map of character strings to mgp_value instances.
|
||||
struct mgp_map;
|
||||
|
||||
/// Vertex in the graph database.
|
||||
struct mgp_vertex;
|
||||
|
||||
/// Edge in the graph database.
|
||||
struct mgp_edge;
|
||||
|
||||
/// Path containing mgp_vertex and mgp_edge instances.
|
||||
struct mgp_path;
|
||||
|
||||
/// All available types that can be stored in a mgp_value
|
||||
enum mgp_value_type {
|
||||
// NOTE: New types need to be appended, so as not to break ABI.
|
||||
MGP_VALUE_TYPE_NULL,
|
||||
MGP_VALUE_TYPE_BOOL,
|
||||
MGP_VALUE_TYPE_INT,
|
||||
MGP_VALUE_TYPE_DOUBLE,
|
||||
MGP_VALUE_TYPE_STRING,
|
||||
MGP_VALUE_TYPE_LIST,
|
||||
MGP_VALUE_TYPE_MAP,
|
||||
MGP_VALUE_TYPE_VERTEX,
|
||||
MGP_VALUE_TYPE_EDGE,
|
||||
MGP_VALUE_TYPE_PATH,
|
||||
};
|
||||
|
||||
/// Free the memory used by the given mgp_value instance.
|
||||
void mgp_value_destroy(struct mgp_value *val);
|
||||
|
||||
/// Construct a value representing `null` in openCypher.
|
||||
/// You need to free the instance through mgp_value_destroy.
|
||||
/// MGP_ERROR_UNABLE_TO_ALLOCATE is returned if unable to allocate a mgp_value.
|
||||
enum mgp_error mgp_value_make_null(struct mgp_memory *memory, struct mgp_value **result);
|
||||
|
||||
/// Construct a boolean value.
|
||||
/// Non-zero values represent `true`, while zero represents `false`.
|
||||
/// You need to free the instance through mgp_value_destroy.
|
||||
/// MGP_ERROR_UNABLE_TO_ALLOCATE is returned if unable to allocate a mgp_value.
|
||||
enum mgp_error mgp_value_make_bool(int val, struct mgp_memory *memory, struct mgp_value **result);
|
||||
|
||||
/// Construct an integer value.
|
||||
/// You need to free the instance through mgp_value_destroy.
|
||||
/// MGP_ERROR_UNABLE_TO_ALLOCATE is returned if unable to allocate a mgp_value.
|
||||
enum mgp_error mgp_value_make_int(int64_t val, struct mgp_memory *memory, struct mgp_value **result);
|
||||
|
||||
/// Construct a double floating point value.
|
||||
/// You need to free the instance through mgp_value_destroy.
|
||||
/// MGP_ERROR_UNABLE_TO_ALLOCATE is returned if unable to allocate a mgp_value.
|
||||
enum mgp_error mgp_value_make_double(double val, struct mgp_memory *memory, struct mgp_value **result);
|
||||
|
||||
/// Construct a character string value from a NULL terminated string.
|
||||
/// You need to free the instance through mgp_value_destroy.
|
||||
/// MGP_ERROR_UNABLE_TO_ALLOCATE is returned if unable to allocate a mgp_value.
|
||||
enum mgp_error mgp_value_make_string(const char *val, struct mgp_memory *memory, struct mgp_value **result);
|
||||
|
||||
/// Create a mgp_value storing a mgp_list.
|
||||
/// You need to free the instance through mgp_value_destroy. The ownership of
|
||||
/// the list is given to the created mgp_value and destroying the mgp_value will
|
||||
/// destroy the mgp_list. Therefore, if a mgp_value is successfully created
|
||||
/// you must not call mgp_list_destroy on the given list.
|
||||
/// MGP_ERROR_UNABLE_TO_ALLOCATE is returned if unable to allocate a mgp_value.
|
||||
enum mgp_error mgp_value_make_list(struct mgp_list *val, struct mgp_value **result);
|
||||
|
||||
/// Create a mgp_value storing a mgp_map.
|
||||
/// You need to free the instance through mgp_value_destroy. The ownership of
|
||||
/// the map is given to the created mgp_value and destroying the mgp_value will
|
||||
/// destroy the mgp_map. Therefore, if a mgp_value is successfully created
|
||||
/// you must not call mgp_map_destroy on the given map.
|
||||
/// MGP_ERROR_UNABLE_TO_ALLOCATE is returned if unable to allocate a mgp_value.
|
||||
enum mgp_error mgp_value_make_map(struct mgp_map *val, struct mgp_value **result);
|
||||
|
||||
/// Create a mgp_value storing a mgp_vertex.
|
||||
/// You need to free the instance through mgp_value_destroy. The ownership of
|
||||
/// the vertex is given to the created mgp_value and destroying the mgp_value
|
||||
/// will destroy the mgp_vertex. Therefore, if a mgp_value is successfully
|
||||
/// created you must not call mgp_vertex_destroy on the given vertex.
|
||||
/// MGP_ERROR_UNABLE_TO_ALLOCATE is returned if unable to allocate a mgp_value.
|
||||
enum mgp_error mgp_value_make_vertex(struct mgp_vertex *val, struct mgp_value **result);
|
||||
|
||||
/// Create a mgp_value storing a mgp_edge.
|
||||
/// You need to free the instance through mgp_value_destroy. The ownership of
|
||||
/// the edge is given to the created mgp_value and destroying the mgp_value will
|
||||
/// destroy the mgp_edge. Therefore, if a mgp_value is successfully created you
|
||||
/// must not call mgp_edge_destroy on the given edge.
|
||||
/// MGP_ERROR_UNABLE_TO_ALLOCATE is returned if unable to allocate a mgp_value.
|
||||
enum mgp_error mgp_value_make_edge(struct mgp_edge *val, struct mgp_value **result);
|
||||
|
||||
/// Create a mgp_value storing a mgp_path.
|
||||
/// You need to free the instance through mgp_value_destroy. The ownership of
|
||||
/// the path is given to the created mgp_value and destroying the mgp_value will
|
||||
/// destroy the mgp_path. Therefore, if a mgp_value is successfully created you
|
||||
/// must not call mgp_path_destroy on the given path.
|
||||
/// MGP_ERROR_UNABLE_TO_ALLOCATE is returned if unable to allocate a mgp_value.
|
||||
enum mgp_error mgp_value_make_path(struct mgp_path *val, struct mgp_value **result);
|
||||
|
||||
/// Get the type of the value contained in mgp_value.
|
||||
/// Current implementation always returns without errors.
|
||||
enum mgp_error mgp_value_get_type(const struct mgp_value *val, enum mgp_value_type *result);
|
||||
|
||||
/// Result is non-zero if the given mgp_value represents `null`.
|
||||
/// Current implementation always returns without errors.
|
||||
enum mgp_error mgp_value_is_null(const struct mgp_value *val, int *result);
|
||||
|
||||
/// Result is non-zero if the given mgp_value stores a boolean.
|
||||
/// Current implementation always returns without errors.
|
||||
enum mgp_error mgp_value_is_bool(const struct mgp_value *val, int *result);
|
||||
|
||||
/// Result is non-zero if the given mgp_value stores an integer.
|
||||
/// Current implementation always returns without errors.
|
||||
enum mgp_error mgp_value_is_int(const struct mgp_value *val, int *result);
|
||||
|
||||
/// Result is non-zero if the given mgp_value stores a double floating-point.
|
||||
/// Current implementation always returns without errors.
|
||||
enum mgp_error mgp_value_is_double(const struct mgp_value *val, int *result);
|
||||
|
||||
/// Result is non-zero if the given mgp_value stores a character string.
|
||||
/// Current implementation always returns without errors.
|
||||
enum mgp_error mgp_value_is_string(const struct mgp_value *val, int *result);
|
||||
|
||||
/// Result is non-zero if the given mgp_value stores a list of values.
|
||||
/// Current implementation always returns without errors.
|
||||
enum mgp_error mgp_value_is_list(const struct mgp_value *val, int *result);
|
||||
|
||||
/// Result is non-zero if the given mgp_value stores a map of values.
|
||||
/// Current implementation always returns without errors.
|
||||
enum mgp_error mgp_value_is_map(const struct mgp_value *val, int *result);
|
||||
|
||||
/// Result is non-zero if the given mgp_value stores a vertex.
|
||||
/// Current implementation always returns without errors.
|
||||
enum mgp_error mgp_value_is_vertex(const struct mgp_value *val, int *result);
|
||||
|
||||
/// Result is non-zero if the given mgp_value stores an edge.
|
||||
/// Current implementation always returns without errors.
|
||||
enum mgp_error mgp_value_is_edge(const struct mgp_value *val, int *result);
|
||||
|
||||
/// Result is non-zero if the given mgp_value stores a path.
|
||||
/// Current implementation always returns without errors.
|
||||
enum mgp_error mgp_value_is_path(const struct mgp_value *val, int *result);
|
||||
|
||||
/// Get the contained boolean value.
|
||||
/// Non-zero values represent `true`, while zero represents `false`.
|
||||
/// Result is undefined if mgp_value does not contain the expected type.
|
||||
/// Current implementation always returns without errors.
|
||||
enum mgp_error mgp_value_get_bool(const struct mgp_value *val, int *result);
|
||||
|
||||
/// Get the contained integer.
|
||||
/// Result is undefined if mgp_value does not contain the expected type.
|
||||
/// Current implementation always returns without errors.
|
||||
enum mgp_error mgp_value_get_int(const struct mgp_value *val, int64_t *result);
|
||||
|
||||
/// Get the contained double floating-point.
|
||||
/// Result is undefined if mgp_value does not contain the expected type.
|
||||
/// Current implementation always returns without errors.
|
||||
enum mgp_error mgp_value_get_double(const struct mgp_value *val, double *result);
|
||||
|
||||
/// Get the contained character string.
|
||||
/// Result is undefined if mgp_value does not contain the expected type.
|
||||
/// Current implementation always returns without errors.
|
||||
enum mgp_error mgp_value_get_string(const struct mgp_value *val, const char **result);
|
||||
|
||||
/// Get the contained list of values.
|
||||
/// Result is undefined if mgp_value does not contain the expected type.
|
||||
/// Current implementation always returns without errors.
|
||||
enum mgp_error mgp_value_get_list(const struct mgp_value *val, const struct mgp_list **result);
|
||||
|
||||
/// Return the contained map of values.
|
||||
/// Result is undefined if mgp_value does not contain the expected type.
|
||||
/// Current implementation always returns without errors.
|
||||
enum mgp_error mgp_value_get_map(const struct mgp_value *val, const struct mgp_map **result);
|
||||
|
||||
/// Get the contained vertex.
|
||||
/// Result is undefined if mgp_value does not contain the expected type.
|
||||
/// Current implementation always returns without errors.
|
||||
enum mgp_error mgp_value_get_vertex(const struct mgp_value *val, const struct mgp_vertex **result);
|
||||
|
||||
/// Get the contained edge.
|
||||
/// Result is undefined if mgp_value does not contain the expected type.
|
||||
/// Current implementation always returns without errors.
|
||||
enum mgp_error mgp_value_get_edge(const struct mgp_value *val, const struct mgp_edge **result);
|
||||
|
||||
/// Get the contained path.
|
||||
/// Result is undefined if mgp_value does not contain the expected type.
|
||||
/// Current implementation always returns without errors.
|
||||
enum mgp_error mgp_value_get_path(const struct mgp_value *val, const struct mgp_path **result);
|
||||
|
||||
/// Create an empty list with given capacity.
|
||||
/// You need to free the created instance with mgp_list_destroy.
|
||||
/// The created list will have allocated enough memory for `capacity` elements
|
||||
/// of mgp_value, but it will not contain any elements. Therefore,
|
||||
/// mgp_list_size will return 0.
|
||||
/// MGP_ERROR_UNABLE_TO_ALLOCATE is returned if unable to allocate a mgp_list.
|
||||
enum mgp_error mgp_list_make_empty(size_t capacity, struct mgp_memory *memory, struct mgp_list **result);
|
||||
|
||||
/// Free the memory used by the given mgp_list and contained elements.
|
||||
void mgp_list_destroy(struct mgp_list *list);
|
||||
|
||||
/// Append a copy of mgp_value to mgp_list if capacity allows.
|
||||
/// The list copies the given value and therefore does not take ownership of the
|
||||
/// original value. You still need to call mgp_value_destroy to free the
|
||||
/// original value.
|
||||
/// Return MGP_ERROR_INSUFFICIENT_BUFFER if there's no capacity.
|
||||
/// Return MGP_ERROR_UNABLE_TO_ALLOCATE if unable to allocate a mgp_value.
|
||||
enum mgp_error mgp_list_append(struct mgp_list *list, const struct mgp_value *val);
|
||||
|
||||
/// Append a copy of mgp_value to mgp_list increasing capacity if needed.
|
||||
/// The list copies the given value and therefore does not take ownership of the
|
||||
/// original value. You still need to call mgp_value_destroy to free the
|
||||
/// original value.
|
||||
/// In case of a capacity change, the previously contained elements will move in
|
||||
/// memory and any references to them will be invalid.
|
||||
/// Return MGP_ERROR_INSUFFICIENT_BUFFER if there's no capacity.
|
||||
/// Return MGP_ERROR_UNABLE_TO_ALLOCATE if unable to allocate a mgp_value.
|
||||
enum mgp_error mgp_list_append_extend(struct mgp_list *list, const struct mgp_value *val);
|
||||
|
||||
/// Get the number of elements stored in mgp_list.
|
||||
/// Current implementation always returns without errors.
|
||||
enum mgp_error mgp_list_size(const struct mgp_list *list, size_t *result);
|
||||
|
||||
/// Get the total number of elements for which there's already allocated
|
||||
/// memory in mgp_list.
|
||||
/// Current implementation always returns without errors.
|
||||
enum mgp_error mgp_list_capacity(const struct mgp_list *list, size_t *result);
|
||||
|
||||
/// Get the element in mgp_list at given position.
|
||||
/// MGP_ERROR_OUT_OF_RANGE is returned if the index is not within mgp_list_size.
|
||||
enum mgp_error mgp_list_at(const struct mgp_list *list, size_t index, const struct mgp_value **result);
|
||||
|
||||
/// Create an empty map of character strings to mgp_value instances.
|
||||
/// You need to free the created instance with mgp_map_destroy.
|
||||
/// MGP_ERROR_UNABLE_TO_ALLOCATE is returned if unable to allocate a mgp_map.
|
||||
enum mgp_error mgp_map_make_empty(struct mgp_memory *memory, struct mgp_map **result);
|
||||
|
||||
/// Free the memory used by the given mgp_map and contained items.
|
||||
void mgp_map_destroy(struct mgp_map *map);
|
||||
|
||||
/// Insert a new mapping from a NULL terminated character string to a value.
|
||||
/// If a mapping with the same key already exists, it is *not* replaced.
|
||||
/// In case of insertion, both the string and the value are copied into the map.
|
||||
/// Therefore, the map does not take ownership of the original key nor value, so
|
||||
/// you still need to free their memory explicitly.
|
||||
/// Return MGP_ERROR_UNABLE_TO_ALLOCATE is returned if unable to allocate for insertion.
|
||||
/// Return MGP_ERROR_KEY_ALREADY_EXISTS if a previous mapping already exists.
|
||||
enum mgp_error mgp_map_insert(struct mgp_map *map, const char *key, const struct mgp_value *value);
|
||||
|
||||
/// Get the number of items stored in mgp_map.
|
||||
/// Current implementation always returns without errors.
|
||||
enum mgp_error mgp_map_size(const struct mgp_map *map, size_t *result);
|
||||
|
||||
/// Get the mapped mgp_value to the given character string.
|
||||
/// Result is NULL if no mapping exists.
|
||||
enum mgp_error mgp_map_at(const struct mgp_map *map, const char *key, const struct mgp_value **result);
|
||||
|
||||
/// An item in the mgp_map.
|
||||
struct mgp_map_item;
|
||||
|
||||
/// Get the key of the mapped item.
|
||||
enum mgp_error mgp_map_item_key(const struct mgp_map_item *item, const char **result);
|
||||
|
||||
/// Get the value of the mapped item.
|
||||
enum mgp_error mgp_map_item_value(const struct mgp_map_item *item, const struct mgp_value **result);
|
||||
|
||||
/// An iterator over the items in mgp_map.
|
||||
struct mgp_map_items_iterator;
|
||||
|
||||
/// Start iterating over items contained in the given map.
|
||||
/// The resulting mgp_map_items_iterator needs to be deallocated with
|
||||
/// mgp_map_items_iterator_destroy.
|
||||
/// MGP_ERROR_UNABLE_TO_ALLOCATE is returned if unable to allocate a mgp_map_items_iterator.
|
||||
enum mgp_error mgp_map_iter_items(const struct mgp_map *map, struct mgp_memory *memory,
|
||||
struct mgp_map_items_iterator **result);
|
||||
|
||||
/// Deallocate memory used by mgp_map_items_iterator.
|
||||
void mgp_map_items_iterator_destroy(struct mgp_map_items_iterator *it);
|
||||
|
||||
/// Get the current item pointed to by the iterator.
|
||||
/// When the mgp_map_items_iterator_next is invoked, the returned pointer
|
||||
/// to mgp_map_item becomes invalid. On the other hand, pointers obtained
|
||||
/// with mgp_map_item_key and mgp_map_item_value remain valid
|
||||
/// throughout the lifetime of a map. Therefore, you can store the key as well
|
||||
/// as the value before, and use them after invoking
|
||||
/// mgp_map_items_iterator_next.
|
||||
/// Result is NULL if the end of the iteration has been reached.
|
||||
enum mgp_error mgp_map_items_iterator_get(const struct mgp_map_items_iterator *it, const struct mgp_map_item **result);
|
||||
|
||||
/// Advance the iterator to the next item stored in map and return it.
|
||||
/// The previous pointer obtained through mgp_map_items_iterator_get will
|
||||
/// be invalidated, but the pointers to key and value will remain valid.
|
||||
/// Result is NULL if the end of the iteration has been reached.
|
||||
enum mgp_error mgp_map_items_iterator_next(struct mgp_map_items_iterator *it, const struct mgp_map_item **result);
|
||||
|
||||
/// Create a path with the copy of the given starting vertex.
|
||||
/// You need to free the created instance with mgp_path_destroy.
|
||||
/// MGP_ERROR_UNABLE_TO_ALLOCATE is returned if unable to allocate a mgp_path.
|
||||
enum mgp_error mgp_path_make_with_start(const struct mgp_vertex *vertex, struct mgp_memory *memory,
|
||||
struct mgp_path **result);
|
||||
|
||||
/// Copy a mgp_path.
|
||||
/// Returned pointer must be freed with mgp_path_destroy.
|
||||
/// MGP_ERROR_UNABLE_TO_ALLOCATE is returned if unable to allocate a mgp_path.
|
||||
enum mgp_error mgp_path_copy(const struct mgp_path *path, struct mgp_memory *memory, struct mgp_path **result);
|
||||
|
||||
/// Free the memory used by the given mgp_path and contained vertices and edges.
|
||||
void mgp_path_destroy(struct mgp_path *path);
|
||||
|
||||
/// Append an edge continuing from the last vertex on the path.
|
||||
/// The edge is copied into the path. Therefore, the path does not take
|
||||
/// ownership of the original edge, so you still need to free the edge memory
|
||||
/// explicitly.
|
||||
/// The last vertex on the path will become the other endpoint of the given
|
||||
/// edge, as continued from the current last vertex.
|
||||
/// Return MGP_ERROR_LOGIC_ERROR if the current last vertex in the path is not part of the given edge.
|
||||
/// Return MGP_ERROR_UNABLE_TO_ALLOCATE if unable to allocate memory for path extension.
|
||||
enum mgp_error mgp_path_expand(struct mgp_path *path, const struct mgp_edge *edge);
|
||||
|
||||
/// Get the number of edges in a mgp_path.
|
||||
/// Current implementation always returns without errors.
|
||||
enum mgp_error mgp_path_size(const struct mgp_path *path, size_t *result);
|
||||
|
||||
/// Get the vertex from a path at given index.
|
||||
/// The valid index range is [0, mgp_path_size].
|
||||
/// MGP_ERROR_OUT_OF_RANGE is returned if index is out of range.
|
||||
enum mgp_error mgp_path_vertex_at(const struct mgp_path *path, size_t index, const struct mgp_vertex **result);
|
||||
|
||||
/// Get the edge from a path at given index.
|
||||
/// The valid index range is [0, mgp_path_size - 1].
|
||||
/// MGP_ERROR_OUT_OF_RANGE is returned if index is out of range.
|
||||
enum mgp_error mgp_path_edge_at(const struct mgp_path *path, size_t index, const struct mgp_edge **result);
|
||||
|
||||
/// Result is non-zero if given paths are equal, otherwise 0.
|
||||
enum mgp_error mgp_path_equal(const struct mgp_path *p1, const struct mgp_path *p2, int *result);
|
||||
|
||||
///@}
|
||||
|
||||
/// @name Procedure Result
|
||||
/// These functions and types are used to set the result of your custom
|
||||
/// procedure.
|
||||
///@{
|
||||
|
||||
/// Stores either an error result or a list of mgp_result_record instances.
|
||||
struct mgp_result;
|
||||
/// Represents a record of resulting field values.
|
||||
struct mgp_result_record;
|
||||
|
||||
/// Set the error as the result of the procedure.
|
||||
/// Return MGP_ERROR_UNABLE_TO_ALLOCATE ff there's no memory for copying the error message.
|
||||
enum mgp_error mgp_result_set_error_msg(struct mgp_result *res, const char *error_msg);
|
||||
|
||||
/// Create a new record for results.
|
||||
/// The previously obtained mgp_result_record pointer is no longer valid, and you must not use it.
|
||||
/// Return MGP_ERROR_UNABLE_TO_ALLOCATE if unable to allocate a mgp_result_record.
|
||||
enum mgp_error mgp_result_new_record(struct mgp_result *res, struct mgp_result_record **result);
|
||||
|
||||
/// Assign a value to a field in the given record.
|
||||
/// Return MGP_ERROR_UNABLE_TO_ALLOCATE if unable to allocate memory to copy the mgp_value to mgp_result_record.
|
||||
/// Return MGP_ERROR_OUT_OF_RANGE if there is no field named `field_name`.
|
||||
/// Return MGP_ERROR_LOGIC_ERROR `val` does not satisfy the type of the field name `field_name`.
|
||||
enum mgp_error mgp_result_record_insert(struct mgp_result_record *record, const char *field_name,
|
||||
const struct mgp_value *val);
|
||||
///@}
|
||||
|
||||
/// @name Graph Constructs
|
||||
///@{
|
||||
|
||||
/// Label of a vertex.
|
||||
struct mgp_label {
|
||||
/// Name of the label as a NULL terminated character string.
|
||||
const char *name;
|
||||
};
|
||||
|
||||
/// Type of an edge.
|
||||
struct mgp_edge_type {
|
||||
/// Name of the type as a NULL terminated character string.
|
||||
const char *name;
|
||||
};
|
||||
|
||||
/// Iterator over property values of a vertex or an edge.
|
||||
struct mgp_properties_iterator;
|
||||
|
||||
/// Free the memory used by a mgp_properties_iterator.
|
||||
void mgp_properties_iterator_destroy(struct mgp_properties_iterator *it);
|
||||
|
||||
/// Reference to a named property value.
|
||||
struct mgp_property {
|
||||
/// Name (key) of a property as a NULL terminated string.
|
||||
const char *name;
|
||||
/// Value of the referenced property.
|
||||
const struct mgp_value *value;
|
||||
};
|
||||
|
||||
/// Get the current property pointed to by the iterator.
|
||||
/// When the mgp_properties_iterator_next is invoked, the previous
|
||||
/// mgp_property is invalidated and its value must not be used.
|
||||
/// Result is NULL if the end of the iteration has been reached.
|
||||
enum mgp_error mgp_properties_iterator_get(const struct mgp_properties_iterator *it,
|
||||
const struct mgp_property **result);
|
||||
|
||||
/// Advance the iterator to the next property and return it.
|
||||
/// The previous mgp_property obtained through mgp_properties_iterator_get
|
||||
/// will be invalidated, and you must not use its value.
|
||||
/// Result is NULL if the end of the iteration has been reached.
|
||||
enum mgp_error mgp_properties_iterator_next(struct mgp_properties_iterator *it, const struct mgp_property **result);
|
||||
|
||||
/// Iterator over edges of a vertex.
|
||||
struct mgp_edges_iterator;
|
||||
|
||||
/// Free the memory used by a mgp_edges_iterator.
|
||||
void mgp_edges_iterator_destroy(struct mgp_edges_iterator *it);
|
||||
|
||||
/// ID of a vertex; valid during a single query execution.
|
||||
struct mgp_vertex_id {
|
||||
int64_t as_int;
|
||||
};
|
||||
|
||||
/// Get the ID of given vertex.
|
||||
/// The ID is only valid for a single query execution, you should never store it
|
||||
/// globally in a query module.
|
||||
enum mgp_error mgp_vertex_get_id(const struct mgp_vertex *v, struct mgp_vertex_id *result);
|
||||
|
||||
/// Copy a mgp_vertex.
|
||||
/// Resulting pointer must be freed with mgp_vertex_destroy.
|
||||
/// Return MGP_ERROR_UNABLE_TO_ALLOCATE if unable to allocate a mgp_vertex.
|
||||
enum mgp_error mgp_vertex_copy(const struct mgp_vertex *v, struct mgp_memory *memory, struct mgp_vertex **result);
|
||||
|
||||
/// Free the memory used by a mgp_vertex.
|
||||
void mgp_vertex_destroy(struct mgp_vertex *v);
|
||||
|
||||
/// Result is non-zero if given vertices are equal, otherwise 0.
|
||||
enum mgp_error mgp_vertex_equal(const struct mgp_vertex *v1, const struct mgp_vertex *v2, int *result);
|
||||
|
||||
/// Get the number of labels a given vertex has.
|
||||
enum mgp_error mgp_vertex_labels_count(const struct mgp_vertex *v, size_t *result);
|
||||
|
||||
/// Get mgp_label in mgp_vertex at given index.
|
||||
/// Return MGP_ERROR_OUT_OF_RANGE if the index is out of range.
|
||||
enum mgp_error mgp_vertex_label_at(const struct mgp_vertex *v, size_t index, struct mgp_label *result);
|
||||
|
||||
/// Result is non-zero if the given vertex has the given label.
|
||||
enum mgp_error mgp_vertex_has_label(const struct mgp_vertex *v, struct mgp_label label, int *result);
|
||||
|
||||
/// Result is non-zero if the given vertex has a label with given name.
|
||||
enum mgp_error mgp_vertex_has_label_named(const struct mgp_vertex *v, const char *label_name, int *result);
|
||||
|
||||
/// Get a copy of a vertex property mapped to a given name.
|
||||
/// Resulting value must be freed with mgp_value_destroy.
|
||||
/// Return MGP_ERROR_UNABLE_TO_ALLOCATE if unable to allocate a mgp_value.
|
||||
enum mgp_error mgp_vertex_get_property(const struct mgp_vertex *v, const char *property_name, struct mgp_memory *memory,
|
||||
struct mgp_value **result);
|
||||
|
||||
/// Start iterating over properties stored in the given vertex.
|
||||
/// The resulting mgp_properties_iterator needs to be deallocated with
|
||||
/// mgp_properties_iterator_destroy.
|
||||
/// Return MGP_ERROR_UNABLE_TO_ALLOCATE if unable to allocate a mgp_properties_iterator.
|
||||
enum mgp_error mgp_vertex_iter_properties(const struct mgp_vertex *v, struct mgp_memory *memory,
|
||||
struct mgp_properties_iterator **result);
|
||||
|
||||
/// Start iterating over inbound edges of the given vertex.
|
||||
/// The resulting mgp_edges_iterator needs to be deallocated with
|
||||
/// mgp_edges_iterator_destroy.
|
||||
/// Return MGP_ERROR_UNABLE_TO_ALLOCATE if unable to allocate a mgp_edges_iterator.
|
||||
enum mgp_error mgp_vertex_iter_in_edges(const struct mgp_vertex *v, struct mgp_memory *memory,
|
||||
struct mgp_edges_iterator **result);
|
||||
|
||||
/// Start iterating over outbound edges of the given vertex.
|
||||
/// The returned mgp_edges_iterator needs to be deallocated with
|
||||
/// mgp_edges_iterator_destroy.
|
||||
/// Return MGP_ERROR_UNABLE_TO_ALLOCATE if unable to allocate a mgp_edges_iterator.
|
||||
enum mgp_error mgp_vertex_iter_out_edges(const struct mgp_vertex *v, struct mgp_memory *memory,
|
||||
struct mgp_edges_iterator **result);
|
||||
|
||||
/// Get the current edge pointed to by the iterator.
|
||||
/// When the mgp_edges_iterator_next is invoked, the previous
|
||||
/// mgp_edge is invalidated and its value must not be used.
|
||||
/// Result is NULL if the end of the iteration has been reached.
|
||||
enum mgp_error mgp_edges_iterator_get(const struct mgp_edges_iterator *it, const struct mgp_edge **result);
|
||||
|
||||
/// Advance the iterator to the next edge and return it.
|
||||
/// The previous mgp_edge obtained through mgp_edges_iterator_get
|
||||
/// will be invalidated, and you must not use its value.
|
||||
/// Result is NULL if the end of the iteration has been reached.
|
||||
enum mgp_error mgp_edges_iterator_next(struct mgp_edges_iterator *it, const struct mgp_edge **result);
|
||||
|
||||
/// ID of an edge; valid during a single query execution.
|
||||
struct mgp_edge_id {
|
||||
int64_t as_int;
|
||||
};
|
||||
|
||||
/// Get the ID of given edge.
|
||||
/// The ID is only valid for a single query execution, you should never store it
|
||||
/// globally in a query module.
|
||||
enum mgp_error mgp_edge_get_id(const struct mgp_edge *e, struct mgp_edge_id *result);
|
||||
|
||||
/// Copy a mgp_edge.
|
||||
/// Resulting pointer must be freed with mgp_edge_destroy.
|
||||
/// Return MGP_ERROR_UNABLE_TO_ALLOCATE if unable to allocate a mgp_edge.
|
||||
enum mgp_error mgp_edge_copy(const struct mgp_edge *e, struct mgp_memory *memory, struct mgp_edge **result);
|
||||
|
||||
/// Free the memory used by a mgp_edge.
|
||||
void mgp_edge_destroy(struct mgp_edge *e);
|
||||
|
||||
/// Result is non-zero if given edges are equal, otherwise 0.
|
||||
enum mgp_error mgp_edge_equal(const struct mgp_edge *e1, const struct mgp_edge *e2, int *result);
|
||||
|
||||
/// Get the type of the given edge.
|
||||
enum mgp_error mgp_edge_get_type(const struct mgp_edge *e, struct mgp_edge_type *result);
|
||||
|
||||
/// Get the source vertex of the given edge.
|
||||
/// Current implementation always returns without errors.
|
||||
enum mgp_error mgp_edge_get_from(const struct mgp_edge *e, const struct mgp_vertex **result);
|
||||
|
||||
/// Get the destination vertex of the given edge.
|
||||
/// Current implementation always returns without errors.
|
||||
enum mgp_error mgp_edge_get_to(const struct mgp_edge *e, const struct mgp_vertex **result);
|
||||
|
||||
/// Get a copy of a edge property mapped to a given name.
|
||||
/// Resulting value must be freed with mgp_value_destroy.
|
||||
/// Return MGP_ERROR_UNABLE_TO_ALLOCATE if unable to allocate a mgp_value.
|
||||
enum mgp_error mgp_edge_get_property(const struct mgp_edge *e, const char *property_name, struct mgp_memory *memory,
|
||||
struct mgp_value **result);
|
||||
|
||||
/// Start iterating over properties stored in the given edge.
|
||||
/// Resulting mgp_properties_iterator needs to be deallocated with
|
||||
/// mgp_properties_iterator_destroy.
|
||||
/// Return MGP_ERROR_UNABLE_TO_ALLOCATE if unable to allocate a mgp_properties_iterator.
|
||||
enum mgp_error mgp_edge_iter_properties(const struct mgp_edge *e, struct mgp_memory *memory,
|
||||
struct mgp_properties_iterator **result);
|
||||
|
||||
/// State of the graph database.
|
||||
struct mgp_graph;
|
||||
|
||||
/// Return the vertex corresponding to given ID.
|
||||
/// Resulting vertex must be freed using mgp_vertex_destroy.
|
||||
/// Return MGP_ERROR_UNABLE_TO_ALLOCATE if unable to allocate the vertex or if ID is not valid.
|
||||
enum mgp_error mgp_graph_get_vertex_by_id(const struct mgp_graph *g, struct mgp_vertex_id id, struct mgp_memory *memory,
|
||||
struct mgp_vertex **result);
|
||||
|
||||
/// Iterator over vertices.
|
||||
struct mgp_vertices_iterator;
|
||||
|
||||
/// Free the memory used by a mgp_vertices_iterator.
|
||||
void mgp_vertices_iterator_destroy(struct mgp_vertices_iterator *it);
|
||||
|
||||
/// Start iterating over vertices of the given graph.
|
||||
/// Resulting mgp_vertices_iterator needs to be deallocated with mgp_vertices_iterator_destroy.
|
||||
/// Return MGP_ERROR_UNABLE_TO_ALLOCATE if unable to allocate a mgp_vertices_iterator.
|
||||
enum mgp_error mgp_graph_iter_vertices(const struct mgp_graph *g, struct mgp_memory *memory,
|
||||
struct mgp_vertices_iterator **result);
|
||||
|
||||
/// Get the current vertex pointed to by the iterator.
|
||||
/// When the mgp_vertices_iterator_next is invoked, the previous
|
||||
/// mgp_vertex is invalidated and its value must not be used.
|
||||
/// Result is NULL if the end of the iteration has been reached.
|
||||
enum mgp_error mgp_vertices_iterator_get(const struct mgp_vertices_iterator *it, const struct mgp_vertex **result);
|
||||
|
||||
/// Advance the iterator to the next vertex and return it.
|
||||
/// The previous mgp_vertex obtained through mgp_vertices_iterator_get
|
||||
/// will be invalidated, and you must not use its value.
|
||||
/// Result is NULL if the end of the iteration has been reached.
|
||||
enum mgp_error mgp_vertices_iterator_next(struct mgp_vertices_iterator *it, const struct mgp_vertex **result);
|
||||
///@}
|
||||
|
||||
/// @name Type System
|
||||
///
|
||||
/// The following structures and functions are used to build a type
|
||||
/// representation used in openCypher. The primary purpose is to create a
|
||||
/// procedure signature for use with openCypher. Memgraph will use the built
|
||||
/// procedure signature to perform various static and dynamic checks when the
|
||||
/// custom procedure is invoked.
|
||||
///@{
|
||||
|
||||
/// A type for values in openCypher.
|
||||
struct mgp_type;
|
||||
|
||||
/// Get the type representing any value that isn't `null`.
|
||||
///
|
||||
/// The ANY type is the parent type of all types.
|
||||
/// Return MGP_ERROR_UNABLE_TO_ALLOCATE if unable to allocate the new type.
|
||||
enum mgp_error mgp_type_any(const struct mgp_type **result);
|
||||
|
||||
/// Get the type representing boolean values.
|
||||
/// Return MGP_ERROR_UNABLE_TO_ALLOCATE if unable to allocate the new type.
|
||||
enum mgp_error mgp_type_bool(const struct mgp_type **result);
|
||||
|
||||
/// Get the type representing character string values.
|
||||
/// Return MGP_ERROR_UNABLE_TO_ALLOCATE if unable to allocate the new type.
|
||||
enum mgp_error mgp_type_string(const struct mgp_type **result);
|
||||
|
||||
/// Get the type representing integer values.
|
||||
/// Return MGP_ERROR_UNABLE_TO_ALLOCATE if unable to allocate the new type.
|
||||
enum mgp_error mgp_type_int(const struct mgp_type **result);
|
||||
|
||||
/// Get the type representing floating-point values.
|
||||
/// Return MGP_ERROR_UNABLE_TO_ALLOCATE if unable to allocate the new type.
|
||||
enum mgp_error mgp_type_float(const struct mgp_type **result);
|
||||
|
||||
/// Get the type representing any number value.
|
||||
///
|
||||
/// This is the parent type for numeric types, i.e. INTEGER and FLOAT.
|
||||
/// Return MGP_ERROR_UNABLE_TO_ALLOCATE if unable to allocate the new type.
|
||||
enum mgp_error mgp_type_number(const struct mgp_type **result);
|
||||
|
||||
/// Get the type representing map values.
|
||||
///
|
||||
/// Map values are those which map string keys to values of any type. For
|
||||
/// example `{ database: "Memgraph", version: 1.42 }`. Note that graph nodes
|
||||
/// contain property maps, so a node value will also satisfy the MAP type. The
|
||||
/// same applies for graph relationship values.
|
||||
///
|
||||
/// @sa mgp_type_node
|
||||
/// @sa mgp_type_relationship
|
||||
/// Return MGP_ERROR_UNABLE_TO_ALLOCATE if unable to allocate the new type.
|
||||
enum mgp_error mgp_type_map(const struct mgp_type **result);
|
||||
|
||||
/// Get the type representing graph node values.
|
||||
///
|
||||
/// Since a node contains a map of properties, the node itself is also of MAP
|
||||
/// type.
|
||||
/// Return MGP_ERROR_UNABLE_TO_ALLOCATE if unable to allocate the new type.
|
||||
enum mgp_error mgp_type_node(const struct mgp_type **result);
|
||||
|
||||
/// Get the type representing graph relationship values.
|
||||
///
|
||||
/// Since a relationship contains a map of properties, the relationship itself
|
||||
/// is also of MAP type.
|
||||
/// Return MGP_ERROR_UNABLE_TO_ALLOCATE if unable to allocate the new type.
|
||||
enum mgp_error mgp_type_relationship(const struct mgp_type **result);
|
||||
|
||||
/// Get the type representing a graph path (walk) from one node to another.
|
||||
/// Return MGP_ERROR_UNABLE_TO_ALLOCATE if unable to allocate the new type.
|
||||
enum mgp_error mgp_type_path(const struct mgp_type **result);
|
||||
|
||||
/// Build a type representing a list of values of given `element_type`.
|
||||
///
|
||||
/// Return MGP_ERROR_UNABLE_TO_ALLOCATE if unable to allocate the new type.
|
||||
enum mgp_error mgp_type_list(const struct mgp_type *element_type, const struct mgp_type **result);
|
||||
|
||||
/// Build a type representing either a `null` value or a value of given `type`.
|
||||
///
|
||||
/// Return MGP_ERROR_UNABLE_TO_ALLOCATE if unable to allocate the new type.
|
||||
enum mgp_error mgp_type_nullable(const struct mgp_type *type, const struct mgp_type **result);
|
||||
///@}
|
||||
|
||||
/// @name Query Module & Procedures
|
||||
///
|
||||
/// The following structures and functions are used to build a query module. You
|
||||
/// will receive an empty instance of mgp_module through your
|
||||
/// `int mgp_init_module(struct mgp_module *module, struct mgp_memory *memory)`
|
||||
/// function. Each shared library that wishes to provide a query module needs to
|
||||
/// have the said function. Inside you can fill the module with procedures,
|
||||
/// which can then be called through openCypher.
|
||||
///
|
||||
/// Arguments to `mgp_init_module` will not live longer than the function's
|
||||
/// execution, so you must not store them globally. Additionally, you must not
|
||||
/// use the passed in mgp_memory to allocate global resources.
|
||||
///@{
|
||||
|
||||
/// Stores information on your query module.
|
||||
struct mgp_module;
|
||||
|
||||
/// Describes a procedure of a query module.
|
||||
struct mgp_proc;
|
||||
|
||||
/// Entry-point for a query module procedure, invoked through openCypher.
|
||||
///
|
||||
/// Passed in arguments will not live longer than the callback's execution.
|
||||
/// Therefore, you must not store them globally or use the passed in mgp_memory
|
||||
/// to allocate global resources.
|
||||
typedef void (*mgp_proc_cb)(const struct mgp_list *, const struct mgp_graph *, struct mgp_result *,
|
||||
struct mgp_memory *);
|
||||
|
||||
/// Register a read-only procedure with a module.
|
||||
///
|
||||
/// The `name` must be a sequence of digits, underscores, lowercase and
|
||||
/// uppercase Latin letters. The name must begin with a non-digit character.
|
||||
/// Note that Unicode characters are not allowed. Additionally, names are
|
||||
/// case-sensitive.
|
||||
///
|
||||
/// Return MGP_ERROR_UNABLE_TO_ALLOCATE if unable to allocate memory for mgp_proc.
|
||||
/// Return MGP_ERROR_INVALID_ARGUMENT if `name` is not a valid procedure name.
|
||||
/// RETURN MGP_ERROR_LOGIC_ERROR if a procedure with the same name was already registered.
|
||||
enum mgp_error mgp_module_add_read_procedure(struct mgp_module *module, const char *name, mgp_proc_cb cb,
|
||||
struct mgp_proc **result);
|
||||
|
||||
/// Add a required argument to a procedure.
|
||||
///
|
||||
/// The order of adding arguments will correspond to the order the procedure
|
||||
/// must receive them through openCypher. Required arguments will be followed by
|
||||
/// optional arguments.
|
||||
///
|
||||
/// The `name` must be a valid identifier, following the same rules as the
|
||||
/// procedure`name` in mgp_module_add_read_procedure.
|
||||
///
|
||||
/// Passed in `type` describes what kind of values can be used as the argument.
|
||||
///
|
||||
/// Return MGP_ERROR_UNABLE_TO_ALLOCATE if unable to allocate memory for an argument.
|
||||
/// Return MGP_ERROR_INVALID_ARGUMENT if `name` is not a valid argument name.
|
||||
/// RETURN MGP_ERROR_LOGIC_ERROR if the procedure already has any optional argument.
|
||||
enum mgp_error mgp_proc_add_arg(struct mgp_proc *proc, const char *name, const struct mgp_type *type);
|
||||
|
||||
/// Add an optional argument with a default value to a procedure.
|
||||
///
|
||||
/// The order of adding arguments will correspond to the order the procedure
|
||||
/// must receive them through openCypher. Optional arguments must follow the
|
||||
/// required arguments.
|
||||
///
|
||||
/// The `name` must be a valid identifier, following the same rules as the
|
||||
/// procedure `name` in mgp_module_add_read_procedure.
|
||||
///
|
||||
/// Passed in `type` describes what kind of values can be used as the argument.
|
||||
///
|
||||
/// `default_value` is copied and set as the default value for the argument.
|
||||
/// Don't forget to call mgp_value_destroy when you are done using
|
||||
/// `default_value`. When the procedure is called, if this argument is not
|
||||
/// provided, `default_value` will be used instead. `default_value` must not be
|
||||
/// a graph element (node, relationship, path) and it must satisfy the given
|
||||
/// `type`.
|
||||
///
|
||||
/// Return MGP_ERROR_UNABLE_TO_ALLOCATE if unable to allocate memory for an argument.
|
||||
/// Return MGP_ERROR_INVALID_ARGUMENT if `name` is not a valid argument name.
|
||||
/// RETURN MGP_ERROR_OUT_OF_RANGE if `default_value` is a graph element (vertex, edge or path).
|
||||
/// RETURN MGP_ERROR_LOGIC_ERROR if `default_value` does not satisfy `type`.
|
||||
enum mgp_error mgp_proc_add_opt_arg(struct mgp_proc *proc, const char *name, const struct mgp_type *type,
|
||||
const struct mgp_value *default_value);
|
||||
|
||||
/// Add a result field to a procedure.
|
||||
///
|
||||
/// The `name` must be a valid identifier, following the same rules as the
|
||||
/// procedure `name` in mgp_module_add_read_procedure.
|
||||
///
|
||||
/// Passed in `type` describes what kind of values can be returned through the
|
||||
/// result field.
|
||||
///
|
||||
/// Return MGP_ERROR_UNABLE_TO_ALLOCATE if unable to allocate memory for an argument.
|
||||
/// Return MGP_ERROR_INVALID_ARGUMENT if `name` is not a valid result name.
|
||||
/// RETURN MGP_ERROR_LOGIC_ERROR if a result field with the same name was already added.
|
||||
enum mgp_error mgp_proc_add_result(struct mgp_proc *proc, const char *name, const struct mgp_type *type);
|
||||
|
||||
/// Add a result field to a procedure and mark it as deprecated.
|
||||
///
|
||||
/// This is the same as mgp_proc_add_result, but the result field will be marked
|
||||
/// as deprecated.
|
||||
///
|
||||
/// Return MGP_ERROR_UNABLE_TO_ALLOCATE if unable to allocate memory for an argument.
|
||||
/// Return MGP_ERROR_INVALID_ARGUMENT if `name` is not a valid result name.
|
||||
/// RETURN MGP_ERROR_LOGIC_ERROR if a result field with the same name was already added.
|
||||
enum mgp_error mgp_proc_add_deprecated_result(struct mgp_proc *proc, const char *name, const struct mgp_type *type);
|
||||
///@}
|
||||
|
||||
/// @name Execution
|
||||
///
|
||||
/// The following functions are used to control the execution of the procedure.
|
||||
///
|
||||
/// @{
|
||||
|
||||
/// Return non-zero if the currently executing procedure should abort as soon as
|
||||
/// possible.
|
||||
///
|
||||
/// Procedures which perform heavyweight processing run the risk of running too
|
||||
/// long and going over the query execution time limit. To prevent this, such
|
||||
/// procedures should periodically call this function at critical points in
|
||||
/// their code in order to determine whether they should abort or not. Note that
|
||||
/// this mechanism is purely cooperative and depends on the procedure doing the
|
||||
/// checking and aborting on its own.
|
||||
int mgp_must_abort(const struct mgp_graph *graph);
|
||||
|
||||
/// @}
|
||||
|
||||
/// @name Kafka message API
|
||||
/// Currently the API below is for kafka only but in the future
|
||||
/// mgp_message and mgp_messages might be generic to support
|
||||
/// other streaming systems.
|
||||
///@{
|
||||
|
||||
/// A single Kafka message
|
||||
struct mgp_message;
|
||||
|
||||
/// A list of Kafka messages
|
||||
struct mgp_messages;
|
||||
|
||||
/// Payload is not null terminated and not a string but rather a byte array.
|
||||
/// You need to call mgp_message_payload_size() first, to read the size of
|
||||
/// the payload.
|
||||
enum mgp_error mgp_message_payload(const struct mgp_message *message, const char **result);
|
||||
|
||||
/// Return the payload size
|
||||
enum mgp_error mgp_message_payload_size(const struct mgp_message *message, size_t *result);
|
||||
|
||||
/// Return the name of topic
|
||||
enum mgp_error mgp_message_topic_name(const struct mgp_message *message, const char **result);
|
||||
|
||||
/// Return the key of mgp_message as a byte array
|
||||
enum mgp_error mgp_message_key(const struct mgp_message *message, const char **result);
|
||||
|
||||
/// Return the key size of mgp_message
|
||||
enum mgp_error mgp_message_key_size(const struct mgp_message *message, size_t *result);
|
||||
|
||||
/// Return the timestamp of mgp_message as a byte array
|
||||
enum mgp_error mgp_message_timestamp(const struct mgp_message *message, int64_t *result);
|
||||
|
||||
/// Return the number of messages contained in the mgp_messages list
|
||||
/// Current implementation always returns without errors.
|
||||
enum mgp_error mgp_messages_size(const struct mgp_messages *message, size_t *result);
|
||||
|
||||
/// Return the message from a messages list at given index
|
||||
enum mgp_error mgp_messages_at(const struct mgp_messages *message, size_t index, const struct mgp_message **result);
|
||||
|
||||
/// Entry-point for a module transformation, invoked through a stream transformation.
|
||||
///
|
||||
/// Passed in arguments will not live longer than the callback's execution.
|
||||
/// Therefore, you must not store them globally or use the passed in mgp_memory
|
||||
/// to allocate global resources.
|
||||
typedef void (*mgp_trans_cb)(const struct mgp_messages *, const struct mgp_graph *, struct mgp_result *,
|
||||
struct mgp_memory *);
|
||||
|
||||
/// Register a transformation with a module.
|
||||
///
|
||||
/// The `name` must be a sequence of digits, underscores, lowercase and
|
||||
/// uppercase Latin letters. The name must begin with a non-digit character.
|
||||
/// Note that Unicode characters are not allowed. Additionally, names are
|
||||
/// case-sensitive.
|
||||
///
|
||||
/// Return MGP_ERROR_UNABLE_TO_ALLOCATE if unable to allocate memory for transformation.
|
||||
/// Return MGP_ERROR_INVALID_ARGUMENT if `name` is not a valid transformation name.
|
||||
/// RETURN MGP_ERROR_LOGIC_ERROR if a transformation with the same name was already registered.
|
||||
enum mgp_error mgp_module_add_transformation(struct mgp_module *module, const char *name, mgp_trans_cb cb);
|
||||
/// @}
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif // MG_PROCEDURE_H
|
||||
@@ -1,3 +0,0 @@
|
||||
{
|
||||
mgp_*;
|
||||
};
|
||||
943
include/mgp.py
943
include/mgp.py
@@ -1,943 +0,0 @@
|
||||
'''
|
||||
This module provides the API for usage in custom openCypher procedures.
|
||||
'''
|
||||
|
||||
# C API using `mgp_memory` is not exposed in Python, instead the usage of such
|
||||
# API is hidden behind Python API. Any function requiring an instance of
|
||||
# `mgp_memory` should go through a `ProcCtx` instance.
|
||||
#
|
||||
# `mgp_value` does not exist as such in Python, instead all `mgp_value`
|
||||
# instances are marshalled to an appropriate Python object. This implies that
|
||||
# `mgp_list` and `mgp_map` are mapped to `list` and `dict` respectively.
|
||||
#
|
||||
# Only the public API is stubbed out here. Any private details are left for the
|
||||
# actual implementation. Functions have type annotations as supported by Python
|
||||
# 3.5, but variable type annotations are only available with Python 3.6+
|
||||
|
||||
from collections import namedtuple
|
||||
import functools
|
||||
import inspect
|
||||
import sys
|
||||
import typing
|
||||
|
||||
import _mgp
|
||||
|
||||
|
||||
class InvalidContextError(Exception):
|
||||
'''Signals using a graph element instance outside of the registered procedure.'''
|
||||
pass
|
||||
|
||||
|
||||
class Label:
|
||||
'''Label of a Vertex.'''
|
||||
__slots__ = ('_name',)
|
||||
|
||||
def __init__(self, name):
|
||||
self._name = name
|
||||
|
||||
@property
|
||||
def name(self) -> str:
|
||||
return self._name
|
||||
|
||||
def __eq__(self, other) -> bool:
|
||||
if isinstance(other, Label):
|
||||
return self._name == other.name
|
||||
if isinstance(other, str):
|
||||
return self._name == other
|
||||
return NotImplemented
|
||||
|
||||
|
||||
# Named property value of a Vertex or an Edge.
|
||||
# It would be better to use typing.NamedTuple with typed fields, but that is
|
||||
# not available in Python 3.5.
|
||||
Property = namedtuple('Property', ('name', 'value'))
|
||||
|
||||
|
||||
class Properties:
|
||||
'''A collection of properties either on a Vertex or an Edge.'''
|
||||
__slots__ = ('_vertex_or_edge', '_len',)
|
||||
|
||||
def __init__(self, vertex_or_edge):
|
||||
if not isinstance(vertex_or_edge, (_mgp.Vertex, _mgp.Edge)):
|
||||
raise TypeError("Expected '_mgp.Vertex' or '_mgp.Edge', \
|
||||
got {}".format(type(vertex_or_edge)))
|
||||
self._len = None
|
||||
self._vertex_or_edge = vertex_or_edge
|
||||
|
||||
def __deepcopy__(self, memo):
|
||||
# This is the same as the shallow copy, as the underlying C API should
|
||||
# not support deepcopy. Besides, it doesn't make much sense to actually
|
||||
# copy _mgp.Edge and _mgp.Vertex types as they are actually references
|
||||
# to graph elements and not proper values.
|
||||
return Properties(self._vertex_or_edge)
|
||||
|
||||
def get(self, property_name: str, default=None) -> object:
|
||||
'''Get the value of a property with the given name or return default.
|
||||
|
||||
Raise InvalidContextError.
|
||||
'''
|
||||
if not self._vertex_or_edge.is_valid():
|
||||
raise InvalidContextError()
|
||||
try:
|
||||
return self[property_name]
|
||||
except KeyError:
|
||||
return default
|
||||
|
||||
def items(self) -> typing.Iterable[Property]:
|
||||
'''Raise InvalidContextError.'''
|
||||
if not self._vertex_or_edge.is_valid():
|
||||
raise InvalidContextError()
|
||||
properties_it = self._vertex_or_edge.iter_properties()
|
||||
prop = properties_it.get()
|
||||
while prop is not None:
|
||||
yield Property(*prop)
|
||||
if not self._vertex_or_edge.is_valid():
|
||||
raise InvalidContextError()
|
||||
prop = properties_it.next()
|
||||
|
||||
def keys(self) -> typing.Iterable[str]:
|
||||
'''Iterate over property names.
|
||||
|
||||
Raise InvalidContextError.
|
||||
'''
|
||||
if not self._vertex_or_edge.is_valid():
|
||||
raise InvalidContextError()
|
||||
for item in self.items():
|
||||
yield item.name
|
||||
|
||||
def values(self) -> typing.Iterable[object]:
|
||||
'''Iterate over property values.
|
||||
|
||||
Raise InvalidContextError.
|
||||
'''
|
||||
if not self._vertex_or_edge.is_valid():
|
||||
raise InvalidContextError()
|
||||
for item in self.items():
|
||||
yield item.value
|
||||
|
||||
def __len__(self) -> int:
|
||||
'''Raise InvalidContextError.'''
|
||||
if not self._vertex_or_edge.is_valid():
|
||||
raise InvalidContextError()
|
||||
if self._len is None:
|
||||
self._len = sum(1 for item in self.items())
|
||||
return self._len
|
||||
|
||||
def __iter__(self) -> typing.Iterable[str]:
|
||||
'''Iterate over property names.
|
||||
|
||||
Raise InvalidContextError.
|
||||
'''
|
||||
if not self._vertex_or_edge.is_valid():
|
||||
raise InvalidContextError()
|
||||
for item in self.items():
|
||||
yield item.name
|
||||
|
||||
def __getitem__(self, property_name: str) -> object:
|
||||
'''Get the value of a property with the given name or raise KeyError.
|
||||
|
||||
Raise InvalidContextError.'''
|
||||
if not self._vertex_or_edge.is_valid():
|
||||
raise InvalidContextError()
|
||||
prop = self._vertex_or_edge.get_property(property_name)
|
||||
if prop is None:
|
||||
raise KeyError()
|
||||
return prop
|
||||
|
||||
def __contains__(self, property_name: str) -> bool:
|
||||
if not self._vertex_or_edge.is_valid():
|
||||
raise InvalidContextError()
|
||||
try:
|
||||
_ = self[property_name]
|
||||
return True
|
||||
except KeyError:
|
||||
return False
|
||||
|
||||
|
||||
class EdgeType:
|
||||
'''Type of an Edge.'''
|
||||
__slots__ = ('_name',)
|
||||
|
||||
def __init__(self, name):
|
||||
self._name = name
|
||||
|
||||
@property
|
||||
def name(self) -> str:
|
||||
return self._name
|
||||
|
||||
def __eq__(self, other) -> bool:
|
||||
if isinstance(other, EdgeType):
|
||||
return self.name == other.name
|
||||
if isinstance(other, str):
|
||||
return self.name == other
|
||||
return NotImplemented
|
||||
|
||||
|
||||
if sys.version_info >= (3, 5, 2):
|
||||
EdgeId = typing.NewType('EdgeId', int)
|
||||
else:
|
||||
EdgeId = int
|
||||
|
||||
|
||||
class Edge:
|
||||
'''Edge in the graph database.
|
||||
|
||||
Access to an Edge is only valid during a single execution of a procedure in
|
||||
a query. You should not globally store an instance of an Edge. Using an
|
||||
invalid Edge instance will raise InvalidContextError.
|
||||
'''
|
||||
__slots__ = ('_edge',)
|
||||
|
||||
def __init__(self, edge):
|
||||
if not isinstance(edge, _mgp.Edge):
|
||||
raise TypeError(
|
||||
"Expected '_mgp.Edge', got '{}'".format(type(edge)))
|
||||
self._edge = edge
|
||||
|
||||
def __deepcopy__(self, memo):
|
||||
# This is the same as the shallow copy, because we want to share the
|
||||
# underlying C struct. Besides, it doesn't make much sense to actually
|
||||
# copy _mgp.Edge as that is actually a reference to a graph element
|
||||
# and not a proper value.
|
||||
return Edge(self._edge)
|
||||
|
||||
def is_valid(self) -> bool:
|
||||
'''Return True if `self` is in valid context and may be used.'''
|
||||
return self._edge.is_valid()
|
||||
|
||||
@property
|
||||
def id(self) -> EdgeId:
|
||||
'''Raise InvalidContextError.'''
|
||||
if not self.is_valid():
|
||||
raise InvalidContextError()
|
||||
return self._edge.get_id()
|
||||
|
||||
@property
|
||||
def type(self) -> EdgeType:
|
||||
'''Raise InvalidContextError.'''
|
||||
if not self.is_valid():
|
||||
raise InvalidContextError()
|
||||
return EdgeType(self._edge.get_type_name())
|
||||
|
||||
@property
|
||||
def from_vertex(self): # -> Vertex:
|
||||
'''Raise InvalidContextError.'''
|
||||
if not self.is_valid():
|
||||
raise InvalidContextError()
|
||||
return Vertex(self._edge.from_vertex())
|
||||
|
||||
@property
|
||||
def to_vertex(self): # -> Vertex:
|
||||
'''Raise InvalidContextError.'''
|
||||
if not self.is_valid():
|
||||
raise InvalidContextError()
|
||||
return Vertex(self._edge.to_vertex())
|
||||
|
||||
@property
|
||||
def properties(self) -> Properties:
|
||||
'''Raise InvalidContextError.'''
|
||||
if not self.is_valid():
|
||||
raise InvalidContextError()
|
||||
return Properties(self._edge)
|
||||
|
||||
def __eq__(self, other) -> bool:
|
||||
'''Raise InvalidContextError.'''
|
||||
if not self.is_valid():
|
||||
raise InvalidContextError()
|
||||
if not isinstance(other, Edge):
|
||||
return NotImplemented
|
||||
return self._edge == other._edge
|
||||
|
||||
def __hash__(self) -> int:
|
||||
return hash(self.id)
|
||||
|
||||
|
||||
if sys.version_info >= (3, 5, 2):
|
||||
VertexId = typing.NewType('VertexId', int)
|
||||
else:
|
||||
VertexId = int
|
||||
|
||||
|
||||
class Vertex:
|
||||
'''Vertex in the graph database.
|
||||
|
||||
Access to a Vertex is only valid during a single execution of a procedure
|
||||
in a query. You should not globally store an instance of a Vertex. Using an
|
||||
invalid Vertex instance will raise InvalidContextError.
|
||||
'''
|
||||
__slots__ = ('_vertex',)
|
||||
|
||||
def __init__(self, vertex):
|
||||
if not isinstance(vertex, _mgp.Vertex):
|
||||
raise TypeError(
|
||||
"Expected '_mgp.Vertex', got '{}'".format(type(vertex)))
|
||||
self._vertex = vertex
|
||||
|
||||
def __deepcopy__(self, memo):
|
||||
# This is the same as the shallow copy, because we want to share the
|
||||
# underlying C struct. Besides, it doesn't make much sense to actually
|
||||
# copy _mgp.Vertex as that is actually a reference to a graph element
|
||||
# and not a proper value.
|
||||
return Vertex(self._vertex)
|
||||
|
||||
def is_valid(self) -> bool:
|
||||
'''Return True if `self` is in valid context and may be used'''
|
||||
return self._vertex.is_valid()
|
||||
|
||||
@property
|
||||
def id(self) -> VertexId:
|
||||
'''Raise InvalidContextError.'''
|
||||
if not self.is_valid():
|
||||
raise InvalidContextError()
|
||||
return self._vertex.get_id()
|
||||
|
||||
@property
|
||||
def labels(self) -> typing.List[Label]:
|
||||
'''Raise InvalidContextError.'''
|
||||
if not self.is_valid():
|
||||
raise InvalidContextError()
|
||||
return tuple(Label(self._vertex.label_at(i))
|
||||
for i in range(self._vertex.labels_count()))
|
||||
|
||||
@property
|
||||
def properties(self) -> Properties:
|
||||
'''Raise InvalidContextError.'''
|
||||
if not self.is_valid():
|
||||
raise InvalidContextError()
|
||||
return Properties(self._vertex)
|
||||
|
||||
@property
|
||||
def in_edges(self) -> typing.Iterable[Edge]:
|
||||
'''Raise InvalidContextError.'''
|
||||
if not self.is_valid():
|
||||
raise InvalidContextError()
|
||||
edges_it = self._vertex.iter_in_edges()
|
||||
edge = edges_it.get()
|
||||
while edge is not None:
|
||||
yield Edge(edge)
|
||||
if not self.is_valid():
|
||||
raise InvalidContextError()
|
||||
edge = edges_it.next()
|
||||
|
||||
@property
|
||||
def out_edges(self) -> typing.Iterable[Edge]:
|
||||
'''Raise InvalidContextError.'''
|
||||
if not self.is_valid():
|
||||
raise InvalidContextError()
|
||||
edges_it = self._vertex.iter_out_edges()
|
||||
edge = edges_it.get()
|
||||
while edge is not None:
|
||||
yield Edge(edge)
|
||||
if not self.is_valid():
|
||||
raise InvalidContextError()
|
||||
edge = edges_it.next()
|
||||
|
||||
def __eq__(self, other) -> bool:
|
||||
'''Raise InvalidContextError'''
|
||||
if not self.is_valid():
|
||||
raise InvalidContextError()
|
||||
if not isinstance(other, Vertex):
|
||||
return NotImplemented
|
||||
return self._vertex == other._vertex
|
||||
|
||||
def __hash__(self) -> int:
|
||||
return hash(self.id)
|
||||
|
||||
|
||||
class Path:
|
||||
'''Path containing Vertex and Edge instances.'''
|
||||
__slots__ = ('_path', '_vertices', '_edges')
|
||||
|
||||
def __init__(self, starting_vertex_or_path: typing.Union[_mgp.Path, Vertex]):
|
||||
'''Initialize with a starting Vertex.
|
||||
|
||||
Raise InvalidContextError if passed in Vertex is invalid.
|
||||
'''
|
||||
# We cache calls to `vertices` and `edges`, so as to avoid needless
|
||||
# allocations at the C level.
|
||||
self._vertices = None
|
||||
self._edges = None
|
||||
# Accepting _mgp.Path is just for internal usage.
|
||||
if isinstance(starting_vertex_or_path, _mgp.Path):
|
||||
self._path = starting_vertex_or_path
|
||||
elif isinstance(starting_vertex_or_path, Vertex):
|
||||
vertex = starting_vertex_or_path._vertex
|
||||
if not vertex.is_valid():
|
||||
raise InvalidContextError()
|
||||
self._path = _mgp.Path.make_with_start(vertex)
|
||||
else:
|
||||
raise TypeError("Expected '_mgp.Vertex' or '_mgp.Path', got '{}'"
|
||||
.format(type(starting_vertex_or_path)))
|
||||
|
||||
def __copy__(self):
|
||||
if not self.is_valid():
|
||||
raise InvalidContextError()
|
||||
assert len(self.vertices) >= 1
|
||||
path = Path(self.vertices[0])
|
||||
for e in self.edges:
|
||||
path.expand(e)
|
||||
return path
|
||||
|
||||
def __deepcopy__(self, memo):
|
||||
try:
|
||||
return Path(memo[id(self._path)])
|
||||
except KeyError:
|
||||
pass
|
||||
# This is the same as the shallow copy, as the underlying C API should
|
||||
# not support deepcopy. Besides, it doesn't make much sense to actually
|
||||
# copy _mgp.Edge and _mgp.Vertex types as they are actually references
|
||||
# to graph elements and not proper values.
|
||||
path = self.__copy__()
|
||||
memo[id(self._path)] = path._path
|
||||
return path
|
||||
|
||||
def is_valid(self) -> bool:
|
||||
return self._path.is_valid()
|
||||
|
||||
def expand(self, edge: Edge):
|
||||
'''Append an edge continuing from the last vertex on the path.
|
||||
|
||||
The last vertex on the path will become the other endpoint of the given
|
||||
edge, as continued from the current last vertex.
|
||||
|
||||
Raise ValueError if the current last vertex in the path is not part of
|
||||
the given edge.
|
||||
Raise InvalidContextError if using an invalid Path instance or if
|
||||
passed in edge is invalid.
|
||||
'''
|
||||
if not isinstance(edge, Edge):
|
||||
raise TypeError(
|
||||
"Expected '_mgp.Edge', got '{}'".format(type(edge)))
|
||||
if not self.is_valid() or not edge.is_valid():
|
||||
raise InvalidContextError()
|
||||
self._path.expand(edge._edge)
|
||||
# Invalidate our cached tuples
|
||||
self._vertices = None
|
||||
self._edges = None
|
||||
|
||||
@property
|
||||
def vertices(self) -> typing.Tuple[Vertex, ...]:
|
||||
'''Vertices ordered from the start to the end of the path.
|
||||
|
||||
Raise InvalidContextError if using an invalid Path instance.'''
|
||||
if not self.is_valid():
|
||||
raise InvalidContextError()
|
||||
if self._vertices is None:
|
||||
num_vertices = self._path.size() + 1
|
||||
self._vertices = tuple(Vertex(self._path.vertex_at(i))
|
||||
for i in range(num_vertices))
|
||||
return self._vertices
|
||||
|
||||
@property
|
||||
def edges(self) -> typing.Tuple[Edge, ...]:
|
||||
'''Edges ordered from the start to the end of the path.
|
||||
|
||||
Raise InvalidContextError if using an invalid Path instance.'''
|
||||
if not self.is_valid():
|
||||
raise InvalidContextError()
|
||||
if self._edges is None:
|
||||
num_edges = self._path.size()
|
||||
self._edges = tuple(Edge(self._path.edge_at(i))
|
||||
for i in range(num_edges))
|
||||
return self._edges
|
||||
|
||||
|
||||
class Record:
|
||||
'''Represents a record of resulting field values.'''
|
||||
__slots__ = ('fields',)
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
'''Initialize with name=value fields in kwargs.'''
|
||||
self.fields = kwargs
|
||||
|
||||
|
||||
class Vertices:
|
||||
'''Iterable over vertices in a graph.'''
|
||||
__slots__ = ('_graph', '_len')
|
||||
|
||||
def __init__(self, graph):
|
||||
if not isinstance(graph, _mgp.Graph):
|
||||
raise TypeError(
|
||||
"Expected '_mgp.Graph', got '{}'".format(type(graph)))
|
||||
self._graph = graph
|
||||
self._len = None
|
||||
|
||||
def __deepcopy__(self, memo):
|
||||
# This is the same as the shallow copy, because we want to share the
|
||||
# underlying C struct. Besides, it doesn't make much sense to actually
|
||||
# copy _mgp.Graph as that always references the whole graph state.
|
||||
return Vertices(self._graph)
|
||||
|
||||
def is_valid(self) -> bool:
|
||||
'''Return True if `self` is in valid context and may be used.'''
|
||||
return self._graph.is_valid()
|
||||
|
||||
def __iter__(self) -> typing.Iterable[Vertex]:
|
||||
'''Raise InvalidContextError if context is invalid.'''
|
||||
if not self.is_valid():
|
||||
raise InvalidContextError()
|
||||
vertices_it = self._graph.iter_vertices()
|
||||
vertex = vertices_it.get()
|
||||
while vertex is not None:
|
||||
yield Vertex(vertex)
|
||||
if not self.is_valid():
|
||||
raise InvalidContextError()
|
||||
vertex = vertices_it.next()
|
||||
|
||||
def __contains__(self, vertex):
|
||||
try:
|
||||
_ = self._graph.get_vertex_by_id(vertex.id)
|
||||
return True
|
||||
except IndexError:
|
||||
return False
|
||||
|
||||
def __len__(self):
|
||||
if not self._len:
|
||||
self._len = sum(1 for _ in self)
|
||||
return self._len
|
||||
|
||||
|
||||
class Graph:
|
||||
'''State of the graph database in current ProcCtx.'''
|
||||
__slots__ = ('_graph',)
|
||||
|
||||
def __init__(self, graph):
|
||||
if not isinstance(graph, _mgp.Graph):
|
||||
raise TypeError(
|
||||
"Expected '_mgp.Graph', got '{}'".format(type(graph)))
|
||||
self._graph = graph
|
||||
|
||||
def __deepcopy__(self, memo):
|
||||
# This is the same as the shallow copy, because we want to share the
|
||||
# underlying C struct. Besides, it doesn't make much sense to actually
|
||||
# copy _mgp.Graph as that always references the whole graph state.
|
||||
return Graph(self._graph)
|
||||
|
||||
def is_valid(self) -> bool:
|
||||
'''Return True if `self` is in valid context and may be used.'''
|
||||
return self._graph.is_valid()
|
||||
|
||||
def get_vertex_by_id(self, vertex_id: VertexId) -> Vertex:
|
||||
'''Return the Vertex corresponding to given vertex_id from the graph.
|
||||
|
||||
Access to a Vertex is only valid during a single execution of a
|
||||
procedure in a query. You should not globally store the returned
|
||||
Vertex.
|
||||
|
||||
Raise IndexError if unable to find the given vertex_id.
|
||||
Raise InvalidContextError if context is invalid.
|
||||
'''
|
||||
if not self.is_valid():
|
||||
raise InvalidContextError()
|
||||
vertex = self._graph.get_vertex_by_id(vertex_id)
|
||||
return Vertex(vertex)
|
||||
|
||||
@property
|
||||
def vertices(self) -> Vertices:
|
||||
'''All vertices in the graph.
|
||||
|
||||
Access to a Vertex is only valid during a single execution of a
|
||||
procedure in a query. You should not globally store the returned Vertex
|
||||
instances.
|
||||
|
||||
Raise InvalidContextError if context is invalid.
|
||||
'''
|
||||
if not self.is_valid():
|
||||
raise InvalidContextError()
|
||||
return Vertices(self._graph)
|
||||
|
||||
|
||||
class AbortError(Exception):
|
||||
'''Signals that the procedure was asked to abort its execution.'''
|
||||
pass
|
||||
|
||||
|
||||
class ProcCtx:
|
||||
'''Context of a procedure being executed.
|
||||
|
||||
Access to a ProcCtx is only valid during a single execution of a procedure
|
||||
in a query. You should not globally store a ProcCtx instance.
|
||||
'''
|
||||
__slots__ = ('_graph',)
|
||||
|
||||
def __init__(self, graph):
|
||||
if not isinstance(graph, _mgp.Graph):
|
||||
raise TypeError(
|
||||
"Expected '_mgp.Graph', got '{}'".format(type(graph)))
|
||||
self._graph = Graph(graph)
|
||||
|
||||
def is_valid(self) -> bool:
|
||||
return self._graph.is_valid()
|
||||
|
||||
@property
|
||||
def graph(self) -> Graph:
|
||||
'''Raise InvalidContextError if context is invalid.'''
|
||||
if not self.is_valid():
|
||||
raise InvalidContextError()
|
||||
return self._graph
|
||||
|
||||
def must_abort(self) -> bool:
|
||||
if not self.is_valid():
|
||||
raise InvalidContextError()
|
||||
return self._graph._graph.must_abort()
|
||||
|
||||
def check_must_abort(self):
|
||||
if self.must_abort():
|
||||
raise AbortError
|
||||
|
||||
|
||||
# Additional typing support
|
||||
|
||||
Number = typing.Union[int, float]
|
||||
|
||||
Map = typing.Union[dict, Edge, Vertex]
|
||||
|
||||
Any = typing.Union[bool, str, Number, Map, Path, list]
|
||||
|
||||
List = typing.List
|
||||
|
||||
Nullable = typing.Optional
|
||||
|
||||
|
||||
class UnsupportedTypingError(Exception):
|
||||
'''Signals a typing annotation is not supported as a _mgp.CypherType.'''
|
||||
|
||||
def __init__(self, type_):
|
||||
super().__init__("Unsupported typing annotation '{}'".format(type_))
|
||||
|
||||
|
||||
def _typing_to_cypher_type(type_):
|
||||
'''Convert typing annotation to a _mgp.CypherType instance.'''
|
||||
simple_types = {
|
||||
typing.Any: _mgp.type_nullable(_mgp.type_any()),
|
||||
object: _mgp.type_nullable(_mgp.type_any()),
|
||||
list: _mgp.type_list(_mgp.type_nullable(_mgp.type_any())),
|
||||
Any: _mgp.type_any(),
|
||||
bool: _mgp.type_bool(),
|
||||
str: _mgp.type_string(),
|
||||
int: _mgp.type_int(),
|
||||
float: _mgp.type_float(),
|
||||
Number: _mgp.type_number(),
|
||||
Map: _mgp.type_map(),
|
||||
Vertex: _mgp.type_node(),
|
||||
Edge: _mgp.type_relationship(),
|
||||
Path: _mgp.type_path()
|
||||
}
|
||||
try:
|
||||
return simple_types[type_]
|
||||
except KeyError:
|
||||
pass
|
||||
if sys.version_info >= (3, 8):
|
||||
complex_type = typing.get_origin(type_)
|
||||
type_args = typing.get_args(type_)
|
||||
if complex_type == typing.Union:
|
||||
# If we have a Union with NoneType inside, it means we are building
|
||||
# a nullable type.
|
||||
# isinstance doesn't work here because subscripted generics cannot
|
||||
# be used with class and instance checks. type comparison should be
|
||||
# fine because subclasses are not used.
|
||||
if type(None) in type_args:
|
||||
types = tuple(t for t in type_args if t is not type(None)) # noqa E721
|
||||
if len(types) == 1:
|
||||
type_arg, = types
|
||||
else:
|
||||
# We cannot do typing.Union[*types], so do the equivalent
|
||||
# with __getitem__ which does not even need arg unpacking.
|
||||
type_arg = typing.Union.__getitem__(types)
|
||||
return _mgp.type_nullable(_typing_to_cypher_type(type_arg))
|
||||
elif complex_type == list:
|
||||
type_arg, = type_args
|
||||
return _mgp.type_list(_typing_to_cypher_type(type_arg))
|
||||
raise UnsupportedTypingError(type_)
|
||||
else:
|
||||
# We cannot get to type args in any reliable way prior to 3.8, but we
|
||||
# still want to support typing.Optional and typing.List, so just parse
|
||||
# their string representations. Hopefully, that is always pretty
|
||||
# printed the same way. `typing.List[type]` is printed as such, while
|
||||
# `typing.Optional[type]` is printed as 'typing.Union[type, NoneType]'
|
||||
def parse_type_args(type_as_str):
|
||||
return tuple(map(str.strip,
|
||||
type_as_str[type_as_str.index('[') + 1: -1].split(',')))
|
||||
|
||||
def fully_qualified_name(cls):
|
||||
if cls.__module__ is None or cls.__module__ == 'builtins':
|
||||
return cls.__name__
|
||||
return cls.__module__ + '.' + cls.__name__
|
||||
|
||||
def get_simple_type(type_as_str):
|
||||
for simple_type, cypher_type in simple_types.items():
|
||||
if type_as_str == str(simple_type):
|
||||
return cypher_type
|
||||
# Fallback to comparing to __name__ if it exits. This handles
|
||||
# the cases like when we have 'object' which is
|
||||
# `object.__name__`, but `str(object)` is "<class 'object'>"
|
||||
try:
|
||||
if type_as_str == fully_qualified_name(simple_type):
|
||||
return cypher_type
|
||||
except AttributeError:
|
||||
pass
|
||||
|
||||
def parse_typing(type_as_str):
|
||||
if type_as_str.startswith('typing.Union'):
|
||||
type_args_as_str = parse_type_args(type_as_str)
|
||||
none_type_as_str = type(None).__name__
|
||||
if none_type_as_str in type_args_as_str:
|
||||
types = tuple(
|
||||
t for t in type_args_as_str if t != none_type_as_str)
|
||||
if len(types) == 1:
|
||||
type_arg_as_str, = types
|
||||
else:
|
||||
type_arg_as_str = 'typing.Union[' + \
|
||||
', '.join(types) + ']'
|
||||
simple_type = get_simple_type(type_arg_as_str)
|
||||
if simple_type is not None:
|
||||
return _mgp.type_nullable(simple_type)
|
||||
return _mgp.type_nullable(parse_typing(type_arg_as_str))
|
||||
elif type_as_str.startswith('typing.List'):
|
||||
type_arg_as_str = parse_type_args(type_as_str)
|
||||
|
||||
if len(type_arg_as_str) > 1:
|
||||
# Nested object could be a type consisting of a list of types (e.g. mgp.Map)
|
||||
# so we need to join the parts.
|
||||
type_arg_as_str = ', '.join(type_arg_as_str)
|
||||
else:
|
||||
type_arg_as_str = type_arg_as_str[0]
|
||||
|
||||
simple_type = get_simple_type(type_arg_as_str)
|
||||
if simple_type is not None:
|
||||
return _mgp.type_list(simple_type)
|
||||
return _mgp.type_list(parse_typing(type_arg_as_str))
|
||||
raise UnsupportedTypingError(type_)
|
||||
|
||||
return parse_typing(str(type_))
|
||||
|
||||
|
||||
# Procedure registration
|
||||
|
||||
class Deprecated:
|
||||
'''Annotate a resulting Record's field as deprecated.'''
|
||||
__slots__ = ('field_type',)
|
||||
|
||||
def __init__(self, type_):
|
||||
self.field_type = type_
|
||||
|
||||
|
||||
def raise_if_does_not_meet_requirements(func: typing.Callable[..., Record]):
|
||||
if not callable(func):
|
||||
raise TypeError("Expected a callable object, got an instance of '{}'"
|
||||
.format(type(func)))
|
||||
if inspect.iscoroutinefunction(func):
|
||||
raise TypeError("Callable must not be 'async def' function")
|
||||
if sys.version_info >= (3, 6):
|
||||
if inspect.isasyncgenfunction(func):
|
||||
raise TypeError("Callable must not be 'async def' function")
|
||||
if inspect.isgeneratorfunction(func):
|
||||
raise NotImplementedError("Generator functions are not supported")
|
||||
|
||||
|
||||
def read_proc(func: typing.Callable[..., Record]):
|
||||
'''
|
||||
Register `func` as a a read-only procedure of the current module.
|
||||
|
||||
`read_proc` is meant to be used as a decorator function to register module
|
||||
procedures. The registered `func` needs to be a callable which optionally
|
||||
takes `ProcCtx` as the first argument. Other arguments of `func` will be
|
||||
bound to values passed in the cypherQuery. The full signature of `func`
|
||||
needs to be annotated with types. The return type must be
|
||||
`Record(field_name=type, ...)` and the procedure must produce either a
|
||||
complete Record or None. To mark a field as deprecated, use
|
||||
`Record(field_name=Deprecated(type), ...)`. Multiple records can be
|
||||
produced by returning an iterable of them. Registering generator functions
|
||||
is currently not supported.
|
||||
|
||||
Example usage.
|
||||
|
||||
```
|
||||
import mgp
|
||||
|
||||
@mgp.read_proc
|
||||
def procedure(context: mgp.ProcCtx,
|
||||
required_arg: mgp.Nullable[mgp.Any],
|
||||
optional_arg: mgp.Nullable[mgp.Any] = None
|
||||
) -> mgp.Record(result=str, args=list):
|
||||
args = [required_arg, optional_arg]
|
||||
# Multiple rows can be produced by returning an iterable of mgp.Record
|
||||
return mgp.Record(args=args, result='Hello World!')
|
||||
```
|
||||
|
||||
The example procedure above returns 2 fields: `args` and `result`.
|
||||
* `args` is a copy of arguments passed to the procedure.
|
||||
* `result` is the result of this procedure, a "Hello World!" string.
|
||||
Any errors can be reported by raising an Exception.
|
||||
|
||||
The procedure can be invoked in openCypher using the following calls:
|
||||
CALL example.procedure(1, 2) YIELD args, result;
|
||||
CALL example.procedure(1) YIELD args, result;
|
||||
Naturally, you may pass in different arguments or yield less fields.
|
||||
'''
|
||||
raise_if_does_not_meet_requirements(func)
|
||||
sig = inspect.signature(func)
|
||||
params = tuple(sig.parameters.values())
|
||||
if params and params[0].annotation is ProcCtx:
|
||||
@functools.wraps(func)
|
||||
def wrapper(graph, args):
|
||||
return func(ProcCtx(graph), *args)
|
||||
params = params[1:]
|
||||
mgp_proc = _mgp._MODULE.add_read_procedure(wrapper)
|
||||
else:
|
||||
@functools.wraps(func)
|
||||
def wrapper(graph, args):
|
||||
return func(*args)
|
||||
mgp_proc = _mgp._MODULE.add_read_procedure(wrapper)
|
||||
for param in params:
|
||||
name = param.name
|
||||
type_ = param.annotation
|
||||
if type_ is param.empty:
|
||||
type_ = object
|
||||
cypher_type = _typing_to_cypher_type(type_)
|
||||
if param.default is param.empty:
|
||||
mgp_proc.add_arg(name, cypher_type)
|
||||
else:
|
||||
mgp_proc.add_opt_arg(name, cypher_type, param.default)
|
||||
if sig.return_annotation is not sig.empty:
|
||||
record = sig.return_annotation
|
||||
if not isinstance(record, Record):
|
||||
raise TypeError("Expected '{}' to return 'mgp.Record', got '{}'"
|
||||
.format(func.__name__, type(record)))
|
||||
for name, type_ in record.fields.items():
|
||||
if isinstance(type_, Deprecated):
|
||||
cypher_type = _typing_to_cypher_type(type_.field_type)
|
||||
mgp_proc.add_deprecated_result(name, cypher_type)
|
||||
else:
|
||||
mgp_proc.add_result(name, _typing_to_cypher_type(type_))
|
||||
return func
|
||||
|
||||
|
||||
class InvalidMessageError(Exception):
|
||||
'''Signals using a message instance outside of the registered transformation.'''
|
||||
pass
|
||||
|
||||
|
||||
class Message:
|
||||
'''Represents a message from a stream.'''
|
||||
__slots__ = ('_message',)
|
||||
|
||||
def __init__(self, message):
|
||||
if not isinstance(message, _mgp.Message):
|
||||
raise TypeError(
|
||||
"Expected '_mgp.Message', got '{}'".format(type(message)))
|
||||
self._message = message
|
||||
|
||||
def __deepcopy__(self, memo):
|
||||
# This is the same as the shallow copy, because we want to share the
|
||||
# underlying C struct. Besides, it doesn't make much sense to actually
|
||||
# copy _mgp.Messages as that always references all the messages.
|
||||
return Message(self._message)
|
||||
|
||||
def is_valid(self) -> bool:
|
||||
'''Return True if `self` is in valid context and may be used.'''
|
||||
return self._message.is_valid()
|
||||
|
||||
def payload(self) -> bytes:
|
||||
if not self.is_valid():
|
||||
raise InvalidMessageError()
|
||||
return self._message.payload()
|
||||
|
||||
def topic_name(self) -> str:
|
||||
if not self.is_valid():
|
||||
raise InvalidMessageError()
|
||||
return self._message.topic_name()
|
||||
|
||||
def key(self) -> bytes:
|
||||
if not self.is_valid():
|
||||
raise InvalidMessageError()
|
||||
return self._message.key()
|
||||
|
||||
def timestamp(self) -> int:
|
||||
if not self.is_valid():
|
||||
raise InvalidMessageError()
|
||||
return self._message.timestamp()
|
||||
|
||||
|
||||
class InvalidMessagesError(Exception):
|
||||
'''Signals using a messages instance outside of the registered transformation.'''
|
||||
pass
|
||||
|
||||
|
||||
class Messages:
|
||||
'''Represents a list of messages from a stream.'''
|
||||
__slots__ = ('_messages',)
|
||||
|
||||
def __init__(self, messages):
|
||||
if not isinstance(messages, _mgp.Messages):
|
||||
raise TypeError(
|
||||
"Expected '_mgp.Messages', got '{}'".format(type(messages)))
|
||||
self._messages = messages
|
||||
|
||||
def __deepcopy__(self, memo):
|
||||
# This is the same as the shallow copy, because we want to share the
|
||||
# underlying C struct. Besides, it doesn't make much sense to actually
|
||||
# copy _mgp.Messages as that always references all the messages.
|
||||
return Messages(self._messages)
|
||||
|
||||
def is_valid(self) -> bool:
|
||||
'''Return True if `self` is in valid context and may be used.'''
|
||||
return self._messages.is_valid()
|
||||
|
||||
def message_at(self, id: int) -> Message:
|
||||
'''Raise InvalidMessagesError if context is invalid.'''
|
||||
if not self.is_valid():
|
||||
raise InvalidMessagesError()
|
||||
return Message(self._messages.message_at(id))
|
||||
|
||||
def total_messages(self) -> int:
|
||||
'''Raise InvalidContextError if context is invalid.'''
|
||||
if not self.is_valid():
|
||||
raise InvalidMessagesError()
|
||||
return self._messages.total_messages()
|
||||
|
||||
|
||||
class TransCtx:
|
||||
'''Context of a transformation being executed.
|
||||
|
||||
Access to a TransCtx is only valid during a single execution of a transformation.
|
||||
You should not globally store a TransCtx instance.
|
||||
'''
|
||||
__slots__ = ('_graph')
|
||||
|
||||
def __init__(self, graph):
|
||||
if not isinstance(graph, _mgp.Graph):
|
||||
raise TypeError(
|
||||
"Expected '_mgp.Graph', got '{}'".format(type(graph)))
|
||||
self._graph = Graph(graph)
|
||||
|
||||
def is_valid(self) -> bool:
|
||||
return self._graph.is_valid()
|
||||
|
||||
@property
|
||||
def graph(self) -> Graph:
|
||||
'''Raise InvalidContextError if context is invalid.'''
|
||||
if not self.is_valid():
|
||||
raise InvalidContextError()
|
||||
return self._graph
|
||||
|
||||
|
||||
def transformation(func: typing.Callable[..., Record]):
|
||||
raise_if_does_not_meet_requirements(func)
|
||||
sig = inspect.signature(func)
|
||||
params = tuple(sig.parameters.values())
|
||||
if not params or not params[0].annotation is Messages:
|
||||
if not len(params) == 2 or not params[1].annotation is Messages:
|
||||
raise NotImplementedError(
|
||||
"Valid signatures for transformations are (TransCtx, Messages) or (Messages)")
|
||||
if params[0].annotation is TransCtx:
|
||||
@functools.wraps(func)
|
||||
def wrapper(graph, messages):
|
||||
return func(TransCtx(graph), messages)
|
||||
_mgp._MODULE.add_transformation(wrapper)
|
||||
else:
|
||||
@functools.wraps(func)
|
||||
def wrapper(graph, messages):
|
||||
return func(messages)
|
||||
_mgp._MODULE.add_transformation(wrapper)
|
||||
return func
|
||||
112
init
112
init
@@ -1,112 +0,0 @@
|
||||
#!/bin/bash -e
|
||||
|
||||
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
||||
cd "$DIR"
|
||||
|
||||
source "$DIR/environment/util.sh"
|
||||
|
||||
function print_help () {
|
||||
echo "Usage: $0 [OPTION]"
|
||||
echo -e "Check for missing packages and setup the project.\n"
|
||||
echo "Optional arguments:"
|
||||
echo -e " -h\tdisplay this help and exit"
|
||||
}
|
||||
|
||||
function setup_virtualenv () {
|
||||
pushd $1 > /dev/null
|
||||
echo "Setting up virtualenv for: $1"
|
||||
|
||||
# remove old virtualenv
|
||||
if [ -d ve3 ]; then
|
||||
rm -rf ve3
|
||||
fi
|
||||
|
||||
# create new virtualenv
|
||||
virtualenv -p python3 ve3 || exit 1
|
||||
source ve3/bin/activate
|
||||
pip --timeout 1000 install -r requirements.txt || exit 1
|
||||
deactivate
|
||||
|
||||
popd > /dev/null
|
||||
}
|
||||
|
||||
if [[ $# -gt 1 ]]; then
|
||||
print_help
|
||||
exit 1
|
||||
elif [[ $# -eq 1 ]]; then
|
||||
case "$1" in
|
||||
-h)
|
||||
print_help
|
||||
exit 0
|
||||
;;
|
||||
*)
|
||||
# unknown option
|
||||
print_help
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
|
||||
DISTRO=$(operating_system)
|
||||
echo "ALL BUILD PACKAGES: $($DIR/environment/os/$DISTRO.sh list MEMGRAPH_BUILD_DEPS)"
|
||||
$DIR/environment/os/$DISTRO.sh check MEMGRAPH_BUILD_DEPS
|
||||
echo "All packages are in-place..."
|
||||
|
||||
# create a default build directory
|
||||
mkdir -p ./build
|
||||
|
||||
# quicklisp package manager for Common Lisp
|
||||
quicklisp_install_dir="$HOME/quicklisp"
|
||||
if [[ -v QUICKLISP_HOME ]]; then
|
||||
quicklisp_install_dir="${QUICKLISP_HOME}"
|
||||
fi
|
||||
|
||||
if [[ ! -f "${quicklisp_install_dir}/setup.lisp" ]]; then
|
||||
wget -nv https://beta.quicklisp.org/quicklisp.lisp -O quicklisp.lisp || exit 1
|
||||
echo \
|
||||
"
|
||||
(load \"${DIR}/quicklisp.lisp\")
|
||||
(quicklisp-quickstart:install :path \"${quicklisp_install_dir}\")
|
||||
" | sbcl --script || exit 1
|
||||
rm -rf quicklisp.lisp || exit 1
|
||||
fi
|
||||
ln -Tfs "$DIR/src/lisp" "${quicklisp_install_dir}/local-projects/lcp"
|
||||
# Install LCP dependencies
|
||||
# TODO: We should at some point cache or have a mirror of packages we use.
|
||||
# TODO: move the installation of LCP's dependencies into ./setup.sh
|
||||
echo \
|
||||
"
|
||||
(load \"${quicklisp_install_dir}/setup.lisp\")
|
||||
(ql:quickload '(:lcp :lcp/test) :silent t)
|
||||
" | sbcl --script
|
||||
|
||||
# Setup libs (download).
|
||||
cd libs
|
||||
./cleanup.sh
|
||||
./setup.sh
|
||||
cd ..
|
||||
|
||||
# setup gql_behave dependencies
|
||||
setup_virtualenv tests/gql_behave
|
||||
|
||||
# setup stress dependencies
|
||||
setup_virtualenv tests/stress
|
||||
|
||||
# setup integration/ldap dependencies
|
||||
setup_virtualenv tests/integration/ldap
|
||||
|
||||
# Setup tests dependencies.
|
||||
# cd tests
|
||||
# ./setup.sh
|
||||
# cd ..
|
||||
# TODO(gitbuda): Remove setup_virtualenv, replace it with tests/ve3. Take care
|
||||
# of the build order because tests/setup.py builds pymgclient which depends on
|
||||
# mgclient which is build after this script by calling make.
|
||||
|
||||
echo "Done installing dependencies for Memgraph"
|
||||
|
||||
echo "Linking git hooks"
|
||||
for hook in $(find $DIR/.githooks -type f -printf "%f\n"); do
|
||||
ln -s -f "$DIR/.githooks/$hook" "$DIR/.git/hooks/$hook"
|
||||
echo "Added $hook hook"
|
||||
done;
|
||||
7
libs/.gitignore
vendored
7
libs/.gitignore
vendored
@@ -1,7 +0,0 @@
|
||||
*
|
||||
!.gitignore
|
||||
!setup.sh
|
||||
!cleanup.sh
|
||||
!CMakeLists.txt
|
||||
!__main.cpp
|
||||
!jemalloc.cmake
|
||||
@@ -1,243 +0,0 @@
|
||||
include(ExternalProject)
|
||||
|
||||
include(GNUInstallDirs)
|
||||
|
||||
include(ProcessorCount)
|
||||
ProcessorCount(NPROC)
|
||||
if (NPROC EQUAL 0)
|
||||
set(NPROC 1)
|
||||
endif()
|
||||
|
||||
set(LIB_DIR ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
|
||||
# convenience functions
|
||||
function(import_header_library name include_dir)
|
||||
add_library(${name} INTERFACE IMPORTED GLOBAL)
|
||||
set_property(TARGET ${name} PROPERTY
|
||||
INTERFACE_INCLUDE_DIRECTORIES ${include_dir})
|
||||
string(TOUPPER ${name} _upper_name)
|
||||
set(${_upper_name}_INCLUDE_DIR ${include_dir} CACHE FILEPATH
|
||||
"Path to ${name} include directory" FORCE)
|
||||
mark_as_advanced(${_upper_name}_INCLUDE_DIR)
|
||||
endfunction(import_header_library)
|
||||
|
||||
function(import_library name type location include_dir)
|
||||
add_library(${name} ${type} IMPORTED GLOBAL)
|
||||
if (${ARGN})
|
||||
# Optional argument is the name of the external project that we need to
|
||||
# depend on.
|
||||
add_dependencies(${name} ${ARGN0})
|
||||
else()
|
||||
add_dependencies(${name} ${name}-proj)
|
||||
endif()
|
||||
set_property(TARGET ${name} PROPERTY IMPORTED_LOCATION ${location})
|
||||
# We need to create the include directory first in order to be able to add it
|
||||
# as an include directory. The header files in the include directory will be
|
||||
# generated later during the build process.
|
||||
file(MAKE_DIRECTORY ${include_dir})
|
||||
target_include_directories(${name} INTERFACE ${include_dir})
|
||||
endfunction(import_library)
|
||||
|
||||
# Calls `ExternalProject_Add(${name}-proj` with default arguments for cmake
|
||||
# configuration. CMAKE_BUILD_TYPE is set to Release, CMAKE_C_COMPILER and
|
||||
# CMAKE_CXX_COMPILER are forwarded as used in this project. You can pass
|
||||
# NO_C_COMPILER option to avoid forwarding CMAKE_C_COMPILER. Installation is
|
||||
# done in SOURCE_DIR, which defaults to ${CMAKE_CURRENT_SOURCE_DIR}/${name}.
|
||||
# You can pass additional arguments via CMAKE_ARGS. Dependencies and
|
||||
# installation can be set as in regular ExternalProject_Add, via DEPENDS and
|
||||
# INSTALL_COMMAND arguments.
|
||||
function(add_external_project name)
|
||||
set(options NO_C_COMPILER)
|
||||
set(one_value_kwargs SOURCE_DIR)
|
||||
set(multi_value_kwargs CMAKE_ARGS DEPENDS INSTALL_COMMAND BUILD_COMMAND
|
||||
CONFIGURE_COMMAND)
|
||||
cmake_parse_arguments(KW "${options}" "${one_value_kwargs}" "${multi_value_kwargs}" ${ARGN})
|
||||
set(source_dir ${CMAKE_CURRENT_SOURCE_DIR}/${name})
|
||||
if (KW_SOURCE_DIR)
|
||||
set(source_dir ${KW_SOURCE_DIR})
|
||||
endif()
|
||||
if (NOT KW_NO_C_COMPILER)
|
||||
set(KW_CMAKE_ARGS -DCMAKE_C_COMPILER=${CMAKE_C_COMPILER} ${KW_CMAKE_ARGS})
|
||||
endif()
|
||||
ExternalProject_Add(${name}-proj DEPENDS ${KW_DEPENDS}
|
||||
PREFIX ${source_dir} SOURCE_DIR ${source_dir}
|
||||
CONFIGURE_COMMAND ${KW_CONFIGURE_COMMAND}
|
||||
CMAKE_ARGS -DCMAKE_BUILD_TYPE=Release
|
||||
-DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}
|
||||
-DCMAKE_INSTALL_PREFIX=${source_dir}
|
||||
${KW_CMAKE_ARGS}
|
||||
INSTALL_COMMAND ${KW_INSTALL_COMMAND}
|
||||
BUILD_COMMAND ${KW_BUILD_COMMAND})
|
||||
endfunction(add_external_project)
|
||||
|
||||
# Calls `add_external_project`, sets NAME_LIBRARY, NAME_INCLUDE_DIR variables
|
||||
# and adds the library via `import_library`.
|
||||
macro(import_external_library name type library_location include_dir)
|
||||
add_external_project(${name} ${ARGN})
|
||||
string(TOUPPER ${name} _upper_name)
|
||||
set(${_upper_name}_LIBRARY ${library_location} CACHE FILEPATH
|
||||
"Path to ${name} library" FORCE)
|
||||
set(${_upper_name}_INCLUDE_DIR ${include_dir} CACHE FILEPATH
|
||||
"Path to ${name} include directory" FORCE)
|
||||
mark_as_advanced(${_upper_name}_LIBRARY ${_upper_name}_INCLUDE_DIR)
|
||||
import_library(${name} ${type} ${${_upper_name}_LIBRARY} ${${_upper_name}_INCLUDE_DIR})
|
||||
endmacro(import_external_library)
|
||||
|
||||
# setup antlr
|
||||
import_external_library(antlr4 STATIC
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/antlr4/runtime/Cpp/lib/libantlr4-runtime.a
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/antlr4/runtime/Cpp/include/antlr4-runtime
|
||||
SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/antlr4/runtime/Cpp
|
||||
CMAKE_ARGS # http://stackoverflow.com/questions/37096062/get-a-basic-c-program-to-compile-using-clang-on-ubuntu-16/38385967#38385967
|
||||
-DWITH_LIBCXX=OFF # because of debian bug
|
||||
-DCMAKE_SKIP_INSTALL_ALL_DEPENDENCY=true
|
||||
-DCMAKE_CXX_STANDARD=20
|
||||
BUILD_COMMAND $(MAKE) antlr4_static
|
||||
INSTALL_COMMAND $(MAKE) install)
|
||||
|
||||
# Setup google benchmark.
|
||||
import_external_library(benchmark STATIC
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/benchmark/lib/libbenchmark.a
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/benchmark/include
|
||||
# Skip testing. The tests don't compile with Clang 8.
|
||||
CMAKE_ARGS -DBENCHMARK_ENABLE_TESTING=OFF)
|
||||
|
||||
# setup fmt format
|
||||
import_external_library(fmt STATIC
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/fmt/${CMAKE_INSTALL_LIBDIR}/libfmt.a
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/fmt/include
|
||||
# Skip testing.
|
||||
CMAKE_ARGS -DFMT_TEST=OFF)
|
||||
|
||||
# setup rapidcheck (it cannot be external, since it doesn't have install
|
||||
# target)
|
||||
set(RC_ENABLE_GTEST ON CACHE BOOL "Build Google Test integration" FORCE)
|
||||
set(RC_ENABLE_GMOCK ON CACHE BOOL "Build Google Mock integration" FORCE)
|
||||
mark_as_advanced(RC_ENABLE_GTEST RC_ENABLE_GMOCK)
|
||||
add_subdirectory(rapidcheck EXCLUDE_FROM_ALL)
|
||||
|
||||
# setup google test
|
||||
add_external_project(gtest SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/googletest)
|
||||
set(GTEST_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/googletest/include
|
||||
CACHE PATH "Path to gtest and gmock include directory" FORCE)
|
||||
set(GMOCK_LIBRARY ${CMAKE_CURRENT_SOURCE_DIR}/googletest/lib/libgmock.a
|
||||
CACHE FILEPATH "Path to gmock library" FORCE)
|
||||
set(GMOCK_MAIN_LIBRARY ${CMAKE_CURRENT_SOURCE_DIR}/googletest/lib/libgmock_main.a
|
||||
CACHE FILEPATH "Path to gmock_main library" FORCE)
|
||||
set(GTEST_LIBRARY ${CMAKE_CURRENT_SOURCE_DIR}/googletest/lib/libgtest.a
|
||||
CACHE FILEPATH "Path to gtest library" FORCE)
|
||||
set(GTEST_MAIN_LIBRARY ${CMAKE_CURRENT_SOURCE_DIR}/googletest/lib/libgtest_main.a
|
||||
CACHE FILEPATH "Path to gtest_main library" FORCE)
|
||||
mark_as_advanced(GTEST_INCLUDE_DIR GMOCK_LIBRARY GMOCK_MAIN_LIBRARY GTEST_LIBRARY GTEST_MAIN_LIBRARY)
|
||||
import_library(gtest STATIC ${GTEST_LIBRARY} ${GTEST_INCLUDE_DIR} gtest-proj)
|
||||
import_library(gtest_main STATIC ${GTEST_MAIN_LIBRARY} ${GTEST_INCLUDE_DIR} gtest-proj)
|
||||
import_library(gmock STATIC ${GMOCK_LIBRARY} ${GTEST_INCLUDE_DIR} gtest-proj)
|
||||
import_library(gmock_main STATIC ${GMOCK_MAIN_LIBRARY} ${GTEST_INCLUDE_DIR} gtest-proj)
|
||||
|
||||
# setup google flags
|
||||
set(GFLAGS_NO_FILENAMES "0")
|
||||
if ("${CMAKE_BUILD_TYPE}" MATCHES "^(R|r)(E|e)(L|l).+")
|
||||
set(GFLAGS_NO_FILENAMES "1")
|
||||
endif()
|
||||
|
||||
# setup google flags
|
||||
import_external_library(gflags STATIC
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/gflags/lib/libgflags.a
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/gflags/include
|
||||
# Not needed, since gflags is C++ only.
|
||||
NO_C_COMPILER
|
||||
# Don't register installation in ~/.cmake
|
||||
CMAKE_ARGS -DREGISTER_INSTALL_PREFIX=OFF
|
||||
-DBUILD_gflags_nothreads_LIB=OFF
|
||||
-DGFLAGS_NO_FILENAMES=${GFLAGS_NO_FILENAMES})
|
||||
|
||||
# Setup cppitertools
|
||||
import_header_library(cppitertools ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
|
||||
# Setup json
|
||||
import_header_library(json ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
|
||||
# Setup bzip2
|
||||
import_external_library(bzip2 STATIC
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/bzip2/libbz2.a
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/bzip2
|
||||
# bzip2's Makefile has -g CFLAG which is redundant
|
||||
CONFIGURE_COMMAND sed -i "s/-Wall -Winline -O2 -g/-Wall -Winline -O2/g" ${CMAKE_CURRENT_SOURCE_DIR}/bzip2/Makefile
|
||||
BUILD_COMMAND make -C ${CMAKE_CURRENT_SOURCE_DIR}/bzip2
|
||||
CC=${CMAKE_C_COMPILER}
|
||||
CXX=${CMAKE_CXX_COMPILER}
|
||||
INSTALL_COMMAND true)
|
||||
|
||||
# Setup zlib
|
||||
import_external_library(zlib STATIC
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/zlib/lib/libz.a
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/zlib
|
||||
CMAKE_ARGS -DCMAKE_SKIP_INSTALL_ALL_DEPENDENCY=true
|
||||
BUILD_COMMAND $(MAKE) zlibstatic)
|
||||
|
||||
# Setup RocksDB
|
||||
import_external_library(rocksdb STATIC
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/rocksdb/lib/librocksdb.a
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/rocksdb/include
|
||||
DEPENDS gflags-proj
|
||||
CMAKE_ARGS -Dgflags_DIR=${CMAKE_CURRENT_SOURCE_DIR}/gflags/lib/cmake/gflags
|
||||
-DUSE_RTTI=ON
|
||||
-DWITH_TESTS=OFF
|
||||
-DCMAKE_INSTALL_LIBDIR=lib
|
||||
-DCMAKE_SKIP_INSTALL_ALL_DEPENDENCY=true
|
||||
BUILD_COMMAND $(MAKE) rocksdb)
|
||||
|
||||
# Setup libbcrypt
|
||||
import_external_library(libbcrypt STATIC
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/libbcrypt/bcrypt.a
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/libbcrypt
|
||||
CONFIGURE_COMMAND sed s/-Wcast-align// -i ${CMAKE_CURRENT_SOURCE_DIR}/libbcrypt/crypt_blowfish/Makefile
|
||||
BUILD_COMMAND make -C ${CMAKE_CURRENT_SOURCE_DIR}/libbcrypt
|
||||
CC=${CMAKE_C_COMPILER}
|
||||
CXX=${CMAKE_CXX_COMPILER}
|
||||
INSTALL_COMMAND true)
|
||||
|
||||
# Setup mgclient
|
||||
import_external_library(mgclient STATIC
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/mgclient/lib/libmgclient.a
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/mgclient/include
|
||||
CMAKE_ARGS -DCMAKE_C_COMPILER=${CMAKE_C_COMPILER}
|
||||
-DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}
|
||||
-DBUILD_TESTING=OFF)
|
||||
find_package(OpenSSL REQUIRED)
|
||||
target_link_libraries(mgclient INTERFACE ${OPENSSL_LIBRARIES})
|
||||
|
||||
add_external_project(mgconsole
|
||||
SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/mgconsole
|
||||
CMAKE_ARGS
|
||||
-DCMAKE_INSTALL_PREFIX:PATH=${CMAKE_BINARY_DIR}
|
||||
BUILD_COMMAND $(MAKE) mgconsole)
|
||||
|
||||
add_custom_target(mgconsole DEPENDS mgconsole-proj)
|
||||
|
||||
# Setup spdlog
|
||||
import_external_library(spdlog STATIC
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/spdlog/${CMAKE_INSTALL_LIBDIR}/libspdlog.a
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/spdlog/include
|
||||
BUILD_COMMAND $(MAKE) spdlog)
|
||||
|
||||
include(jemalloc.cmake)
|
||||
|
||||
# Setup librdkafka.
|
||||
import_external_library(librdkafka STATIC
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/librdkafka/lib/librdkafka.a
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/librdkafka/include
|
||||
CMAKE_ARGS -DRDKAFKA_BUILD_STATIC=ON
|
||||
-DRDKAFKA_BUILD_EXAMPLES=OFF
|
||||
-DRDKAFKA_BUILD_TESTS=OFF
|
||||
-DCMAKE_INSTALL_LIBDIR=lib
|
||||
-DWITH_SSL=ON
|
||||
# If we want SASL, we need to install it on build machines
|
||||
-DWITH_SASL=OFF)
|
||||
target_link_libraries(librdkafka INTERFACE ${OPENSSL_LIBRARIES} zlib)
|
||||
|
||||
import_library(librdkafka++ STATIC
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/librdkafka/lib/librdkafka++.a
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/librdkafka/include
|
||||
)
|
||||
target_link_libraries(librdkafka++ INTERFACE librdkafka)
|
||||
@@ -1,15 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# go to script directory
|
||||
working_dir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
||||
cd ${working_dir}
|
||||
|
||||
# remove archives
|
||||
rm *.jar *.tar.gz *.tar 2>/dev/null
|
||||
|
||||
# remove lib directories
|
||||
for folder in * ; do
|
||||
if [ -d "$folder" ]; then
|
||||
rm -rf $folder
|
||||
fi
|
||||
done
|
||||
@@ -1,55 +0,0 @@
|
||||
set(JEMALLOC_DIR "${LIB_DIR}/jemalloc")
|
||||
|
||||
set(JEMALLOC_SRCS
|
||||
${JEMALLOC_DIR}/src/arena.c
|
||||
${JEMALLOC_DIR}/src/background_thread.c
|
||||
${JEMALLOC_DIR}/src/base.c
|
||||
${JEMALLOC_DIR}/src/bin.c
|
||||
${JEMALLOC_DIR}/src/bitmap.c
|
||||
${JEMALLOC_DIR}/src/ckh.c
|
||||
${JEMALLOC_DIR}/src/ctl.c
|
||||
${JEMALLOC_DIR}/src/div.c
|
||||
${JEMALLOC_DIR}/src/extent.c
|
||||
${JEMALLOC_DIR}/src/extent_dss.c
|
||||
${JEMALLOC_DIR}/src/extent_mmap.c
|
||||
${JEMALLOC_DIR}/src/hash.c
|
||||
${JEMALLOC_DIR}/src/hook.c
|
||||
${JEMALLOC_DIR}/src/jemalloc.c
|
||||
${JEMALLOC_DIR}/src/large.c
|
||||
${JEMALLOC_DIR}/src/log.c
|
||||
${JEMALLOC_DIR}/src/malloc_io.c
|
||||
${JEMALLOC_DIR}/src/mutex.c
|
||||
${JEMALLOC_DIR}/src/mutex_pool.c
|
||||
${JEMALLOC_DIR}/src/nstime.c
|
||||
${JEMALLOC_DIR}/src/pages.c
|
||||
${JEMALLOC_DIR}/src/prng.c
|
||||
${JEMALLOC_DIR}/src/prof.c
|
||||
${JEMALLOC_DIR}/src/rtree.c
|
||||
${JEMALLOC_DIR}/src/sc.c
|
||||
${JEMALLOC_DIR}/src/stats.c
|
||||
${JEMALLOC_DIR}/src/sz.c
|
||||
${JEMALLOC_DIR}/src/tcache.c
|
||||
${JEMALLOC_DIR}/src/test_hooks.c
|
||||
${JEMALLOC_DIR}/src/ticker.c
|
||||
${JEMALLOC_DIR}/src/tsd.c
|
||||
${JEMALLOC_DIR}/src/witness.c
|
||||
${JEMALLOC_DIR}/src/safety_check.c
|
||||
)
|
||||
|
||||
add_library(jemalloc ${JEMALLOC_SRCS})
|
||||
target_include_directories(jemalloc PUBLIC "${JEMALLOC_DIR}/include")
|
||||
|
||||
find_package(Threads REQUIRED)
|
||||
target_link_libraries(jemalloc PUBLIC Threads::Threads)
|
||||
|
||||
target_compile_definitions(jemalloc PRIVATE -DJEMALLOC_NO_PRIVATE_NAMESPACE)
|
||||
|
||||
if (CMAKE_BUILD_TYPE STREQUAL "DEBUG")
|
||||
target_compile_definitions(jemalloc PRIVATE -DJEMALLOC_DEBUG=1 -DJEMALLOC_PROF=1)
|
||||
endif()
|
||||
|
||||
target_compile_options(jemalloc PRIVATE -Wno-redundant-decls)
|
||||
# for RTLD_NEXT
|
||||
target_compile_definitions(jemalloc PRIVATE _GNU_SOURCE)
|
||||
|
||||
set_property(TARGET jemalloc APPEND PROPERTY INTERFACE_COMPILE_DEFINITIONS USE_JEMALLOC=1)
|
||||
251
libs/setup.sh
251
libs/setup.sh
@@ -1,251 +0,0 @@
|
||||
#!/bin/bash -e
|
||||
|
||||
# Download external dependencies.
|
||||
# Don't forget to add/update the license in release/third-party-licenses of added/updated libs!
|
||||
|
||||
local_cache_host=${MGDEPS_CACHE_HOST_PORT:-mgdeps-cache:8000}
|
||||
working_dir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
||||
cd "${working_dir}"
|
||||
|
||||
# Clones a git repository and optionally cherry picks additional commits. The
|
||||
# function will try to preserve any local changes in the repo.
|
||||
# clone GIT_REPO DIR_NAME CHECKOUT_ID [CHERRY_PICK_ID]...
|
||||
clone () {
|
||||
local git_repo=$1
|
||||
local dir_name=$2
|
||||
local checkout_id=$3
|
||||
shift 3
|
||||
# Clone if there's no repo.
|
||||
if [[ ! -d "$dir_name" ]]; then
|
||||
echo "Cloning from $git_repo"
|
||||
# If the clone fails, it doesn't make sense to continue with the function
|
||||
# execution but the whole script should continue executing because we might
|
||||
# clone the same repo from a different source.
|
||||
git clone "$git_repo" "$dir_name" || return 1
|
||||
fi
|
||||
pushd "$dir_name"
|
||||
# Just fetch new commits from remote repository. Don't merge/pull them in, so
|
||||
# that we don't clobber local modifications.
|
||||
git fetch
|
||||
# Check whether we have any local changes which need to be preserved.
|
||||
local local_changes=true
|
||||
if git diff --no-ext-diff --quiet && git diff --no-ext-diff --cached --quiet; then
|
||||
local_changes=false
|
||||
fi
|
||||
# Stash regardless of local_changes, so that a user gets a message on stdout.
|
||||
git stash
|
||||
# Checkout the primary commit (there's no need to pull/merge).
|
||||
# The checkout fail should exit this script immediately because the target
|
||||
# commit is not there and that will most likely create build-time errors.
|
||||
git checkout "$checkout_id" || exit 1
|
||||
# Apply any optional cherry pick fixes.
|
||||
while [[ $# -ne 0 ]]; do
|
||||
local cherry_pick_id=$1
|
||||
shift
|
||||
# The cherry-pick fail should exit this script immediately because the
|
||||
# target commit is not there and that will most likely create build-time
|
||||
# errors.
|
||||
git cherry-pick -n "$cherry_pick_id" || exit 1
|
||||
done
|
||||
# Reapply any local changes.
|
||||
if [[ $local_changes == true ]]; then
|
||||
git stash pop
|
||||
fi
|
||||
popd
|
||||
}
|
||||
|
||||
file_get_try_double () {
|
||||
primary_url="$1"
|
||||
secondary_url="$2"
|
||||
echo "Download primary from $primary_url secondary from $secondary_url"
|
||||
if [ -z "$primary_url" ]; then echo "Primary should not be empty." && exit 1; fi
|
||||
if [ -z "$secondary_url" ]; then echo "Secondary should not be empty." && exit 1; fi
|
||||
filename="$(basename "$secondary_url")"
|
||||
wget -nv "$primary_url" -O "$filename" || wget -nv "$secondary_url" -O "$filename" || exit 1
|
||||
echo ""
|
||||
}
|
||||
|
||||
repo_clone_try_double () {
|
||||
primary_url="$1"
|
||||
secondary_url="$2"
|
||||
folder_name="$3"
|
||||
ref="$4"
|
||||
echo "Cloning primary from $primary_url secondary from $secondary_url"
|
||||
if [ -z "$primary_url" ]; then echo "Primary should not be empty." && exit 1; fi
|
||||
if [ -z "$secondary_url" ]; then echo "Secondary should not be empty." && exit 1; fi
|
||||
if [ -z "$folder_name" ]; then echo "Clone folder should not be empty." && exit 1; fi
|
||||
if [ -z "$ref" ]; then echo "Git clone ref should not be empty." && exit 1; fi
|
||||
clone "$primary_url" "$folder_name" "$ref" || clone "$secondary_url" "$folder_name" "$ref" || exit 1
|
||||
echo ""
|
||||
}
|
||||
|
||||
# List all dependencies.
|
||||
|
||||
# The reason for introducing primary and secondary urls are:
|
||||
# * HTTPS is hard to cache
|
||||
# * Remote development workflow is more flexible if people don't have to connect to VPN
|
||||
# * Direct download from the "source of truth" is slower and unreliable because of the whole internet in-between
|
||||
# * When a new dependency has to be added, both urls could be the same, later someone could optimize if required
|
||||
|
||||
# The goal of having primary urls is to have links to the "local" cache of
|
||||
# dependencies where these dependencies could be downloaded as fast as
|
||||
# possible. The actual cache server could be on your local machine, on a
|
||||
# dedicated machine inside the build cluster or on the actual build machine.
|
||||
# Download from primary_urls might fail because the cache is not installed.
|
||||
declare -A primary_urls=(
|
||||
["antlr4-code"]="http://$local_cache_host/git/antlr4.git"
|
||||
["antlr4-generator"]="http://$local_cache_host/file/antlr-4.9.2-complete.jar"
|
||||
["cppitertools"]="http://$local_cache_host/git/cppitertools.git"
|
||||
["fmt"]="http://$local_cache_host/git/fmt.git"
|
||||
["rapidcheck"]="http://$local_cache_host/git/rapidcheck.git"
|
||||
["gbenchmark"]="http://$local_cache_host/git/benchmark.git"
|
||||
["gtest"]="http://$local_cache_host/git/googletest.git"
|
||||
["gflags"]="http://$local_cache_host/git/gflags.git"
|
||||
["libbcrypt"]="http://$local_cache_host/git/libbcrypt.git"
|
||||
["bzip2"]="http://$local_cache_host/git/bzip2.git"
|
||||
["zlib"]="http://$local_cache_host/git/zlib.git"
|
||||
["rocksdb"]="http://$local_cache_host/git/rocksdb.git"
|
||||
["mgclient"]="http://$local_cache_host/git/mgclient.git"
|
||||
["pymgclient"]="http://$local_cache_host/git/pymgclient.git"
|
||||
["mgconsole"]="http://$local_cache_host/git/mgconsole.git"
|
||||
["spdlog"]="http://$local_cache_host/git/spdlog"
|
||||
["jemalloc"]="http://$local_cache_host/git/jemalloc.git"
|
||||
["nlohmann"]="http://$local_cache_host/file/nlohmann/json/b3e5cb7f20dcc5c806e418df34324eca60d17d4e/single_include/nlohmann/json.hpp"
|
||||
["neo4j"]="http://$local_cache_host/file/neo4j-community-3.2.3-unix.tar.gz"
|
||||
["librdkafka"]="http://$local_cache_host/git/librdkafka.git"
|
||||
)
|
||||
|
||||
# The goal of secondary urls is to have links to the "source of truth" of
|
||||
# dependencies, e.g., Github or S3. Download from secondary urls, if happens
|
||||
# at all, should never fail. In other words, if it fails, the whole build
|
||||
# should fail.
|
||||
declare -A secondary_urls=(
|
||||
["antlr4-code"]="https://github.com/antlr/antlr4.git"
|
||||
["antlr4-generator"]="http://www.antlr.org/download/antlr-4.9.2-complete.jar"
|
||||
["cppitertools"]="https://github.com/ryanhaining/cppitertools.git"
|
||||
["fmt"]="https://github.com/fmtlib/fmt.git"
|
||||
["rapidcheck"]="https://github.com/emil-e/rapidcheck.git"
|
||||
["gbenchmark"]="https://github.com/google/benchmark.git"
|
||||
["gtest"]="https://github.com/google/googletest.git"
|
||||
["gflags"]="https://github.com/memgraph/gflags.git"
|
||||
["libbcrypt"]="https://github.com/rg3/libbcrypt"
|
||||
["bzip2"]="https://github.com/VFR-maniac/bzip2"
|
||||
["zlib"]="https://github.com/madler/zlib.git"
|
||||
["rocksdb"]="https://github.com/facebook/rocksdb.git"
|
||||
["mgclient"]="https://github.com/memgraph/mgclient.git"
|
||||
["pymgclient"]="https://github.com/memgraph/pymgclient.git"
|
||||
["mgconsole"]="http://github.com/memgraph/mgconsole.git"
|
||||
["spdlog"]="https://github.com/gabime/spdlog"
|
||||
["jemalloc"]="https://github.com/jemalloc/jemalloc.git"
|
||||
["nlohmann"]="https://raw.githubusercontent.com/nlohmann/json/b3e5cb7f20dcc5c806e418df34324eca60d17d4e/single_include/nlohmann/json.hpp"
|
||||
["neo4j"]="https://s3-eu-west-1.amazonaws.com/deps.memgraph.io/neo4j-community-3.2.3-unix.tar.gz"
|
||||
["librdkafka"]="https://github.com/edenhill/librdkafka.git"
|
||||
)
|
||||
|
||||
# antlr
|
||||
file_get_try_double "${primary_urls[antlr4-generator]}" "${secondary_urls[antlr4-generator]}"
|
||||
|
||||
antlr4_tag="5e5b6d35b4183fd330102c40947b95c4b5c6abb5" # v4.9.2
|
||||
repo_clone_try_double "${primary_urls[antlr4-code]}" "${secondary_urls[antlr4-code]}" "antlr4" "$antlr4_tag"
|
||||
# remove shared library from install dependencies
|
||||
sed -i 's/install(TARGETS antlr4_shared/install(TARGETS antlr4_shared OPTIONAL/' antlr4/runtime/Cpp/runtime/CMakeLists.txt
|
||||
# fix issue https://github.com/antlr/antlr4/issues/3194 - should update Antlr commit once the PR related to the issue gets merged
|
||||
sed -i 's/std::is_nothrow_copy_constructible/std::is_copy_constructible/' antlr4/runtime/Cpp/runtime/src/support/Any.h
|
||||
# replace the utf8cpp version which is used because the older one uses gtest that doesn't
|
||||
# compile with the newer compilers because of uninitialized variable
|
||||
# the newer utf8cpp switched to ftest
|
||||
sed -i 's/v3.1.1/v3.2.1/' antlr4/runtime/Cpp/runtime/CMakeLists.txt
|
||||
|
||||
# cppitertools v2.0 2019-12-23
|
||||
cppitertools_ref="cb3635456bdb531121b82b4d2e3afc7ae1f56d47"
|
||||
repo_clone_try_double "${primary_urls[cppitertools]}" "${secondary_urls[cppitertools]}" "cppitertools" "$cppitertools_ref"
|
||||
|
||||
# fmt
|
||||
fmt_tag="7bdf0628b1276379886c7f6dda2cef2b3b374f0b" # (2020-11-25)
|
||||
repo_clone_try_double "${primary_urls[fmt]}" "${secondary_urls[fmt]}" "fmt" "$fmt_tag"
|
||||
|
||||
# rapidcheck
|
||||
rapidcheck_tag="7bc7d302191a4f3d0bf005692677126136e02f60" # (2020-05-04)
|
||||
repo_clone_try_double "${primary_urls[rapidcheck]}" "${secondary_urls[rapidcheck]}" "rapidcheck" "$rapidcheck_tag"
|
||||
|
||||
# google benchmark
|
||||
benchmark_tag="4f8bfeae470950ef005327973f15b0044eceaceb" # v1.1.0
|
||||
repo_clone_try_double "${primary_urls[gbenchmark]}" "${secondary_urls[gbenchmark]}" "benchmark" "$benchmark_tag"
|
||||
|
||||
# google test
|
||||
googletest_tag="ec44c6c1675c25b9827aacd08c02433cccde7780" # v1.8.0
|
||||
repo_clone_try_double "${primary_urls[gtest]}" "${secondary_urls[gtest]}" "googletest" "$googletest_tag"
|
||||
|
||||
# google flags
|
||||
gflags_tag="b37ceb03a0e56c9f15ce80409438a555f8a67b7c" # custom version (May 6, 2017)
|
||||
repo_clone_try_double "${primary_urls[gflags]}" "${secondary_urls[gflags]}" "gflags" "$gflags_tag"
|
||||
|
||||
# libbcrypt
|
||||
libbcrypt_tag="8aa32ad94ebe06b76853b0767c910c9fbf7ccef4" # custom version (Dec 16, 2016)
|
||||
repo_clone_try_double "${primary_urls[libbcrypt]}" "${secondary_urls[libbcrypt]}" "libbcrypt" "$libbcrypt_tag"
|
||||
|
||||
# neo4j
|
||||
file_get_try_double "${primary_urls[neo4j]}" "${secondary_urls[neo4j]}"
|
||||
tar -xzf neo4j-community-3.2.3-unix.tar.gz
|
||||
mv neo4j-community-3.2.3 neo4j
|
||||
rm neo4j-community-3.2.3-unix.tar.gz
|
||||
|
||||
# nlohmann json
|
||||
# We wget header instead of cloning repo since repo is huge (lots of test data).
|
||||
# We use head on Sep 1, 2017 instead of last release since it was long time ago.
|
||||
mkdir -p json
|
||||
cd json
|
||||
file_get_try_double "${primary_urls[nlohmann]}" "${secondary_urls[nlohmann]}"
|
||||
cd ..
|
||||
|
||||
bzip2_tag="0405487e2b1de738e7f1c8afb50d19cf44e8d580" # v1.0.6 (May 26, 2011)
|
||||
repo_clone_try_double "${primary_urls[bzip2]}" "${secondary_urls[bzip2]}" "bzip2" "$bzip2_tag"
|
||||
|
||||
zlib_tag="cacf7f1d4e3d44d871b605da3b647f07d718623f" # v1.2.11.
|
||||
repo_clone_try_double "${primary_urls[zlib]}" "${secondary_urls[zlib]}" "zlib" "$zlib_tag"
|
||||
# remove shared library from install dependencies
|
||||
sed -i 's/install(TARGETS zlib zlibstatic/install(TARGETS zlibstatic/g' zlib/CMakeLists.txt
|
||||
|
||||
rocksdb_tag="f3e33549c151f30ac4eb7c22356c6d0331f37652" # (2020-10-14)
|
||||
repo_clone_try_double "${primary_urls[rocksdb]}" "${secondary_urls[rocksdb]}" "rocksdb" "$rocksdb_tag"
|
||||
# remove shared library from install dependencies
|
||||
sed -i 's/TARGETS ${ROCKSDB_SHARED_LIB}/TARGETS ${ROCKSDB_SHARED_LIB} OPTIONAL/' rocksdb/CMakeLists.txt
|
||||
|
||||
# mgclient
|
||||
mgclient_tag="v1.2.0" # (2021-01-14)
|
||||
repo_clone_try_double "${primary_urls[mgclient]}" "${secondary_urls[mgclient]}" "mgclient" "$mgclient_tag"
|
||||
sed -i 's/\${CMAKE_INSTALL_LIBDIR}/lib/' mgclient/src/CMakeLists.txt
|
||||
|
||||
# pymgclient
|
||||
pymgclient_tag="4f85c179e56302d46a1e3e2cf43509db65f062b3" # (2021-01-15)
|
||||
repo_clone_try_double "${primary_urls[pymgclient]}" "${secondary_urls[pymgclient]}" "pymgclient" "$pymgclient_tag"
|
||||
|
||||
# mgconsole
|
||||
mgconsole_tag="01ae99bfce772e540e75c076ba03cf06c0c2ac7d" # (2021-05-26)
|
||||
repo_clone_try_double "${primary_urls[mgconsole]}" "${secondary_urls[mgconsole]}" "mgconsole" "$mgconsole_tag"
|
||||
|
||||
spdlog_tag="46d418164dd4cd9822cf8ca62a116a3f71569241" # (2020-12-01)
|
||||
repo_clone_try_double "${primary_urls[spdlog]}" "${secondary_urls[spdlog]}" "spdlog" "$spdlog_tag"
|
||||
|
||||
jemalloc_tag="ea6b3e973b477b8061e0076bb257dbd7f3faa756" # (2021-02-11)
|
||||
repo_clone_try_double "${primary_urls[jemalloc]}" "${secondary_urls[jemalloc]}" "jemalloc" "$jemalloc_tag"
|
||||
pushd jemalloc
|
||||
# ThreadPool select job randomly, and there can be some threads that had been
|
||||
# performed some memory heavy task before and will be inactive for some time,
|
||||
# but until it will became active again, the memory will not be freed since by
|
||||
# default each thread has it's own arena, but there should be not more then
|
||||
# 4*CPU arenas (see opt.nareans description).
|
||||
#
|
||||
# By enabling percpu_arena number of arenas limited to number of CPUs and hence
|
||||
# this problem should go away.
|
||||
#
|
||||
# muzzy_decay_ms -- use MADV_FREE when available on newer Linuxes, to
|
||||
# avoid spurious latencies and additional work associated with
|
||||
# MADV_DONTNEED. See
|
||||
# https://github.com/ClickHouse/ClickHouse/issues/11121 for motivation.
|
||||
./autogen.sh --with-malloc-conf="percpu_arena:percpu,oversize_threshold:0,muzzy_decay_ms:5000,dirty_decay_ms:5000"
|
||||
popd
|
||||
|
||||
# librdkafka
|
||||
librdkafka_tag="v1.7.0" # (2021-05-06)
|
||||
repo_clone_try_double "${primary_urls[librdkafka]}" "${secondary_urls[librdkafka]}" "librdkafka" "$librdkafka_tag"
|
||||
@@ -1,37 +0,0 @@
|
||||
# Memgraph Query Modules CMake configuration
|
||||
# You should use the top level CMake configuration with -DQUERY_MODULES=ON
|
||||
# These modules are meant to be shipped with Memgraph installation.
|
||||
|
||||
project(memgraph_query_modules)
|
||||
|
||||
disallow_in_source_build()
|
||||
|
||||
# Everything that is installed here, should be under the "query_modules" component.
|
||||
set(CMAKE_INSTALL_DEFAULT_COMPONENT_NAME "query_modules")
|
||||
|
||||
add_library(example SHARED example.c)
|
||||
target_include_directories(example PRIVATE ${CMAKE_SOURCE_DIR}/include)
|
||||
target_compile_options(example PRIVATE -Wall)
|
||||
|
||||
# Strip the library in release build.
|
||||
string(TOLOWER ${CMAKE_BUILD_TYPE} lower_build_type)
|
||||
if (lower_build_type STREQUAL "release")
|
||||
add_custom_command(TARGET example POST_BUILD
|
||||
COMMAND strip -s $<TARGET_FILE:example>
|
||||
COMMENT "Stripping symbols and sections from example module")
|
||||
endif()
|
||||
|
||||
install(PROGRAMS $<TARGET_FILE:example>
|
||||
DESTINATION lib/memgraph/query_modules
|
||||
RENAME example.so)
|
||||
# Also install the source of the example, so user can read it.
|
||||
install(FILES example.c DESTINATION lib/memgraph/query_modules/src)
|
||||
|
||||
# Install the Python example
|
||||
install(FILES example.py DESTINATION lib/memgraph/query_modules RENAME py_example.py)
|
||||
|
||||
# Install the Python modules
|
||||
install(FILES graph_analyzer.py DESTINATION lib/memgraph/query_modules)
|
||||
install(FILES mgp_networkx.py DESTINATION lib/memgraph/query_modules)
|
||||
install(FILES nxalg.py DESTINATION lib/memgraph/query_modules)
|
||||
install(FILES wcc.py DESTINATION lib/memgraph/query_modules)
|
||||
@@ -1,123 +0,0 @@
|
||||
// Compile with clang or gcc:
|
||||
// clang -Wall -shared -fPIC -I <path-to-memgraph-include> example.c -o example.so
|
||||
// <path-to-memgraph-include> for installed Memgraph will usually be something
|
||||
// like `/usr/include/memgraph` or `/usr/local/include/memgraph`.
|
||||
// To use the compiled module, you need to run Memgraph configured to load
|
||||
// modules from the directory where the compiled module can be found.
|
||||
#include "mg_procedure.h"
|
||||
|
||||
// This example procedure returns 2 fields: `args` and `result`.
|
||||
// * `args` is a copy of arguments passed to the procedure.
|
||||
// * `result` is the result of this procedure, a "Hello World!" string.
|
||||
// In case of memory errors, this function will report them and finish
|
||||
// executing.
|
||||
//
|
||||
// The procedure can be invoked in openCypher using the following calls:
|
||||
// CALL example.procedure(1, 2) YIELD args, result;
|
||||
// CALL example.procedure(1) YIELD args, result;
|
||||
// Naturally, you may pass in different arguments or yield less fields.
|
||||
static void procedure(const struct mgp_list *args, const struct mgp_graph *graph, struct mgp_result *result,
|
||||
struct mgp_memory *memory) {
|
||||
size_t args_size = 0;
|
||||
if (mgp_list_size(args, &args_size) != MGP_ERROR_NO_ERROR) {
|
||||
goto error_something_went_wrong;
|
||||
}
|
||||
struct mgp_list *args_copy = NULL;
|
||||
if (mgp_list_make_empty(args_size, memory, &args_copy) != MGP_ERROR_NO_ERROR) {
|
||||
goto error_something_went_wrong;
|
||||
}
|
||||
for (size_t i = 0; i < args_size; ++i) {
|
||||
const struct mgp_value *value = NULL;
|
||||
if (mgp_list_at(args, i, &value) != MGP_ERROR_NO_ERROR) {
|
||||
goto error_free_list;
|
||||
}
|
||||
if (mgp_list_append(args_copy, value) != MGP_ERROR_NO_ERROR) {
|
||||
goto error_free_list;
|
||||
}
|
||||
}
|
||||
struct mgp_result_record *record = NULL;
|
||||
if (mgp_result_new_record(result, &record) != MGP_ERROR_NO_ERROR) {
|
||||
goto error_free_list;
|
||||
}
|
||||
// Transfer ownership of args_copy to mgp_value.
|
||||
struct mgp_value *args_value = NULL;
|
||||
if (mgp_value_make_list(args_copy, &args_value) != MGP_ERROR_NO_ERROR) {
|
||||
goto error_free_list;
|
||||
}
|
||||
// Release `args_value` and contained `args_copy`.
|
||||
if (mgp_result_record_insert(record, "args", args_value) != MGP_ERROR_NO_ERROR) {
|
||||
mgp_value_destroy(args_value);
|
||||
goto error_something_went_wrong;
|
||||
}
|
||||
mgp_value_destroy(args_value);
|
||||
struct mgp_value *hello_world_value = NULL;
|
||||
if (mgp_value_make_string("Hello World!", memory, &hello_world_value) != MGP_ERROR_NO_ERROR) {
|
||||
goto error_something_went_wrong;
|
||||
}
|
||||
enum mgp_error insert_result = mgp_result_record_insert(record, "result", hello_world_value);
|
||||
mgp_value_destroy(hello_world_value);
|
||||
if (insert_result != MGP_ERROR_NO_ERROR) {
|
||||
goto error_something_went_wrong;
|
||||
}
|
||||
// We have successfully finished, so return without error reporting.
|
||||
return;
|
||||
|
||||
error_free_list:
|
||||
mgp_list_destroy(args_copy);
|
||||
error_something_went_wrong:
|
||||
mgp_result_set_error_msg(result, "Something went wrong!");
|
||||
return;
|
||||
}
|
||||
|
||||
// Each module needs to define mgp_init_module function.
|
||||
// Here you can register multiple procedures your module supports.
|
||||
int mgp_init_module(struct mgp_module *module, struct mgp_memory *memory) {
|
||||
struct mgp_proc *proc = NULL;
|
||||
if (mgp_module_add_read_procedure(module, "procedure", procedure, &proc) != MGP_ERROR_NO_ERROR) {
|
||||
return 1;
|
||||
}
|
||||
const struct mgp_type *any_type = NULL;
|
||||
if (mgp_type_any(&any_type) != MGP_ERROR_NO_ERROR) {
|
||||
return 1;
|
||||
}
|
||||
const struct mgp_type *nullable_any_type = NULL;
|
||||
if (mgp_type_nullable(any_type, &nullable_any_type) != MGP_ERROR_NO_ERROR) {
|
||||
return 1;
|
||||
}
|
||||
if (mgp_proc_add_arg(proc, "required_arg", nullable_any_type) != MGP_ERROR_NO_ERROR) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
struct mgp_value *null_value = NULL;
|
||||
if (mgp_value_make_null(memory, &null_value) != MGP_ERROR_NO_ERROR) {
|
||||
return 1;
|
||||
}
|
||||
if (mgp_proc_add_opt_arg(proc, "optional_arg", nullable_any_type, null_value) != MGP_ERROR_NO_ERROR) {
|
||||
mgp_value_destroy(null_value);
|
||||
return 1;
|
||||
}
|
||||
mgp_value_destroy(null_value);
|
||||
const struct mgp_type *string = NULL;
|
||||
if (mgp_type_string(&string) != MGP_ERROR_NO_ERROR) {
|
||||
return 1;
|
||||
}
|
||||
if (mgp_proc_add_result(proc, "result", string) != MGP_ERROR_NO_ERROR) {
|
||||
return 1;
|
||||
}
|
||||
const struct mgp_type *list_of_anything = NULL;
|
||||
if (mgp_type_list(nullable_any_type, &list_of_anything) != MGP_ERROR_NO_ERROR) {
|
||||
return 1;
|
||||
}
|
||||
if (mgp_proc_add_result(proc, "args", list_of_anything)) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// This is an optional function if you need to release any resources before the
|
||||
// module is unloaded. You will probably need this if you acquired some
|
||||
// resources in mgp_init_module.
|
||||
int mgp_shutdown_module() {
|
||||
// Return 0 to indicate success.
|
||||
return 0;
|
||||
}
|
||||
@@ -1,55 +0,0 @@
|
||||
# Build Memgraph with Python 3.5+ support and run Memgraph so that it loads
|
||||
# this file as a Query Module. The procedure implemented in this module is just
|
||||
# a rewrite of the `example.c` procedure.
|
||||
import mgp
|
||||
|
||||
import copy
|
||||
|
||||
|
||||
@mgp.read_proc
|
||||
def procedure(context: mgp.ProcCtx,
|
||||
required_arg: mgp.Nullable[mgp.Any],
|
||||
optional_arg: mgp.Nullable[mgp.Any] = None
|
||||
) -> mgp.Record(args=list,
|
||||
vertex_count=int,
|
||||
avg_degree=mgp.Number,
|
||||
props=mgp.Nullable[mgp.Map]):
|
||||
'''
|
||||
This example procedure returns 4 fields.
|
||||
|
||||
* `args` is a copy of arguments passed to the procedure.
|
||||
* `vertex_count` is the number of vertices in the database.
|
||||
* `avg_degree` is the average degree of vertices.
|
||||
* `props` is the properties map of the passed in `required_arg`, if it is
|
||||
an Edge or a Vertex. In case of a Path instance, properties of the
|
||||
starting vertex are returned.
|
||||
|
||||
Any errors can be reported by raising an Exception.
|
||||
|
||||
The procedure can be invoked in openCypher using the following calls:
|
||||
CALL example.procedure(1, 2) YIELD args, vertex_count;
|
||||
MATCH (n) CALL example.procedure(n, 1) YIELD * RETURN *;
|
||||
|
||||
Naturally, you may pass in different arguments or yield different fields.
|
||||
'''
|
||||
# Create a properties map if we received an Edge, Vertex, or Path instance.
|
||||
props = None
|
||||
if isinstance(required_arg, (mgp.Edge, mgp.Vertex)):
|
||||
props = dict(required_arg.properties.items())
|
||||
elif isinstance(required_arg, mgp.Path):
|
||||
start_vertex, = required_arg.vertices
|
||||
props = dict(start_vertex.properties.items())
|
||||
# Count the vertices and edges in the database; this may take a while.
|
||||
vertex_count = 0
|
||||
edge_count = 0
|
||||
for v in context.graph.vertices:
|
||||
vertex_count += 1
|
||||
edge_count += sum(1 for e in v.in_edges)
|
||||
edge_count += sum(1 for e in v.out_edges)
|
||||
# Calculate the average degree, as if edges are not directed.
|
||||
avg_degree = 0 if vertex_count == 0 else edge_count / vertex_count
|
||||
# Copy the received arguments to make it equivalent to the C example.
|
||||
args_copy = [copy.deepcopy(required_arg), copy.deepcopy(optional_arg)]
|
||||
# Multiple rows can be produced by returning an iterable of mgp.Record.
|
||||
return mgp.Record(args=args_copy, vertex_count=vertex_count,
|
||||
avg_degree=avg_degree, props=props)
|
||||
@@ -1,280 +0,0 @@
|
||||
import sys
|
||||
import mgp
|
||||
from collections import OrderedDict
|
||||
from itertools import chain, repeat
|
||||
from inspect import cleandoc
|
||||
from typing import List, Tuple
|
||||
try:
|
||||
import networkx as nx
|
||||
except ImportError as import_error:
|
||||
sys.stderr.write((
|
||||
'\n'
|
||||
'NOTE: Please install networkx to be able to use graph_analyzer '
|
||||
'module. Using Python:\n'
|
||||
+ sys.version +
|
||||
'\n'))
|
||||
raise import_error
|
||||
# Imported last because it also depends on networkx.
|
||||
from mgp_networkx import MemgraphMultiDiGraph # noqa E402
|
||||
|
||||
|
||||
_MAX_LIST_SIZE = 10
|
||||
|
||||
|
||||
@mgp.read_proc
|
||||
def help() -> mgp.Record(name=str, value=str):
|
||||
'''Shows manual page for graph_analyzer.'''
|
||||
records = []
|
||||
|
||||
def make_records(name, doc):
|
||||
return (mgp.Record(name=n, value=v) for n, v in
|
||||
zip(chain([name], repeat('')), cleandoc(doc).splitlines()))
|
||||
|
||||
for func in (help, analyze, analyze_subgraph):
|
||||
records.extend(make_records("Procedure '{}'".format(func.__name__),
|
||||
func.__doc__))
|
||||
|
||||
for m, v in _get_analysis_mapping().items():
|
||||
records.extend(make_records("Analysis '{}'".format(m), v.__doc__))
|
||||
|
||||
return records
|
||||
|
||||
|
||||
@mgp.read_proc
|
||||
def analyze(context: mgp.ProcCtx,
|
||||
analyses: mgp.Nullable[List[str]] = None
|
||||
) -> mgp.Record(name=str, value=str):
|
||||
'''
|
||||
Shows graph information.
|
||||
|
||||
In case of multiple results, only the first 10 will be shown.
|
||||
|
||||
The optional parameter is a list of graph analyses to run.
|
||||
If NULL, all available analyses are run.
|
||||
|
||||
Example call (give all information):
|
||||
CALL graph_analyzer.analyze() YIELD *;
|
||||
|
||||
Example call (with parameter):
|
||||
CALL graph_analyzer.analyze(['nodes', 'edges']) YIELD *;
|
||||
'''
|
||||
g = MemgraphMultiDiGraph(ctx=context)
|
||||
recs = _analyze_graph(context, g, analyses)
|
||||
return [mgp.Record(name=name, value=value) for name, value in recs]
|
||||
|
||||
|
||||
@mgp.read_proc
|
||||
def analyze_subgraph(context: mgp.ProcCtx,
|
||||
vertices: mgp.List[mgp.Vertex],
|
||||
edges: mgp.List[mgp.Edge],
|
||||
analyses: mgp.Nullable[List[str]] = None
|
||||
) -> mgp.Record(name=str, value=str):
|
||||
'''
|
||||
Shows subgraph information.
|
||||
|
||||
In case of multiple results, only the first 10 will be shown.
|
||||
|
||||
The optional parameter is a list of graph analyses to run.
|
||||
If NULL, all available analyses are run.
|
||||
|
||||
Example call (give all information):
|
||||
MATCH (n)-[e]->(m) WITH
|
||||
collect(n) AS nodes,
|
||||
collect(e) AS edges
|
||||
CALL graph_analyzer.analyze_subgraph(nodes, edges) YIELD *
|
||||
RETURN name, value;
|
||||
|
||||
Example call (with parameter):
|
||||
MATCH (n)-[e]->(m) WITH
|
||||
collect(n) AS nodes,
|
||||
collect(e) AS edges
|
||||
CALL graph_analyzer.analyze_subgraph(nodes, edges, ['nodes', 'edges'])
|
||||
YIELD *
|
||||
RETURN name, value;
|
||||
'''
|
||||
vertices, edges = map(set, [vertices, edges])
|
||||
g = nx.subgraph_view(
|
||||
MemgraphMultiDiGraph(ctx=context),
|
||||
lambda n: n in vertices,
|
||||
lambda n1, n2, e: e in edges)
|
||||
recs = _analyze_graph(context, g, analyses)
|
||||
return [mgp.Record(name=name, value=value) for name, value in recs]
|
||||
|
||||
|
||||
def _get_analysis_mapping():
|
||||
return OrderedDict([
|
||||
('nodes', _number_of_nodes),
|
||||
('edges', _number_of_edges),
|
||||
('bridges', _bridges),
|
||||
('articulation_points', _articulation_points),
|
||||
('avg_degree', _avg_degree),
|
||||
('sorted_nodes_degree', _sorted_nodes_degree),
|
||||
('self_loops', _self_loops),
|
||||
('is_bipartite', _is_bipartite),
|
||||
('is_planar', _is_planar),
|
||||
('is_biconnected: ', _is_biconnected),
|
||||
('is_weakly_connected', _is_weakly_connected),
|
||||
('number_of_weakly_components', _weakly_components),
|
||||
('is_strongly_connected', _is_strongly_connected),
|
||||
('strongly_components', _strongly_components),
|
||||
('is_dag', _is_dag),
|
||||
('is_eulerian', _is_eulerian),
|
||||
('is_forest', _is_forest),
|
||||
('is_tree', _is_tree)])
|
||||
|
||||
|
||||
def _get_analysis_func(name: str):
|
||||
_name_to_proc = _get_analysis_mapping()
|
||||
return _name_to_proc.get(name.lower())
|
||||
|
||||
|
||||
def _get_analysis_funcs():
|
||||
return _get_analysis_mapping().values()
|
||||
|
||||
|
||||
def _analyze_graph(context: mgp.ProcCtx,
|
||||
g: nx.MultiDiGraph,
|
||||
analyses: List[str]
|
||||
) -> List[Tuple[str, str]]:
|
||||
|
||||
functions = (_get_analysis_funcs() if analyses is None
|
||||
else [_get_analysis_func(name) for name in analyses])
|
||||
|
||||
records = []
|
||||
for index, f in enumerate(functions):
|
||||
context.check_must_abort()
|
||||
if f is None:
|
||||
raise KeyError('Graph analysis is not supported: ' +
|
||||
analyses[index])
|
||||
name, value = f(g)
|
||||
if isinstance(value, (list, set, tuple)):
|
||||
value = list(value)[:_MAX_LIST_SIZE]
|
||||
records.append((name, str(value)))
|
||||
|
||||
return records
|
||||
|
||||
|
||||
def _number_of_nodes(g: nx.MultiDiGraph) -> Tuple[str, int]:
|
||||
'''Returns number of nodes.'''
|
||||
return 'Number of nodes', nx.number_of_nodes(g)
|
||||
|
||||
|
||||
def _number_of_edges(g: nx.MultiDiGraph) -> Tuple[str, int]:
|
||||
'''Returns number of edges.'''
|
||||
return 'Number of edges', nx.number_of_edges(g)
|
||||
|
||||
|
||||
def _avg_degree(g: nx.MultiDiGraph) -> Tuple[str, float]:
|
||||
'''Returns average degree.'''
|
||||
_, number_of_nodes = _number_of_nodes(g)
|
||||
_, number_of_edges = _number_of_edges(g)
|
||||
avg_degree = (0 if number_of_nodes == 0
|
||||
else number_of_edges / number_of_nodes)
|
||||
return 'Average degree', avg_degree
|
||||
|
||||
|
||||
def _sorted_nodes_degree(g: nx.MultiDiGraph) -> Tuple[str, List[int]]:
|
||||
'''Returns list of sorted nodes degree. [(node_id, degree), ...]'''
|
||||
nodes_degree = [(n, g.degree(n)) for n in g.nodes()]
|
||||
nodes_degree.sort(key=lambda x: x[1], reverse=True)
|
||||
return 'Sorted nodes degree', nodes_degree
|
||||
|
||||
|
||||
def _self_loops(g: nx.MultiDiGraph) -> Tuple[str, int]:
|
||||
'''Returns number of self loops.'''
|
||||
return 'Self loops', sum((1 if e[0] == e[1] else 0 for e in g.edges()))
|
||||
|
||||
|
||||
def _is_bipartite(g: nx.MultiDiGraph) -> Tuple[str, bool]:
|
||||
'''Checks if graph is bipartite.'''
|
||||
_, number_of_nodes = _number_of_nodes(g)
|
||||
ret = (False if number_of_nodes == 0
|
||||
else nx.algorithms.bipartite.basic.is_bipartite(g))
|
||||
return 'Is bipartite', ret
|
||||
|
||||
|
||||
def _is_planar(g: nx.MultiDiGraph) -> Tuple[str, bool]:
|
||||
'''Checks if graph is planar.'''
|
||||
_, number_of_nodes = _number_of_nodes(g)
|
||||
ret = (False if number_of_nodes == 0
|
||||
else nx.algorithms.planarity.check_planarity(g)[0])
|
||||
return 'Is planar', ret
|
||||
|
||||
|
||||
def _is_biconnected(g: nx.MultiDiGraph) -> Tuple[str, bool]:
|
||||
'''Check if graph is biconnected.'''
|
||||
_, number_of_nodes = _number_of_nodes(g)
|
||||
ret = (False if number_of_nodes == 0
|
||||
else nx.is_biconnected(nx.MultiDiGraph.to_undirected(g)))
|
||||
return 'Is biconnected', ret
|
||||
|
||||
|
||||
def _is_weakly_connected(g: nx.MultiDiGraph) -> Tuple[str, bool]:
|
||||
'''Check if graph is weakly connected.'''
|
||||
_, number_of_nodes = _number_of_nodes(g)
|
||||
ret = False if number_of_nodes == 0 else nx.is_weakly_connected(g)
|
||||
return 'Is weakly connected', ret
|
||||
|
||||
|
||||
def _is_strongly_connected(g: nx.MultiDiGraph) -> Tuple[str, bool]:
|
||||
'''Checks if graph is strongly connected.'''
|
||||
_, number_of_nodes = _number_of_nodes(g)
|
||||
ret = False if number_of_nodes == 0 else nx.is_strongly_connected(g)
|
||||
return 'Is strongly connected', ret
|
||||
|
||||
|
||||
def _is_dag(g: nx.MultiDiGraph) -> Tuple[str, bool]:
|
||||
'''Check if graph is directed acyclic graph (DAG)'''
|
||||
_, number_of_nodes = _number_of_nodes(g)
|
||||
ret = (False if number_of_nodes == 0
|
||||
else nx.algorithms.dag.is_directed_acyclic_graph(g))
|
||||
return 'Is DAG', ret
|
||||
|
||||
|
||||
def _is_eulerian(g: nx.MultiDiGraph) -> Tuple[str, bool]:
|
||||
'''Checks if graph is Eulerian.'''
|
||||
_, number_of_nodes = _number_of_nodes(g)
|
||||
ret = (False if number_of_nodes == 0
|
||||
else nx.algorithms.euler.is_eulerian(g))
|
||||
return 'Is eulerian', ret
|
||||
|
||||
|
||||
def _is_forest(g: nx.MultiDiGraph) -> Tuple[str, bool]:
|
||||
'''Checks if graph is forest, all components must be trees.'''
|
||||
_, number_of_nodes = _number_of_nodes(g)
|
||||
ret = (False if number_of_nodes == 0
|
||||
else nx.algorithms.tree.recognition.is_forest(g))
|
||||
return 'Is forest', ret
|
||||
|
||||
|
||||
def _is_tree(g: nx.MultiDiGraph) -> Tuple[str, bool]:
|
||||
'''Checks if graph is tree.'''
|
||||
_, number_of_nodes = _number_of_nodes(g)
|
||||
ret = (False if number_of_nodes == 0
|
||||
else nx.algorithms.tree.recognition.is_tree(g))
|
||||
return 'Is tree', ret
|
||||
|
||||
|
||||
def _bridges(g: nx.MultiDiGraph) -> Tuple[str, int]:
|
||||
'''Returns number of bridges, multiple edges between same nodes are
|
||||
mapped to one edge.'''
|
||||
return 'Number of bridges', sum(1 for _ in nx.bridges(nx.Graph(g)))
|
||||
|
||||
|
||||
def _articulation_points(g: nx.MultiDiGraph):
|
||||
'''Returns number of articulation points.'''
|
||||
undirected = nx.MultiDiGraph.to_undirected(g)
|
||||
return ('Number of articulation points',
|
||||
sum(1 for _ in nx.articulation_points(undirected)))
|
||||
|
||||
|
||||
def _weakly_components(g: nx.MultiDiGraph):
|
||||
'''Returns number of weakly components.'''
|
||||
comps = nx.algorithms.components.number_weakly_connected_components(g)
|
||||
return 'Number of weakly connected components', comps
|
||||
|
||||
|
||||
def _strongly_components(g: nx.MultiDiGraph):
|
||||
'''Returns number of strongly connected components.'''
|
||||
comps = nx.algorithms.components.number_strongly_connected_components(g)
|
||||
return 'Number of strongly connected components', comps
|
||||
@@ -1,289 +0,0 @@
|
||||
import sys
|
||||
import mgp
|
||||
import collections
|
||||
try:
|
||||
import networkx as nx
|
||||
except ImportError as import_error:
|
||||
sys.stderr.write((
|
||||
'\n'
|
||||
'NOTE: Please install networkx to be able to use Memgraph NetworkX '
|
||||
'wrappers. Using Python:\n'
|
||||
+ sys.version +
|
||||
'\n'))
|
||||
raise import_error
|
||||
|
||||
|
||||
class MemgraphAdjlistOuterDict(collections.abc.Mapping):
|
||||
__slots__ = ('_ctx', '_succ', '_multi')
|
||||
|
||||
def __init__(self, ctx, succ=True, multi=True):
|
||||
self._ctx = ctx
|
||||
self._succ = succ
|
||||
self._multi = multi
|
||||
|
||||
def __getitem__(self, key):
|
||||
if key not in self:
|
||||
raise KeyError
|
||||
return MemgraphAdjlistInnerDict(key, succ=self._succ,
|
||||
multi=self._multi)
|
||||
|
||||
def __iter__(self):
|
||||
return iter(self._ctx.graph.vertices)
|
||||
|
||||
def __len__(self):
|
||||
return len(self._ctx.graph.vertices)
|
||||
|
||||
def __contains__(self, key):
|
||||
if not isinstance(key, mgp.Vertex):
|
||||
raise TypeError
|
||||
return key in self._ctx.graph.vertices
|
||||
|
||||
|
||||
class MemgraphAdjlistInnerDict(collections.abc.Mapping):
|
||||
__slots__ = ('_node', '_succ', '_multi', '_neighbors')
|
||||
|
||||
def __init__(self, node, succ=True, multi=True):
|
||||
self._node = node
|
||||
self._succ = succ
|
||||
self._multi = multi
|
||||
self._neighbors = None
|
||||
|
||||
def __getitem__(self, key):
|
||||
# NOTE: NetworkX 2.4, classes/coreviews.py:143. UnionAtlas expects a
|
||||
# KeyError when indexing with a vertex that is not a neighbor.
|
||||
if key not in self:
|
||||
raise KeyError
|
||||
if not self._multi:
|
||||
return UnhashableProperties(self._get_edge(key).properties)
|
||||
return MemgraphEdgeKeyDict(self._node, key, self._succ)
|
||||
|
||||
def __iter__(self):
|
||||
yield from self._get_neighbors()
|
||||
|
||||
def __len__(self):
|
||||
return len(self._get_neighbors())
|
||||
|
||||
def __contains__(self, key):
|
||||
if not isinstance(key, mgp.Vertex):
|
||||
raise TypeError
|
||||
return key in self._get_neighbors()
|
||||
|
||||
def _get_neighbors(self):
|
||||
if not self._neighbors:
|
||||
if self._succ:
|
||||
self._neighbors = set(
|
||||
e.to_vertex for e in self._node.out_edges)
|
||||
else:
|
||||
self._neighbors = set(
|
||||
e.from_vertex for e in self._node.in_edges)
|
||||
return self._neighbors
|
||||
|
||||
def _get_edge(self, neighbor):
|
||||
if self._succ:
|
||||
edge = list(filter(lambda e: e.to_vertex == neighbor,
|
||||
self._node.out_edges))
|
||||
else:
|
||||
edge = list(filter(lambda e: e.from_vertex == neighbor,
|
||||
self._node.in_edges))
|
||||
|
||||
assert len(edge) >= 1
|
||||
if len(edge) > 1:
|
||||
raise RuntimeError('Graph contains multiedges but '
|
||||
'is of non-multigraph type: {}'.format(edge))
|
||||
|
||||
return edge[0]
|
||||
|
||||
|
||||
class MemgraphEdgeKeyDict(collections.abc.Mapping):
|
||||
__slots__ = ('_node', '_neighbor', '_succ', '_edges')
|
||||
|
||||
def __init__(self, node, neighbor, succ=True):
|
||||
self._node = node
|
||||
self._neighbor = neighbor
|
||||
self._succ = succ
|
||||
self._edges = None
|
||||
|
||||
def __getitem__(self, key):
|
||||
if key not in self:
|
||||
raise KeyError
|
||||
return UnhashableProperties(key.properties)
|
||||
|
||||
def __iter__(self):
|
||||
yield from self._get_edges()
|
||||
|
||||
def __len__(self):
|
||||
return len(self._get_edges())
|
||||
|
||||
def __contains__(self, key):
|
||||
if not isinstance(key, mgp.Edge):
|
||||
raise TypeError
|
||||
return key in self._get_edges()
|
||||
|
||||
def _get_edges(self):
|
||||
if not self._edges:
|
||||
if self._succ:
|
||||
self._edges = list(filter(
|
||||
lambda e: e.to_vertex == self._neighbor,
|
||||
self._node.out_edges))
|
||||
else:
|
||||
self._edges = list(filter(
|
||||
lambda e: e.from_vertex == self._neighbor,
|
||||
self._node.in_edges))
|
||||
return self._edges
|
||||
|
||||
|
||||
class UnhashableProperties(collections.abc.Mapping):
|
||||
__slots__ = ('_properties')
|
||||
|
||||
def __init__(self, properties):
|
||||
self._properties = properties
|
||||
|
||||
def __getitem__(self, key):
|
||||
return self._properties[key]
|
||||
|
||||
def __iter__(self):
|
||||
yield from self._properties
|
||||
|
||||
def __len__(self):
|
||||
return len(self._properties)
|
||||
|
||||
def __contains__(self, key):
|
||||
return key in self._properties
|
||||
|
||||
# NOTE: Explicitly disable hashing. See the comment in MemgraphNodeDict.
|
||||
__hash__ = None
|
||||
|
||||
|
||||
class MemgraphNodeDict(collections.abc.Mapping):
|
||||
__slots__ = ('_ctx',)
|
||||
|
||||
def __init__(self, ctx):
|
||||
self._ctx = ctx
|
||||
|
||||
def __getitem__(self, key):
|
||||
if key not in self:
|
||||
raise KeyError
|
||||
# NOTE: NetworkX 2.4, classes/digraph.py:484. NetworkX expects the
|
||||
# tuples provided to add_nodes_from to be unhashable and cause a
|
||||
# TypeError when trying to index the node dictionary. This happens
|
||||
# because the data dictionary element of the tuple is unhashable. We do
|
||||
# the same thing by returning an unhashable data dictionary.
|
||||
return UnhashableProperties(key.properties)
|
||||
|
||||
def __iter__(self):
|
||||
return iter(self._ctx.graph.vertices)
|
||||
|
||||
def __len__(self):
|
||||
return len(self._ctx.graph.vertices)
|
||||
|
||||
def __contains__(self, key):
|
||||
# NOTE: NetworkX 2.4, graph.py:425. Graph.__contains__ relies on
|
||||
# self._node's (i.e. the dictionary produced by node_dict_factory)
|
||||
# __contains__ to raise a TypeError when indexing with something weird,
|
||||
# e.g. with sets. This is the behavior of dict.
|
||||
if not isinstance(key, mgp.Vertex):
|
||||
raise TypeError
|
||||
return key in self._ctx.graph.vertices
|
||||
|
||||
|
||||
class MemgraphDiGraphBase:
|
||||
def __init__(self, incoming_graph_data=None, ctx=None, multi=True,
|
||||
**kwargs):
|
||||
# NOTE: We assume that our graph will never be given any initial data
|
||||
# because we already pull our data from the Memgraph database. This
|
||||
# assert is triggered by certain NetworkX procedures because they
|
||||
# create a new instance of our class and try to populate it with their
|
||||
# own data.
|
||||
assert incoming_graph_data is None
|
||||
|
||||
# NOTE: We allow for ctx to be None in order to allow certain NetworkX
|
||||
# procedures (such as `subgraph`) to work. Such procedures directly
|
||||
# modify the graph's internal attributes and don't try to populate it
|
||||
# with initial data or modify it.
|
||||
|
||||
self.node_dict_factory = lambda: MemgraphNodeDict(ctx) \
|
||||
if ctx else self._error
|
||||
self.node_attr_dict_factory = self._error
|
||||
|
||||
self.adjlist_outer_dict_factory = \
|
||||
lambda: MemgraphAdjlistOuterDict(ctx, multi=multi) \
|
||||
if ctx else self._error
|
||||
self.adjlist_inner_dict_factory = self._error
|
||||
self.edge_key_dict_factory = self._error
|
||||
self.edge_attr_dict_factory = self._error
|
||||
|
||||
# NOTE: We forbid any mutating operations because our graph is
|
||||
# immutable and pulls its data from the Memgraph database.
|
||||
for f in ['add_node', 'add_nodes_from', 'remove_node',
|
||||
'remove_nodes_from', 'add_edge', 'add_edges_from',
|
||||
'add_weighted_edges_from', 'new_edge_key', 'remove_edge',
|
||||
'remove_edges_from', 'update', 'clear']:
|
||||
setattr(self, f, lambda *args, **kwargs: self._error())
|
||||
|
||||
super().__init__(None, **kwargs)
|
||||
|
||||
# NOTE: This is a necessary hack because NetworkX assumes that the
|
||||
# customizable factory functions will only ever return *empty*
|
||||
# dictionaries. In our case, the factory functions return our custom,
|
||||
# already populated, dictionaries. Because self._pred and self._end are
|
||||
# initialized by the same factory function, they end up storing the
|
||||
# same adjacency lists which is not good. We correct that here.
|
||||
self._pred = MemgraphAdjlistOuterDict(ctx, succ=False, multi=multi)
|
||||
|
||||
def _error(self):
|
||||
raise RuntimeError('Modification operations are not supported')
|
||||
|
||||
|
||||
class MemgraphMultiDiGraph(MemgraphDiGraphBase, nx.MultiDiGraph):
|
||||
def __init__(self, incoming_graph_data=None, ctx=None, **kwargs):
|
||||
super().__init__(incoming_graph_data=incoming_graph_data,
|
||||
ctx=ctx, multi=True, **kwargs)
|
||||
|
||||
|
||||
def MemgraphMultiGraph(incoming_graph_data=None, ctx=None, **kwargs):
|
||||
return MemgraphMultiDiGraph(incoming_graph_data=incoming_graph_data,
|
||||
ctx=ctx, **kwargs).to_undirected(as_view=True)
|
||||
|
||||
|
||||
class MemgraphDiGraph(MemgraphDiGraphBase, nx.DiGraph):
|
||||
def __init__(self, incoming_graph_data=None, ctx=None, **kwargs):
|
||||
super().__init__(incoming_graph_data=incoming_graph_data,
|
||||
ctx=ctx, multi=False, **kwargs)
|
||||
|
||||
|
||||
def MemgraphGraph(incoming_graph_data=None, ctx=None, **kwargs):
|
||||
return MemgraphDiGraph(incoming_graph_data=incoming_graph_data,
|
||||
ctx=ctx, **kwargs).to_undirected(as_view=True)
|
||||
|
||||
|
||||
class PropertiesDictionary(collections.abc.Mapping):
|
||||
__slots__ = ('_ctx', '_prop', '_len')
|
||||
|
||||
def __init__(self, ctx, prop):
|
||||
self._ctx = ctx
|
||||
self._prop = prop
|
||||
self._len = None
|
||||
|
||||
def __getitem__(self, vertex):
|
||||
if vertex not in self:
|
||||
raise KeyError
|
||||
try:
|
||||
return vertex.properties[self._prop]
|
||||
except KeyError:
|
||||
raise KeyError(("{} doesn\t have the required " +
|
||||
"property '{}'").format(vertex, self._prop))
|
||||
|
||||
def __iter__(self):
|
||||
for v in self._ctx.graph.vertices:
|
||||
if self._prop in v.properties:
|
||||
yield v
|
||||
|
||||
def __len__(self):
|
||||
if not self._len:
|
||||
self._len = sum(1 for _ in self)
|
||||
return self._len
|
||||
|
||||
def __contains__(self, vertex):
|
||||
if not isinstance(vertex, mgp.Vertex):
|
||||
raise TypeError
|
||||
return self._prop in vertex.properties
|
||||
@@ -1,825 +0,0 @@
|
||||
import sys
|
||||
import mgp
|
||||
try:
|
||||
import networkx as nx
|
||||
import numpy # noqa E401
|
||||
import scipy # noqa E401
|
||||
except ImportError as import_error:
|
||||
sys.stderr.write((
|
||||
'\n'
|
||||
'NOTE: Please install networkx, numpy, scipy to be able to '
|
||||
'use proxied NetworkX algorithms. E.g., CALL nxalg.pagerank(...).\n'
|
||||
'Using Python:\n'
|
||||
+ sys.version +
|
||||
'\n'))
|
||||
raise import_error
|
||||
# Imported last because it also depends on networkx.
|
||||
from mgp_networkx import (MemgraphMultiDiGraph, MemgraphDiGraph, # noqa: E402
|
||||
MemgraphMultiGraph, MemgraphGraph,
|
||||
PropertiesDictionary)
|
||||
|
||||
|
||||
# networkx.algorithms.approximation.connectivity.node_connectivity
|
||||
@mgp.read_proc
|
||||
def node_connectivity(ctx: mgp.ProcCtx,
|
||||
source: mgp.Nullable[mgp.Vertex] = None,
|
||||
target: mgp.Nullable[mgp.Vertex] = None
|
||||
) -> mgp.Record(connectivity=int):
|
||||
return mgp.Record(connectivity=nx.node_connectivity(
|
||||
MemgraphMultiDiGraph(ctx=ctx), source, target))
|
||||
|
||||
|
||||
# networkx.algorithms.assortativity.degree_assortativity_coefficient
|
||||
@mgp.read_proc
|
||||
def degree_assortativity_coefficient(
|
||||
ctx: mgp.ProcCtx,
|
||||
x: str = 'out',
|
||||
y: str = 'in',
|
||||
weight: mgp.Nullable[str] = None,
|
||||
nodes: mgp.Nullable[mgp.List[mgp.Vertex]] = None
|
||||
) -> mgp.Record(assortativity=float):
|
||||
return mgp.Record(assortativity=nx.degree_assortativity_coefficient(
|
||||
MemgraphMultiDiGraph(ctx=ctx), x, y, weight, nodes))
|
||||
|
||||
|
||||
# networkx.algorithms.asteroidal.is_at_free
|
||||
@mgp.read_proc
|
||||
def is_at_free(ctx: mgp.ProcCtx) -> mgp.Record(is_at_free=bool):
|
||||
return mgp.Record(is_at_free=nx.is_at_free(MemgraphGraph(ctx=ctx)))
|
||||
|
||||
|
||||
# networkx.algorithms.bipartite.basic.is_bipartite
|
||||
@mgp.read_proc
|
||||
def is_bipartite(ctx: mgp.ProcCtx) -> mgp.Record(is_bipartite=bool):
|
||||
return mgp.Record(is_bipartite=nx.is_bipartite(
|
||||
MemgraphMultiDiGraph(ctx=ctx)))
|
||||
|
||||
|
||||
# networkx.algorithms.boundary.node_boundary
|
||||
@mgp.read_proc
|
||||
def node_boundary(ctx: mgp.ProcCtx,
|
||||
nbunch1: mgp.List[mgp.Vertex],
|
||||
nbunch2: mgp.Nullable[mgp.List[mgp.Vertex]] = None
|
||||
) -> mgp.Record(boundary=mgp.List[mgp.Vertex]):
|
||||
return mgp.Record(boundary=list(nx.node_boundary(
|
||||
MemgraphMultiDiGraph(ctx=ctx), nbunch1, nbunch2)))
|
||||
|
||||
|
||||
# networkx.algorithms.bridges.bridges
|
||||
@mgp.read_proc
|
||||
def bridges(ctx: mgp.ProcCtx,
|
||||
root: mgp.Nullable[mgp.Vertex] = None
|
||||
) -> mgp.Record(bridges=mgp.List[mgp.Edge]):
|
||||
g = MemgraphMultiGraph(ctx=ctx)
|
||||
return mgp.Record(
|
||||
bridges=[next(iter(g[u][v]))
|
||||
for u, v in nx.bridges(MemgraphGraph(ctx=ctx),
|
||||
root=root)])
|
||||
|
||||
|
||||
# networkx.algorithms.centrality.betweenness_centrality
|
||||
@mgp.read_proc
|
||||
def betweenness_centrality(ctx: mgp.ProcCtx,
|
||||
k: mgp.Nullable[int] = None,
|
||||
normalized: bool = True,
|
||||
weight: mgp.Nullable[str] = None,
|
||||
endpoints: bool = False,
|
||||
seed: mgp.Nullable[int] = None
|
||||
) -> mgp.Record(node=mgp.Vertex,
|
||||
betweenness=mgp.Number):
|
||||
return [mgp.Record(node=n, betweenness=b)
|
||||
for n, b in nx.betweenness_centrality(
|
||||
MemgraphDiGraph(ctx=ctx), k=k, normalized=normalized,
|
||||
weight=weight, endpoints=endpoints, seed=seed).items()]
|
||||
|
||||
|
||||
# networkx.algorithms.chains.chain_decomposition
|
||||
@mgp.read_proc
|
||||
def chain_decomposition(ctx: mgp.ProcCtx,
|
||||
root: mgp.Nullable[mgp.Vertex] = None
|
||||
) -> mgp.Record(chains=mgp.List[mgp.List[mgp.Edge]]):
|
||||
g = MemgraphMultiGraph(ctx=ctx)
|
||||
return mgp.Record(
|
||||
chains=[[next(iter(g[u][v])) for u, v in d]
|
||||
for d in nx.chain_decomposition(MemgraphGraph(ctx=ctx),
|
||||
root=root)])
|
||||
|
||||
|
||||
# networkx.algorithms.chordal.is_chordal
|
||||
@mgp.read_proc
|
||||
def is_chordal(ctx: mgp.ProcCtx) -> mgp.Record(is_chordal=bool):
|
||||
return mgp.Record(is_chordal=nx.is_chordal(MemgraphGraph(ctx=ctx)))
|
||||
|
||||
|
||||
# networkx.algorithms.clique.find_cliques
|
||||
@mgp.read_proc
|
||||
def find_cliques(ctx: mgp.ProcCtx
|
||||
) -> mgp.Record(cliques=mgp.List[mgp.List[mgp.Vertex]]):
|
||||
return mgp.Record(cliques=list(nx.find_cliques(
|
||||
MemgraphMultiGraph(ctx=ctx))))
|
||||
|
||||
|
||||
# networkx.algorithms.cluster.clustering
|
||||
@mgp.read_proc
|
||||
def clustering(ctx: mgp.ProcCtx,
|
||||
nodes: mgp.Nullable[mgp.List[mgp.Vertex]] = None,
|
||||
weight: mgp.Nullable[str] = None
|
||||
) -> mgp.Record(node=mgp.Vertex, clustering=mgp.Number):
|
||||
return [mgp.Record(node=n, clustering=c)
|
||||
for n, c in nx.clustering(
|
||||
MemgraphDiGraph(ctx=ctx), nodes=nodes,
|
||||
weight=weight).items()]
|
||||
|
||||
|
||||
# networkx.algorithms.coloring.greedy_color
|
||||
@mgp.read_proc
|
||||
def greedy_color(ctx: mgp.ProcCtx,
|
||||
strategy: str = 'largest_first',
|
||||
interchange: bool = False
|
||||
) -> mgp.Record(node=mgp.Vertex, color=int):
|
||||
return [mgp.Record(node=n, color=c) for n, c in nx.greedy_color(
|
||||
MemgraphMultiDiGraph(ctx=ctx), strategy, interchange).items()]
|
||||
|
||||
|
||||
# networkx.algorithms.communicability_alg.communicability
|
||||
@mgp.read_proc
|
||||
def communicability(ctx: mgp.ProcCtx
|
||||
) -> mgp.Record(node1=mgp.Vertex, node2=mgp.Vertex,
|
||||
communicability=mgp.Number):
|
||||
return [mgp.Record(node1=n1, node2=n2, communicability=v)
|
||||
for n1, d in nx.communicability(MemgraphGraph(ctx=ctx)).items()
|
||||
for n2, v in d.items()]
|
||||
|
||||
|
||||
# networkx.algorithms.community.kclique.k_clique_communities
|
||||
@mgp.read_proc
|
||||
def k_clique_communities(
|
||||
ctx: mgp.ProcCtx,
|
||||
k: int,
|
||||
cliques: mgp.Nullable[mgp.List[mgp.List[mgp.Vertex]]] = None
|
||||
) -> mgp.Record(communities=mgp.List[mgp.List[mgp.Vertex]]):
|
||||
return mgp.Record(communities=[
|
||||
list(s) for s in nx.community.k_clique_communities(
|
||||
MemgraphMultiGraph(ctx=ctx), k, cliques)])
|
||||
|
||||
|
||||
# networkx.algorithms.approximation.kcomponents.k_components
|
||||
@mgp.read_proc
|
||||
def k_components(ctx: mgp.ProcCtx,
|
||||
density: mgp.Number = 0.95
|
||||
) -> mgp.Record(k=int,
|
||||
components=mgp.List[mgp.List[mgp.Vertex]]):
|
||||
kcomps = nx.k_components(MemgraphMultiGraph(ctx=ctx), density)
|
||||
|
||||
return [mgp.Record(k=k, components=[list(s) for s in comps])
|
||||
for k, comps in kcomps.items()]
|
||||
|
||||
|
||||
# networkx.algorithms.components.biconnected_components
|
||||
@mgp.read_proc
|
||||
def biconnected_components(
|
||||
ctx: mgp.ProcCtx
|
||||
) -> mgp.Record(components=mgp.List[mgp.List[mgp.Vertex]]):
|
||||
comps = nx.biconnected_components(MemgraphMultiGraph(ctx=ctx))
|
||||
return mgp.Record(components=[list(s) for s in comps])
|
||||
|
||||
|
||||
# networkx.algorithms.components.strongly_connected_components
|
||||
@mgp.read_proc
|
||||
def strongly_connected_components(
|
||||
ctx: mgp.ProcCtx
|
||||
) -> mgp.Record(components=mgp.List[mgp.List[mgp.Vertex]]):
|
||||
comps = nx.strongly_connected_components(MemgraphMultiDiGraph(ctx=ctx))
|
||||
return mgp.Record(components=[list(s) for s in comps])
|
||||
|
||||
|
||||
# networkx.algorithms.connectivity.edge_kcomponents.k_edge_components
|
||||
#
|
||||
# NOTE: NetworkX 2.4, algorithms/connectivity/edge_kcompnents.py:367. We create
|
||||
# a *copy* of the graph because the algorithm copies the graph using
|
||||
# __class__() and tries to modify it.
|
||||
@mgp.read_proc
|
||||
def k_edge_components(
|
||||
ctx: mgp.ProcCtx,
|
||||
k: int
|
||||
) -> mgp.Record(components=mgp.List[mgp.List[mgp.Vertex]]):
|
||||
return mgp.Record(components=[list(s) for s in nx.k_edge_components(
|
||||
nx.DiGraph(MemgraphDiGraph(ctx=ctx)), k)])
|
||||
|
||||
|
||||
# networkx.algorithms.core.core_number
|
||||
@mgp.read_proc
|
||||
def core_number(ctx: mgp.ProcCtx
|
||||
) -> mgp.Record(node=mgp.Vertex, core=mgp.Number):
|
||||
return [mgp.Record(node=n, core=c)
|
||||
for n, c in nx.core_number(MemgraphDiGraph(ctx=ctx)).items()]
|
||||
|
||||
|
||||
# networkx.algorithms.covering.is_edge_cover
|
||||
@mgp.read_proc
|
||||
def is_edge_cover(ctx: mgp.ProcCtx, cover: mgp.List[mgp.Edge]
|
||||
) -> mgp.Record(is_edge_cover=bool):
|
||||
cover = set([(e.from_vertex, e.to_vertex) for e in cover])
|
||||
return mgp.Record(is_edge_cover=nx.is_edge_cover(
|
||||
MemgraphMultiGraph(ctx=ctx), cover))
|
||||
|
||||
|
||||
# networkx.algorithms.cycles.find_cycle
|
||||
@mgp.read_proc
|
||||
def find_cycle(ctx: mgp.ProcCtx,
|
||||
source: mgp.Nullable[mgp.List[mgp.Vertex]] = None,
|
||||
orientation: mgp.Nullable[str] = None
|
||||
) -> mgp.Record(cycle=mgp.Nullable[mgp.List[mgp.Edge]]):
|
||||
try:
|
||||
return mgp.Record(cycle=[e for _, _, e in nx.find_cycle(
|
||||
MemgraphMultiDiGraph(ctx=ctx), source, orientation)])
|
||||
except nx.NetworkXNoCycle:
|
||||
return mgp.Record(cycle=None)
|
||||
|
||||
|
||||
# networkx.algorithms.cycles.simple_cycles
|
||||
#
|
||||
# NOTE: NetworkX 2.4, algorithms/cycles.py:183. We create a *copy* of the graph
|
||||
# because the algorithm copies the graph using type() and tries to pass initial
|
||||
# data.
|
||||
@mgp.read_proc
|
||||
def simple_cycles(ctx: mgp.ProcCtx
|
||||
) -> mgp.Record(cycles=mgp.List[mgp.List[mgp.Vertex]]):
|
||||
return mgp.Record(cycles=list(nx.simple_cycles(
|
||||
nx.MultiDiGraph(MemgraphMultiDiGraph(ctx=ctx)).copy())))
|
||||
|
||||
|
||||
# networkx.algorithms.cuts.node_expansion
|
||||
@mgp.read_proc
|
||||
def node_expansion(ctx: mgp.ProcCtx, s: mgp.List[mgp.Vertex]
|
||||
) -> mgp.Record(node_expansion=mgp.Number):
|
||||
return mgp.Record(node_expansion=nx.node_expansion(
|
||||
MemgraphMultiDiGraph(ctx=ctx), set(s)))
|
||||
|
||||
|
||||
# networkx.algorithms.dag.topological_sort
|
||||
@mgp.read_proc
|
||||
def topological_sort(ctx: mgp.ProcCtx
|
||||
) -> mgp.Record(nodes=mgp.Nullable[mgp.List[mgp.Vertex]]):
|
||||
return mgp.Record(nodes=list(nx.topological_sort(
|
||||
MemgraphMultiDiGraph(ctx=ctx))))
|
||||
|
||||
|
||||
# networkx.algorithms.dag.ancestors
|
||||
@mgp.read_proc
|
||||
def ancestors(ctx: mgp.ProcCtx,
|
||||
source: mgp.Vertex
|
||||
) -> mgp.Record(ancestors=mgp.List[mgp.Vertex]):
|
||||
return mgp.Record(ancestors=list(nx.ancestors(
|
||||
MemgraphMultiDiGraph(ctx=ctx), source)))
|
||||
|
||||
|
||||
# networkx.algorithms.dag.descendants
|
||||
@mgp.read_proc
|
||||
def descendants(ctx: mgp.ProcCtx,
|
||||
source: mgp.Vertex
|
||||
) -> mgp.Record(descendants=mgp.List[mgp.Vertex]):
|
||||
return mgp.Record(descendants=list(nx.descendants(
|
||||
MemgraphMultiDiGraph(ctx=ctx), source)))
|
||||
|
||||
|
||||
# networkx.algorithms.distance_measures.center
|
||||
#
|
||||
# NOTE: Takes more parameters.
|
||||
@mgp.read_proc
|
||||
def center(ctx: mgp.ProcCtx) -> mgp.Record(center=mgp.List[mgp.Vertex]):
|
||||
return mgp.Record(center=list(nx.center(MemgraphMultiDiGraph(ctx=ctx))))
|
||||
|
||||
|
||||
# networkx.algorithms.distance_measures.diameter
|
||||
#
|
||||
# NOTE: Takes more parameters.
|
||||
@mgp.read_proc
|
||||
def diameter(ctx: mgp.ProcCtx) -> mgp.Record(diameter=int):
|
||||
return mgp.Record(diameter=nx.diameter(MemgraphMultiDiGraph(ctx=ctx)))
|
||||
|
||||
|
||||
# networkx.algorithms.distance_regular.is_distance_regular
|
||||
@mgp.read_proc
|
||||
def is_distance_regular(ctx: mgp.ProcCtx
|
||||
) -> mgp.Record(is_distance_regular=bool):
|
||||
return mgp.Record(is_distance_regular=nx.is_distance_regular(
|
||||
MemgraphMultiGraph(ctx=ctx)))
|
||||
|
||||
|
||||
# networkx.algorithms.strongly_regular.is_strongly_regular
|
||||
@mgp.read_proc
|
||||
def is_strongly_regular(ctx: mgp.ProcCtx
|
||||
) -> mgp.Record(is_strongly_regular=bool):
|
||||
return mgp.Record(is_strongly_regular=nx.is_strongly_regular(
|
||||
MemgraphMultiGraph(ctx=ctx)))
|
||||
|
||||
|
||||
# networkx.algorithms.dominance.dominance_frontiers
|
||||
@mgp.read_proc
|
||||
def dominance_frontiers(ctx: mgp.ProcCtx, start: mgp.Vertex,
|
||||
) -> mgp.Record(node=mgp.Vertex,
|
||||
frontier=mgp.List[mgp.Vertex]):
|
||||
return [mgp.Record(node=n, frontier=list(f))
|
||||
for n, f in nx.dominance_frontiers(
|
||||
MemgraphMultiDiGraph(ctx=ctx), start).items()]
|
||||
|
||||
|
||||
# networkx.algorithms.dominance.immediate_dominatorss
|
||||
@mgp.read_proc
|
||||
def immediate_dominators(ctx: mgp.ProcCtx, start: mgp.Vertex,
|
||||
) -> mgp.Record(node=mgp.Vertex,
|
||||
dominator=mgp.Vertex):
|
||||
return [mgp.Record(node=n, dominator=d)
|
||||
for n, d in nx.immediate_dominators(
|
||||
MemgraphMultiDiGraph(ctx=ctx), start).items()]
|
||||
|
||||
|
||||
# networkx.algorithms.dominating.dominating_set
|
||||
@mgp.read_proc
|
||||
def dominating_set(ctx: mgp.ProcCtx, start: mgp.Vertex,
|
||||
) -> mgp.Record(dominating_set=mgp.List[mgp.Vertex]):
|
||||
return mgp.Record(dominating_set=list(nx.dominating_set(
|
||||
MemgraphMultiDiGraph(ctx=ctx), start)))
|
||||
|
||||
|
||||
# networkx.algorithms.efficiency_measures.local_efficiency
|
||||
@mgp.read_proc
|
||||
def local_efficiency(ctx: mgp.ProcCtx) -> mgp.Record(local_efficiency=float):
|
||||
return mgp.Record(local_efficiency=nx.local_efficiency(
|
||||
MemgraphMultiGraph(ctx=ctx)))
|
||||
|
||||
|
||||
# networkx.algorithms.efficiency_measures.global_efficiency
|
||||
@mgp.read_proc
|
||||
def global_efficiency(ctx: mgp.ProcCtx) -> mgp.Record(global_efficiency=float):
|
||||
return mgp.Record(global_efficiency=nx.global_efficiency(
|
||||
MemgraphMultiGraph(ctx=ctx)))
|
||||
|
||||
|
||||
# networkx.algorithms.euler.is_eulerian
|
||||
@mgp.read_proc
|
||||
def is_eulerian(ctx: mgp.ProcCtx) -> mgp.Record(is_eulerian=bool):
|
||||
return mgp.Record(is_eulerian=nx.is_eulerian(
|
||||
MemgraphMultiDiGraph(ctx=ctx)))
|
||||
|
||||
|
||||
# networkx.algorithms.euler.is_semieulerian
|
||||
@mgp.read_proc
|
||||
def is_semieulerian(ctx: mgp.ProcCtx) -> mgp.Record(is_semieulerian=bool):
|
||||
return mgp.Record(is_semieulerian=nx.is_semieulerian(
|
||||
MemgraphMultiDiGraph(ctx=ctx)))
|
||||
|
||||
|
||||
# networkx.algorithms.euler.has_eulerian_path
|
||||
@mgp.read_proc
|
||||
def has_eulerian_path(ctx: mgp.ProcCtx) -> mgp.Record(has_eulerian_path=bool):
|
||||
return mgp.Record(has_eulerian_path=nx.has_eulerian_path(
|
||||
MemgraphMultiDiGraph(ctx=ctx)))
|
||||
|
||||
|
||||
# networkx.algorithms.hierarchy.flow_hierarchy
|
||||
@mgp.read_proc
|
||||
def flow_hierarchy(ctx: mgp.ProcCtx,
|
||||
weight: mgp.Nullable[str] = None
|
||||
) -> mgp.Record(flow_hierarchy=float):
|
||||
return mgp.Record(flow_hierarchy=nx.flow_hierarchy(
|
||||
MemgraphMultiDiGraph(ctx=ctx), weight=weight))
|
||||
|
||||
|
||||
# networkx.algorithms.isolate.isolates
|
||||
@mgp.read_proc
|
||||
def isolates(ctx: mgp.ProcCtx) -> mgp.Record(isolates=mgp.List[mgp.Vertex]):
|
||||
return mgp.Record(isolates=list(nx.isolates(
|
||||
MemgraphMultiDiGraph(ctx=ctx))))
|
||||
|
||||
|
||||
# networkx.algorithms.isolate.is_isolate
|
||||
@mgp.read_proc
|
||||
def is_isolate(ctx: mgp.ProcCtx, n: mgp.Vertex
|
||||
) -> mgp.Record(is_isolate=bool):
|
||||
return mgp.Record(is_isolate=nx.is_isolate(
|
||||
MemgraphMultiDiGraph(ctx=ctx), n))
|
||||
|
||||
|
||||
# networkx.algorithms.isomorphism.is_isomorphic
|
||||
@mgp.read_proc
|
||||
def is_isomorphic(ctx: mgp.ProcCtx,
|
||||
nodes1: mgp.List[mgp.Vertex],
|
||||
edges1: mgp.List[mgp.Edge],
|
||||
nodes2: mgp.List[mgp.Vertex],
|
||||
edges2: mgp.List[mgp.Edge]
|
||||
) -> mgp.Record(is_isomorphic=bool):
|
||||
nodes1, edges1, nodes2, edges2 = map(set, [nodes1, edges1, nodes2, edges2])
|
||||
g = MemgraphMultiDiGraph(ctx=ctx)
|
||||
g1 = nx.subgraph_view(
|
||||
g, lambda n: n in nodes1, lambda n1, n2, e: e in edges1)
|
||||
g2 = nx.subgraph_view(
|
||||
g, lambda n: n in nodes2, lambda n1, n2, e: e in edges2)
|
||||
return mgp.Record(is_isomorphic=nx.is_isomorphic(g1, g2))
|
||||
|
||||
|
||||
# networkx.algorithms.link_analysis.pagerank_alg.pagerank
|
||||
@mgp.read_proc
|
||||
def pagerank(ctx: mgp.ProcCtx,
|
||||
alpha: mgp.Number = 0.85,
|
||||
personalization: mgp.Nullable[str] = None,
|
||||
max_iter: int = 100,
|
||||
tol: mgp.Number = 1e-06,
|
||||
nstart: mgp.Nullable[str] = None,
|
||||
weight: mgp.Nullable[str] = 'weight',
|
||||
dangling: mgp.Nullable[str] = None,
|
||||
) -> mgp.Record(node=mgp.Vertex, rank=float):
|
||||
def to_properties_dictionary(prop):
|
||||
return None if prop is None else PropertiesDictionary(ctx, prop)
|
||||
|
||||
pg = nx.pagerank(MemgraphDiGraph(ctx=ctx), alpha=alpha,
|
||||
personalization=to_properties_dictionary(personalization),
|
||||
max_iter=max_iter, tol=tol,
|
||||
nstart=to_properties_dictionary(nstart), weight=weight,
|
||||
dangling=to_properties_dictionary(dangling))
|
||||
|
||||
return [mgp.Record(node=k, rank=v) for k, v in pg.items()]
|
||||
|
||||
|
||||
# networkx.algorithms.link_prediction.jaccard_coefficient
|
||||
@mgp.read_proc
|
||||
def jaccard_coefficient(
|
||||
ctx: mgp.ProcCtx,
|
||||
ebunch: mgp.Nullable[mgp.List[mgp.List[mgp.Vertex]]] = None
|
||||
) -> mgp.Record(u=mgp.Vertex, v=mgp.Vertex,
|
||||
coef=float):
|
||||
return [mgp.Record(u=u, v=v, coef=c) for u, v, c
|
||||
in nx.jaccard_coefficient(MemgraphGraph(ctx=ctx), ebunch)]
|
||||
|
||||
|
||||
# networkx.algorithms.lowest_common_ancestors.lowest_common_ancestor
|
||||
@mgp.read_proc
|
||||
def lowest_common_ancestor(ctx: mgp.ProcCtx, node1: mgp.Vertex,
|
||||
node2: mgp.Vertex
|
||||
) -> mgp.Record(ancestor=mgp.Nullable[mgp.Vertex]):
|
||||
return mgp.Record(ancestor=nx.lowest_common_ancestor(
|
||||
MemgraphDiGraph(ctx=ctx), node1, node2))
|
||||
|
||||
|
||||
# networkx.algorithms.matching.maximal_matching
|
||||
@mgp.read_proc
|
||||
def maximal_matching(ctx: mgp.ProcCtx) -> mgp.Record(edges=mgp.List[mgp.Edge]):
|
||||
g = MemgraphMultiDiGraph(ctx=ctx)
|
||||
return mgp.Record(edges=list(
|
||||
next(iter(g[u][v])) for u, v in nx.maximal_matching(g)))
|
||||
|
||||
|
||||
# networkx.algorithms.planarity.check_planarity
|
||||
#
|
||||
# NOTE: Returns a graph.
|
||||
@mgp.read_proc
|
||||
def check_planarity(ctx: mgp.ProcCtx) -> mgp.Record(is_planar=bool):
|
||||
return mgp.Record(is_planar=nx.check_planarity(
|
||||
MemgraphMultiDiGraph(ctx=ctx))[0])
|
||||
|
||||
|
||||
# networkx.algorithms.non_randomness.non_randomness
|
||||
@mgp.read_proc
|
||||
def non_randomness(ctx: mgp.ProcCtx,
|
||||
k: mgp.Nullable[int] = None
|
||||
) -> mgp.Record(non_randomness=float,
|
||||
relative_non_randomness=float):
|
||||
nn, rnn = nx.non_randomness(
|
||||
MemgraphGraph(ctx=ctx), k=k)
|
||||
return mgp.Record(non_randomness=nn, relative_non_randomness=rnn)
|
||||
|
||||
|
||||
# networkx.algorithms.reciprocity.reciprocity
|
||||
@mgp.read_proc
|
||||
def reciprocity(ctx: mgp.ProcCtx,
|
||||
nodes: mgp.Nullable[mgp.List[mgp.Vertex]] = None
|
||||
) -> mgp.Record(node=mgp.Nullable[mgp.Vertex],
|
||||
reciprocity=mgp.Nullable[float]):
|
||||
rp = nx.reciprocity(MemgraphMultiDiGraph(ctx=ctx), nodes=nodes)
|
||||
if nodes is None:
|
||||
return mgp.Record(node=None, reciprocity=rp)
|
||||
else:
|
||||
return [mgp.Record(node=n, reciprocity=r) for n, r in rp.items()]
|
||||
|
||||
|
||||
# networkx.algorithms.shortest_paths.generic.shortest_path
|
||||
@mgp.read_proc
|
||||
def shortest_path(ctx: mgp.ProcCtx,
|
||||
source: mgp.Nullable[mgp.Vertex] = None,
|
||||
target: mgp.Nullable[mgp.Vertex] = None,
|
||||
weight: mgp.Nullable[str] = None,
|
||||
method: str = 'dijkstra'
|
||||
) -> mgp.Record(source=mgp.Vertex, target=mgp.Vertex,
|
||||
path=mgp.List[mgp.Vertex]):
|
||||
sp = nx.shortest_path(MemgraphMultiDiGraph(ctx=ctx), source=source,
|
||||
target=target, weight=weight, method=method)
|
||||
|
||||
if source and target:
|
||||
sp = {source: {target: sp}}
|
||||
elif source and not target:
|
||||
sp = {source: sp}
|
||||
elif not source and target:
|
||||
sp = {source: {target: p} for source, p in sp.items()}
|
||||
|
||||
return [mgp.Record(source=s, target=t, path=p)
|
||||
for s, d in sp.items()
|
||||
for t, p in d.items()]
|
||||
|
||||
|
||||
# networkx.algorithms.shortest_paths.generic.shortest_path_length
|
||||
@mgp.read_proc
|
||||
def shortest_path_length(ctx: mgp.ProcCtx,
|
||||
source: mgp.Nullable[mgp.Vertex] = None,
|
||||
target: mgp.Nullable[mgp.Vertex] = None,
|
||||
weight: mgp.Nullable[str] = None,
|
||||
method: str = 'dijkstra'
|
||||
) -> mgp.Record(source=mgp.Vertex, target=mgp.Vertex,
|
||||
length=mgp.Number):
|
||||
sp = nx.shortest_path_length(MemgraphMultiDiGraph(ctx=ctx), source=source,
|
||||
target=target, weight=weight, method=method)
|
||||
|
||||
if source and target:
|
||||
sp = {source: {target: sp}}
|
||||
elif source and not target:
|
||||
sp = {source: sp}
|
||||
elif not source and target:
|
||||
sp = {source: {target: l} for source, l in sp.items()}
|
||||
else:
|
||||
sp = dict(sp)
|
||||
|
||||
return [mgp.Record(source=s, target=t, length=l)
|
||||
for s, d in sp.items()
|
||||
for t, l in d.items()]
|
||||
|
||||
|
||||
# networkx.algorithms.shortest_paths.generic.all_shortest_paths
|
||||
@mgp.read_proc
|
||||
def all_shortest_paths(ctx: mgp.ProcCtx,
|
||||
source: mgp.Vertex,
|
||||
target: mgp.Vertex,
|
||||
weight: mgp.Nullable[str] = None,
|
||||
method: str = 'dijkstra'
|
||||
) -> mgp.Record(paths=mgp.List[mgp.List[mgp.Vertex]]):
|
||||
return mgp.Record(paths=list(nx.all_shortest_paths(
|
||||
MemgraphMultiDiGraph(ctx=ctx), source=source, target=target,
|
||||
weight=weight, method=method)))
|
||||
|
||||
|
||||
# networkx.algorithms.shortest_paths.generic.has_path
|
||||
@mgp.read_proc
|
||||
def has_path(ctx: mgp.ProcCtx,
|
||||
source: mgp.Vertex,
|
||||
target: mgp.Vertex) -> mgp.Record(has_path=bool):
|
||||
return mgp.Record(has_path=nx.has_path(MemgraphMultiDiGraph(ctx=ctx),
|
||||
source, target))
|
||||
|
||||
|
||||
# networkx.algorithms.shortest_paths.weighted.multi_source_dijkstra_path
|
||||
@mgp.read_proc
|
||||
def multi_source_dijkstra_path(ctx: mgp.ProcCtx,
|
||||
sources: mgp.List[mgp.Vertex],
|
||||
cutoff: mgp.Nullable[int] = None,
|
||||
weight: str = 'weight'
|
||||
) -> mgp.Record(target=mgp.Vertex,
|
||||
path=mgp.List[mgp.Vertex]):
|
||||
return [mgp.Record(target=t, path=p)
|
||||
for t, p in nx.multi_source_dijkstra_path(
|
||||
MemgraphMultiDiGraph(ctx=ctx), sources, cutoff=cutoff,
|
||||
weight=weight).items()]
|
||||
|
||||
|
||||
# networkx.algorithms.shortest_paths.weighted.multi_source_dijkstra_path_length
|
||||
@mgp.read_proc
|
||||
def multi_source_dijkstra_path_length(ctx: mgp.ProcCtx,
|
||||
sources: mgp.List[mgp.Vertex],
|
||||
cutoff: mgp.Nullable[int] = None,
|
||||
weight: str = 'weight'
|
||||
) -> mgp.Record(target=mgp.Vertex,
|
||||
length=mgp.Number):
|
||||
return [mgp.Record(target=t, length=l)
|
||||
for t, l in nx.multi_source_dijkstra_path_length(
|
||||
MemgraphMultiDiGraph(ctx=ctx), sources, cutoff=cutoff,
|
||||
weight=weight).items()]
|
||||
|
||||
|
||||
# networkx.algorithms.simple_paths.is_simple_path
|
||||
@mgp.read_proc
|
||||
def is_simple_path(ctx: mgp.ProcCtx,
|
||||
nodes: mgp.List[mgp.Vertex]
|
||||
) -> mgp.Record(is_simple_path=bool):
|
||||
return mgp.Record(is_simple_path=nx.is_simple_path(
|
||||
MemgraphMultiDiGraph(ctx=ctx), nodes))
|
||||
|
||||
|
||||
# networkx.algorithms.simple_paths.all_simple_paths
|
||||
@mgp.read_proc
|
||||
def all_simple_paths(ctx: mgp.ProcCtx,
|
||||
source: mgp.Vertex,
|
||||
target: mgp.Vertex,
|
||||
cutoff: mgp.Nullable[int] = None
|
||||
) -> mgp.Record(paths=mgp.List[mgp.List[mgp.Vertex]]):
|
||||
return mgp.Record(paths=list(nx.all_simple_paths(
|
||||
MemgraphMultiDiGraph(ctx=ctx), source, target, cutoff=cutoff)))
|
||||
|
||||
|
||||
# networkx.algorithms.tournament.is_tournament
|
||||
@mgp.read_proc
|
||||
def is_tournament(ctx: mgp.ProcCtx) -> mgp.Record(is_tournament=bool):
|
||||
return mgp.Record(is_tournament=nx.tournament.is_tournament(
|
||||
MemgraphDiGraph(ctx=ctx)))
|
||||
|
||||
|
||||
# networkx.algorithms.traversal.breadth_first_search.bfs_edges
|
||||
@mgp.read_proc
|
||||
def bfs_edges(ctx: mgp.ProcCtx,
|
||||
source: mgp.Vertex,
|
||||
reverse: bool = False,
|
||||
depth_limit: mgp.Nullable[int] = None
|
||||
) -> mgp.Record(edges=mgp.List[mgp.Edge]):
|
||||
return mgp.Record(edges=list(nx.bfs_edges(
|
||||
MemgraphMultiDiGraph(ctx=ctx), source, reverse=reverse,
|
||||
depth_limit=depth_limit)))
|
||||
|
||||
|
||||
# networkx.algorithms.traversal.breadth_first_search.bfs_tree
|
||||
@mgp.read_proc
|
||||
def bfs_tree(ctx: mgp.ProcCtx,
|
||||
source: mgp.Vertex,
|
||||
reverse: bool = False,
|
||||
depth_limit: mgp.Nullable[int] = None
|
||||
) -> mgp.Record(tree=mgp.List[mgp.Vertex]):
|
||||
return mgp.Record(tree=list(nx.bfs_tree(
|
||||
MemgraphMultiDiGraph(ctx=ctx), source, reverse=reverse,
|
||||
depth_limit=depth_limit)))
|
||||
|
||||
|
||||
# networkx.algorithms.traversal.breadth_first_search.bfs_predecessors
|
||||
@mgp.read_proc
|
||||
def bfs_predecessors(ctx: mgp.ProcCtx,
|
||||
source: mgp.Vertex,
|
||||
depth_limit: mgp.Nullable[int] = None
|
||||
) -> mgp.Record(node=mgp.Vertex,
|
||||
predecessor=mgp.Vertex):
|
||||
return [mgp.Record(node=n, predecessor=p)
|
||||
for n, p in nx.bfs_predecessors(
|
||||
MemgraphMultiDiGraph(ctx=ctx), source,
|
||||
depth_limit=depth_limit)]
|
||||
|
||||
|
||||
# networkx.algorithms.traversal.breadth_first_search.bfs_successors
|
||||
@mgp.read_proc
|
||||
def bfs_successors(ctx: mgp.ProcCtx,
|
||||
source: mgp.Vertex,
|
||||
depth_limit: mgp.Nullable[int] = None
|
||||
) -> mgp.Record(node=mgp.Vertex,
|
||||
successors=mgp.List[mgp.Vertex]):
|
||||
return [mgp.Record(node=n, successors=s)
|
||||
for n, s in nx.bfs_successors(
|
||||
MemgraphMultiDiGraph(ctx=ctx), source,
|
||||
depth_limit=depth_limit)]
|
||||
|
||||
|
||||
# networkx.algorithms.traversal.depth_first_search.dfs_tree
|
||||
@mgp.read_proc
|
||||
def dfs_tree(ctx: mgp.ProcCtx,
|
||||
source: mgp.Vertex,
|
||||
depth_limit: mgp.Nullable[int] = None
|
||||
) -> mgp.Record(tree=mgp.List[mgp.Vertex]):
|
||||
return mgp.Record(tree=list(nx.dfs_tree(
|
||||
MemgraphMultiDiGraph(ctx=ctx), source, depth_limit=depth_limit)))
|
||||
|
||||
|
||||
# networkx.algorithms.traversal.depth_first_search.dfs_predecessors
|
||||
@mgp.read_proc
|
||||
def dfs_predecessors(ctx: mgp.ProcCtx,
|
||||
source: mgp.Vertex,
|
||||
depth_limit: mgp.Nullable[int] = None
|
||||
) -> mgp.Record(node=mgp.Vertex,
|
||||
predecessor=mgp.Vertex):
|
||||
return [mgp.Record(node=n, predecessor=p)
|
||||
for n, p in nx.dfs_predecessors(
|
||||
MemgraphMultiDiGraph(ctx=ctx), source,
|
||||
depth_limit=depth_limit).items()]
|
||||
|
||||
|
||||
# networkx.algorithms.traversal.depth_first_search.dfs_successors
|
||||
@mgp.read_proc
|
||||
def dfs_successors(ctx: mgp.ProcCtx,
|
||||
source: mgp.Vertex,
|
||||
depth_limit: mgp.Nullable[int] = None
|
||||
) -> mgp.Record(node=mgp.Vertex,
|
||||
successors=mgp.List[mgp.Vertex]):
|
||||
return [mgp.Record(node=n, successors=s)
|
||||
for n, s in nx.dfs_successors(
|
||||
MemgraphMultiDiGraph(ctx=ctx), source,
|
||||
depth_limit=depth_limit).items()]
|
||||
|
||||
|
||||
# networkx.algorithms.traversal.depth_first_search.dfs_preorder_nodes
|
||||
@mgp.read_proc
|
||||
def dfs_preorder_nodes(ctx: mgp.ProcCtx,
|
||||
source: mgp.Vertex,
|
||||
depth_limit: mgp.Nullable[int] = None
|
||||
) -> mgp.Record(nodes=mgp.List[mgp.Vertex]):
|
||||
return mgp.Record(nodes=list(nx.dfs_preorder_nodes(
|
||||
MemgraphMultiDiGraph(ctx=ctx), source, depth_limit=depth_limit)))
|
||||
|
||||
|
||||
# networkx.algorithms.traversal.depth_first_search.dfs_postorder_nodes
|
||||
@mgp.read_proc
|
||||
def dfs_postorder_nodes(ctx: mgp.ProcCtx,
|
||||
source: mgp.Vertex,
|
||||
depth_limit: mgp.Nullable[int] = None
|
||||
) -> mgp.Record(nodes=mgp.List[mgp.Vertex]):
|
||||
return mgp.Record(nodes=list(nx.dfs_postorder_nodes(
|
||||
MemgraphMultiDiGraph(ctx=ctx), source, depth_limit=depth_limit)))
|
||||
|
||||
|
||||
# networkx.algorithms.traversal.edgebfs.edge_bfs
|
||||
@mgp.read_proc
|
||||
def edge_bfs(ctx: mgp.ProcCtx,
|
||||
source: mgp.Nullable[mgp.Vertex] = None,
|
||||
orientation: mgp.Nullable[str] = None
|
||||
) -> mgp.Record(edges=mgp.List[mgp.Edge]):
|
||||
return mgp.Record(edges=list(e for _, _, e in nx.edge_bfs(
|
||||
MemgraphMultiDiGraph(ctx=ctx), source=source,
|
||||
orientation=orientation)))
|
||||
|
||||
|
||||
# networkx.algorithms.traversal.edgedfs.edge_dfs
|
||||
@mgp.read_proc
|
||||
def edge_dfs(ctx: mgp.ProcCtx,
|
||||
source: mgp.Nullable[mgp.Vertex] = None,
|
||||
orientation: mgp.Nullable[str] = None
|
||||
) -> mgp.Record(edges=mgp.List[mgp.Edge]):
|
||||
return mgp.Record(edges=list(e for _, _, e in nx.edge_dfs(
|
||||
MemgraphMultiDiGraph(ctx=ctx), source=source,
|
||||
orientation=orientation)))
|
||||
|
||||
|
||||
# networkx.algorithms.tree.recognition.is_tree
|
||||
@mgp.read_proc
|
||||
def is_tree(ctx: mgp.ProcCtx) -> mgp.Record(is_tree=bool):
|
||||
return mgp.Record(is_tree=nx.is_tree(MemgraphDiGraph(ctx=ctx)))
|
||||
|
||||
|
||||
# networkx.algorithms.tree.recognition.is_forest
|
||||
@mgp.read_proc
|
||||
def is_forest(ctx: mgp.ProcCtx) -> mgp.Record(is_forest=bool):
|
||||
return mgp.Record(is_forest=nx.is_forest(MemgraphDiGraph(ctx=ctx)))
|
||||
|
||||
|
||||
# networkx.algorithms.tree.recognition.is_arborescence
|
||||
@mgp.read_proc
|
||||
def is_arborescence(ctx: mgp.ProcCtx) -> mgp.Record(is_arborescence=bool):
|
||||
return mgp.Record(is_arborescence=nx.is_arborescence(
|
||||
MemgraphDiGraph(ctx=ctx)))
|
||||
|
||||
|
||||
# networkx.algorithms.tree.recognition.is_branching
|
||||
@mgp.read_proc
|
||||
def is_branching(ctx: mgp.ProcCtx) -> mgp.Record(is_branching=bool):
|
||||
return mgp.Record(is_branching=nx.is_branching(MemgraphDiGraph(ctx=ctx)))
|
||||
|
||||
|
||||
# networkx.algorithms.tree.mst.minimum_spanning_tree
|
||||
@mgp.read_proc
|
||||
def minimum_spanning_tree(ctx: mgp.ProcCtx,
|
||||
weight: str = 'weight',
|
||||
algorithm: str = 'kruskal',
|
||||
ignore_nan: bool = False
|
||||
) -> mgp.Record(nodes=mgp.List[mgp.Vertex],
|
||||
edges=mgp.List[mgp.Edge]):
|
||||
gres = nx.minimum_spanning_tree(MemgraphMultiGraph(ctx=ctx),
|
||||
weight, algorithm, ignore_nan)
|
||||
return mgp.Record(nodes=list(gres.nodes()),
|
||||
edges=[e for _, _, e in gres.edges(keys=True)])
|
||||
|
||||
|
||||
# networkx.algorithms.triads.triadic_census
|
||||
@mgp.read_proc
|
||||
def triadic_census(ctx: mgp.ProcCtx) -> mgp.Record(triad=str, count=int):
|
||||
return [mgp.Record(triad=t, count=c)
|
||||
for t, c in nx.triadic_census(MemgraphDiGraph(ctx=ctx)).items()]
|
||||
|
||||
|
||||
# networkx.algorithms.voronoi.voronoi_cells
|
||||
@mgp.read_proc
|
||||
def voronoi_cells(ctx: mgp.ProcCtx,
|
||||
center_nodes: mgp.List[mgp.Vertex],
|
||||
weight: str = 'weight'
|
||||
) -> mgp.Record(center=mgp.Vertex,
|
||||
cell=mgp.List[mgp.Vertex]):
|
||||
return [mgp.Record(center=c1, cell=list(c2))
|
||||
for c1, c2 in nx.voronoi_cells(
|
||||
MemgraphMultiDiGraph(ctx=ctx), center_nodes,
|
||||
weight=weight).items()]
|
||||
|
||||
|
||||
# networkx.algorithms.wiener.wiener_index
|
||||
@mgp.read_proc
|
||||
def wiener_index(ctx: mgp.ProcCtx, weight: mgp.Nullable[str] = None
|
||||
) -> mgp.Record(wiener_index=mgp.Number):
|
||||
return mgp.Record(wiener_index=nx.wiener_index(
|
||||
MemgraphMultiDiGraph(ctx=ctx), weight=weight))
|
||||
@@ -1,51 +0,0 @@
|
||||
import sys
|
||||
import mgp
|
||||
try:
|
||||
import networkx as nx
|
||||
except ImportError as import_error:
|
||||
sys.stderr.write(
|
||||
'\n'
|
||||
'NOTE: Please install networkx to be able to use wcc module.\n'
|
||||
'Using Python:\n'
|
||||
+ sys.version +
|
||||
'\n')
|
||||
raise import_error
|
||||
|
||||
|
||||
@mgp.read_proc
|
||||
def get_components(vertices: mgp.List[mgp.Vertex],
|
||||
edges: mgp.List[mgp.Edge]
|
||||
) -> mgp.Record(n_components=int,
|
||||
components=mgp.List[mgp.List[mgp.Vertex]]):
|
||||
'''
|
||||
This procedure finds weakly connected components of a given subgraph of a
|
||||
directed graph.
|
||||
|
||||
The subgraph is defined by a list of vertices and a list edges which are
|
||||
passed as arguments of the procedure. More precisely, a set of vertices of
|
||||
a subgraph contains all vertices provided in a list of vertices along with
|
||||
all vertices that are endpoints of provided edges. Similarly, a set of
|
||||
edges of a subgraph contains all edges from the list of provided edges.
|
||||
|
||||
The procedure returns 2 fields:
|
||||
* `n_components` is the number of weakly connected components of the
|
||||
subgraph.
|
||||
* `components` is a list of weakly connected components. Each component
|
||||
is given as a list of `mgp.Vertex` objects from that component.
|
||||
|
||||
For example, weakly connected components in a subgraph formed from all
|
||||
vertices labeled `Person` and edges between such vertices can be obtained
|
||||
using the following openCypher query:
|
||||
|
||||
MATCH (n:Person)-[e]->(m:Person)
|
||||
WITH collect(n) AS nodes, collect(e) AS edges
|
||||
CALL wcc.get_components(nodes, edges) YIELD *
|
||||
RETURN n_components, components;
|
||||
'''
|
||||
g = nx.DiGraph()
|
||||
g.add_nodes_from(vertices)
|
||||
g.add_edges_from([(edge.from_vertex, edge.to_vertex) for edge in edges])
|
||||
|
||||
components = [list(wcc) for wcc in nx.weakly_connected_components(g)]
|
||||
|
||||
return mgp.Record(n_components=len(components), components=components)
|
||||
@@ -1,84 +0,0 @@
|
||||
# Install the license file.
|
||||
if (MG_ENTERPRISE)
|
||||
install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/LICENSE_ENTERPRISE.md
|
||||
DESTINATION share/doc/memgraph RENAME copyright)
|
||||
else()
|
||||
install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/LICENSE_COMMUNITY.md
|
||||
DESTINATION share/doc/memgraph RENAME copyright)
|
||||
endif()
|
||||
|
||||
install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/third-party-licenses
|
||||
DESTINATION share/doc/memgraph)
|
||||
|
||||
# Install systemd service (must use absolute path).
|
||||
install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/memgraph.service
|
||||
DESTINATION /lib/systemd/system)
|
||||
|
||||
# ---- Setup CPack --------
|
||||
|
||||
# General setup
|
||||
set(CPACK_PACKAGE_NAME memgraph)
|
||||
set(CPACK_PACKAGE_VENDOR "Memgraph Ltd.")
|
||||
set(CPACK_PACKAGE_DESCRIPTION_SUMMARY
|
||||
"High performance, in-memory, transactional graph database")
|
||||
|
||||
# DEB specific
|
||||
# Instead of using "name <email>" format, we use "email (name)" to prevent
|
||||
# errors due to full stop, '.' at the end of "Ltd". (See: RFC 822)
|
||||
set(CPACK_DEBIAN_PACKAGE_MAINTAINER "tech@memgraph.com (Memgraph Ltd.)")
|
||||
set(CPACK_DEBIAN_PACKAGE_SECTION non-free/database)
|
||||
set(CPACK_DEBIAN_PACKAGE_HOMEPAGE https://memgraph.com)
|
||||
set(CPACK_DEBIAN_PACKAGE_VERSION "${MEMGRAPH_VERSION_DEB}")
|
||||
set(CPACK_DEBIAN_FILE_NAME "memgraph_${MEMGRAPH_VERSION_DEB}_amd64.deb")
|
||||
if (MG_ENTERPRISE)
|
||||
set(CPACK_DEBIAN_PACKAGE_CONTROL_EXTRA
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/debian/enterprise/conffiles;"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/debian/enterprise/copyright;"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/debian/preinst;"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/debian/prerm;"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/debian/postrm;"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/debian/postinst;")
|
||||
else()
|
||||
set(CPACK_DEBIAN_PACKAGE_CONTROL_EXTRA
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/debian/community/conffiles;"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/debian/community/copyright;"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/debian/preinst;"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/debian/prerm;"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/debian/postrm;"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/debian/postinst;")
|
||||
endif()
|
||||
set(CPACK_DEBIAN_PACKAGE_SHLIBDEPS ON)
|
||||
# Description formatting is important, summary must be followed with a newline and 1 space.
|
||||
set(CPACK_DEBIAN_PACKAGE_DESCRIPTION "${CPACK_PACKAGE_DESCRIPTION_SUMMARY}
|
||||
Contains Memgraph, the graph database. It aims to deliver developers the
|
||||
speed, simplicity and scale required to build the next generation of
|
||||
applications driver by real-time connected data.")
|
||||
# Add `openssl` package to dependencies list. Used to generate SSL certificates.
|
||||
# We also depend on `python3` because we embed it in Memgraph.
|
||||
set(CPACK_DEBIAN_PACKAGE_DEPENDS "openssl (>= 1.1.0), python3 (>= 3.5.0)")
|
||||
|
||||
# RPM specific
|
||||
set(CPACK_RPM_PACKAGE_URL https://memgraph.com)
|
||||
set(CPACK_RPM_PACKAGE_VERSION "${MEMGRAPH_VERSION_RPM}")
|
||||
set(CPACK_RPM_FILE_NAME "memgraph-${MEMGRAPH_VERSION_RPM}-1.x86_64.rpm")
|
||||
set(CPACK_RPM_EXCLUDE_FROM_AUTO_FILELIST_ADDITION
|
||||
/var /var/lib /var/log /etc/logrotate.d
|
||||
/lib /lib/systemd /lib/systemd/system /lib/systemd/system/memgraph.service)
|
||||
set(CPACK_RPM_PACKAGE_REQUIRES_PRE "shadow-utils")
|
||||
if (MG_ENTERPRISE)
|
||||
set(CPACK_RPM_USER_BINARY_SPECFILE "${CMAKE_CURRENT_SOURCE_DIR}/rpm/enterprise/memgraph.spec.in")
|
||||
set(CPACK_RPM_PACKAGE_LICENSE "Memgraph Enterprise Trial License")
|
||||
else()
|
||||
set(CPACK_RPM_USER_BINARY_SPECFILE "${CMAKE_CURRENT_SOURCE_DIR}/rpm/community/memgraph.spec.in")
|
||||
set(CPACK_RPM_PACKAGE_LICENSE "Memgraph Community License")
|
||||
endif()
|
||||
# Description formatting is important, no line must be greater than 80 characters.
|
||||
set(CPACK_RPM_PACKAGE_DESCRIPTION "Contains Memgraph, the graph database.
|
||||
It aims to deliver developers the speed, simplicity and scale required to build
|
||||
the next generation of applications driver by real-time connected data.")
|
||||
# Add `openssl` package to dependencies list. Used to generate SSL certificates.
|
||||
# We also depend on `python3` because we embed it in Memgraph.
|
||||
set(CPACK_RPM_PACKAGE_REQUIRES "openssl >= 1.0.0, curl >= 7.29.0, python3 >= 3.5.0")
|
||||
|
||||
# All variables must be set before including.
|
||||
include(CPack)
|
||||
@@ -1,98 +0,0 @@
|
||||
# Memgraph Community User License Agreement
|
||||
|
||||
This License Agreement governs your use of the Memgraph Community Release (the
|
||||
"Software") and documentation ("Documentation").
|
||||
|
||||
BY DOWNLOADING AND/OR ACCESSING THIS SOFTWARE, YOU ("LICENSEE") AGREE TO THESE
|
||||
TERMS.
|
||||
|
||||
1. License Grant
|
||||
|
||||
The Software and Documentation are provided to Licensee at no charge and are
|
||||
licensed, not sold to Licensee. No ownership of any part of the Software and
|
||||
Documentation is hereby transferred to Licensee. Subject to (i) the terms and
|
||||
conditions of this License Agreement, and (ii) any additional license
|
||||
restrictions and parameters contained on Licensor’s quotation, website, or
|
||||
order form, Licensor hereby grants Licensee a personal, non-assignable,
|
||||
non-transferable and non-exclusive license to install, access and use the
|
||||
Software (in object code form only) and Documentation for Licensee’s internal
|
||||
business purposes (including for use in a production environment) only. All
|
||||
rights relating to the Software and Documentation that are not expressly
|
||||
licensed in this License Agreement, whether now existing or which may hereafter
|
||||
come into existence are reserved for Licensor. Licensee shall not remove,
|
||||
obscure, or alter any proprietary rights notices (including without limitation
|
||||
copyright and trademark notices), which may be affixed to or contained within
|
||||
the Software or Documentation.
|
||||
|
||||
Licensor may terminate this License Agreement with immediate effect upon
|
||||
written notice to the Licensee. Upon termination Licensee shall delete all
|
||||
electronic copies of all or any part of the Software and/or the Documentation
|
||||
resident in its systems or elsewhere.
|
||||
|
||||
2. Restrictions
|
||||
|
||||
Licensee will not, directly or indirectly, (a) copy the Software or
|
||||
Documentation in any manner or for any purpose; (b) install, access or use any
|
||||
component of the Software or Documentation for any purpose not expressly
|
||||
granted in Section 1 above; (c) resell, distribute, publicly display or
|
||||
publicly perform the Software or Documentation or any component thereof, by
|
||||
transfer, lease, loan or any other means, or make it available for use by
|
||||
others in any time-sharing, service bureau or similar arrangement; (d)
|
||||
disassemble, decrypt, extract, reverse engineer or reverse compile the
|
||||
Software, or otherwise attempt to discover the source code, confidential
|
||||
algorithms or techniques incorporated in the Software; (e) export the Software
|
||||
or Documentation in violation of any applicable laws or regulations; (f)
|
||||
modify, translate, adapt, or create derivative works from the Software or
|
||||
Documentation; (g) circumvent, disable or otherwise interfere with
|
||||
security-related features of the Software or Documentation; (h) use the
|
||||
Software or Documentation for any illegal purpose, in any manner that is
|
||||
inconsistent with the terms of this License Agreement, or to engage in illegal
|
||||
activity; (i) remove or alter any trademark, logo, copyright or other
|
||||
proprietary notices, legends, symbols or labels on, or embedded in, the
|
||||
Software or Documentation; or (j) provide access to the Software or
|
||||
Documentation to third parties.
|
||||
|
||||
3. Warranty Disclaimer
|
||||
|
||||
THE SOFTWARE AND DOCUMENTATION ARE PROVIDED "AS IS" AND LICENSOR MAKES NO
|
||||
WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE OR NON
|
||||
INFRINGEMENT OF THIRD PARTIES’ INTELLECTUAL PROPERTY RIGHTS OR OTHER
|
||||
PROPRIETARY RIGHTS. NEITHER THIS LICENSE AGREEMENT NOR ANY DOCUMENTATION
|
||||
FURNISHED UNDER IT IS INTENDED TO EXPRESS OR IMPLY ANY WARRANTY THAT THE
|
||||
OPERATION OF THE SOFTWARE WILL BE UNINTERRUPTED, TIMELY, OR ERROR-FREE.
|
||||
|
||||
4. Limitation of Liability
|
||||
|
||||
Licensor shall not in any circumstances be liable, whether in tort (including
|
||||
for negligence or breach of statutory duty howsoever arising), contract,
|
||||
misrepresentation (whether innocent or negligent) or otherwise for: loss of
|
||||
profits, loss of business, depletion of goodwill or similar losses, loss of
|
||||
anticipated savings, loss of goods, loss or corruption of data or computer
|
||||
downtime, or any special, indirect, consequential or pure economic loss, costs,
|
||||
damages, charges or expenses.
|
||||
|
||||
Licensor's total aggregate liability in contract, tort (including without
|
||||
limitation negligence or breach of statutory duty howsoever arising),
|
||||
misrepresentation (whether innocent or negligent), restitution or otherwise,
|
||||
arising in connection with the performance or contemplated performance of this
|
||||
License Agreement shall in all circumstances be limited to GBP10.00 (ten pounds
|
||||
sterling).
|
||||
|
||||
Nothing in this License Agreement shall limit Licensor’s liability in the case
|
||||
of death or personal injury caused by negligence, fraud, or fraudulent
|
||||
misrepresentation, or where it otherwise cannot be limited by law.
|
||||
|
||||
5. Technical Data
|
||||
|
||||
Licensor may collect and use technical information (such as usage patterns)
|
||||
gathered when the Licensee downloads and uses the Software. This is generally
|
||||
statistical data which does not identify an identified or identifiable
|
||||
individual. It may also include Licensee’s IP address which is personal data
|
||||
and is processed in accordance with our Privacy Policy. We only use this
|
||||
technical information to improve our products.
|
||||
|
||||
6. Law and Jurisdiction
|
||||
|
||||
This License Agreement is governed by the laws of England and is subject to the
|
||||
non-exclusive jurisdiction of the courts of England.
|
||||
@@ -1,671 +0,0 @@
|
||||
# Memgraph Enterprise - Software Subscription Agreement
|
||||
|
||||
Memgraph Limited is registered in England under registration 10195084 and has
|
||||
its registered office at Suite 4, Ironstone House, Ironstone Way, Brixworth,
|
||||
Northampton, NN6 9UD ("Memgraph").
|
||||
|
||||
Memgraph agrees to license and/or grant you (the "Customer") access to the
|
||||
Software, as defined below and provide support and services to you only if you
|
||||
accept and agree to be bound by the terms and conditions in this Software
|
||||
Subscription Agreement (the "Agreement"). By signing an Order Document (as
|
||||
defined below), which is subject to and part of this Agreement, installing and
|
||||
using the Software or by downloading a trial version of the Software, you agree
|
||||
to be bound by the terms of this Agreement.
|
||||
|
||||
Memgraph Enterprise Trial Users: If you receive free of charge trial access to
|
||||
the Software, you are deemed a "Customer" for purposes of this Agreement except
|
||||
that you are subject to the additional restrictions and limitations set forth
|
||||
in Section 3.2 below as to such Software.
|
||||
|
||||
## 1. DEFINITIONS.
|
||||
|
||||
1.1. "Applicable Laws" means (i) all applicable laws, statutes and regulations,
|
||||
and (ii) regulatory policies, guidelines and industry codes (in each case
|
||||
having the force of law), which apply to the provisions of the Software and
|
||||
Services and this Agreement.
|
||||
|
||||
1.2. "Confidential Information" means all information disclosed
|
||||
by a party ("Disclosing Party") to the other party ("Receiving Party"), whether
|
||||
orally or in writing, that is designated as confidential or that reasonably
|
||||
should be understood to be confidential given the nature of the information and
|
||||
the circumstances of disclosure. Customer's Confidential Information includes
|
||||
Customer Data; Memgraph Confidential Information includes the Software and
|
||||
Services; and Confidential Information of each party includes the terms and
|
||||
conditions of this Agreement and all Orders (including pricing), as well as
|
||||
business and marketing plans, technology and technical information, product
|
||||
plans and designs, and business processes disclosed by such party. However,
|
||||
Confidential Information does not include any information that (i) is or
|
||||
becomes generally known to the public without breach of any obligation owed to
|
||||
the Disclosing Party, (ii) was known to the Receiving Party prior to its
|
||||
disclosure by the Disclosing Party without breach of any obligation owed to the
|
||||
Disclosing Party, (iii) is received from a third party without breach of any
|
||||
obligation owed to the Disclosing Party, or (iv) was independently developed by
|
||||
the Receiving Party.
|
||||
|
||||
1.3. "Customer Data" means business information or other data loaded by or for
|
||||
Customer and/or processed by the Software.
|
||||
|
||||
1.4. "Data Protection Legislation" means all applicable data protection and
|
||||
privacy legislation in force from time to time in the UK including the General
|
||||
Data Protection Regulation ((EU) 2016/679); the Data Protection Act 2018; the
|
||||
Privacy and Electronic Communications Directive 2002/58/EC (as updated by
|
||||
Directive 2009/136/EC) and the Privacy and Electronic Communications
|
||||
Regulations 2003 (SI 2003/2426) as amended.
|
||||
|
||||
1.5. "Order Document" or "Order" means an order on the Memgraph form of
|
||||
provisioning document that is submitted by or on behalf of Customer, and
|
||||
executed by or on behalf of the parties referencing this Agreement and that
|
||||
specifies the Software and/or Services ordered by Customer, as well as the
|
||||
specific terms and conditions, for that particular transaction.
|
||||
|
||||
1.6. "Services" means those services, including Support Services, which may be
|
||||
provided to Customer by Memgraph pursuant to the terms of this Agreement and
|
||||
are expressly limited to those services directly related to Customer's use of
|
||||
the Software, and expressly exclude any other services.
|
||||
|
||||
1.7. "Software" means the Memgraph proprietary downloadable graph database
|
||||
enterprise software ("Enterprise Software") and the associated technical
|
||||
documentation located at https://docs.memgraph.com/ ("Documentation"), as well
|
||||
as software updates, upgrades, bug fixes, or modified versions thereof that
|
||||
Memgraph licenses or provides to Customer directly or indirectly throughout the
|
||||
Subscription Term.
|
||||
|
||||
1.8. "Subscription Term" means the fixed term, of not less than one (1) year,
|
||||
designated in an Order Document beginning on the Effective Date and ending at
|
||||
the end of the period stated therein. If no expiration date is specified in an
|
||||
Order Document, the Subscription Term shall be a one (1) year period ("Minimum
|
||||
Subscription Term"). A "Subscription" is the binding, non-cancellable contract
|
||||
for the use of the Software for the Subscription Term as set forth in an Order
|
||||
Document.
|
||||
|
||||
1.9. "Support" means the support and maintenance services, including any
|
||||
updates, upgrades, patches, enhancements and bug fixes for the Software that
|
||||
may be provided to Customer by Memgraph pursuant to the terms of this
|
||||
Agreement.
|
||||
|
||||
1.10. "Users" means employees and Contractors of Customer that Customer has
|
||||
permitted or authorized to access and use of the Software on Customer's behalf
|
||||
pursuant to the terms of this Agreement.
|
||||
|
||||
## 2. ORDERS, DELIVERY; SUPPORT.
|
||||
|
||||
2.1. Delivery. Memgraph will promptly deliver the Software after it accepts an
|
||||
Order and Customer issues a purchase order referencing such Order. Unless
|
||||
otherwise stated in an Order, Customer is solely responsible for installing
|
||||
Software on Customer's own computer equipment. In some instances, Customer's
|
||||
purchasing relationship exists solely between Customer and an authorised
|
||||
reseller of Memgraph's Software and Services (a "Reseller"), in which case
|
||||
Sections 5.1-5.3 (Fees and Payment) will be inapplicable to such Order(s), and
|
||||
the Reseller shall be responsible for submitting Orders and the appropriate
|
||||
payment method therewith to Memgraph. An Order is not binding until Memgraph
|
||||
accepts and countersigns the Order.
|
||||
|
||||
2.2 Support. Memgraph will use commercially reasonable efforts to provide
|
||||
Support to Customer in accordance with Memgraph's then-current terms and
|
||||
conditions set forth at
|
||||
https://download.memgraph.com/legal/memgraph-support-terms-and-conditions.pdf
|
||||
at the support tier stated in the applicable Order. The Support terms and
|
||||
conditions are subject to change at Memgraph's discretion; however, Memgraph
|
||||
will not materially reduce the level of Support during a Subscription Term for
|
||||
which Fees have been paid.
|
||||
|
||||
## 3. LICENCE GRANTS; RESTRICTIONS AND PROPRIETARY RIGHTS.
|
||||
|
||||
Customer's licence and access rights and benefits and Memgraph's obligations to
|
||||
Customer will vary depending on the product and the type of licence Memgraph is
|
||||
granting. If you purchased a licence to Memgraph Software, your licence will be
|
||||
subject to certain use and/or capacity restrictions, as identified on the
|
||||
applicable Order Document.
|
||||
|
||||
3.1. Enterprise Software Licence. In consideration of the Fees paid hereunder
|
||||
and subject to the terms of this Agreement and the applicable Order, Memgraph
|
||||
grants Customer a world-wide, non-exclusive, non-transferable,
|
||||
non-sublicenseable, and limited licence during the applicable Subscription
|
||||
Term, to install, and use the Enterprise Software up to the maximum capacity
|
||||
("Licensed Capacity"), and subject to the usage rules, specified in the
|
||||
applicable Order Document, and to use Documentation solely for Customer's
|
||||
internal business purposes in connection with operation of the Enterprise
|
||||
Software.
|
||||
|
||||
3.2. Enterprise Trial Licence. If the Customer downloads, accesses, or uses the
|
||||
Software under a trial licence ("Trial Licence"), then Customer may use one (1)
|
||||
copy of the Software in accordance with the terms and conditions of this
|
||||
Agreement for a thirty (30) day period, or such longer trial period represented
|
||||
by the applicable licence key issued by or expressly authorised by Memgraph
|
||||
(the "Trial Period"). Trial Licences are permitted solely for Customer's
|
||||
evaluation use to determine whether to purchase a Subscription to the Software.
|
||||
Customer may not use a Trial Licence for any other purpose. At the end of the
|
||||
Trial Period, the Trial Licence will expire (and this Agreement will terminate
|
||||
as to such Licence and continue to apply to any subsequent Subscription or use
|
||||
of the Software; if Customer decides not to obtain a Subscription upon
|
||||
expiration of the Trial Period, it will promptly cease using and will delete
|
||||
the Software from its computer systems. Memgraph has the right to terminate a
|
||||
Trial Licence at any time for any reason.
|
||||
|
||||
3.3. NO OBLIGATIONS. NOTWITHSTANDING ANYTHING TO THE CONTRARY IN THIS AGREEMENT
|
||||
OR IN ANY ORDER DOCUMENT, MEMGRAPH WILL HAVE NO WARRANTY, INDEMNITY, SUPPORT,
|
||||
OR SERVICE LEVEL, OBLIGATIONS WITH RESPECT TO ANY ENTERPRISE TRIAL, OR OTHER
|
||||
NO-CHARGE SOFTWARE (INCLUDING TOOLS AND UTILITIES) LICENCES.
|
||||
|
||||
3.4. General Restrictions. Customer acknowledges that the Software, and its
|
||||
structure, organization, and source code, constitute Memgraph's and its
|
||||
suppliers' valuable trade secrets, and that usage of the Software is subject to
|
||||
the following restrictions:
|
||||
|
||||
3.4.1. Restrictions. Customer agrees not to, and not to authorize any third
|
||||
party to: (i) allow access or use of the Software by anyone other than its
|
||||
Users; (ii) distribute, embed, sell, rent, transfer, lease, lend, sublicense,
|
||||
loan, assign, pledge, grant a security interest in, or otherwise make the
|
||||
Software accessible or available to any third party; except to the limited
|
||||
extent expressly provided in Section 3.4.2, use the Software in any
|
||||
service-bureau, timesharing, outsourcing or similar arrangement; or (iii)
|
||||
disassemble, decompile, reverse engineer or otherwise attempt to derive the
|
||||
structure, sequence or organization of source code or APIs; (iv) remove or
|
||||
alter product identification, copyright, trademark or other proprietary
|
||||
markings contained in or on the Software; (v) modify, adapt, recast, transform
|
||||
or otherwise prepare a derivative work of the Software or portion thereof; (vi)
|
||||
conduct any competitive analysis, publish or share with any third party any
|
||||
results of any technical evaluation or tests performed on the Software, or
|
||||
disclose Software features, errors or bugs to a third party without Memgraph's
|
||||
prior written consent; or (vii) engage in any act designed to circumvent any
|
||||
restriction set forth in this Agreement, in the Software, or in an Order,
|
||||
including but not limited to restrictions related to Licensed Capacity.
|
||||
|
||||
3.4.2. Internal Use Licences; Users. The Software is licensed for Customer's
|
||||
internal business use and not for distribution or use by third parties. For
|
||||
clarity, however, Customer may make available to third parties any
|
||||
Customer-hosted services or other Customer applications or services that make
|
||||
use of or incorporate the Software, provided and solely to the extent that (i)
|
||||
Customer's application or hosted service adds primary and significant
|
||||
functionality to the Software, (ii) Customer does not embed or otherwise
|
||||
distribute the Software to third parties, (iii) Customer does not provide third
|
||||
parties direct access to operate or control the Software itself; and (iv)
|
||||
Customer at all times remains in compliance with the terms of the applicable
|
||||
licence grants under this Agreement. Subject to the terms and conditions of
|
||||
this Agreement, in addition to Customer's employees, Customer may permit its
|
||||
independent contractors and consultants ("Contractors") to serve as Users.
|
||||
Customer will remain responsible for compliance by each of its Users (including
|
||||
but not limited to any Contractor Users) with all of the terms and conditions
|
||||
of this Agreement, and any use of the Software by any Contractors must be for
|
||||
the sole benefit of Customer.
|
||||
|
||||
3.5. Ownership; Reservation of Rights. This is an agreement for use of Memgraph
|
||||
Software and not an agreement for sale. Customer acknowledges that it is
|
||||
obtaining only a limited right to use the Software on a licensed basis, and
|
||||
that irrespective of any use of the words "purchase", "sale" or like terms
|
||||
hereunder no ownership rights are being conveyed to Customer. Customer agrees
|
||||
that Memgraph or its suppliers retain all right, title and interest (including
|
||||
all patent, copyright, trade secret and other intellectual property rights) in
|
||||
and to the Memgraph Software. Nothing in this Section shall be deemed as
|
||||
granting Memgraph ownership of Customer Data or in any way impacting Customer's
|
||||
ownership of Customer Data.
|
||||
|
||||
3.6. Third Party Code. The Software may contain or be provided with components
|
||||
which are licensed from third parties, including components subject to the
|
||||
terms and conditions of "open source" software licences ("Open Source
|
||||
Software"). Open Source Software may be identified in the Software,
|
||||
Documentation, or in a list of the Open Source Software provided to you upon
|
||||
your written request. To the extent required by the licence that accompanies
|
||||
the Open Source Software, the terms of such licence will apply in lieu of the
|
||||
terms of this Agreement with respect to such Open Source Software, including,
|
||||
without limitation, any provisions governing access to source code,
|
||||
modification, or reverse engineering.
|
||||
|
||||
3.7. IP Ownership. The Parties agree that neither party shall gain, by virtue
|
||||
of this Agreement, any rights of ownership or any other interest, right or
|
||||
title of copyrights, patents, trade secrets, trademarks, or any other
|
||||
intellectual property rights owned by the other Party. Any and all new works
|
||||
developed in the course of performing obligations pursuant to this Agreement
|
||||
and all new inventions, innovations or ideas developed by a Party in the course
|
||||
of performance of its activities under this Agreement, will belong to that
|
||||
Party who develops the same. Notwithstanding anything to the contrary in this
|
||||
Section, the Parties understand and agree that any and all proprietary
|
||||
materials developed by a Party prior to this Agreement and any modifications,
|
||||
enhancements, improvements or inventions made to such proprietary materials
|
||||
shall be owned by that Party, regardless of which Party prepared or developed
|
||||
such modifications, enhancements, improvements or inventions.
|
||||
|
||||
## 4. CUSTOMER DATA; OBLIGATIONS OF CUSTOMER AND MEMGRAPH.
|
||||
|
||||
4.1. Customer shall retain all of its rights, title, and interest in and to its
|
||||
intellectual property rights in Customer Data. Customer grants to Memgraph a
|
||||
non-exclusive, worldwide, limited-term licence solely to host, copy, transmit
|
||||
and display Customer Data as reasonably necessary for Memgraph to support
|
||||
Customer's use of the Software, to ensure the security of and to administrate
|
||||
the Software, and to deliver Services in accordance with this Agreement or as
|
||||
otherwise outlined in https://memgraph.com/legal/privacy-policy/.
|
||||
|
||||
4.2. Protection of Customer Data. Memgraph will maintain appropriate
|
||||
administrative, physical, and technical safeguards, consistent with generally
|
||||
prevailing industry standards, for protection of the security, confidentiality,
|
||||
and integrity of Customer Data, as described in the Documentation. Those
|
||||
safeguards will include, but will not be limited to, measures for preventing
|
||||
access, use, modification, or disclosure of Customer Data by Memgraph
|
||||
personnel, except as permitted by this Agreement.
|
||||
|
||||
4.3. Personal data. Both parties will comply with all applicable requirements
|
||||
of the Data Protection Legislation. This section 4 is in addition to, and does
|
||||
not relieve, remove or replace, a party's obligations under the Data Protection
|
||||
Legislation. Notwithstanding the foregoing, the parties acknowledge that, in
|
||||
the ordinary course of providing the Services, Memgraph shall not process
|
||||
personal data (as defined in the Data Protection Legislation) on behalf of the
|
||||
Customer. In the event that the Customer requires Memgraph to process personal
|
||||
data on its behalf, it shall notify Memgraph and the parties shall execute such
|
||||
terms as necessary under applicable law.
|
||||
|
||||
## 5. FEES AND PAYMENT.
|
||||
|
||||
5.1. Fees. Customer will pay Memgraph the fees for the Licences and Services as
|
||||
set forth in the applicable Order ("Fees"). Customer acknowledges and agrees
|
||||
that if Customer's use of the Software exceeds the Licensed Capacity set forth
|
||||
on the applicable Orders or otherwise requires the payment of additional fees
|
||||
(per the terms of this Agreement), Customer shall be invoiced for such usage
|
||||
and Customer agrees to pay the additional fees in accordance with this Section.
|
||||
Notwithstanding the terms of Section 5.4 below (Reconciliation), Customer
|
||||
acknowledges and agrees that it is obligated to ensure that its Software usage
|
||||
does not exceed the Licensed Capacity and to promptly notify Memgraph of any
|
||||
such excess usage no more than thirty (30) days from the last day of the
|
||||
calendar month during which such excess usage occurred.
|
||||
|
||||
5.2. Payment Terms. Except as otherwise specifically set forth on an Order
|
||||
Document, all fees are due and payable within thirty days after the date of
|
||||
invoice. Renewal Fees for any renewal Subscription Term (if purchased by
|
||||
Customer) will be due and payable within thirty (30) days of expiration of the
|
||||
then-current term. If Fees are not paid when due, or in the event of other
|
||||
breach of this Agreement, Customer shall discontinue use of the Software and
|
||||
Memgraph may suspend its performance, including its delivery of technical
|
||||
support of the Software or other Services without further notice and without
|
||||
penalty. All Orders (including multi-year Subscriptions with annual payment
|
||||
schedules) are non-cancellable and all amounts paid are non-refundable, unless
|
||||
otherwise expressly set forth herein. Any invoiced amount not received by the
|
||||
due date will accrue late interest at the rate of 1.5% of the outstanding
|
||||
balance per month, or the maximum rate permitted by applicable law, whichever
|
||||
is lower.
|
||||
|
||||
5.3. Taxes. Fees are exclusive of taxes. Customer will pay any sales, use,
|
||||
value added, duties, fees and other governmental assessments or charges arising
|
||||
out of this Agreement and the transactions contemplated herein. Customer will
|
||||
make all payments free and clear of, and without reduction for, any withholding
|
||||
taxes.
|
||||
|
||||
5.4. Reconciliation. At Memgraph's request from time to time, not exceeding
|
||||
once per quarter, Customer will provide Memgraph with a report detailing its
|
||||
use of the Software, including its non-production and/or production use and
|
||||
using the self-monitoring capabilities of the Software or other means, and
|
||||
Memgraph may inspect Customer's records related to such report not more
|
||||
frequently than annually to ensure payment of Fees. Any on-site review will be
|
||||
conducted during regular business hours at Customer's offices. The parties will
|
||||
use reasonable good faith efforts to promptly resolve any discrepancies between
|
||||
licensed usage and actual usage.
|
||||
|
||||
## 6. APPLICABLE LAWS.
|
||||
|
||||
6.1. Each Party shall perform this Agreement in accordance with all Applicable
|
||||
Laws. Without prejudice to the foregoing, each Party shall:
|
||||
|
||||
6.1.1. comply with all Applicable Laws relating to anti-bribery,
|
||||
anti-corruption, anti-slavery and human trafficking, including the Bribery Act
|
||||
2010 and the Modern Slavery Act 2015 (the "Relevant Requirements");
|
||||
|
||||
6.1.2. have and maintain in place throughout the Term its own policies and
|
||||
procedures, including adequate procedures under the Bribery Act 2010, to ensure
|
||||
compliance with the Relevant Requirements, and will enforce them where
|
||||
appropriate;
|
||||
|
||||
6.1.3. (if not prohibited by law or regulation from doing so) promptly report
|
||||
to the other Party any request or demand for any undue financial or other
|
||||
advantage of any kind received by the reporting Party in connection with the
|
||||
performance of this Agreement; and
|
||||
|
||||
6.1.4. (if not prohibited by law or regulation from doing so) notify the other
|
||||
Party (and email shall be sufficient for this purpose) as soon as it becomes
|
||||
aware of any actual or suspected slavery or human trafficking in a supply chain
|
||||
which has a connection with this Agreement.
|
||||
|
||||
## 7. REPRESENTATIONS AND WARRANTIES.
|
||||
|
||||
7.1. Mutual Representations and Warranties. Each Party represents and warrants
|
||||
to the other that: (i) it is a corporation lawfully incorporated and validly
|
||||
existing pursuant to the laws of its place of incorporation; (ii) it has all
|
||||
requisite power and authority, corporate or otherwise, to execute, deliver and
|
||||
perform its obligations under this Agreement; and (iii) this Agreement
|
||||
constitutes its legal, valid and binding obligations and may be enforced
|
||||
against it.
|
||||
|
||||
7.2. Limited Memgraph Warranty; Remedies. Memgraph warrants that the Software,
|
||||
when used as permitted hereunder, will operate in all material respects as
|
||||
described in the applicable Documentation, and that Services will be provided
|
||||
in a professional manner consistent with industry standards.
|
||||
|
||||
7.3. Limitations; Remedy. Memgraph does not warrant that the Software or the
|
||||
Services will be error-free, uninterrupted or meet Customer's specific
|
||||
requirements or that performance of the Services will be uninterrupted.
|
||||
Memgraph will have no warranty obligation under Section 7.2 for Customer's
|
||||
misuse or failure to use the Software in accordance with its Documentation or
|
||||
this Agreement. Customer's sole and exclusive remedy, and Memgraph's sole and
|
||||
exclusive obligation, for breach of warranty will be (i) during the thirty (30)
|
||||
day period following initial Delivery of the Software under an Order,
|
||||
Memgraph's correction of the program errors that cause the breach of warranty,
|
||||
or if Memgraph cannot substantially correct such breach in a commercially
|
||||
reasonable manner, a refund of the fees paid for the nonconforming Software
|
||||
(ii) during the remainder of the relevant Subscription Term, Memgraph's
|
||||
delivery of Support with respect to any such program errors. In the event of a
|
||||
refund remedy, Customer's licences and right to use the Software or receive
|
||||
Services will end. In the event of any noticed breach of warranty with respect
|
||||
to Services, Memgraph's sole and exclusive obligation shall be the
|
||||
re-performance of the deficient Services.
|
||||
|
||||
7.4. Disclaimer. THIS SECTION 7 IS A LIMITED WARRANTY AND, EXCEPT EXPRESSLY AS
|
||||
SET FORTH IN SECTION 7.2, THE SOFTWARE, INCLUDING WITHOUT LIMITATION THE
|
||||
THIRD-PARTY CODE, AND ALL SERVICES ARE PROVIDED "AS IS". MEMGRAPH MAKES NO
|
||||
OTHER WARRANTIES OR REPRESENTATIONS, EXPRESS, IMPLIED, STATUTORY OR OTHERWISE,
|
||||
AND DISCLAIMS ALL IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
|
||||
PARTICULAR PURPOSE, TITLE, AND NON-INFRINGEMENT.
|
||||
|
||||
## 8. INDEMNIFICATION.
|
||||
|
||||
8.1. By Memgraph. Memgraph will defend against any action against Customer
|
||||
brought by a third party to the extent the action is based on a claim that the
|
||||
Software infringes a third party's patent, copyright or trademark (a "Claim")
|
||||
and indemnify Customer from the damages, liabilities, costs and expenses
|
||||
(including reasonable attorneys' fees) awarded against Customer or agreed in
|
||||
settlement by Customer resulting from such Claim. If your use of the Software
|
||||
is (or in Memgraph's opinion likely to be) enjoined, then Memgraph may, at its
|
||||
own expense and at its option: (i) substitute substantially similar
|
||||
functionality for the Software which renders it non-infringing; (ii) procure
|
||||
for Customer the right to continue to use the Software; or if (i) and (ii) are
|
||||
not commercially reasonable, terminate this Agreement and refund Customer any
|
||||
prepaid, unused (pro-rated) Fees for the duration of the then-current
|
||||
Subscription Term. The foregoing obligations of Memgraph will not apply: (i) if
|
||||
the Software is modified by any party other than Memgraph, but solely to the
|
||||
extent the alleged infringement is caused by such modification; (ii) if the
|
||||
Software is used in combination with other products or processes not provided
|
||||
or authorized by Memgraph, but solely to the extent the alleged infringement is
|
||||
caused by such combination; (iii) use of any version or release of Software
|
||||
other than the most current version or release made available to Customer by
|
||||
Memgraph, if its use would have avoided the infringement; (iv) any unauthorized
|
||||
use of the Software. THIS SECTION 8.1 SETS FORTH MEMGRAPH'S SOLE LIABILITY AND
|
||||
CUSTOMER'S SOLE AND EXCLUSIVE REMEDY WITH RESPECT TO ANY CLAIM OF INTELLECTUAL
|
||||
PROPERTY INFRINGEMENT.
|
||||
|
||||
8.2. By Customer. Customer will indemnify and hold Memgraph and its suppliers
|
||||
harmless against any claims, liabilities, costs, and expenses (including
|
||||
reasonable attorneys' fees) that Memgraph or its suppliers may incur as a
|
||||
result of a third-party claim arising from or related to Customer Data, or
|
||||
misuse or unauthorised use of the Software by Customer or any User.
|
||||
|
||||
8.3. Conditions. All defence and indemnity obligations under Sections 8.1 and
|
||||
8.2 are conditioned on the indemnitee (i) giving the indemnitor written notice
|
||||
of the relevant claim within thirty (30) days after the indemnitee receives
|
||||
notice of the Claim (or sooner if required by applicable law); (ii) reasonably
|
||||
cooperating with the indemnitor, at the indemnitor's expense, in the defence of
|
||||
the claim; and (iii) giving the indemnitor sole control of the defence and any
|
||||
settlement negotiations. The indemnitee may participate in the defence at its
|
||||
expense.
|
||||
|
||||
## 9. LIMITATION OF LIABILITY.
|
||||
|
||||
9.1. TO THE EXTENT PERMITTED BY LAW, NEITHER MEMGRAPH NOR CUSTOMER SHALL BE
|
||||
LIABLE TO THE OTHER OR ANY THIRD PARTY FOR LOST PROFITS (WHETHER DIRECT OR
|
||||
INDIRECT) OR LOSS OF USE OR DATA, SUBSTITUTE GOODS OR SERVICES, OR FOR
|
||||
INCIDENTAL, CONSEQUENTIAL, PUNITIVE, SPECIAL OR EXEMPLARY DAMAGES (INCLUDING
|
||||
DAMAGE TO BUSINESS, REPUTATION OR GOODWILL), OR INDIRECT DAMAGES OF ANY TYPE
|
||||
HOWEVER CAUSED, WHETHER BY BREACH OF WARRANTY, BREACH OF CONTRACT, IN TORT
|
||||
(INCLUDING NEGLIGENCE) OR ANY OTHER LEGAL OR EQUITABLE CAUSE OF ACTION EVEN IF
|
||||
SUCH PARTY HAS BEEN ADVISED OF SUCH DAMAGES IN ADVANCE OR IF SUCH DAMAGES WERE
|
||||
FORESEEABLE.
|
||||
|
||||
9.2. LIMITATIONS ON DIRECT DAMAGES. EXCEPT FOR ANY EXCLUDED CLAIMS AND ANY
|
||||
DAMAGES THAT CANNOT BE LIMITED UNDER APPLICABLE LAW, IN NO EVENT WILL
|
||||
MEMGRAPH'S TOTAL AGGREGATE LIABILITY ARISING FROM OR RELATED TO THIS AGREEMENT,
|
||||
EXCEED AN AMOUNT EQUAL TO THE TOTAL AMOUNT OF FEES PAID OR PAYABLE BY CUSTOMER
|
||||
TO MEMGRAPH UNDER THIS AGREEMENT DURING THE TWELVE MONTHS PRECEDING THE CLAIM.
|
||||
THE FOREGOING LIMITATIONS SHALL NOT APPLY TO: (i) PAYMENTS TO A THIRD PARTY
|
||||
ARISING FROM A PARTY'S OBLIGATIONS UNDER SECTION 8 (INDEMNIFICATION); (ii)
|
||||
BREACH BY A PARTY OF SECTION 10 (CONFIDENTIAL INFORMATION), AND (iii)
|
||||
INFRINGEMENT BY A PARTY OF THE OTHER PARTY'S INTELLECTUAL PROPERTY RIGHTS
|
||||
(COLLECTIVELY EXCLUSIONS (i)-(iii) ARE REFERRED TO AS THE "EXCLUDED CLAIMS").
|
||||
WITH RESPECT TO ANY EXCLUDED CLAIMS, MEMGRAPH'S TOTAL AGGREGATE LIABILITY SHALL
|
||||
IN NO EVENT EXCEED £1,000,000.
|
||||
|
||||
9.3. Nothing in this Agreement excludes the liability of Memgraph for death or
|
||||
personal injury caused by the Supplier's negligence; or for fraud or fraudulent
|
||||
misrepresentation.
|
||||
|
||||
## 10. CONFIDENTIALITY.
|
||||
|
||||
10.1. The Receiving Party will use the same degree of care that it uses to
|
||||
protect the confidentiality of its own confidential information of like kind
|
||||
(but not less than reasonable care) to (i) not use any confidential information
|
||||
of the Disclosing Party for any purpose outside the scope of this agreement and
|
||||
(ii) except as otherwise authorized by the Disclosing Party in writing, limit
|
||||
access to confidential information of the Disclosing Party to those of its and
|
||||
its affiliates' employees and contractors who need that access for purposes
|
||||
consistent with this agreement and who have signed confidentiality agreements
|
||||
with the receiving party containing protections not materially less protective
|
||||
of the confidential information than those herein. Neither party will disclose
|
||||
the terms of this agreement or any Orders to any third-party other than its
|
||||
affiliates, legal counsel, and accountants without the other party's prior
|
||||
written consent, provided that a party that makes any such disclosure to its
|
||||
affiliate, legal counsel or accountants will remain responsible for such
|
||||
affiliate's, legal counsel's, or accountant's compliance with this
|
||||
"confidentiality" section.
|
||||
|
||||
10.2. Compelled Disclosure. The Receiving Party may disclose confidential
|
||||
information of the Disclosing Party to the extent compelled by law to do so,
|
||||
provided the Receiving Party gives the Disclosing Party prior notice of the
|
||||
compelled disclosure (to the extent legally permitted) and reasonable
|
||||
assistance, at the Disclosing Party's cost, if the Disclosing Party wishes to
|
||||
contest the disclosure. If the receiving party is compelled by law to disclose
|
||||
the Disclosing Party's confidential information as part of a civil proceeding
|
||||
to which the Disclosing Party is a party, and the Disclosing Party is not
|
||||
contesting the disclosure, the Disclosing Party will reimburse the Receiving
|
||||
Party for its reasonable cost of complying and providing secure access to that
|
||||
confidential information.
|
||||
|
||||
## 11. TERMINATION.
|
||||
|
||||
11.1. Term. The term ("Term") of this Agreement will commence on the Effective
|
||||
Date and continue until all Subscriptions, licence terms and Orders expire,
|
||||
unless earlier terminated in accordance with this Section 11.
|
||||
|
||||
11.2. Termination for Cause. In the event of a material breach of this
|
||||
Agreement (excluding any breaches for which an exclusive remedy is expressly
|
||||
provided), the non-breaching party may terminate this Agreement if such breach
|
||||
is not cured within thirty (30) days after written notice thereof (except that
|
||||
for a breach of Section 3.4 ("General Restrictions"), there will be no cure
|
||||
period). For clarity, material breach of this Agreement includes, but is not
|
||||
limited to, failure to timely pay amounts due hereunder, exceeding the scope of
|
||||
any Licence granted hereunder (including the Licensed Capacity), violating the
|
||||
Licence restrictions, breach of Section 6.1 and failing to protect the other
|
||||
party's Confidential Information.
|
||||
|
||||
11.3. Without affecting any other right or remedy available to it, either party
|
||||
may terminate this Agreement with immediate effect by giving written notice to
|
||||
the other party if the other party:
|
||||
|
||||
11.3.1. suspends, or threatens to suspend, payment of its debts or is unable to
|
||||
pay its debts as they fall due or admits inability to pay its debts or is
|
||||
deemed unable to pay its debts within the meaning of section 123 of the
|
||||
Insolvency Act 1986, as if the words "it is proved to the satisfaction of the
|
||||
court" did not appear in sections 123(1)(e) or 123(2) of the Insolvency Act
|
||||
1986; or
|
||||
|
||||
11.3.2. the other party commences negotiations with all or any class of its
|
||||
creditors with a view to rescheduling any of its debts, or makes a proposal for
|
||||
or enters into any compromise or arrangement with its creditors other than for
|
||||
the sole purpose of a scheme for a solvent amalgamation of that other party
|
||||
with one or more other companies or the solvent reconstruction of that other
|
||||
party; or
|
||||
|
||||
11.3.3. a petition is filed, a notice is given, a resolution is passed, or an
|
||||
order is made, for or in connection with the winding up of that other party
|
||||
other than for the sole purpose of a scheme for a solvent amalgamation of that
|
||||
other party with one or more other companies or the solvent reconstruction of
|
||||
that other party; or
|
||||
|
||||
11.3.4. an application is made to court, or an order is made, for the
|
||||
appointment of an administrator, or if a notice of intention to appoint an
|
||||
administrator is given or if an administrator is appointed, over the other
|
||||
party; or
|
||||
|
||||
11.3.5. the holder of a qualifying floating charge over the assets of that
|
||||
other party has become entitled to appoint or has appointed an administrative
|
||||
receiver; or
|
||||
|
||||
11.3.6. a person becomes entitled to appoint a receiver over the assets of the
|
||||
other party or a receiver is appointed over the assets of the other party; or
|
||||
|
||||
11.3.7. a creditor or encumbrancer of the other party attaches or takes
|
||||
possession of, or a distress, execution, sequestration or other such process is
|
||||
levied or enforced on or sued against, the whole or any part of the other
|
||||
party's assets and such attachment or process is not discharged within 30 days;
|
||||
or
|
||||
|
||||
11.3.8. any event occurs, or proceeding is taken, with respect to the other
|
||||
party in any jurisdiction to which it is subject that has an effect equivalent
|
||||
or similar to any of the events mentioned in clause 11.3.1 to clause 11.3.7
|
||||
(inclusive); or
|
||||
|
||||
11.3.9. the other party suspends or ceases, or threatens to suspend or cease,
|
||||
carrying on all or a substantial part of its business.
|
||||
|
||||
11.4. Effect of Termination. Upon the termination of this Agreement: (i) all
|
||||
licences will terminate; (ii) Customer will immediately discontinue all use of
|
||||
the affected Software, erase all full and partial copies of the Software and
|
||||
(subject to this Section) all other tangible embodiments of Memgraph
|
||||
Confidential Information in Customer's possession or control, and promptly
|
||||
certify the same to Memgraph; (iii) Memgraph may immediately cease providing
|
||||
the Services; (iv) (subject to this Section), Memgraph will return or delete
|
||||
all tangible embodiments of Customer Confidential Information in Memgraph's
|
||||
possession or control; and (v) Sections 1 ("Definitions"), 3.4 ("General
|
||||
Restrictions"), 3.5 ("Ownership; Reservation of Rights"), 5 ("Fees and
|
||||
Payment"), 7.3 ("Limitations"), 7.4 ("Disclaimer"), 8 ("Indemnification"), 9
|
||||
("Limitation of Liability"), 10 ("Confidentiality"), 11.4 ("Effect of
|
||||
Termination"), and 12 ("Miscellaneous") will survive. If a party's file
|
||||
retention policies or a valid legal order provides for backup or archival
|
||||
copies of files to be retained, such party will notify the other party of such
|
||||
policy or order, protect the other party's Confidential Information as required
|
||||
hereunder, and permanently erase, delete, or destroy such Confidential
|
||||
Information as soon as permissible under such policy or order.
|
||||
|
||||
## 12. MISCELLANEOUS.
|
||||
|
||||
12.1. Assignment. This Agreement will bind and inure to the benefit of each
|
||||
party's permitted successors and assigns. Memgraph may assign this Agreement to
|
||||
any affiliate or in connection with a merger, reorganization, acquisition, or
|
||||
other transfer of all or substantially all of Memgraph's assets or voting
|
||||
securities. Customer may not assign or transfer this Agreement, in whole or in
|
||||
part, without Memgraph's written consent except that Customer may assign its
|
||||
rights and obligations under this Agreement, in whole but not in part, without
|
||||
Memgraph's written consent in connection with any merger, consolidation, sale
|
||||
of all or substantially all of Customer's assets or voting stock, or any other
|
||||
similar transaction provided that: (i) the assignee is not a direct competitor
|
||||
of Memgraph; (ii) Customer provides prompt written notice of such assignment to
|
||||
Memgraph; (iii) the assignee is capable of fully performing Customer's
|
||||
obligations under this Agreement; and (iv) the assignee agrees to be bound by
|
||||
the terms and conditions of this Agreement. Any attempt to transfer or assign
|
||||
this Agreement without such written consent will be null and void.
|
||||
|
||||
12.2. Force Majeure. Memgraph shall have no liability to the Customer under
|
||||
this Agreement if it is prevented from or delayed in performing its obligations
|
||||
under this Agreement, or from carrying on its business, by acts, events,
|
||||
omissions or accidents beyond its reasonable control, including strikes,
|
||||
lock-outs or other industrial disputes (whether involving the workforce of
|
||||
Memgraph or any other party), failure of a utility service or transport or
|
||||
telecommunications network, act of God, war, pandemic, riot, civil commotion,
|
||||
malicious damage, compliance with any law or governmental order, rule,
|
||||
regulation or direction, accident, breakdown of plant or machinery, fire,
|
||||
flood, storm or default of suppliers or subcontractors, provided that the
|
||||
Customer is notified of such an event and its expected duration.
|
||||
|
||||
12.3. Governing Law. This Agreement and any dispute or claim arising out of or
|
||||
in connection with it or its subject matter or formation (including
|
||||
non-contractual disputes or claims) shall be governed by and construed in
|
||||
accordance with the law of England and Wales.
|
||||
|
||||
12.4. Jurisdiction. Each party irrevocably agrees that the courts of England
|
||||
and Wales shall have exclusive jurisdiction to settle any dispute or claim
|
||||
arising out of or in connection with this Agreement or its subject matter or
|
||||
formation (including non-contractual disputes or claims).
|
||||
|
||||
12.5. Severability; Waiver; Construction. If a court of competent jurisdiction
|
||||
adjudges any provision of this Agreement to be invalid or unenforceable, the
|
||||
remaining provisions of this Agreement, if capable of substantial performance,
|
||||
will continue in full force and effect without being impaired or invalidated in
|
||||
any way. The parties agree to replace any invalid provision with a valid
|
||||
provision that most closely approximates the intent and economic effect of the
|
||||
invalid provision. All waivers must be in writing. A party's consent to, or
|
||||
waiver of, enforcement of this Agreement on one occasion will not be deemed a
|
||||
waiver of any other provision or such provision on any other occasion. In this
|
||||
Agreement, the word "including" means "including but not limited to." No
|
||||
presumption will operate in favour of or against any party as a result of its
|
||||
role in drafting this Agreement.
|
||||
|
||||
12.6. Subcontractors. Memgraph may use the services of subcontractors in
|
||||
connection with its performance of this Agreement, provided that Memgraph
|
||||
remains solely responsible for (i) compliance of any such subcontractor with
|
||||
the terms of this Agreement and (ii) the overall performance of Memgraph as
|
||||
required under this Agreement.
|
||||
|
||||
12.7. Use of Aggregate Data. Customer agrees that Memgraph may collect, use and
|
||||
disclose quantitative data and metadata derived from the use of the Software
|
||||
(i) for its own internal, statistical analysis, (ii) to develop and improve the
|
||||
Software and (iii) to create and distribute reports and other materials
|
||||
regarding use of the Software. For clarity, any such data collected, used, and
|
||||
disclosed will be in anonymized aggregate form only and shall not identify
|
||||
Customer or its Users, or disclose any Customer Data.
|
||||
|
||||
12.8. Independent Contractors. The parties are independent contractors. No
|
||||
agency, partnership, franchise, joint venture, or employment relationship is
|
||||
intended or created by this Agreement. Neither party has the power or authority
|
||||
to create or assume any obligation, or make any representations or warranties,
|
||||
on behalf of the other party.
|
||||
|
||||
12.9. Publicity. Memgraph may, in conformity with Customer's trademark usage
|
||||
guidelines, use Customer's name and logo in Memgraph's sales and marketing
|
||||
materials, including in business presentations, Customer lists, and on
|
||||
websites. Neither party will issue a press release regarding this Agreement
|
||||
without the other party's prior written consent. Neither party will disclose
|
||||
the terms of this Agreement to any third party, except as required by law.
|
||||
|
||||
12.10. Notice. Any notice, consent, or waiver hereunder must be in writing,
|
||||
addressed to the attention of "Legal Department" at the address set forth
|
||||
above, and delivered by personal delivery, reputable rapid courier, or
|
||||
certified/registered mail, return receipt requested, and will be deemed given
|
||||
upon personal delivery, one (1) day after deposit with an overnight domestic
|
||||
courier, two (2) days after deposit with an international courier, or five (5)
|
||||
days after deposit in the certified or registered mail. A party may specify a
|
||||
new address by providing notice to the other party in accordance with this
|
||||
Section.
|
||||
|
||||
12.11. Compliance with Law. Each party will comply with all applicable laws,
|
||||
regulations, and orders of any governmental authority of competent jurisdiction
|
||||
in its performance under this Agreement, including but not limited to those
|
||||
applicable to data collection and the privacy and security of personal
|
||||
information, including trans-border data transfers and data breach notification
|
||||
requirements as required of each party by law.
|
||||
|
||||
12.12. Supremacy; Modification. This Agreement will prevail over any written
|
||||
instrument submitted by Customer; the terms of any purchase order,
|
||||
acknowledgement, or similar document submitted by Customer to Memgraph will
|
||||
have no effect. If the express terms of an Order Document conflict with this
|
||||
Agreement, the terms on the Order Document will prevail, but only with respect
|
||||
to that Order Document. This Agreement cannot be varied or supplemented by
|
||||
course of dealing or by usage of trade. All modifications or amendments to this
|
||||
Agreement must be in writing and signed by both parties, except that subsequent
|
||||
renewals and purchases of additional Licensed Capacity can be procured by
|
||||
payment against an issued invoice as set forth in Section 5 ("Fees and
|
||||
payment") above.
|
||||
|
||||
12.13. No Third Party Beneficiaries. This Agreement is not intended and shall
|
||||
not be construed to give any third party any interest or rights with respect to
|
||||
or in connection with any agreement or provision herein, except as expressly
|
||||
provided for in this Agreement.
|
||||
|
||||
12.14. Entire Agreement. This Agreement in its original English text, sets
|
||||
forth the complete, exclusive, and final agreement of the parties concerning
|
||||
the subject matter hereof, supersedes, replaces, and merges all prior and
|
||||
contemporaneous agreements, communications, and understandings, both written
|
||||
and oral, between them concerning the subject matter hereof. This Agreement may
|
||||
be executed in counterparts.
|
||||
@@ -1,4 +0,0 @@
|
||||
# Memgraph Release
|
||||
|
||||
Please continue in
|
||||
[Notion](https://www.notion.so/memgraph/Release-621733518c82456ebc119d2a025b5dd3).
|
||||
@@ -1,47 +0,0 @@
|
||||
# Maintainer: tech@memgraph.com (Memgraph Ltd.)
|
||||
pkgname=memgraph
|
||||
pkgrel=1
|
||||
epoch=
|
||||
# TODO: Maybe take pkgdesc from CMake?
|
||||
pkgdesc="High performance, in-memory, transactional graph database"
|
||||
# TODO: Autogenerate architecture? Though, we only support x86_64...
|
||||
arch=('x86_64')
|
||||
url="https://memgraph.com"
|
||||
license=('custom')
|
||||
groups=()
|
||||
depends=('gcc-libs')
|
||||
makedepends=()
|
||||
checkdepends=()
|
||||
optdepends=()
|
||||
provides=()
|
||||
conflicts=()
|
||||
replaces=()
|
||||
backup=("etc/memgraph/memgraph.conf" "etc/logrotate.d/memgraph")
|
||||
options=()
|
||||
install=memgraph.install
|
||||
changelog=
|
||||
source=("$pkgname-$pkgver.tar.gz")
|
||||
noextract=()
|
||||
validpgpkeys=()
|
||||
|
||||
package() {
|
||||
cd $(find . -maxdepth 1 -type d -name 'memgraph*')
|
||||
# By default, we install the systemd service in /lib (as expected on Debian),
|
||||
# so move anything like that in /usr/lib.
|
||||
if [[ -d "lib" ]]; then
|
||||
mkdir -p usr/lib
|
||||
cp -a lib/* usr/lib
|
||||
rm -rf lib
|
||||
fi
|
||||
# In case the binary package is built with /usr/local prefix instead of /usr.
|
||||
if [[ -d "usr/local" ]]; then
|
||||
mkdir -p usr
|
||||
cp -a usr/local/* usr
|
||||
rm -rf usr/local
|
||||
fi
|
||||
# Move the license to Arch specific location.
|
||||
install -Dm644 usr/share/doc/memgraph/copyright usr/share/licenses/memgraph/LICENSE
|
||||
# We currently don't have anything in usr/share/doc/memgraph
|
||||
rm -rf usr/share/doc/memgraph
|
||||
cp -a . $pkgdir
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
post_install() {
|
||||
# Add the 'memgraph' user and group and set permissions on
|
||||
# 'var/*/memgraph' directories.
|
||||
getent group memgraph >/dev/null || groupadd -r memgraph || exit 1
|
||||
getent passwd memgraph >/dev/null || \
|
||||
useradd -r -g memgraph -d /var/lib/memgraph memgraph || exit 1
|
||||
chown memgraph:memgraph /var/lib/memgraph || exit 1
|
||||
chmod 750 /var/lib/memgraph || exit 1
|
||||
chown memgraph:adm /var/log/memgraph || exit 1
|
||||
chmod 750 /var/log/memgraph || exit 1
|
||||
echo "Enable and start 'memgraph.service' to use Memgraph" || exit 1
|
||||
}
|
||||
|
||||
pre_remove() {
|
||||
systemctl disable memgraph.service
|
||||
}
|
||||
@@ -1,48 +0,0 @@
|
||||
#!/bin/bash -e
|
||||
|
||||
function print_help () {
|
||||
echo "Usage: $0 MEMGRAPH_PACKAGE.tar.gz"
|
||||
echo "Optional arguments:"
|
||||
echo -e " -h|--help Print help."
|
||||
}
|
||||
|
||||
if [[ $# -ne 1 || "$1" == "-h" || "$1" == "--help" ]]; then
|
||||
print_help
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ ! -f "$1" ]]; then
|
||||
echo "File '$1' does not exist!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Extract version from .tar.gz name
|
||||
tgz_name=`echo $(basename $1) | sed 's/.tar.gz//'`
|
||||
version=`echo ${tgz_name} | sed 's/.*[-_]\(.*\)-.*/\1/'`
|
||||
|
||||
script_dir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
||||
rm -rf ${script_dir}/_pack
|
||||
mkdir -p ${script_dir}/_pack
|
||||
# Copy the .tar.gz to packaging directory.
|
||||
cp "$1" ${script_dir}/_pack/memgraph-${version}.tar.gz
|
||||
|
||||
cd ${script_dir}/_pack
|
||||
|
||||
# Setup PKGBUILD.
|
||||
echo "pkgver=${version}" > PKGBUILD
|
||||
cat ../PKGBUILD.proto >> PKGBUILD
|
||||
# Copy the installation script.
|
||||
cp ../memgraph.install ./
|
||||
|
||||
# Check PKGBUILD validity
|
||||
updpkgsums PKGBUILD
|
||||
namcap PKGBUILD
|
||||
|
||||
# TODO: Maybe add a custom makepkg.conf and use that
|
||||
makepkg PACKAGER="tech@memgraph.com (Memgraph Ltd.)"
|
||||
# Check the final package archive validity and move it in parent directory.
|
||||
pkg_name=memgraph-${version}-1-x86_64.pkg.tar.xz
|
||||
namcap --exclude=emptydir $pkg_name
|
||||
cp $pkg_name ../
|
||||
echo "Built Arch Package at '${script_dir}/${pkg_name}'"
|
||||
rm -rf ${script_dir}/_pack
|
||||
@@ -1,2 +0,0 @@
|
||||
/etc/memgraph/memgraph.conf
|
||||
/etc/logrotate.d/memgraph
|
||||
@@ -1 +0,0 @@
|
||||
../../LICENSE_COMMUNITY.md
|
||||
@@ -1,3 +0,0 @@
|
||||
/etc/memgraph/memgraph.conf
|
||||
/etc/memgraph/auth_module/ldap.example.yaml
|
||||
/etc/logrotate.d/memgraph
|
||||
@@ -1 +0,0 @@
|
||||
../../LICENSE_ENTERPRISE.md
|
||||
@@ -1,78 +0,0 @@
|
||||
#!/bin/sh
|
||||
# postinst script for memgraph
|
||||
#
|
||||
# see: dh_installdeb(1)
|
||||
|
||||
set -e
|
||||
|
||||
# summary of how this script can be called:
|
||||
# * <postinst> `configure' <most-recently-configured-version>
|
||||
# * <old-postinst> `abort-upgrade' <new version>
|
||||
# * <conflictor's-postinst> `abort-remove' `in-favour' <package>
|
||||
# <new-version>
|
||||
# * <postinst> `abort-remove'
|
||||
# * <deconfigured's-postinst> `abort-deconfigure' `in-favour'
|
||||
# <failed-install-package> <version> `removing'
|
||||
# <conflicting-package> <version>
|
||||
# for details, see https://www.debian.org/doc/debian-policy/ or
|
||||
# the debian-policy package
|
||||
|
||||
case "$1" in
|
||||
configure)
|
||||
# Add the 'memgraph' user and group and set permissions on
|
||||
# 'var/*/memgraph' directories.
|
||||
adduser --quiet --system --group --home /var/lib/memgraph --no-create-home --shell /bin/bash memgraph || exit 1
|
||||
echo "Don't forget to switch to the 'memgraph' user to use Memgraph" || exit 1
|
||||
chown memgraph:memgraph /var/lib/memgraph || exit 1
|
||||
chmod 750 /var/lib/memgraph || exit 1
|
||||
chown memgraph:adm /var/log/memgraph || exit 1
|
||||
chmod 750 /var/log/memgraph || exit 1
|
||||
|
||||
# Generate SSL certificates
|
||||
if [ ! -d /etc/memgraph/ssl ]; then
|
||||
mkdir /etc/memgraph/ssl || exit 1
|
||||
openssl req -x509 -newkey rsa:4096 -days 3650 -nodes \
|
||||
-keyout /etc/memgraph/ssl/key.pem -out /etc/memgraph/ssl/cert.pem \
|
||||
-subj "/C=GB/ST=London/L=London/O=Memgraph Ltd./CN=Memgraph DB" || exit 1
|
||||
chown memgraph:memgraph /etc/memgraph/ssl/* || exit 1
|
||||
chmod 400 /etc/memgraph/ssl/* || exit 1
|
||||
fi
|
||||
;;
|
||||
|
||||
abort-upgrade|abort-remove|abort-deconfigure)
|
||||
;;
|
||||
|
||||
*)
|
||||
echo "postinst called with unknown argument \`$1'" >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
# Always setup the systemd memgraph.service. The following was autogenerated
|
||||
# by dh_systemd_enable and dh_systemd_start, so it should behave as expected.
|
||||
|
||||
# This will only remove masks created by d-s-h on package removal.
|
||||
deb-systemd-helper unmask memgraph.service >/dev/null || true
|
||||
|
||||
# was-enabled defaults to true, so new installations run enable.
|
||||
if deb-systemd-helper --quiet was-enabled memgraph.service; then
|
||||
# Enables the unit on first installation, creates new
|
||||
# symlinks on upgrades if the unit file has changed.
|
||||
deb-systemd-helper enable memgraph.service >/dev/null || true
|
||||
else
|
||||
# Update the statefile to add new symlinks (if any), which need to be
|
||||
# cleaned up on purge. Also remove old symlinks.
|
||||
deb-systemd-helper update-state memgraph.service >/dev/null || true
|
||||
fi
|
||||
|
||||
if [ -d /run/systemd/system ]; then
|
||||
systemctl --system daemon-reload >/dev/null || true
|
||||
deb-systemd-invoke start memgraph.service >/dev/null || true
|
||||
fi
|
||||
|
||||
# Take a look at the preinst script for the detailed explanation.
|
||||
if dpkg-maintscript-helper supports rm_conffile 2>/dev/null; then
|
||||
dpkg-maintscript-helper rm_conffile /etc/logrotate.d/memgraph_audit 1.1.999 -- "$@"
|
||||
fi
|
||||
|
||||
exit 0
|
||||
@@ -1,73 +0,0 @@
|
||||
#!/bin/sh
|
||||
# postrm script for memgraph
|
||||
#
|
||||
# see: dh_installdeb(1)
|
||||
|
||||
set -e
|
||||
|
||||
# summary of how this script can be called:
|
||||
# * <postrm> `remove'
|
||||
# * <postrm> `purge'
|
||||
# * <old-postrm> `upgrade' <new-version>
|
||||
# * <new-postrm> `failed-upgrade' <old-version>
|
||||
# * <new-postrm> `abort-install'
|
||||
# * <new-postrm> `abort-install' <old-version>
|
||||
# * <new-postrm> `abort-upgrade' <old-version>
|
||||
# * <disappearer's-postrm> `disappear' <overwriter>
|
||||
# <overwriter-version>
|
||||
# for details, see https://www.debian.org/doc/debian-policy/ or
|
||||
# the debian-policy package
|
||||
|
||||
var_files="/var/lib/memgraph /var/log/memgraph"
|
||||
|
||||
case "$1" in
|
||||
purge)
|
||||
# Remove 'var/*/memgraph' directories, even if they contain something.
|
||||
for var_file in $var_files; do
|
||||
rm -rf $var_file
|
||||
done
|
||||
# Remove generated SSL certificates
|
||||
if [ -d /etc/memgraph/ssl ]; then
|
||||
rm -rf /etc/memgraph/ssl
|
||||
fi
|
||||
# Don't remove the 'memgraph' user, since we cannot be sure whether it
|
||||
# existed before.
|
||||
;;
|
||||
|
||||
remove|upgrade|failed-upgrade|abort-install|abort-upgrade|disappear)
|
||||
# Default behaviour does what we expect, removes untouched installed
|
||||
# files but keeps configuration.
|
||||
;;
|
||||
|
||||
*)
|
||||
echo "postrm called with unknown argument \`$1'" >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
# Remove and purge systemd memgraph.service. The following was autogenerated
|
||||
# by dh_systemd_enable and dh_systemd_start.
|
||||
|
||||
if [ -d /run/systemd/system ]; then
|
||||
systemctl --system daemon-reload >/dev/null || true
|
||||
fi
|
||||
|
||||
if [ "$1" = "remove" ]; then
|
||||
if [ -x "/usr/bin/deb-systemd-helper" ]; then
|
||||
deb-systemd-helper mask memgraph.service >/dev/null
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ "$1" = "purge" ]; then
|
||||
if [ -x "/usr/bin/deb-systemd-helper" ]; then
|
||||
deb-systemd-helper purge memgraph.service >/dev/null
|
||||
deb-systemd-helper unmask memgraph.service >/dev/null
|
||||
fi
|
||||
fi
|
||||
|
||||
# Take a look at the preinst script for the detailed explanation.
|
||||
if dpkg-maintscript-helper supports rm_conffile 2>/dev/null; then
|
||||
dpkg-maintscript-helper rm_conffile /etc/logrotate.d/memgraph_audit 1.1.999 -- "$@"
|
||||
fi
|
||||
|
||||
exit 0
|
||||
@@ -1,19 +0,0 @@
|
||||
#!/bin/sh
|
||||
# preinst script for memgraph
|
||||
#
|
||||
# see: dh_installdeb(1)
|
||||
|
||||
set -e
|
||||
|
||||
# Manage (remove) /etc/logrotate.d/memgraph_audit file because the whole
|
||||
# logrotate config is moved to /etc/logrotate.d/memgraph since v1.2.0.
|
||||
# Note: Only used to manage Memgraph Enterprise config but packaged into the
|
||||
# Memgraph Community as well.
|
||||
if dpkg-maintscript-helper supports rm_conffile 2>/dev/null; then
|
||||
# 1.1.999 is chosen because it's high enough version number. It's highly
|
||||
# unlikely (impossible) that the patch number in v1.1 reaches 999
|
||||
# (it's 0 on 2020-10-17).
|
||||
# Tested with: `dpkg --compare-versions -- "1.2" le-nl "1.1.999"`
|
||||
# (used inside dpkg-maintscript-helper script).
|
||||
dpkg-maintscript-helper rm_conffile /etc/logrotate.d/memgraph_audit 1.1.999 -- "$@"
|
||||
fi
|
||||
@@ -1,32 +0,0 @@
|
||||
#!/bin/sh
|
||||
# prerm script for memgraph
|
||||
#
|
||||
# see: dh_installdeb(1)
|
||||
|
||||
set -e
|
||||
|
||||
# summary of how this script can be called:
|
||||
# * <prerm> `remove'
|
||||
# * <old-prerm> `upgrade' <new-version>
|
||||
# * <new-prerm> `failed-upgrade' <old-version>
|
||||
# * <conflictor's-prerm> `remove' `in-favour' <package> <new-version>
|
||||
# * <deconfigured's-prerm> `deconfigure' `in-favour'
|
||||
# <package-being-installed> <version> `removing'
|
||||
# <conflicting-package> <version>
|
||||
# for details, see https://www.debian.org/doc/debian-policy/ or
|
||||
# the debian-policy package
|
||||
|
||||
case "$1" in
|
||||
remove|upgrade|deconfigure|failed-upgrade)
|
||||
if [ -d /run/systemd/system ]; then
|
||||
deb-systemd-invoke stop memgraph.service >/dev/null
|
||||
fi
|
||||
;;
|
||||
|
||||
*)
|
||||
echo "prerm called with unknown argument \`$1'" >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
exit 0
|
||||
@@ -1,30 +0,0 @@
|
||||
FROM debian:buster
|
||||
# NOTE: If you change the base distro update release/package as well.
|
||||
|
||||
ARG deb_release
|
||||
|
||||
RUN apt-get update && apt-get install -y \
|
||||
openssl libcurl4 libssl1.1 python3 libpython3.7 python3-pip \
|
||||
--no-install-recommends \
|
||||
&& rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
|
||||
|
||||
RUN pip3 install networkx==2.4 numpy==1.19.2 scipy==1.5.2
|
||||
|
||||
COPY ${deb_release} /
|
||||
|
||||
# Install memgraph package
|
||||
RUN dpkg -i ${deb_release}
|
||||
|
||||
# Memgraph listens for Bolt Protocol on this port by default.
|
||||
EXPOSE 7687
|
||||
# Snapshots and logging volumes
|
||||
VOLUME /var/log/memgraph
|
||||
VOLUME /var/lib/memgraph
|
||||
# Configuration volume
|
||||
VOLUME /etc/memgraph
|
||||
|
||||
USER memgraph
|
||||
WORKDIR /usr/lib/memgraph
|
||||
|
||||
ENTRYPOINT ["/usr/lib/memgraph/memgraph"]
|
||||
CMD [""]
|
||||
@@ -1,30 +0,0 @@
|
||||
FROM debian:buster
|
||||
# NOTE: If you change the base distro update release/package as well.
|
||||
|
||||
ARG deb_release
|
||||
|
||||
RUN apt-get update && apt-get install -y \
|
||||
openssl libcurl4 libssl1.1 libseccomp2 python3 libpython3.7 python3-pip \
|
||||
--no-install-recommends \
|
||||
&& rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
|
||||
|
||||
RUN pip3 install networkx==2.4 numpy==1.19.2 scipy==1.5.2
|
||||
|
||||
COPY ${deb_release} /
|
||||
|
||||
# Install memgraph package
|
||||
RUN dpkg -i ${deb_release}
|
||||
|
||||
# Memgraph listens for Bolt Protocol on this port by default.
|
||||
EXPOSE 7687
|
||||
# Snapshots and logging volumes
|
||||
VOLUME /var/log/memgraph
|
||||
VOLUME /var/lib/memgraph
|
||||
# Configuration volume
|
||||
VOLUME /etc/memgraph
|
||||
|
||||
USER memgraph
|
||||
WORKDIR /usr/lib/memgraph
|
||||
|
||||
ENTRYPOINT ["/usr/lib/memgraph/memgraph"]
|
||||
CMD [""]
|
||||
@@ -1,47 +0,0 @@
|
||||
#!/bin/bash -e
|
||||
|
||||
# Build and package Docker image of Memgraph.
|
||||
|
||||
function print_help () {
|
||||
echo "Usage: $0 [--latest] MEMGRAPH_PACKAGE.deb"
|
||||
echo "Optional arguments:"
|
||||
echo -e "\t-h|--help\t\tPrint help."
|
||||
echo -e "\t--latest\t\tTag image as latest version."
|
||||
}
|
||||
|
||||
working_dir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
||||
|
||||
latest_image=""
|
||||
tag_latest=""
|
||||
if [[ $# -eq 2 && "$1" == "--latest" ]]; then
|
||||
latest_image="memgraph:latest"
|
||||
tag_latest="-t memgraph:latest"
|
||||
shift
|
||||
elif [[ $# -ne 1 || "$1" == "-h" || "$1" == "--help" ]]; then
|
||||
print_help
|
||||
exit 1
|
||||
fi
|
||||
|
||||
deb_path="$1"
|
||||
if [[ ! -f "$deb_path" ]]; then
|
||||
echo "File '$deb_path' does not exist!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Copy the .deb to working directory.
|
||||
cp "$deb_path" "${working_dir}/"
|
||||
cd ${working_dir}
|
||||
|
||||
# Extract version and offering from deb name.
|
||||
deb_name=`echo $(basename "$deb_path") | sed 's/.deb$//'`
|
||||
version=`echo ${deb_name} | cut -d '_' -f 2 | rev | cut -d '-' -f 2- | rev | tr '+~' '__'`
|
||||
offering=`echo ${version} | cut -d '-' -f 2`
|
||||
dockerfile_path="${working_dir}/memgraph_${offering}.dockerfile"
|
||||
image_name="memgraph:${version}"
|
||||
package_name="memgraph-${version}-docker.tar.gz"
|
||||
|
||||
# Build docker image.
|
||||
docker build -t ${image_name} ${tag_latest} -f ${dockerfile_path} --build-arg deb_release=${deb_name}.deb .
|
||||
docker save ${image_name} ${latest_image} > ${package_name}
|
||||
rm "${deb_name}.deb"
|
||||
echo "Built Docker image at '${working_dir}/${package_name}'"
|
||||
@@ -1,266 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
import argparse
|
||||
import re
|
||||
import subprocess
|
||||
import sys
|
||||
import os
|
||||
|
||||
|
||||
# This script is used to determine the current version of Memgraph. The script
|
||||
# determines the current version using `git` automatically. The user can also
|
||||
# manually specify a version override and then the supplied version will be
|
||||
# used instead of the version determined by `git`. All versions (automatically
|
||||
# detected and manually specified) can have a custom version suffix added to
|
||||
# them.
|
||||
#
|
||||
# The current version can be one of either:
|
||||
# - release version
|
||||
# - development version
|
||||
#
|
||||
# The release version is either associated with a `release/X.Y` branch
|
||||
# (automatic detection) or is manually specified. When the version is
|
||||
# automatically detected from the branch a `.0` is appended to the version.
|
||||
# Example 1:
|
||||
# - branch: release/0.50
|
||||
# - version: 0.50.0
|
||||
# Example 2:
|
||||
# - manually supplied version: 0.50.1
|
||||
# - version: 0.50.1
|
||||
#
|
||||
# The development version is always determined using `git` in the following
|
||||
# way:
|
||||
# - release version - nearest (older) `release/X.Y` branch version
|
||||
# - distance from the release branch - Z commits
|
||||
# - the current commit short hash
|
||||
# Example:
|
||||
# - release version: 0.50.0 (nearest older branch `release/0.50`)
|
||||
# - distance from the release branch: 42 (commits)
|
||||
# - current commit short hash: 7e1eef94
|
||||
#
|
||||
# The script then uses the collected information to generate the versions that
|
||||
# will be used in the binary, DEB package and RPM package. All of the versions
|
||||
# have different naming conventions that have to be met and they differ among
|
||||
# each other.
|
||||
#
|
||||
# The binary version is determined using the following two templates:
|
||||
# Release version:
|
||||
# <VERSION>-<OFFERING>[-<SUFFIX>]
|
||||
# Development version:
|
||||
# <VERSION>+<DISTANCE>~<SHORTHASH>-<OFFERING>[-<SUFFIX>]
|
||||
# Examples:
|
||||
# Release version:
|
||||
# 0.50.1-community
|
||||
# 0.50.1-enterprise
|
||||
# 0.50.1-enterprise-veryimportantcustomer
|
||||
# Development version (master, 12 commits after release/0.50):
|
||||
# 0.50.0+12~7e1eef94-community
|
||||
# 0.50.0+12~7e1eef94-enterprise
|
||||
# 0.50.0+12~7e1eef94-enterprise-veryimportantcustomer
|
||||
#
|
||||
# The DEB package version is determined using the following two templates:
|
||||
# Release version:
|
||||
# <VERSION>-<OFFERING>[-<SUFFIX>]-1
|
||||
# Development version (master, 12 commits after release/0.50):
|
||||
# <VERSION>+<DISTANCE>~<SHORTHASH>-<OFFERING>[-<SUFFIX>]-1
|
||||
# Examples:
|
||||
# Release version:
|
||||
# 0.50.1-community-1
|
||||
# 0.50.1-enterprise-1
|
||||
# 0.50.1-enterprise-veryimportantcustomer-1
|
||||
# Development version (master, 12 commits after release/0.50):
|
||||
# 0.50.0+12~7e1eef94-community-1
|
||||
# 0.50.0+12~7e1eef94-enterprise-1
|
||||
# 0.50.0+12~7e1eef94-enterprise-veryimportantcustomer-1
|
||||
# For more documentation about the DEB package naming conventions see:
|
||||
# https://www.debian.org/doc/debian-policy/ch-controlfields.html#version
|
||||
#
|
||||
# The RPM package version is determined using the following two templates:
|
||||
# Release version:
|
||||
# <VERSION>_1.<OFFERING>[.<SUFFIX>]
|
||||
# Development version:
|
||||
# <VERSION>_0.<DISTANCE>.<SHORTHASH>.<OFFERING>[.<SUFFIX>]
|
||||
# Examples:
|
||||
# Release version:
|
||||
# 0.50.1_1.community
|
||||
# 0.50.1_1.enterprise
|
||||
# 0.50.1_1.enterprise.veryimportantcustomer
|
||||
# Development version:
|
||||
# 0.50.0_0.12.7e1eef94.community
|
||||
# 0.50.0_0.12.7e1eef94.enterprise
|
||||
# 0.50.0_0.12.7e1eef94.enterprise.veryimportantcustomer
|
||||
# For more documentation about the RPM package naming conventions see:
|
||||
# https://docs.fedoraproject.org/en-US/packaging-guidelines/Versioning/
|
||||
# https://fedoraproject.org/wiki/Package_Versioning_Examples
|
||||
|
||||
|
||||
def get_output(*cmd, multiple=False):
|
||||
ret = subprocess.run(cmd, stdout=subprocess.PIPE, check=True)
|
||||
if multiple:
|
||||
return list(map(lambda x: x.strip(),
|
||||
ret.stdout.decode("utf-8").strip().split("\n")))
|
||||
return ret.stdout.decode("utf-8").strip()
|
||||
|
||||
|
||||
def format_version(variant, version, offering, distance=None, shorthash=None,
|
||||
suffix=None):
|
||||
if not distance:
|
||||
# This is a release version.
|
||||
if variant == "deb":
|
||||
# <VERSION>-<OFFERING>[-<SUFFIX>]-1
|
||||
ret = "{}-{}".format(version, offering)
|
||||
if suffix:
|
||||
ret += "-" + suffix
|
||||
ret += "-1"
|
||||
return ret
|
||||
elif variant == "rpm":
|
||||
# <VERSION>_1.<OFFERING>[.<SUFFIX>]
|
||||
ret = "{}_1.{}".format(version, offering)
|
||||
if suffix:
|
||||
ret += "." + suffix
|
||||
return ret
|
||||
else:
|
||||
# <VERSION>-<OFFERING>[-<SUFFIX>]
|
||||
ret = "{}-{}".format(version, offering)
|
||||
if suffix:
|
||||
ret += "-" + suffix
|
||||
return ret
|
||||
else:
|
||||
# This is a development version.
|
||||
if variant == "deb":
|
||||
# <VERSION>+<DISTANCE>~<SHORTHASH>-<OFFERING>[-<SUFFIX>]-1
|
||||
ret = "{}+{}~{}-{}".format(version, distance, shorthash, offering)
|
||||
if suffix:
|
||||
ret += "-" + suffix
|
||||
ret += "-1"
|
||||
return ret
|
||||
elif variant == "rpm":
|
||||
# <VERSION>_0.<DISTANCE>.<SHORTHASH>.<OFFERING>[.<SUFFIX>]
|
||||
ret = "{}_0.{}.{}.{}".format(
|
||||
version, distance, shorthash, offering)
|
||||
if suffix:
|
||||
ret += "." + suffix
|
||||
return ret
|
||||
else:
|
||||
# <VERSION>+<DISTANCE>~<SHORTHASH>-<OFFERING>[-<SUFFIX>]
|
||||
ret = "{}+{}~{}-{}".format(version, distance, shorthash, offering)
|
||||
if suffix:
|
||||
ret += "-" + suffix
|
||||
return ret
|
||||
|
||||
|
||||
# Parse arguments.
|
||||
parser = argparse.ArgumentParser(
|
||||
description="Get the current version of Memgraph.")
|
||||
parser.add_argument(
|
||||
"--enterprise", action="store_true",
|
||||
help="set the current offering to enterprise (default 'community')")
|
||||
parser.add_argument(
|
||||
"version", help="manual version override, if supplied the version isn't "
|
||||
"determined using git")
|
||||
parser.add_argument(
|
||||
"suffix", help="custom suffix for the current version being built")
|
||||
parser.add_argument(
|
||||
"--variant", choices=("binary", "deb", "rpm"), default="binary",
|
||||
help="which variant of the version string should be generated")
|
||||
parser.add_argument(
|
||||
"--memgraph-root-dir", help="The root directory of the checked out "
|
||||
"Memgraph repository.", default=".")
|
||||
args = parser.parse_args()
|
||||
|
||||
if not os.path.isdir(args.memgraph_root_dir):
|
||||
raise Exception("The root directory ({}) is not a valid directory".format(
|
||||
args.memgraph_root_dir))
|
||||
|
||||
os.chdir(args.memgraph_root_dir)
|
||||
|
||||
offering = "enterprise" if args.enterprise else "community"
|
||||
|
||||
# Check whether the version was manually supplied.
|
||||
if args.version:
|
||||
if not re.match(r"^[0-9]+\.[0-9]+\.[0-9]+$", args.version):
|
||||
raise Exception("Invalid version supplied '{}'!".format(args.version))
|
||||
print(format_version(args.variant, args.version, offering,
|
||||
suffix=args.suffix), end="")
|
||||
sys.exit(0)
|
||||
|
||||
# Within CI, after the regular checkout, master is sometimes (e.g. in the case
|
||||
# of an epic or task branch) NOT created as a local branch. cpack depends on
|
||||
# variables generated by calling this script during the cmake phase. This
|
||||
# script needs master to be the local branch. `git fetch origin master:master`
|
||||
# is creating the local master branch without checking it out. Does nothing if
|
||||
# master is already there.
|
||||
try:
|
||||
current_branch = get_output("git", "rev-parse", "--abbrev-ref", "HEAD")
|
||||
if current_branch != "master":
|
||||
branches = get_output("git", "branch")
|
||||
if "master" in branches:
|
||||
# If master is present locally, the fetch is allowed to fail
|
||||
# because this script will still be able to compare against the
|
||||
# master branch.
|
||||
try:
|
||||
get_output("git", "fetch", "origin", "master:master")
|
||||
except Exception:
|
||||
pass
|
||||
else:
|
||||
# If master is not present locally, the fetch command has to
|
||||
# succeed because something else will fail otherwise.
|
||||
get_output("git", "fetch", "origin", "master:master")
|
||||
except Exception:
|
||||
print("Fatal error while ensuring local master branch.")
|
||||
sys.exit(1)
|
||||
|
||||
# Get current commit hashes.
|
||||
current_hash = get_output("git", "rev-parse", "HEAD")
|
||||
current_hash_short = get_output("git", "rev-parse", "--short", "HEAD")
|
||||
|
||||
# We want to find branches that exist on some remote and that are named
|
||||
# `release/[0-9]+\.[0-9]+`.
|
||||
branch_regex = re.compile(r"^remotes/[a-zA-Z0-9]+/release/([0-9]+\.[0-9]+)$")
|
||||
|
||||
# Find all existing versions.
|
||||
versions = []
|
||||
branches = get_output("git", "branch", "--all", multiple=True)
|
||||
for branch in branches:
|
||||
match = branch_regex.match(branch)
|
||||
if match is not None:
|
||||
version = tuple(map(int, match.group(1).split(".")))
|
||||
master_branch_merge = get_output("git", "merge-base", "master", branch)
|
||||
versions.append((version, branch, master_branch_merge))
|
||||
versions.sort(reverse=True)
|
||||
|
||||
# Check which existing version branch is closest to the current commit. We are
|
||||
# only interested in branches that were branched out before this commit was
|
||||
# created.
|
||||
current_version = None
|
||||
for version in versions:
|
||||
version_tuple, branch, master_branch_merge = version
|
||||
current_branch_merge = get_output(
|
||||
"git", "merge-base", current_hash, branch)
|
||||
master_current_merge = get_output(
|
||||
"git", "merge-base", current_hash, "master")
|
||||
# The first check checks whether this commit is a child of `master` and
|
||||
# the version branch was created before us.
|
||||
# The second check checks whether this commit is a child of the version
|
||||
# branch.
|
||||
if master_branch_merge == current_branch_merge or \
|
||||
master_branch_merge == master_current_merge:
|
||||
current_version = version
|
||||
break
|
||||
|
||||
# Determine current version.
|
||||
if current_version is None:
|
||||
raise Exception("You are attempting to determine the version for a very "
|
||||
"old version of Memgraph!")
|
||||
version, branch, master_branch_merge = current_version
|
||||
distance = int(get_output("git", "rev-list", "--count", "--first-parent",
|
||||
master_branch_merge + ".." + current_hash))
|
||||
version_str = ".".join(map(str, version)) + ".0"
|
||||
if distance == 0:
|
||||
print(format_version(args.variant, version_str, offering,
|
||||
suffix=args.suffix),
|
||||
end="")
|
||||
else:
|
||||
print(format_version(args.variant, version_str, offering,
|
||||
distance=distance, shorthash=current_hash_short,
|
||||
suffix=args.suffix),
|
||||
end="")
|
||||
@@ -1,2 +0,0 @@
|
||||
# logrotate configuration for Memgraph Community
|
||||
# see "man logrotate" for details
|
||||
@@ -1,13 +0,0 @@
|
||||
# logrotate configuration for Memgraph Enterprise
|
||||
# see "man logrotate" for details
|
||||
|
||||
/var/lib/memgraph/durability/audit/audit.log {
|
||||
# rotate log files daily
|
||||
daily
|
||||
# keep one year worth of audit logs
|
||||
rotate 365
|
||||
# send SIGUSR2 to notify memgraph to recreate logfile
|
||||
postrotate
|
||||
/usr/bin/killall -s SIGUSR2 memgraph
|
||||
endscript
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
[Unit]
|
||||
Description=Memgraph: High performance, in-memory, transactional graph database
|
||||
|
||||
[Service]
|
||||
User=memgraph
|
||||
Group=memgraph
|
||||
ExecStart=/usr/lib/memgraph/memgraph
|
||||
# Uncomment this if Memgraph needs more time to write the snapshot on exit.
|
||||
#TimeoutStopSec=5min
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
@@ -1,14 +0,0 @@
|
||||
FROM centos:7
|
||||
|
||||
ARG TOOLCHAIN_VERSION
|
||||
|
||||
RUN yum -y update \
|
||||
&& yum install -y wget git
|
||||
# Do NOT be smart here and clean the cache because the container is used in the
|
||||
# stateful context.
|
||||
|
||||
RUN wget -q https://s3-eu-west-1.amazonaws.com/deps.memgraph.io/${TOOLCHAIN_VERSION}/${TOOLCHAIN_VERSION}-binaries-centos-7.tar.gz \
|
||||
-O ${TOOLCHAIN_VERSION}-binaries-centos-7.tar.gz \
|
||||
&& tar xzvf ${TOOLCHAIN_VERSION}-binaries-centos-7.tar.gz -C /opt
|
||||
|
||||
ENTRYPOINT ["sleep", "infinity"]
|
||||
@@ -1,14 +0,0 @@
|
||||
FROM centos:8
|
||||
|
||||
ARG TOOLCHAIN_VERSION
|
||||
|
||||
RUN dnf -y update \
|
||||
&& dnf install -y wget git
|
||||
# Do NOT be smart here and clean the cache because the container is used in the
|
||||
# stateful context.
|
||||
|
||||
RUN wget -q https://s3-eu-west-1.amazonaws.com/deps.memgraph.io/${TOOLCHAIN_VERSION}/${TOOLCHAIN_VERSION}-binaries-centos-8.tar.gz \
|
||||
-O ${TOOLCHAIN_VERSION}-binaries-centos-8.tar.gz \
|
||||
&& tar xzvf ${TOOLCHAIN_VERSION}-binaries-centos-8.tar.gz -C /opt
|
||||
|
||||
ENTRYPOINT ["sleep", "infinity"]
|
||||
@@ -1,17 +0,0 @@
|
||||
FROM debian:10
|
||||
|
||||
ARG TOOLCHAIN_VERSION
|
||||
|
||||
# Stops tzdata interactive configuration.
|
||||
ENV DEBIAN_FRONTEND=noninteractive
|
||||
|
||||
RUN apt update && apt install -y \
|
||||
ca-certificates wget git
|
||||
# Do NOT be smart here and clean the cache because the container is used in the
|
||||
# stateful context.
|
||||
|
||||
RUN wget -q https://s3-eu-west-1.amazonaws.com/deps.memgraph.io/${TOOLCHAIN_VERSION}/${TOOLCHAIN_VERSION}-binaries-debian-10.tar.gz \
|
||||
-O ${TOOLCHAIN_VERSION}-binaries-debian-10.tar.gz \
|
||||
&& tar xzvf ${TOOLCHAIN_VERSION}-binaries-debian-10.tar.gz -C /opt
|
||||
|
||||
ENTRYPOINT ["sleep", "infinity"]
|
||||
@@ -1,17 +0,0 @@
|
||||
FROM debian:9
|
||||
|
||||
ARG TOOLCHAIN_VERSION
|
||||
|
||||
# Stops tzdata interactive configuration.
|
||||
ENV DEBIAN_FRONTEND=noninteractive
|
||||
|
||||
RUN apt update && apt install -y \
|
||||
ca-certificates wget git
|
||||
# Do NOT be smart here and clean the cache because the container is used in the
|
||||
# stateful context.
|
||||
|
||||
RUN wget -q https://s3-eu-west-1.amazonaws.com/deps.memgraph.io/${TOOLCHAIN_VERSION}/${TOOLCHAIN_VERSION}-binaries-debian-9.tar.gz \
|
||||
-O ${TOOLCHAIN_VERSION}-binaries-debian-9.tar.gz \
|
||||
&& tar xzvf ${TOOLCHAIN_VERSION}-binaries-debian-9.tar.gz -C /opt
|
||||
|
||||
ENTRYPOINT ["sleep", "infinity"]
|
||||
@@ -1,26 +0,0 @@
|
||||
version: "3"
|
||||
services:
|
||||
mgbuild_centos-7:
|
||||
build:
|
||||
context: centos-7
|
||||
container_name: "mgbuild_centos-7"
|
||||
mgbuild_centos-8:
|
||||
build:
|
||||
context: centos-8
|
||||
container_name: "mgbuild_centos-8"
|
||||
mgbuild_debian-9:
|
||||
build:
|
||||
context: debian-9
|
||||
container_name: "mgbuild_debian-9"
|
||||
mgbuild_debian-10:
|
||||
build:
|
||||
context: debian-10
|
||||
container_name: "mgbuild_debian-10"
|
||||
mgbuild_ubuntu-18.04:
|
||||
build:
|
||||
context: ubuntu-18.04
|
||||
container_name: "mgbuild_ubuntu-18.04"
|
||||
mgbuild_ubuntu-20.04:
|
||||
build:
|
||||
context: ubuntu-20.04
|
||||
container_name: "mgbuild_ubuntu-20.04"
|
||||
@@ -1,154 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -Eeuo pipefail
|
||||
|
||||
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
||||
SUPPORTED_OFFERING=(community enterprise)
|
||||
SUPPORTED_OS=(centos-7 centos-8 debian-9 debian-10 ubuntu-18.04 ubuntu-20.04)
|
||||
PROJECT_ROOT="$SCRIPT_DIR/../.."
|
||||
TOOLCHAIN_VERSION="toolchain-v3"
|
||||
ACTIVATE_TOOLCHAIN="source /opt/${TOOLCHAIN_VERSION}/activate"
|
||||
HOST_OUTPUT_DIR="$PROJECT_ROOT/build/output"
|
||||
|
||||
print_help () {
|
||||
echo "$0 init|package {offering} {os} [--for-docker]|docker|test"
|
||||
echo ""
|
||||
echo " offerings: ${SUPPORTED_OFFERING[*]}"
|
||||
echo " OSs: ${SUPPORTED_OS[*]}"
|
||||
exit 1
|
||||
}
|
||||
|
||||
make_package () {
|
||||
offering="$1"
|
||||
offering_flag=" -DMG_ENTERPRISE=OFF "
|
||||
if [[ "$offering" == "enterprise" ]]; then
|
||||
offering_flag=" -DMG_ENTERPRISE=ON "
|
||||
fi
|
||||
if [[ "$offering" == "community" ]]; then
|
||||
offering_flag=" -DMG_ENTERPRISE=OFF "
|
||||
fi
|
||||
os="$2"
|
||||
package_command=""
|
||||
if [[ "$os" =~ ^"centos".* ]]; then
|
||||
package_command=" cpack -G RPM --config ../CPackConfig.cmake && rpmlint memgraph*.rpm "
|
||||
fi
|
||||
if [[ "$os" =~ ^"debian".* ]]; then
|
||||
package_command=" cpack -G DEB --config ../CPackConfig.cmake "
|
||||
fi
|
||||
if [[ "$os" =~ ^"ubuntu".* ]]; then
|
||||
package_command=" cpack -G DEB --config ../CPackConfig.cmake "
|
||||
fi
|
||||
docker_flag=" -DBUILD_FOR_DOCKER=OFF "
|
||||
if [[ "$#" -gt 2 ]]; then
|
||||
if [[ "$3" == "--for-docker" ]]; then
|
||||
docker_flag=" -DBUILD_FOR_DOCKER=ON "
|
||||
fi
|
||||
fi
|
||||
build_container="mgbuild_$os"
|
||||
echo "Building Memgraph $offering for $os on $build_container..."
|
||||
|
||||
echo "Copying project files..."
|
||||
# If master is not the current branch, fetch it, because the get_version
|
||||
# script depends on it. If we are on master, the fetch command is going to
|
||||
# fail so that's why there is the explicit check.
|
||||
# Required here because Docker build container can't access remote.
|
||||
cd "$PROJECT_ROOT"
|
||||
if [[ "$(git rev-parse --abbrev-ref HEAD)" != "master" ]]; then
|
||||
git fetch origin master:master
|
||||
fi
|
||||
docker exec "$build_container" mkdir -p /memgraph
|
||||
docker cp "$PROJECT_ROOT/." "$build_container:/memgraph/"
|
||||
|
||||
container_build_dir="/memgraph/build"
|
||||
container_output_dir="$container_build_dir/output"
|
||||
|
||||
# TODO(gitbuda): TOOLCHAIN_RUN_DEPS should be installed during the Docker
|
||||
# image build phase, but that is not easy at this point because the
|
||||
# environment/os/{os}.sh does not come within the toolchain package. When
|
||||
# migrating to the next version of toolchain do that, and remove the
|
||||
# TOOLCHAIN_RUN_DEPS installation from here.
|
||||
echo "Installing dependencies..."
|
||||
docker exec "$build_container" bash -c "/memgraph/environment/os/$os.sh install TOOLCHAIN_RUN_DEPS"
|
||||
docker exec "$build_container" bash -c "/memgraph/environment/os/$os.sh install MEMGRAPH_BUILD_DEPS"
|
||||
|
||||
echo "Building targeted package..."
|
||||
docker exec "$build_container" bash -c "cd /memgraph && ./init"
|
||||
docker exec "$build_container" bash -c "cd $container_build_dir && rm -rf ./*"
|
||||
docker exec "$build_container" bash -c "cd $container_build_dir && $ACTIVATE_TOOLCHAIN && cmake -DCMAKE_BUILD_TYPE=release $offering_flag $docker_flag .."
|
||||
# ' is used instead of " because we need to run make within the allowed
|
||||
# container resources.
|
||||
# shellcheck disable=SC2016
|
||||
docker exec "$build_container" bash -c "cd $container_build_dir && $ACTIVATE_TOOLCHAIN "'&& make -j$(nproc)'
|
||||
docker exec "$build_container" bash -c "cd $container_build_dir && $ACTIVATE_TOOLCHAIN "'&& make -j$(nproc) -B mgconsole'
|
||||
docker exec "$build_container" bash -c "mkdir -p $container_output_dir && cd $container_output_dir && $ACTIVATE_TOOLCHAIN && $package_command"
|
||||
|
||||
echo "Copying targeted package to host..."
|
||||
last_package_name=$(docker exec "$build_container" bash -c "cd $container_output_dir && ls -t memgraph* | head -1")
|
||||
# The operating system folder is introduced because multiple different
|
||||
# packages could be preserved during the same build "session".
|
||||
mkdir -p "$HOST_OUTPUT_DIR/$os"
|
||||
package_host_destination="$HOST_OUTPUT_DIR/$os/$last_package_name"
|
||||
docker cp "$build_container:$container_output_dir/$last_package_name" "$package_host_destination"
|
||||
echo "Package saved to $package_host_destination."
|
||||
}
|
||||
|
||||
case "$1" in
|
||||
init)
|
||||
cd "$SCRIPT_DIR"
|
||||
docker-compose build --build-arg TOOLCHAIN_VERSION="${TOOLCHAIN_VERSION}"
|
||||
docker-compose up -d
|
||||
;;
|
||||
|
||||
docker)
|
||||
# NOTE: Docker is build on top of Debian 10 package.
|
||||
based_on_os="debian-10"
|
||||
# shellcheck disable=SC2012
|
||||
last_package_name=$(cd "$HOST_OUTPUT_DIR/$based_on_os" && ls -t memgraph* | head -1)
|
||||
docker_build_folder="$PROJECT_ROOT/release/docker"
|
||||
cd "$docker_build_folder"
|
||||
./package_deb_docker --latest "$HOST_OUTPUT_DIR/$based_on_os/$last_package_name"
|
||||
# shellcheck disable=SC2012
|
||||
docker_image_name=$(cd "$docker_build_folder" && ls -t memgraph* | head -1)
|
||||
docker_host_folder="$HOST_OUTPUT_DIR/docker"
|
||||
docker_host_image_path="$docker_host_folder/$docker_image_name"
|
||||
mkdir -p "$docker_host_folder"
|
||||
cp "$docker_build_folder/$docker_image_name" "$docker_host_image_path"
|
||||
echo "Docker images saved to $docker_host_image_path."
|
||||
;;
|
||||
|
||||
package)
|
||||
shift 1
|
||||
if [[ "$#" -lt 2 ]]; then
|
||||
print_help
|
||||
fi
|
||||
offering="$1"
|
||||
shift 1
|
||||
is_offering_ok=false
|
||||
for supported_offering in "${SUPPORTED_OFFERING[@]}"; do
|
||||
if [[ "$supported_offering" == "${offering}" ]]; then
|
||||
is_offering_ok=true
|
||||
fi
|
||||
done
|
||||
os="$1"
|
||||
shift 1
|
||||
is_os_ok=false
|
||||
for supported_os in "${SUPPORTED_OS[@]}"; do
|
||||
if [[ "$supported_os" == "${os}" ]]; then
|
||||
is_os_ok=true
|
||||
fi
|
||||
done
|
||||
if [[ "$is_offering_ok" == true ]] && [[ "$is_os_ok" == true ]]; then
|
||||
make_package "$offering" "$os" "$@"
|
||||
else
|
||||
print_help
|
||||
fi
|
||||
;;
|
||||
|
||||
test)
|
||||
echo "TODO(gitbuda): Test all packages on mgtest containers."
|
||||
;;
|
||||
|
||||
*)
|
||||
print_help
|
||||
;;
|
||||
esac
|
||||
@@ -1,17 +0,0 @@
|
||||
FROM ubuntu:18.04
|
||||
|
||||
ARG TOOLCHAIN_VERSION
|
||||
|
||||
# Stops tzdata interactive configuration.
|
||||
ENV DEBIAN_FRONTEND=noninteractive
|
||||
|
||||
RUN apt update && apt install -y \
|
||||
ca-certificates wget git
|
||||
# Do NOT be smart here and clean the cache because the container is used in the
|
||||
# stateful context.
|
||||
|
||||
RUN wget -q https://s3-eu-west-1.amazonaws.com/deps.memgraph.io/${TOOLCHAIN_VERSION}/${TOOLCHAIN_VERSION}-binaries-ubuntu-18.04.tar.gz \
|
||||
-O ${TOOLCHAIN_VERSION}-binaries-ubuntu-18.04.tar.gz \
|
||||
&& tar xzvf ${TOOLCHAIN_VERSION}-binaries-ubuntu-18.04.tar.gz -C /opt
|
||||
|
||||
ENTRYPOINT ["sleep", "infinity"]
|
||||
@@ -1,17 +0,0 @@
|
||||
FROM ubuntu:20.04
|
||||
|
||||
ARG TOOLCHAIN_VERSION
|
||||
|
||||
# Stops tzdata interactive configuration.
|
||||
ENV DEBIAN_FRONTEND=noninteractive
|
||||
|
||||
RUN apt update && apt install -y \
|
||||
ca-certificates wget git
|
||||
# Do NOT be smart here and clean the cache because the container is used in the
|
||||
# stateful context.
|
||||
|
||||
RUN wget -q https://s3-eu-west-1.amazonaws.com/deps.memgraph.io/${TOOLCHAIN_VERSION}/${TOOLCHAIN_VERSION}-binaries-ubuntu-20.04.tar.gz \
|
||||
-O ${TOOLCHAIN_VERSION}-binaries-ubuntu-20.04.tar.gz \
|
||||
&& tar xzvf ${TOOLCHAIN_VERSION}-binaries-ubuntu-20.04.tar.gz -C /opt
|
||||
|
||||
ENTRYPOINT ["sleep", "infinity"]
|
||||
@@ -1,138 +0,0 @@
|
||||
# -*- rpm-spec -*-
|
||||
BuildRoot: %_topdir/@CPACK_PACKAGE_FILE_NAME@@CPACK_RPM_PACKAGE_COMPONENT_PART_PATH@
|
||||
Summary: @CPACK_RPM_PACKAGE_SUMMARY@
|
||||
Name: @CPACK_RPM_PACKAGE_NAME@
|
||||
Version: @CPACK_RPM_PACKAGE_VERSION@
|
||||
Release: @CPACK_RPM_PACKAGE_RELEASE@
|
||||
License: @CPACK_RPM_PACKAGE_LICENSE@
|
||||
# Group field is deprecated
|
||||
# Group: @CPACK_RPM_PACKAGE_GROUP@
|
||||
Vendor: @CPACK_RPM_PACKAGE_VENDOR@
|
||||
BuildRequires: systemd
|
||||
|
||||
@TMP_RPM_URL@
|
||||
@TMP_RPM_REQUIRES@
|
||||
@TMP_RPM_REQUIRES_PRE@
|
||||
@TMP_RPM_REQUIRES_POST@
|
||||
@TMP_RPM_REQUIRES_PREUN@
|
||||
@TMP_RPM_REQUIRES_POSTUN@
|
||||
@TMP_RPM_PROVIDES@
|
||||
@TMP_RPM_OBSOLETES@
|
||||
@TMP_RPM_CONFLICTS@
|
||||
@TMP_RPM_AUTOPROV@
|
||||
@TMP_RPM_AUTOREQ@
|
||||
@TMP_RPM_AUTOREQPROV@
|
||||
@TMP_RPM_BUILDARCH@
|
||||
@TMP_RPM_PREFIXES@
|
||||
|
||||
@TMP_RPM_DEBUGINFO@
|
||||
|
||||
# This is needed to prevent Python compilation errors when building the RPM
|
||||
# package
|
||||
# https://github.com/scylladb/scylla/issues/2235
|
||||
%if 0%{?rhel} < 8
|
||||
%global __os_install_post \
|
||||
/usr/lib/rpm/redhat/brp-compress \
|
||||
%{!?__debug_package:\
|
||||
/usr/lib/rpm/redhat/brp-strip %{__strip} \
|
||||
/usr/lib/rpm/redhat/brp-strip-comment-note %{__strip} %{__objdump} \
|
||||
} \
|
||||
/usr/lib/rpm/redhat/brp-strip-static-archive %{__strip} \
|
||||
%{!?__jar_repack:/usr/lib/rpm/redhat/brp-java-repack-jars} \
|
||||
%{nil}
|
||||
%else
|
||||
%global __os_install_post \
|
||||
/usr/lib/rpm/brp-compress \
|
||||
%{!?__debug_package:\
|
||||
/usr/lib/rpm/brp-strip %{__strip} \
|
||||
/usr/lib/rpm/brp-strip-comment-note %{__strip} %{__objdump} \
|
||||
} \
|
||||
/usr/lib/rpm/brp-strip-static-archive %{__strip} \
|
||||
%{nil}
|
||||
%endif
|
||||
|
||||
%define _rpmdir %_topdir/RPMS
|
||||
%define _srcrpmdir %_topdir/SRPMS
|
||||
@FILE_NAME_DEFINE@
|
||||
%define _unpackaged_files_terminate_build 0
|
||||
@TMP_RPM_SPEC_INSTALL_POST@
|
||||
@CPACK_RPM_SPEC_MORE_DEFINE@
|
||||
@CPACK_RPM_COMPRESSION_TYPE_TMP@
|
||||
|
||||
%description
|
||||
@CPACK_RPM_PACKAGE_DESCRIPTION@
|
||||
|
||||
# This is a shortcutted spec file generated by CMake RPM generator
|
||||
# we skip _install step because CPack does that for us.
|
||||
# We do only save CPack installed tree in _prepr
|
||||
# and then restore it in build.
|
||||
%prep
|
||||
# Put the systemd unit where it is expected on this system
|
||||
mkdir -p $RPM_BUILD_ROOT/%{_unitdir}
|
||||
mv $RPM_BUILD_ROOT/lib/systemd/system/memgraph.service $RPM_BUILD_ROOT/%{_unitdir}
|
||||
rm -rf $RPM_BUILD_ROOT/lib
|
||||
# Fix the incorrect directory permissions set by cpack (this is fixed in CMake 3.11)
|
||||
find $RPM_BUILD_ROOT -type d | xargs chmod 755
|
||||
# After setting up custom prep, continue with CMake's default
|
||||
mv $RPM_BUILD_ROOT %_topdir/tmpBBroot
|
||||
|
||||
%install
|
||||
if [ -e $RPM_BUILD_ROOT ];
|
||||
then
|
||||
rm -rf $RPM_BUILD_ROOT
|
||||
fi
|
||||
mv %_topdir/tmpBBroot $RPM_BUILD_ROOT
|
||||
|
||||
@TMP_RPM_DEBUGINFO_INSTALL@
|
||||
|
||||
%clean
|
||||
|
||||
%post
|
||||
# memgraph user and group must be set in preinst
|
||||
chown memgraph:memgraph /var/lib/memgraph || exit 1
|
||||
chmod 750 /var/lib/memgraph || exit 1
|
||||
chown memgraph:adm /var/log/memgraph || exit 1
|
||||
chmod 750 /var/log/memgraph || exit 1
|
||||
|
||||
# Generate SSL certificates
|
||||
if [ ! -d /etc/memgraph/ssl ]; then
|
||||
mkdir /etc/memgraph/ssl || exit 1
|
||||
openssl req -x509 -newkey rsa:4096 -days 3650 -nodes \
|
||||
-keyout /etc/memgraph/ssl/key.pem -out /etc/memgraph/ssl/cert.pem \
|
||||
-subj "/C=GB/ST=London/L=London/O=Memgraph Ltd./CN=Memgraph DB" || exit 1
|
||||
chown memgraph:memgraph /etc/memgraph/ssl/* || exit 1
|
||||
chmod 400 /etc/memgraph/ssl/* || exit 1
|
||||
fi
|
||||
@RPM_SYMLINK_POSTINSTALL@
|
||||
@CPACK_RPM_SPEC_POSTINSTALL@
|
||||
|
||||
%postun
|
||||
@CPACK_RPM_SPEC_POSTUNINSTALL@
|
||||
|
||||
%pre
|
||||
# Add the 'memgraph' user and group
|
||||
getent group memgraph >/dev/null || groupadd -r memgraph || exit 1
|
||||
getent passwd memgraph >/dev/null || \
|
||||
useradd -r -g memgraph -d /var/lib/memgraph -s /bin/bash memgraph || exit 1
|
||||
echo "Don't forget to switch to the 'memgraph' user to use Memgraph" || exit 1
|
||||
@CPACK_RPM_SPEC_PREINSTALL@
|
||||
|
||||
%preun
|
||||
@CPACK_RPM_SPEC_PREUNINSTALL@
|
||||
|
||||
%files
|
||||
%defattr(@TMP_DEFAULT_FILE_PERMISSIONS@,@TMP_DEFAULT_USER@,@TMP_DEFAULT_GROUP@,@TMP_DEFAULT_DIR_PERMISSIONS@)
|
||||
@CPACK_RPM_INSTALL_FILES@
|
||||
# Since we moved the memgraph.service file, declare it explicitly here.
|
||||
# NOTE: memgraph.service must not be marked as configuration file.
|
||||
%{_unitdir}/memgraph.service
|
||||
|
||||
# Override CPACK_RPM_ABSOLUTE_INSTALL_FILES with our %config(noreplace), cpack
|
||||
# uses plain %config.
|
||||
%config(noreplace) "/etc/memgraph/memgraph.conf"
|
||||
%config(noreplace) "/etc/logrotate.d/memgraph"
|
||||
|
||||
@CPACK_RPM_USER_INSTALL_FILES@
|
||||
|
||||
%changelog
|
||||
@CPACK_RPM_SPEC_CHANGELOG@
|
||||
@@ -1,139 +0,0 @@
|
||||
# -*- rpm-spec -*-
|
||||
BuildRoot: %_topdir/@CPACK_PACKAGE_FILE_NAME@@CPACK_RPM_PACKAGE_COMPONENT_PART_PATH@
|
||||
Summary: @CPACK_RPM_PACKAGE_SUMMARY@
|
||||
Name: @CPACK_RPM_PACKAGE_NAME@
|
||||
Version: @CPACK_RPM_PACKAGE_VERSION@
|
||||
Release: @CPACK_RPM_PACKAGE_RELEASE@
|
||||
License: @CPACK_RPM_PACKAGE_LICENSE@
|
||||
# Group field is deprecated
|
||||
# Group: @CPACK_RPM_PACKAGE_GROUP@
|
||||
Vendor: @CPACK_RPM_PACKAGE_VENDOR@
|
||||
BuildRequires: systemd
|
||||
|
||||
@TMP_RPM_URL@
|
||||
@TMP_RPM_REQUIRES@
|
||||
@TMP_RPM_REQUIRES_PRE@
|
||||
@TMP_RPM_REQUIRES_POST@
|
||||
@TMP_RPM_REQUIRES_PREUN@
|
||||
@TMP_RPM_REQUIRES_POSTUN@
|
||||
@TMP_RPM_PROVIDES@
|
||||
@TMP_RPM_OBSOLETES@
|
||||
@TMP_RPM_CONFLICTS@
|
||||
@TMP_RPM_AUTOPROV@
|
||||
@TMP_RPM_AUTOREQ@
|
||||
@TMP_RPM_AUTOREQPROV@
|
||||
@TMP_RPM_BUILDARCH@
|
||||
@TMP_RPM_PREFIXES@
|
||||
|
||||
@TMP_RPM_DEBUGINFO@
|
||||
|
||||
# This is needed to prevent Python compilation errors when building the RPM
|
||||
# package
|
||||
# https://github.com/scylladb/scylla/issues/2235
|
||||
%if 0%{?rhel} < 8
|
||||
%global __os_install_post \
|
||||
/usr/lib/rpm/redhat/brp-compress \
|
||||
%{!?__debug_package:\
|
||||
/usr/lib/rpm/redhat/brp-strip %{__strip} \
|
||||
/usr/lib/rpm/redhat/brp-strip-comment-note %{__strip} %{__objdump} \
|
||||
} \
|
||||
/usr/lib/rpm/redhat/brp-strip-static-archive %{__strip} \
|
||||
%{!?__jar_repack:/usr/lib/rpm/redhat/brp-java-repack-jars} \
|
||||
%{nil}
|
||||
%else
|
||||
%global __os_install_post \
|
||||
/usr/lib/rpm/brp-compress \
|
||||
%{!?__debug_package:\
|
||||
/usr/lib/rpm/brp-strip %{__strip} \
|
||||
/usr/lib/rpm/brp-strip-comment-note %{__strip} %{__objdump} \
|
||||
} \
|
||||
/usr/lib/rpm/brp-strip-static-archive %{__strip} \
|
||||
%{nil}
|
||||
%endif
|
||||
|
||||
%define _rpmdir %_topdir/RPMS
|
||||
%define _srcrpmdir %_topdir/SRPMS
|
||||
@FILE_NAME_DEFINE@
|
||||
%define _unpackaged_files_terminate_build 0
|
||||
@TMP_RPM_SPEC_INSTALL_POST@
|
||||
@CPACK_RPM_SPEC_MORE_DEFINE@
|
||||
@CPACK_RPM_COMPRESSION_TYPE_TMP@
|
||||
|
||||
%description
|
||||
@CPACK_RPM_PACKAGE_DESCRIPTION@
|
||||
|
||||
# This is a shortcutted spec file generated by CMake RPM generator
|
||||
# we skip _install step because CPack does that for us.
|
||||
# We do only save CPack installed tree in _prepr
|
||||
# and then restore it in build.
|
||||
%prep
|
||||
# Put the systemd unit where it is expected on this system
|
||||
mkdir -p $RPM_BUILD_ROOT/%{_unitdir}
|
||||
mv $RPM_BUILD_ROOT/lib/systemd/system/memgraph.service $RPM_BUILD_ROOT/%{_unitdir}
|
||||
rm -rf $RPM_BUILD_ROOT/lib
|
||||
# Fix the incorrect directory permissions set by cpack (this is fixed in CMake 3.11)
|
||||
find $RPM_BUILD_ROOT -type d | xargs chmod 755
|
||||
# After setting up custom prep, continue with CMake's default
|
||||
mv $RPM_BUILD_ROOT %_topdir/tmpBBroot
|
||||
|
||||
%install
|
||||
if [ -e $RPM_BUILD_ROOT ];
|
||||
then
|
||||
rm -rf $RPM_BUILD_ROOT
|
||||
fi
|
||||
mv %_topdir/tmpBBroot $RPM_BUILD_ROOT
|
||||
|
||||
@TMP_RPM_DEBUGINFO_INSTALL@
|
||||
|
||||
%clean
|
||||
|
||||
%post
|
||||
# memgraph user and group must be set in preinst
|
||||
chown memgraph:memgraph /var/lib/memgraph || exit 1
|
||||
chmod 750 /var/lib/memgraph || exit 1
|
||||
chown memgraph:adm /var/log/memgraph || exit 1
|
||||
chmod 750 /var/log/memgraph || exit 1
|
||||
|
||||
# Generate SSL certificates
|
||||
if [ ! -d /etc/memgraph/ssl ]; then
|
||||
mkdir /etc/memgraph/ssl || exit 1
|
||||
openssl req -x509 -newkey rsa:4096 -days 3650 -nodes \
|
||||
-keyout /etc/memgraph/ssl/key.pem -out /etc/memgraph/ssl/cert.pem \
|
||||
-subj "/C=GB/ST=London/L=London/O=Memgraph Ltd./CN=Memgraph DB" || exit 1
|
||||
chown memgraph:memgraph /etc/memgraph/ssl/* || exit 1
|
||||
chmod 400 /etc/memgraph/ssl/* || exit 1
|
||||
fi
|
||||
@RPM_SYMLINK_POSTINSTALL@
|
||||
@CPACK_RPM_SPEC_POSTINSTALL@
|
||||
|
||||
%postun
|
||||
@CPACK_RPM_SPEC_POSTUNINSTALL@
|
||||
|
||||
%pre
|
||||
# Add the 'memgraph' user and group
|
||||
getent group memgraph >/dev/null || groupadd -r memgraph || exit 1
|
||||
getent passwd memgraph >/dev/null || \
|
||||
useradd -r -g memgraph -d /var/lib/memgraph -s /bin/bash memgraph || exit 1
|
||||
echo "Don't forget to switch to the 'memgraph' user to use Memgraph" || exit 1
|
||||
@CPACK_RPM_SPEC_PREINSTALL@
|
||||
|
||||
%preun
|
||||
@CPACK_RPM_SPEC_PREUNINSTALL@
|
||||
|
||||
%files
|
||||
%defattr(@TMP_DEFAULT_FILE_PERMISSIONS@,@TMP_DEFAULT_USER@,@TMP_DEFAULT_GROUP@,@TMP_DEFAULT_DIR_PERMISSIONS@)
|
||||
@CPACK_RPM_INSTALL_FILES@
|
||||
# Since we moved the memgraph.service file, declare it explicitly here.
|
||||
# NOTE: memgraph.service must not be marked as configuration file.
|
||||
%{_unitdir}/memgraph.service
|
||||
|
||||
# Override CPACK_RPM_ABSOLUTE_INSTALL_FILES with our %config(noreplace), cpack
|
||||
# uses plain %config.
|
||||
%config(noreplace) "/etc/memgraph/memgraph.conf"
|
||||
%config(noreplace) "/etc/memgraph/auth_module/ldap.example.yaml"
|
||||
%config(noreplace) "/etc/logrotate.d/memgraph"
|
||||
|
||||
@CPACK_RPM_USER_INSTALL_FILES@
|
||||
|
||||
%changelog
|
||||
@CPACK_RPM_SPEC_CHANGELOG@
|
||||
@@ -1,52 +0,0 @@
|
||||
[The "BSD 3-clause license"]
|
||||
Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
3. Neither the name of the copyright holder nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this software
|
||||
without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
=====
|
||||
|
||||
MIT License for codepointat.js from https://git.io/codepointat
|
||||
MIT License for fromcodepoint.js from https://git.io/vDW1m
|
||||
|
||||
Copyright Mathias Bynens <https://mathiasbynens.be/>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
@@ -1,42 +0,0 @@
|
||||
|
||||
--------------------------------------------------------------------------
|
||||
|
||||
This program, "bzip2", the associated library "libbzip2", and all
|
||||
documentation, are copyright (C) 1996-2010 Julian R Seward. All
|
||||
rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
2. The origin of this software must not be misrepresented; you must
|
||||
not claim that you wrote the original software. If you use this
|
||||
software in a product, an acknowledgment in the product
|
||||
documentation would be appreciated but is not required.
|
||||
|
||||
3. Altered source versions must be plainly marked as such, and must
|
||||
not be misrepresented as being the original software.
|
||||
|
||||
4. The name of the author may not be used to endorse or promote
|
||||
products derived from this software without specific prior written
|
||||
permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
|
||||
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
Julian Seward, jseward@bzip.org
|
||||
bzip2/libbzip2 version 1.0.6 of 6 September 2010
|
||||
|
||||
--------------------------------------------------------------------------
|
||||
@@ -1,23 +0,0 @@
|
||||
Copyright (c) 2013, Ryan Haining, Aaron Josephs, Google
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
Redistributions in binary form must reproduce the above copyright notice, this
|
||||
list of conditions and the following disclaimer in the documentation and/or
|
||||
other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
@@ -1,27 +0,0 @@
|
||||
Copyright (c) 2012 - present, Victor Zverovich
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
--- Optional exception to the license ---
|
||||
|
||||
As an exception, if, as a result of your compiling your source code, portions
|
||||
of this Software are embedded into a machine-executable object form of such
|
||||
source code, you may redistribute such embedded portions in such object form
|
||||
without including the above copyright and permission notices.
|
||||
@@ -1,28 +0,0 @@
|
||||
Copyright (c) 2006, Google Inc.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the following disclaimer
|
||||
in the documentation and/or other materials provided with the
|
||||
distribution.
|
||||
* Neither the name of Google Inc. nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
@@ -1,27 +0,0 @@
|
||||
Unless otherwise specified, files in the jemalloc source distribution are
|
||||
subject to the following license:
|
||||
--------------------------------------------------------------------------------
|
||||
Copyright (C) 2002-present Jason Evans <jasone@canonware.com>.
|
||||
All rights reserved.
|
||||
Copyright (C) 2007-2012 Mozilla Foundation. All rights reserved.
|
||||
Copyright (C) 2009-present Facebook, Inc. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
1. Redistributions of source code must retain the above copyright notice(s),
|
||||
this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright notice(s),
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) ``AS IS'' AND ANY EXPRESS
|
||||
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
|
||||
EVENT SHALL THE COPYRIGHT HOLDER(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
--------------------------------------------------------------------------------
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user