pax_global_header 0000666 0000000 0000000 00000000064 15134225711 0014513 g ustar 00root root 0000000 0000000 52 comment=806fa2ebdb300b3e76ef30cdba61803babbf2683
age-PG18-v1.7.0-rc0/ 0000775 0000000 0000000 00000000000 15134225711 0013601 5 ustar 00root root 0000000 0000000 age-PG18-v1.7.0-rc0/.asf.yaml 0000664 0000000 0000000 00000004353 15134225711 0015321 0 ustar 00root root 0000000 0000000 # Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
notifications:
commits: commits@age.apache.org
pullrequests: commits@age.apache.org
discussions: dev@age.apache.org
github:
description: "Graph database optimized for fast analysis and real-time data processing.
It is provided as an extension to PostgreSQL."
homepage: https://age.apache.org
labels:
- postgresql
- graph-database
- analytics
- postgresql-extension
- graphdb
- multi-model-dbms
- agensgraph
- age-database
features:
wiki: true
issues: true
projects: true
discussions: true
enabled_merge_buttons:
squash: true
merge: false
rebase: true
protected_branches:
master:
required_pull_request_reviews:
required_approving_review_count: 1
PG18:
required_pull_request_reviews:
required_approving_review_count: 1
PG17:
required_pull_request_reviews:
required_approving_review_count: 1
PG16:
required_pull_request_reviews:
required_approving_review_count: 1
PG15:
required_pull_request_reviews:
required_approving_review_count: 1
PG14:
required_pull_request_reviews:
required_approving_review_count: 1
PG13:
required_pull_request_reviews:
required_approving_review_count: 1
PG12:
required_pull_request_reviews:
required_approving_review_count: 1
PG11:
required_pull_request_reviews:
required_approving_review_count: 1
age-PG18-v1.7.0-rc0/.dockerignore 0000664 0000000 0000000 00000000104 15134225711 0016250 0 ustar 00root root 0000000 0000000 *.o
*.so
.gitignore
build.sh
.idea
.deps
.DS_Store
*.tokens
*.interp age-PG18-v1.7.0-rc0/.github/ 0000775 0000000 0000000 00000000000 15134225711 0015141 5 ustar 00root root 0000000 0000000 age-PG18-v1.7.0-rc0/.github/ISSUE_TEMPLATE/ 0000775 0000000 0000000 00000000000 15134225711 0017324 5 ustar 00root root 0000000 0000000 age-PG18-v1.7.0-rc0/.github/ISSUE_TEMPLATE/bug_report.md 0000664 0000000 0000000 00000002141 15134225711 0022014 0 ustar 00root root 0000000 0000000 ---
name: Bug report
about: Create a report to help us improve
title: ''
labels: bug
assignees: ''
---
**Describe the bug**
A clear and concise description of what the bug is.
**How are you accessing AGE (Command line, driver, etc.)?**
- [e.g. JDBC]
**What data setup do we need to do?**
```pgsql
...
SELECT * from cypher('my_graph_name', $$
CREATE (a:Part {part_num: '123'}),
(b:Part {part_num: '345'}),
(c:Part {part_num: '456'}),
(d:Part {part_num: '789'})
$$) as (a agtype);
...
```
**What is the necessary configuration info needed?**
- [e.g. Installed PostGIS]
**What is the command that caused the error?**
```pgsql
SELECT * from cypher('my_graph_name', $$
MATCH (a:Part {part_num: '123'}), (b:Part {part_num: '345'})
CREATE (a)-[u:used_by { quantity: 1 }]->(b)
$$) as (a agtype);
```
```
ERROR: something failed to execute
```
**Expected behavior**
A clear and concise description of what you expected to happen.
**Environment (please complete the following information):**
- Version: [e.g. 0.4.0]
**Additional context**
Add any other context about the problem here.
age-PG18-v1.7.0-rc0/.github/ISSUE_TEMPLATE/feature_request.md 0000664 0000000 0000000 00000001134 15134225711 0023050 0 ustar 00root root 0000000 0000000 ---
name: Feature request
about: Suggest an idea for this project
title: ''
labels: enhancement
assignees: ''
---
**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
**Describe the solution you'd like**
A clear and concise description of what you want to happen.
**Describe alternatives you've considered**
A clear and concise description of any alternative solutions or features you've considered.
**Additional context**
Add any other context or screenshots about the feature request here.
age-PG18-v1.7.0-rc0/.github/ISSUE_TEMPLATE/question.md 0000664 0000000 0000000 00000000134 15134225711 0021513 0 ustar 00root root 0000000 0000000 ---
name: Question
about: Create a question
title: ''
labels: question
assignees: ''
---
age-PG18-v1.7.0-rc0/.github/labeler.yml 0000664 0000000 0000000 00000000410 15134225711 0017265 0 ustar 00root root 0000000 0000000 PG11:
- base-branch: 'PG11'
PG12:
- base-branch: 'PG12'
PG13:
- base-branch: 'PG13'
PG14:
- base-branch: 'PG14'
PG15:
- base-branch: 'PG15'
PG16:
- base-branch: 'PG16'
PG17:
- base-branch: 'PG17'
PG18:
- base-branch: 'PG18'
master:
- base-branch: 'master'
age-PG18-v1.7.0-rc0/.github/workflows/ 0000775 0000000 0000000 00000000000 15134225711 0017176 5 ustar 00root root 0000000 0000000 age-PG18-v1.7.0-rc0/.github/workflows/go-driver.yml 0000664 0000000 0000000 00000001222 15134225711 0021614 0 ustar 00root root 0000000 0000000 name: Go Driver Tests
on:
push:
branches: [ "PG18" ]
pull_request:
branches: [ "PG18" ]
jobs:
build:
runs-on: ubuntu-latest
strategy:
matrix:
go-version: [ '1.20', '1.21' ]
defaults:
run:
working-directory: drivers/golang/age/
steps:
- uses: actions/checkout@v4
- name: Run apache/age docker image
run: docker compose up -d
- name: Set up Go
uses: actions/setup-go@v3
with:
go-version: ${{ matrix.go-version }}
- name: Generate
run: go generate ./../...
- name: Build
run: go build -v ./...
- name: Test
run: go test . -v
age-PG18-v1.7.0-rc0/.github/workflows/installcheck.yaml 0000664 0000000 0000000 00000004330 15134225711 0022526 0 ustar 00root root 0000000 0000000 name: Build / Regression
on:
push:
branches: [ "PG18" ]
pull_request:
branches: [ "PG18" ]
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Get latest commit id of PostgreSQL 18
run: |
echo "PG_COMMIT_HASH=$(git ls-remote https://git.postgresql.org/git/postgresql.git refs/heads/REL_18_STABLE | awk '{print $1}')" >> $GITHUB_ENV
- name: Cache PostgreSQL 18
uses: actions/cache@v3
id: pg18cache
with:
path: ~/pg18
key: ${{ runner.os }}-v1-pg18-${{ env.PG_COMMIT_HASH }}
- name: Install necessary dependencies
run: |
sudo apt-get update
sudo apt-get install -y build-essential libreadline-dev zlib1g-dev flex bison
- name: Install PostgreSQL 18 and some extensions
if: steps.pg18cache.outputs.cache-hit != 'true'
run: |
git clone --depth 1 --branch REL_18_STABLE https://git.postgresql.org/git/postgresql.git ~/pg18source
cd ~/pg18source
./configure --prefix=$HOME/pg18 CFLAGS="-std=gnu99 -ggdb -O0" --enable-cassert
make install -j$(nproc) > /dev/null
cd contrib
cd fuzzystrmatch
make PG_CONFIG=$HOME/pg18/bin/pg_config install -j$(nproc) > /dev/null
cd ../pg_trgm
make PG_CONFIG=$HOME/pg18/bin/pg_config install -j$(nproc) > /dev/null
- uses: actions/checkout@v3
- name: Build AGE
id: build
run: |
make PG_CONFIG=$HOME/pg18/bin/pg_config install -j$(nproc)
- name: Pull and build pgvector
id: pgvector
run: |
git clone https://github.com/pgvector/pgvector.git
cd pgvector
make PG_CONFIG=$HOME/pg18/bin/pg_config install -j$(nproc) > /dev/null
- name: Regression tests
id: regression_tests
run: |
make PG_CONFIG=$HOME/pg18/bin/pg_config installcheck EXTRA_TESTS="pgvector fuzzystrmatch pg_trgm"
continue-on-error: true
- name: Dump regression test errors
if: steps.regression_tests.outcome != 'success'
run: |
echo "Dump section begin."
cat $HOME/work/age/age/regress/regression.diffs
echo "Dump section end."
exit 1
age-PG18-v1.7.0-rc0/.github/workflows/jdbc-driver.yaml 0000664 0000000 0000000 00000000663 15134225711 0022262 0 ustar 00root root 0000000 0000000 name: JDBC Driver Tests
on:
push:
branches: [ "PG18" ]
pull_request:
branches: [ "PG18" ]
jobs:
build:
runs-on: ubuntu-latest
defaults:
run:
working-directory: drivers/jdbc
steps:
- uses: actions/checkout@v4
- name: Set up Java
uses: actions/setup-java@v3
with:
distribution: 'zulu'
java-version: '17'
- name: Build and Test
run: gradle build
age-PG18-v1.7.0-rc0/.github/workflows/labeler.yml 0000664 0000000 0000000 00000001507 15134225711 0021332 0 ustar 00root root 0000000 0000000 name: "Pull Request Labeler"
on:
- pull_request_target
jobs:
triage:
permissions:
contents: write
pull-requests: write
issues: write
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Apply branch labels
uses: actions/labeler@v5.0.0
- name: Apply label based on author
if: |
contains('["jrgemignani", "dehowef", "eyab" "rafsun42", "Zainab-Saad", "MuhammadTahaNaveed"]', github.event.pull_request.user.login)
uses: actions/github-script@v7
with:
script: |
const labelsToAdd = ['override-stale'];
github.rest.issues.addLabels({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
labels: labelsToAdd
});
age-PG18-v1.7.0-rc0/.github/workflows/nodejs-driver.yaml 0000664 0000000 0000000 00000001076 15134225711 0022641 0 ustar 00root root 0000000 0000000 name: Nodejs Driver Tests
on:
push:
branches: [ "PG18" ]
pull_request:
branches: [ "PG18" ]
jobs:
build:
runs-on: ubuntu-latest
defaults:
run:
working-directory: drivers/nodejs/
steps:
- uses: actions/checkout@v4
- name: Run apache/age docker image
run: docker compose up -d
- name: Set up Node
uses: actions/setup-node@v3
with:
node-version: latest
- name: Install dependencies
run: npm install
- name: Build
run: npm run build
- name: Test
run: npm test
age-PG18-v1.7.0-rc0/.github/workflows/python-driver.yaml 0000664 0000000 0000000 00000001533 15134225711 0022676 0 ustar 00root root 0000000 0000000 name: Python Driver Tests
on:
push:
branches: [ "PG18" ]
pull_request:
branches: [ "PG18" ]
jobs:
build:
runs-on: ubuntu-latest
defaults:
run:
working-directory: drivers/python
steps:
- uses: actions/checkout@v4
- name: Run apache/age docker image
run: docker compose up -d
- name: Set up python
uses: actions/setup-python@v4
with:
python-version: '3.12'
- name: Install pre-requisites
run: |
sudo apt-get install python3-dev libpq-dev
pip install -r requirements.txt
- name: Build
run: |
pip install .
- name: Test
run: |
python test_age_py.py -db "postgres" -u "postgres" -pass "agens"
python test_networkx.py -db "postgres" -u "postgres" -pass "agens"
python -m unittest -v test_agtypes.py
age-PG18-v1.7.0-rc0/.gitignore 0000664 0000000 0000000 00000000267 15134225711 0015576 0 ustar 00root root 0000000 0000000 *.o
*.so
build.sh
.idea
.deps
.DS_Store
*.tokens
*.interp
*.dylib
age--*.*.*.sql
!age--*--*sql
__pycache__
**/__pycache__
**/.venv
**/apache_age_python.egg-info
drivers/python/build
age-PG18-v1.7.0-rc0/CONTRIBUTING.md 0000664 0000000 0000000 00000006710 15134225711 0016036 0 ustar 00root root 0000000 0000000 # Contributing to Apache AGE
Welcome, future Contributor!
First off, thank you for considering contributing to Apache AGE. Team AGE welcomes anyone who is willing to help us mature AGE to become a fully-featured graph database extension for PostgreSQL.
There are multiple ways you can contribute to the Apache AGE and [Apache AGE Viewer](https://github.com/apache/age-viewer) projects. We hope that adding features, fixing bugs, and changing documentations can be fun and educational for anyone and everyone.
## Code of Conduct
The community members of Apache AGE are expected to follow the 'Apache Way'. Please read the [Code of Conduct](https://www.apache.org/foundation/policies/conduct) provided by Apache Software Foundation.
## How to Start
A great way to get involved in the project is to ask questions on the mailing lists, Apache AGE Discord, or the Apache Reddit forum (r/apacheage). Reviewing the list of projects in the Apache AGE and AGE Viewer GitHubs may help you understand the overall roadmap.
Once you understand the ins and outs of Apache AGE, share your knowledge by helping the newcomers as well. Spending a few minutes to answer questions are a valuable open source community service, which also demonstrates your expertise.
We strongly recommend you to subscribe the mailing lists, join the Apache AGE Discord and Apache AGE Reddit community (r/apacheage) to keep up to date on what's happening in AGE. Visit [joinus](https://age.apache.org/joinus) for pathways you can follow to help you get started.
## Pull Requests
Changes to AGE source code are proposed, reviewed, and committed via Github pull requests (described in Code Convention). Pull requests are a great way to get your ideas into this repository. Anyone can view and comment on active changes here. Reviewing others' changes are a good way to learn how the change process works and gain exposure to activity in various parts of the code. You can help by reviewing the changes, asking questions, or pointing out issues as simple as typos.
## Documentation Changes
You can propose changes to Apache AGE documentation, edit the Markdown source files for the Apache AGE website pages.
## Bug Reports
Ideally, bug reports are accompanied by a proposed code change to fix the bug. This isn't always possible, as those who discover a bug may not have the experience to fix it. A bug may be reported by creating a GitHub issue, but without creating a pull request.
Bug reports are only useful, however, if they include enough information to understand, isolate and ideally reproduce the bug. Simply encountering an error does not mean a bug should be reported; search GitHub and inquire on the Apache AGE's dev mailing list first. Unreproducible bugs or simple error reports without context shall be closed.
The more context about a bug, the better, such as: how the bug was introduced, by which commit, etc. It assists the committers in the decision process on how far the bug fix should be backported, when the pull request is merged. The pull request to fix the bug should narrow down the problem to the root cause. Data correctness/data loss bugs are very serious. Make sure the corresponding bug report GitHub issue is labeled as correctness or data-loss. Please send an email to dev@age.apache.org after submitting the bug report, to quickly draw attention to the issue. Performance issues are classified as bugs. The pull request to fix a performance bug must provide a benchmark to prove the problem is indeed fixed.
age-PG18-v1.7.0-rc0/LICENSE 0000664 0000000 0000000 00000030432 15134225711 0014610 0 ustar 00root root 0000000 0000000
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
For PostgreSQL Database Management System:
(formerly known as Postgres, then as Postgres95)
Portions Copyright (c) 1996-2010, The PostgreSQL Global Development Group
Portions Copyright (c) 1994, The Regents of the University of California
Permission to use, copy, modify, and distribute this software and its documentation for any purpose,
without fee, and without a written agreement is hereby granted, provided that the above copyright notice
and this paragraph and the following two paragraphs appear in all copies.
IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR DIRECT,
INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS,
ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY
OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA
HAS NO OBLIGATIONS TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
age-PG18-v1.7.0-rc0/META.json 0000664 0000000 0000000 00000004362 15134225711 0015227 0 ustar 00root root 0000000 0000000 {
"name": "ApacheAGE",
"abstract": "Apache AGE is a PostgreSQL Extension that provides graph database functionality",
"description": "Apache AGE is a PostgreSQL Extension that provides graph database functionality. AGE is an acronym for A Graph Extension, and is inspired by Bitnine's fork of PostgreSQL 10, AgensGraph, which is a multi-model database. The goal of the project is to create single storage that can handle both relational and graph model data so that users can use standard ANSI SQL along with openCypher, the Graph query language. A graph consists of a set of vertices (also called nodes) and edges, where each individual vertex and edge possesses a map of properties. A vertex is the basic object of a graph, that can exist independently of everything else in the graph. An edge creates a directed connection between two vertices. A graph database is simply composed of vertices and edges. This type of database is useful when the meaning is in the relationships between the data. Relational databases can easily handle direct relationships, but indirect relationships are more difficult to deal with in relational databases. A graph database stores relationship information as a first-class entity. Apache AGE gives you the best of both worlds, simultaneously.",
"version": "1.3.0",
"maintainer": [
"users@age.apache.org"
],
"license": "apache_2_0",
"provides": {
"ApacheAGE": {
"abstract": "Apache AGE is a PostgreSQL Extension that provides graph database functionality",
"file": "age--1.3.0.sql",
"docfile": "README.md",
"version": "1.3.0"
}
},
"prereqs": {
"runtime": {
"requires": {
"PostgreSQL": "14.0.0"
}
}
},
"resources": {
"homepage": "https://github.com/apache/age/tree/master",
"bugtracker": {
"web": "https://github.com/apache/age/issues"
},
"repository": {
"url": "https://github.com/apache/age.git",
"web": "https://github.com/apache/age",
"type": "git"
}
},
"generated_by": "users@age.apache.org",
"meta-spec": {
"version": "1.0.0",
"url": "http://pgxn.org/meta/spec.txt"
},
"tags": [
"graphdb",
"graph-database"
]
}
age-PG18-v1.7.0-rc0/Makefile 0000664 0000000 0000000 00000015107 15134225711 0015245 0 ustar 00root root 0000000 0000000 # Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
MODULE_big = age
age_sql = age--1.7.0.sql
OBJS = src/backend/age.o \
src/backend/catalog/ag_catalog.o \
src/backend/catalog/ag_graph.o \
src/backend/catalog/ag_label.o \
src/backend/catalog/ag_namespace.o \
src/backend/commands/graph_commands.o \
src/backend/commands/label_commands.o \
src/backend/executor/cypher_create.o \
src/backend/executor/cypher_merge.o \
src/backend/executor/cypher_set.o \
src/backend/executor/cypher_utils.o \
src/backend/nodes/ag_nodes.o \
src/backend/nodes/cypher_copyfuncs.o \
src/backend/nodes/cypher_outfuncs.o \
src/backend/nodes/cypher_readfuncs.o \
src/backend/optimizer/cypher_createplan.o \
src/backend/optimizer/cypher_pathnode.o \
src/backend/optimizer/cypher_paths.o \
src/backend/parser/ag_scanner.o \
src/backend/parser/cypher_analyze.o \
src/backend/parser/cypher_clause.o \
src/backend/executor/cypher_delete.o \
src/backend/parser/cypher_expr.o \
src/backend/parser/cypher_gram.o \
src/backend/parser/cypher_item.o \
src/backend/parser/cypher_keywords.o \
src/backend/parser/cypher_parse_agg.o \
src/backend/parser/cypher_parse_node.o \
src/backend/parser/cypher_parser.o \
src/backend/parser/cypher_transform_entity.o \
src/backend/utils/adt/age_graphid_ds.o \
src/backend/utils/adt/agtype.o \
src/backend/utils/adt/agtype_ext.o \
src/backend/utils/adt/agtype_gin.o \
src/backend/utils/adt/agtype_ops.o \
src/backend/utils/adt/agtype_parser.o \
src/backend/utils/adt/agtype_util.o \
src/backend/utils/adt/agtype_raw.o \
src/backend/utils/adt/age_global_graph.o \
src/backend/utils/adt/age_session_info.o \
src/backend/utils/adt/age_vle.o \
src/backend/utils/adt/cypher_funcs.o \
src/backend/utils/adt/ag_float8_supp.o \
src/backend/utils/adt/graphid.o \
src/backend/utils/ag_func.o \
src/backend/utils/graph_generation.o \
src/backend/utils/cache/ag_cache.o \
src/backend/utils/load/ag_load_labels.o \
src/backend/utils/load/ag_load_edges.o \
src/backend/utils/load/age_load.o \
src/backend/utils/name_validation.o \
src/backend/utils/ag_guc.o
EXTENSION = age
# to allow cleaning of previous (old) age--.sql files
all_age_sql = $(shell find . -maxdepth 1 -type f -regex './age--[0-9]+\.[0-9]+\.[0-9]+\.sql')
SQLS := $(shell cat sql/sql_files)
SQLS := $(addprefix sql/,$(SQLS))
SQLS := $(addsuffix .sql,$(SQLS))
DATA_built = $(age_sql)
# sorted in dependency order
REGRESS = scan \
graphid \
agtype \
agtype_hash_cmp \
catalog \
cypher \
expr \
cypher_create \
cypher_match \
cypher_unwind \
cypher_set \
cypher_remove \
cypher_delete \
cypher_with \
cypher_vle \
cypher_union \
cypher_call \
cypher_merge \
cypher_subquery \
age_global_graph \
age_load \
index \
analyze \
graph_generation \
name_validation \
jsonb_operators \
list_comprehension \
map_projection \
direct_field_access \
security
ifneq ($(EXTRA_TESTS),)
REGRESS += $(EXTRA_TESTS)
endif
REGRESS += drop
srcdir=`pwd`
ag_regress_dir = $(srcdir)/regress
REGRESS_OPTS = --load-extension=age --inputdir=$(ag_regress_dir) --outputdir=$(ag_regress_dir) --temp-instance=$(ag_regress_dir)/instance --port=61958 --encoding=UTF-8 --temp-config $(ag_regress_dir)/age_regression.conf
ag_regress_out = instance/ log/ results/ regression.*
EXTRA_CLEAN = $(addprefix $(ag_regress_dir)/, $(ag_regress_out)) src/backend/parser/cypher_gram.c src/include/parser/cypher_gram_def.h src/include/parser/cypher_kwlist_d.h $(all_age_sql)
GEN_KEYWORDLIST = $(PERL) -I ./tools/ ./tools/gen_keywordlist.pl
GEN_KEYWORDLIST_DEPS = ./tools/gen_keywordlist.pl tools/PerfectHash.pm
ag_include_dir = $(srcdir)/src/include
PG_CPPFLAGS = -I$(ag_include_dir) -I$(ag_include_dir)/parser
PG_CONFIG ?= pg_config
PGXS := $(shell $(PG_CONFIG) --pgxs)
include $(PGXS)
# 32-bit platform support: pass SIZEOF_DATUM=4 to enable (e.g., make SIZEOF_DATUM=4)
# When SIZEOF_DATUM=4, PASSEDBYVALUE is stripped from graphid type for pass-by-reference.
# If not specified, normal 64-bit behavior is used (PASSEDBYVALUE preserved).
src/backend/parser/cypher_keywords.o: src/include/parser/cypher_kwlist_d.h
src/include/parser/cypher_kwlist_d.h: src/include/parser/cypher_kwlist.h $(GEN_KEYWORDLIST_DEPS)
$(GEN_KEYWORDLIST) --extern --varname CypherKeyword --output src/include/parser $<
src/include/parser/cypher_gram_def.h: src/backend/parser/cypher_gram.c
src/backend/parser/cypher_gram.c: BISONFLAGS += --defines=src/include/parser/cypher_gram_def.h
src/backend/parser/cypher_parser.o: src/backend/parser/cypher_gram.c src/include/parser/cypher_gram_def.h
src/backend/parser/cypher_parser.bc: src/backend/parser/cypher_gram.c src/include/parser/cypher_gram_def.h
src/backend/parser/cypher_keywords.o: src/backend/parser/cypher_gram.c src/include/parser/cypher_gram_def.h
src/backend/parser/cypher_keywords.bc: src/backend/parser/cypher_gram.c src/include/parser/cypher_gram_def.h
# Strip PASSEDBYVALUE on 32-bit (SIZEOF_DATUM=4) for graphid pass-by-reference
$(age_sql): $(SQLS)
@cat $(SQLS) > $@
ifeq ($(SIZEOF_DATUM),4)
@echo "32-bit build: removing PASSEDBYVALUE from graphid type"
@sed 's/^ PASSEDBYVALUE,$$/ -- PASSEDBYVALUE removed for 32-bit (see Makefile)/' $@ > $@.tmp && mv $@.tmp $@
@grep -q 'PASSEDBYVALUE removed for 32-bit' $@ || { echo "Error: PASSEDBYVALUE replacement failed in $@"; exit 1; }
endif
src/backend/parser/ag_scanner.c: FLEX_NO_BACKUP=yes
installcheck: export LC_COLLATE=C
age-PG18-v1.7.0-rc0/NOTICE 0000664 0000000 0000000 00000000501 15134225711 0014501 0 ustar 00root root 0000000 0000000 Apache AGE
Copyright 2023 The Apache Software Foundation.
This product includes software developed at
The Apache Software Foundation (http://www.apache.org/).
Portions of Apache AGE were originally developed by Bitnine Co., Ltd. and were
donated to the Apache Software Foundation. Copyright 2019-2020 Bitnine Co., Ltd.
age-PG18-v1.7.0-rc0/README.md 0000664 0000000 0000000 00000024665 15134225711 0015075 0 ustar 00root root 0000000 0000000
is a leading multi-model graph database
Graph Processing & Analytics for Relational Databases
What is Apache AGE?
[Apache AGE](https://age.apache.org/#) is an extension for PostgreSQL that enables users to leverage a graph database on top of the existing relational databases. AGE is an acronym for A Graph Extension and is inspired by Bitnine's AgensGraph, a multi-model database fork of PostgreSQL. The basic principle of the project is to create a single storage that handles both the relational and graph data model so that the users can use the standard ANSI SQL along with openCypher, one of the most popular graph query languages today. There is a strong need for cohesive, easy-to-implement multi-model databases. As an extension of PostgreSQL, AGE supports all the functionalities and features of PostgreSQL while also offering a graph model to boot.
Overview
Apache AGE is :
- **Powerful**: adds graph database support to the already popular PostgreSQL database: PostgreSQL is used by organizations including Apple, Spotify, and NASA.
- **Flexible**: allows you to perform openCypher queries, which makes complex queries much easier to write. It also enables querying multiple graphs at the same time.
- **Intelligent**: allows you to perform graph queries that are the basis for many next-level web services such as fraud detection, master data management, product recommendations, identity and relationship management, experience personalization, knowledge management, and more.
Features
- **Cypher Query**: supports graph query language
- **Hybrid Querying**: enables SQL and/or Cypher
- **Querying**: enables multiple graphs
- **Hierarchical**: graph label organization
- **Property Indexes**: on both vertices(nodes) and edges
- **Full PostgreSQL**: supports PG features
Documentation
Refer to our latest [Apache AGE documentation](https://age.apache.org/age-manual/master/index.html) to learn about installation, features, built-in functions, and Cypher queries.
Pre-Installation
Install the following essential libraries according to each OS. Building AGE from the source depends on the following Linux libraries (Ubuntu package names shown below):
- **CentOS**
```bash
yum install gcc glibc glib-common readline readline-devel zlib zlib-devel flex bison
```
- **Fedora**
```bash
dnf install gcc glibc bison flex readline readline-devel zlib zlib-devel
```
- **Ubuntu**
```bash
sudo apt-get install build-essential libreadline-dev zlib1g-dev flex bison
```
Installation
Apache AGE is intended to be simple to install and run. It can be installed with Docker and other traditional ways.
You can download the Postgres source code and install your own instance of Postgres. You can read instructions on how to install from source code for different versions on the official Postgres Website.
Install AGE on Linux and MacOS
Clone the github repository or download the download an official release.
Run the pg_config utility and check the version of PostgreSQL. Currently, only PostgreSQL versions 11, 12, 13, 14, 15, 16, 17 & 18 are supported. If you have any other version of Postgres, you will need to install PostgreSQL version 11, 12, 13, 14, 15, 16, 17 & 18.
```bash
pg_config
```
Run the following command in the source code directory of Apache AGE to build and install the extension.
```bash
make install
```
If the path to your Postgres installation is not in the PATH variable, add the path in the arguments:
```bash
make PG_CONFIG=/path/to/postgres/bin/pg_config install
```
For every connection of AGE you start, you will need to load the AGE extension.
```bash
CREATE EXTENSION age;
```
```bash
LOAD 'age';
```
```bash
SET search_path = ag_catalog, "$user", public;
```
Quick Start
To create a graph, use the create_graph function located in the ag_catalog namespace.
```bash
SELECT create_graph('graph_name');
```
To create a single vertex with label and properties, use the CREATE clause.
```bash
SELECT *
FROM cypher('graph_name', $$
CREATE (:label {property:"Node A"})
$$) as (v agtype);
```
```bash
SELECT *
FROM cypher('graph_name', $$
CREATE (:label {property:"Node B"})
$$) as (v agtype);
```
To create an edge between two nodes and set its properties:
```bash
SELECT *
FROM cypher('graph_name', $$
MATCH (a:label), (b:label)
WHERE a.property = 'Node A' AND b.property = 'Node B'
CREATE (a)-[e:RELTYPE {property:a.property + '<->' + b.property}]->(b)
RETURN e
$$) as (e agtype);
```
And to query the connected nodes:
```
SELECT * from cypher('graph_name', $$
MATCH (V)-[R]-(V2)
RETURN V,R,V2
$$) as (V agtype, R agtype, V2 agtype);
```
Language Specific Drivers
Starting with Apache AGE is very simple. You can easily select your platform and incorporate the relevant SDK into your code.
- [Apache AGE Rust Driver](https://github.com/Dzordzu/rust-apache-age.git)
- [Apache AGE .NET Driver](https://github.com/Allison-E/pg-age)
Graph Visualization Tool for AGE
Apache AGE Viewer is a user interface for Apache AGE that provides visualization and exploration of data.
This web visualization tool allows users to enter complex graph queries and explore the results in graph and table forms.
Apache AGE Viewer is enhanced to proceed with extensive graph data and discover insights through various graph algorithms.
Apache AGE Viewer will become a graph data administration and development platform for Apache AGE to support multiple relational databases: .
**This is a visualization tool.**
After installing AGE Extension, you may use this tool to get access to the visualization features.

Video Links
You can also get help from these videos.
- Install on [Windows](https://www.youtube.com/watch?v=ddk8VX8Hm-I&list=PLGp3huJbWNDjgwP7s99Q-9_w1vxpjNHXG)
- Install on [MacOS](https://www.youtube.com/watch?v=0-qMwpDh0CA)
Contributing
You can improve ongoing efforts or initiate new ones by sending pull requests to [this repository](https://github.com/apache/age).
Also, you can learn from the code review process, how to merge pull requests, and from code style compliance to documentation by visiting the [Apache AGE official site - Developer Guidelines](https://age.apache.org/contribution/guide).
Send all your comments and inquiries to the user mailing list, users@age.apache.org.
age-PG18-v1.7.0-rc0/RELEASE 0000664 0000000 0000000 00000005207 15134225711 0014610 0 ustar 00root root 0000000 0000000 # Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
Release Notes for Apache AGE release 1.7.0 for PG18 branch
Apache AGE 1.7.0 - Release Notes
NOTE: There isn't an upgrade path for PostgreSQL PG18 1.7.0 as
there isn't a prior version.
Advance PG18 branch to Apache AGE version 1.7.0
Add RLS support and fix permission checks (#2309)
Replace libcsv with pg COPY for csv loading (#2310)
Fix Issue 1884: Ambiguous column reference (#2306)
Upgrade Jest to v29 for node: protocol compatibility (#2307)
Optimize vertex/edge field access with direct array indexing (#2302)
feat: Add 32-bit platform support for graphid type (#2286)
Fix and improve index.sql addendum (#2301)
Fix and improve index.sql regression test coverage (#2300)
Fix Issue 2289: handle empty list in IN expression (#2294)
Revise README for Python driver updates (#2298)
Makefile: fix race condition on cypher_gram_def.h (#2273)
Restrict age_load commands (#2274)
Migrate python driver configuration to pyproject.toml (#2272)
Convert string to raw string to remove invalid escape sequence warning (#2267)
Update grammar file for maintainability (#2270)
Fix ORDER BY alias resolution with AS in Cypher queries (#2269)
Fix possible memory and file descriptors leaks (#2258)
Adjust 'could not find rte for' ERROR message (#2266)
Fix Issue 2256: segmentation fault when calling coalesce function (#2259)
Add index on id columns (#2117)
Fix issue 2245 - Creating more than 41 vlabels causes crash in drop_graph (#2248)
Fix DockerHub build warning messages (#2252)
Update CI for BaseDockerizedTest (#2254)
PG18 port for AGE (#2251)
Updated CI, Labeler, Docker, and branch security files for PG18 (#2246)
Fix issue 2243 - Regression in string concatenation (#2244)
Add fast functions for checking edge uniqueness (#2227)
Bump gopkg.in/yaml.v3 from 3.0.0 to 3.0.1 in /drivers/golang (#2212)
Update branch security (#2219)
Fix issue with CALL/YIELD for user defined and qualified functions. (#2217)
age-PG18-v1.7.0-rc0/age--1.7.0--y.y.y.sql 0000664 0000000 0000000 00000002620 15134225711 0016635 0 ustar 00root root 0000000 0000000 /*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
--* This is a TEMPLATE for upgrading from the previous version of Apache AGE
--* Please adjust the below ALTER EXTENSION to reflect the -- correct version it
--* is upgrading to.
-- This will only work within a major version of PostgreSQL, not across
-- major versions.
-- complain if script is sourced in psql, rather than via CREATE EXTENSION
\echo Use "ALTER EXTENSION age UPDATE TO '1.X.0'" to load this file. \quit
--* Please add all additions, deletions, and modifications to the end of this
--* file. We need to keep the order of these changes.
--* REMOVE ALL LINES ABOVE, and this one, that start with --*
age-PG18-v1.7.0-rc0/age.control 0000664 0000000 0000000 00000001604 15134225711 0015740 0 ustar 00root root 0000000 0000000 # Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
default_version = '1.7.0'
comment = 'AGE database extension'
module_pathname = '$libdir/age'
schema = 'ag_catalog'
age-PG18-v1.7.0-rc0/clang-format.5 0000664 0000000 0000000 00000005105 15134225711 0016242 0 ustar 00root root 0000000 0000000 # Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
AlignAfterOpenBracket: Align
AlignConsecutiveAssignments: false
AlignConsecutiveDeclarations: false
AlignEscapedNewlines: DontAlign
AlignOperands: true
AlignTrailingComments: false
AllowAllParametersOfDeclarationOnNextLine: false
AllowShortBlocksOnASingleLine: false
AllowShortCaseLabelsOnASingleLine: false
AllowShortFunctionsOnASingleLine: None
AllowShortIfStatementsOnASingleLine: false
AllowShortLoopsOnASingleLine: false
AlwaysBreakAfterReturnType: None
AlwaysBreakBeforeMultilineStrings: false
BinPackArguments: true
BinPackParameters: true
BraceWrapping:
AfterControlStatement: true
AfterEnum: true
AfterFunction: true
AfterStruct: true
AfterUnion: true
BeforeElse: true
IndentBraces: false
SplitEmptyFunction: true
SplitEmptyRecord: true
BreakBeforeBinaryOperators: None
BreakBeforeBraces: Custom
BreakBeforeTernaryOperators: false
BreakStringLiterals: false
ColumnLimit: 79
CommentPragmas: ''
ContinuationIndentWidth: 4
Cpp11BracedListStyle: true
DerivePointerAlignment: false
DisableFormat: false
ForEachMacros:
- 'foreach'
IncludeCategories:
IncludeIsMainRegex: '$'
IndentCaseLabels: false
IndentWidth: 4
IndentWrappedFunctionNames: false
KeepEmptyLinesAtTheStartOfBlocks: false
Language: Cpp
MacroBlockBegin: ''
MacroBlockEnd: ''
MaxEmptyLinesToKeep: 1
PenaltyBreakAssignment: 30
PenaltyBreakBeforeFirstCallParameter: 30
PenaltyBreakComment: 10
PenaltyBreakString: 10
PenaltyExcessCharacter: 100
PenaltyReturnTypeOnItsOwnLine: 60
PointerAlignment: Right
ReflowComments: false
SortIncludes: true
SpaceAfterCStyleCast: false
SpaceBeforeAssignmentOperators: true
SpaceBeforeParens: ControlStatements
SpaceInEmptyParentheses: false
SpacesBeforeTrailingComments: 1
SpacesInCStyleCastParentheses: false
SpacesInContainerLiterals: false
SpacesInParentheses: false
SpacesInSquareBrackets: false
TabWidth: 4
UseTab: Never
age-PG18-v1.7.0-rc0/docker/ 0000775 0000000 0000000 00000000000 15134225711 0015050 5 ustar 00root root 0000000 0000000 age-PG18-v1.7.0-rc0/docker/Dockerfile 0000664 0000000 0000000 00000003704 15134225711 0017046 0 ustar 00root root 0000000 0000000 #
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# Build stage: Install necessary development tools for compilation and installation
FROM postgres:18 AS build
RUN apt-get update \
&& apt-get install -y --no-install-recommends --no-install-suggests \
bison \
build-essential \
flex \
postgresql-server-dev-18
COPY . /age
WORKDIR /age
RUN make && make install
# Final stage: Create a final image by copying the files created in the build stage
FROM postgres:18
RUN apt-get update \
&& apt-get install -y --no-install-recommends --no-install-suggests \
locales
RUN echo "en_US.UTF-8 UTF-8" > /etc/locale.gen \
&& locale-gen \
&& update-locale LANG=en_US.UTF-8
ENV LANG=en_US.UTF-8
ENV LC_COLLATE=en_US.UTF-8
ENV LC_CTYPE=en_US.UTF-8
COPY --from=build /usr/lib/postgresql/18/lib/age.so /usr/lib/postgresql/18/lib/
COPY --from=build /usr/share/postgresql/18/extension/age--1.7.0.sql /usr/share/postgresql/18/extension/
COPY --from=build /usr/share/postgresql/18/extension/age.control /usr/share/postgresql/18/extension/
COPY docker/docker-entrypoint-initdb.d/00-create-extension-age.sql /docker-entrypoint-initdb.d/00-create-extension-age.sql
CMD ["postgres", "-c", "shared_preload_libraries=age"]
age-PG18-v1.7.0-rc0/docker/Dockerfile.dev 0000664 0000000 0000000 00000002740 15134225711 0017622 0 ustar 00root root 0000000 0000000 #
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
FROM postgres:18
RUN apt-get update
RUN apt-get install --assume-yes --no-install-recommends --no-install-suggests \
bison \
build-essential \
flex \
postgresql-server-dev-18 \
locales
ENV LANG=en_US.UTF-8
ENV LC_COLLATE=en_US.UTF-8
ENV LC_CTYPE=en_US.UTF-8
RUN echo "en_US.UTF-8 UTF-8" > /etc/locale.gen \
&& locale-gen \
&& update-locale LANG=en_US.UTF-8
COPY . /age
# Set current working directory to /age/ and build.
WORKDIR /age
RUN make install
RUN chown -R postgres /age
USER postgres
RUN make installcheck
COPY docker/docker-entrypoint-initdb.d/00-create-extension-age.sql /docker-entrypoint-initdb.d/00-create-extension-age.sql
CMD ["postgres", "-c", "shared_preload_libraries=age"]
age-PG18-v1.7.0-rc0/docker/docker-entrypoint-initdb.d/ 0000775 0000000 0000000 00000000000 15134225711 0022221 5 ustar 00root root 0000000 0000000 age-PG18-v1.7.0-rc0/docker/docker-entrypoint-initdb.d/00-create-extension-age.sql 0000664 0000000 0000000 00000001467 15134225711 0027176 0 ustar 00root root 0000000 0000000 --
-- Licensed to the Apache Software Foundation (ASF) under one
-- or more contributor license agreements. See the NOTICE file
-- distributed with this work for additional information
-- regarding copyright ownership. The ASF licenses this file
-- to you under the Apache License, Version 2.0 (the
-- "License"); you may not use this file except in compliance
-- with the License. You may obtain a copy of the License at
--
-- http://www.apache.org/licenses/LICENSE-2.0
--
-- Unless required by applicable law or agreed to in writing, software
-- distributed under the License is distributed on an "AS IS" BASIS,
-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-- See the License for the specific language governing permissions and
-- limitations under the License.
--
CREATE EXTENSION age; age-PG18-v1.7.0-rc0/docker/hooks/ 0000775 0000000 0000000 00000000000 15134225711 0016173 5 ustar 00root root 0000000 0000000 age-PG18-v1.7.0-rc0/docker/hooks/build 0000664 0000000 0000000 00000000300 15134225711 0017206 0 ustar 00root root 0000000 0000000 #!/bin/bash
docker buildx create --name multiarch --use --platform linux/amd64,linux/arm64/v8
docker buildx build ../ -t $IMAGE_NAME -f Dockerfile --platform linux/amd64,linux/arm64/v8 --push age-PG18-v1.7.0-rc0/docker/hooks/push 0000664 0000000 0000000 00000000013 15134225711 0017067 0 ustar 00root root 0000000 0000000 #!/bin/bash age-PG18-v1.7.0-rc0/drivers/ 0000775 0000000 0000000 00000000000 15134225711 0015257 5 ustar 00root root 0000000 0000000 age-PG18-v1.7.0-rc0/drivers/Agtype.g4 0000664 0000000 0000000 00000003551 15134225711 0016750 0 ustar 00root root 0000000 0000000 /*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
grammar Agtype;
agType
: agValue EOF
;
agValue
: value typeAnnotation?
;
value
: STRING #StringValue
| INTEGER #IntegerValue
| floatLiteral #FloatValue
| 'true' #TrueBoolean
| 'false' #FalseBoolean
| 'null' #NullValue
| obj #ObjectValue
| array #ArrayValue
;
obj
: '{' pair (',' pair)* '}'
| '{' '}'
;
pair
: STRING ':' agValue
;
array
: '[' agValue (',' agValue)* ']'
| '[' ']'
;
typeAnnotation
: '::' IDENT
;
IDENT
: [A-Z_a-z][$0-9A-Z_a-z]*
;
STRING
: '"' (ESC | SAFECODEPOINT)* '"'
;
fragment ESC
: '\\' (["\\/bfnrt] | UNICODE)
;
fragment UNICODE
: 'u' HEX HEX HEX HEX
;
fragment HEX
: [0-9a-fA-F]
;
fragment SAFECODEPOINT
: ~ ["\\\u0000-\u001F]
;
INTEGER
: '-'? INT
;
fragment INT
: '0' | [1-9] [0-9]*
;
floatLiteral
: RegularFloat
| ExponentFloat
| '-'? 'Infinity'
| 'NaN'
;
RegularFloat
: '-'? INT DECIMAL
;
ExponentFloat
: '-'? INT DECIMAL? SCIENTIFIC
;
fragment DECIMAL
: '.' [0-9]+
;
fragment SCIENTIFIC
: [Ee][+-]? [0-9]+
;
WS
: [ \t\n\r] + -> skip
;
age-PG18-v1.7.0-rc0/drivers/README 0000664 0000000 0000000 00000002036 15134225711 0016140 0 ustar 00root root 0000000 0000000 # Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
This folder contains drivers for specific languages
### For more information about [Apache AGE](https://age.apache.org/)
* Apache Age : https://age.apache.org/
* GitHub : https://github.com/apache/age
* Document : https://age.apache.org/age-manual/master/index.html
age-PG18-v1.7.0-rc0/drivers/docker-compose.yml 0000664 0000000 0000000 00000000321 15134225711 0020710 0 ustar 00root root 0000000 0000000 version: "3.3"
services:
db:
image: apache/age:dev_snapshot_PG18
environment:
- POSTGRES_USER=postgres
- POSTGRES_PASSWORD=agens
- POSTGRES_DB=postgres
ports:
- 5432:5432
age-PG18-v1.7.0-rc0/drivers/golang/ 0000775 0000000 0000000 00000000000 15134225711 0016526 5 ustar 00root root 0000000 0000000 age-PG18-v1.7.0-rc0/drivers/golang/LICENSE 0000664 0000000 0000000 00000026135 15134225711 0017542 0 ustar 00root root 0000000 0000000 Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
age-PG18-v1.7.0-rc0/drivers/golang/README.md 0000664 0000000 0000000 00000004277 15134225711 0020017 0 ustar 00root root 0000000 0000000 # age AGType parser and driver support for Golang
AGType parser and driver support for [Apache AGE](https://age.apache.org/), graph extension for PostgreSQL.
### Features
* Unmarshal AGE result data(AGType) to Vertex, Edge, Path
* Cypher query support for 3rd. Party sql driver (enables to use cypher queries directly)
### Prerequisites (Required)
* Java 11, or greater, installed.
* Go 1.18, or greater, installed.
* This module runs on the golang standard api [database/sql](https://golang.org/pkg/database/sql/) and [antlr4-python3](https://github.com/antlr/antlr4/tree/master/runtime/Go/antlr)
* ANTLR 4.11.1, or greater, installed.
### Installation (From source)
Run (Windows): install.bat
Run (Linux & OSX):
```
cd age/drivers/golang
./install.sh
```
### Go get
```
go get github.com/apache/age/drivers/golang
```
### gomod
```
require github.com/apache/age/drivers/golang {version}
```
Check [latest version](https://github.com/apache/age/releases)
### For more information about [Apache AGE](https://age.apache.org/)
* Apache Age : https://age.apache.org/
* GitHub : https://github.com/apache/age
* Document : https://age.apache.org/docs/
### Check that Apache AGE is loaded on your PostgreSQL database
Connect to your containerized Postgres instance and then run the following commands:
```(sql)
# psql
CREATE EXTENSION age;
LOAD 'age';
SET search_path = ag_catalog, "$user", public;
```
### Test
For the tests to work, please make sure the following has been done.
* The driver has been successfully installed following the instructions above.
* Make sure the database you will run tests against has Apache AGE installed.
* Make sure to modify the DSN value in age/drivers/golang/age/age_test.go
* Make sure the DSN has the correct database and connect string.
* Make sure the database has a graph called testGraph created.
```
cd age/drivers/golang/age
go test . -v
```
### Samples
* Usage 1: using database/sql API and Cypher execution function 'ExecCypher'
Sample : [samples/sql_api_sample.go](samples/sql_api_sample.go)
* Usage 2: using Age Wrapper
Sample : [samples/age_wrapper_sample.go](samples/age_wrapper_sample.go)
* Run Samples : [samples/main.go](samples/main.go)
### License
Apache-2.0 License
age-PG18-v1.7.0-rc0/drivers/golang/TYPES.md 0000664 0000000 0000000 00000001727 15134225711 0017763 0 ustar 00root root 0000000 0000000 # Apache AGE - Go driver Type mapping
* For more information about Apache AGE result types : https://age.apache.org/docs/Apache_AGE_Guide.pdf
| Type | AGE Result | Go Type |
|------|------------|---------|
|Vertex|::vertex |Vertex vertex.Id() int64 vertex.Label() string vertex.Prop(string) interface{} |
|Edge |::edge |Edge edge.Id() int64 edge.Label() string edge.StartId() int64 edge.EndId() int64 edge.Prop(string) interface{} |
|Path |::path |Path path.Size() int // quantity of vertices and edges in this path path.Get(index int) Entity // *Vertex or *Edge path.GetAsVertex(index int) *Vertex path.GetAsEdge(index int) *Edge |
|Integer |int |int64 |
|Float |float NaN, -Infinity, Infinity |float64 math.Nan(), math.Inf(-1),math.Inf(1) |
|Numeric |::numeric |*big.Int *big.Float |
|String|string |string |
|Boolean|bool |bool |
|Null|empty result |nil |
age-PG18-v1.7.0-rc0/drivers/golang/age/ 0000775 0000000 0000000 00000000000 15134225711 0017262 5 ustar 00root root 0000000 0000000 age-PG18-v1.7.0-rc0/drivers/golang/age/age.go 0000664 0000000 0000000 00000016544 15134225711 0020357 0 ustar 00root root 0000000 0000000 /*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package age
import (
"bytes"
"database/sql"
"fmt"
"reflect"
)
// GetReady prepare AGE extension
// load AGE extension
// set graph path
func GetReady(db *sql.DB, graphName string) (bool, error) {
tx, err := db.Begin()
if err != nil {
return false, err
}
_, err = tx.Exec("LOAD 'age';")
if err != nil {
return false, err
}
_, err = tx.Exec("SET search_path = ag_catalog, '$user', public;")
if err != nil {
return false, err
}
var count int = 0
err = tx.QueryRow("SELECT count(*) FROM ag_graph WHERE name=$1", graphName).Scan(&count)
if err != nil {
return false, err
}
if count == 0 {
_, err = tx.Exec("SELECT create_graph($1);", graphName)
if err != nil {
return false, err
}
}
tx.Commit()
return true, nil
}
type CursorProvider func(columnCount int, rows *sql.Rows) Cursor
type Cursor interface {
Next() bool
Close() error
}
func execCypher(cursorProvider CursorProvider, tx *sql.Tx, graphName string, columnCount int, cypher string, args ...interface{}) (Cursor, error) {
var buf bytes.Buffer
cypherStmt := fmt.Sprintf(cypher, args...)
buf.WriteString("SELECT * from cypher(NULL,NULL) as (v0 agtype")
for i := 1; i < columnCount; i++ {
buf.WriteString(fmt.Sprintf(", v%d agtype", i))
}
buf.WriteString(");")
stmt := buf.String()
// Pass in the graph name and cypher statement via parameters to prepare
// the cypher function call for session info.
prepare_stmt := "SELECT * FROM age_prepare_cypher($1, $2);"
_, perr := tx.Exec(prepare_stmt, graphName, cypherStmt)
if perr != nil {
fmt.Println(prepare_stmt + " " + graphName + " " + cypher)
return nil, perr
}
if columnCount == 0 {
_, err := tx.Exec(stmt)
if err != nil {
fmt.Println(stmt)
return nil, err
}
return nil, nil
} else {
rows, err := tx.Query(stmt)
if err != nil {
fmt.Println(stmt)
return nil, err
}
return cursorProvider(columnCount, rows), nil
}
}
// ExecCypher : execute cypher query
// CREATE , DROP ....
// MATCH .... RETURN ....
// CREATE , DROP .... RETURN ...
func ExecCypher(tx *sql.Tx, graphName string, columnCount int, cypher string, args ...interface{}) (*CypherCursor, error) {
cursor, err := execCypher(NewCypherCursor, tx, graphName, columnCount, cypher, args...)
var cypherCursor *CypherCursor
if cursor != nil {
cypherCursor = cursor.(*CypherCursor)
}
return cypherCursor, err
}
// ExecCypherMap
// CREATE , DROP ....
// MATCH .... RETURN ....
// CREATE , DROP .... RETURN ...
func ExecCypherMap(tx *sql.Tx, graphName string, columnCount int, cypher string, args ...interface{}) (*CypherMapCursor, error) {
cursor, err := execCypher(NewCypherMapCursor, tx, graphName, columnCount, cypher, args...)
var cypherMapCursor *CypherMapCursor
if cursor != nil {
cypherMapCursor = cursor.(*CypherMapCursor)
}
return cypherMapCursor, err
}
type Age struct {
db *sql.DB
graphName string
}
type AgeTx struct {
age *Age
tx *sql.Tx
}
/**
@param dsn host=127.0.0.1 port=5432 dbname=postgres user=postgres password=agens sslmode=disable
*/
func ConnectAge(graphName string, dsn string) (*Age, error) {
db, err := sql.Open("postgres", dsn)
if err != nil {
return nil, err
}
age := &Age{db: db, graphName: graphName}
_, err = age.GetReady()
if err != nil {
db.Close()
age = nil
}
return age, err
}
func NewAge(graphName string, db *sql.DB) *Age {
return &Age{db: db, graphName: graphName}
}
func (age *Age) GetReady() (bool, error) {
tx, err := age.db.Begin()
if err != nil {
return false, err
}
_, err = tx.Exec("LOAD 'age';")
if err != nil {
return false, err
}
_, err = tx.Exec("SET search_path = ag_catalog, '$user', public;")
if err != nil {
return false, err
}
var count int = 0
err = tx.QueryRow("SELECT count(*) FROM ag_graph WHERE name=$1", age.graphName).Scan(&count)
if err != nil {
return false, err
}
if count == 0 {
_, err = tx.Exec("SELECT create_graph($1);", age.graphName)
if err != nil {
return false, err
}
}
tx.Commit()
return true, nil
}
func (a *Age) Close() error {
return a.db.Close()
}
func (a *Age) DB() *sql.DB {
return a.db
}
func (a *Age) Begin() (*AgeTx, error) {
ageTx := &AgeTx{age: a}
tx, err := a.db.Begin()
if err != nil {
return nil, err
}
ageTx.tx = tx
return ageTx, err
}
func (t *AgeTx) Commit() error {
return t.tx.Commit()
}
func (t *AgeTx) Rollback() error {
return t.tx.Rollback()
}
/** CREATE , DROP .... */
func (a *AgeTx) ExecCypher(columnCount int, cypher string, args ...interface{}) (*CypherCursor, error) {
return ExecCypher(a.tx, a.age.graphName, columnCount, cypher, args...)
}
func (a *AgeTx) ExecCypherMap(columnCount int, cypher string, args ...interface{}) (*CypherMapCursor, error) {
return ExecCypherMap(a.tx, a.age.graphName, columnCount, cypher, args...)
}
type CypherCursor struct {
Cursor
columnCount int
rows *sql.Rows
unmarshaler Unmarshaller
}
func NewCypherCursor(columnCount int, rows *sql.Rows) Cursor {
return &CypherCursor{columnCount: columnCount, rows: rows, unmarshaler: NewAGUnmarshaler()}
}
func (c *CypherCursor) Next() bool {
return c.rows.Next()
}
func (c *CypherCursor) GetRow() ([]Entity, error) {
var gstrs = make([]interface{}, c.columnCount)
for i := 0; i < c.columnCount; i++ {
gstrs[i] = new(string)
}
err := c.rows.Scan(gstrs...)
if err != nil {
return nil, fmt.Errorf("CypherCursor.GetRow:: %s", err)
}
entArr := make([]Entity, c.columnCount)
for i := 0; i < c.columnCount; i++ {
gstr := gstrs[i].(*string)
e, err := c.unmarshaler.unmarshal(*gstr)
if err != nil {
fmt.Println(i, ">>", gstr)
return nil, err
}
entArr[i] = e
}
return entArr, nil
}
func (c *CypherCursor) Close() error {
return c.rows.Close()
}
//
type CypherMapCursor struct {
CypherCursor
mapper *AGMapper
}
func NewCypherMapCursor(columnCount int, rows *sql.Rows) Cursor {
mapper := NewAGMapper(make(map[string]reflect.Type))
pcursor := CypherCursor{columnCount: columnCount, rows: rows, unmarshaler: mapper}
return &CypherMapCursor{CypherCursor: pcursor, mapper: mapper}
}
func (c *CypherMapCursor) PutType(label string, tp reflect.Type) {
c.mapper.PutType(label, tp)
}
func (c *CypherMapCursor) GetRow() ([]interface{}, error) {
entities, err := c.CypherCursor.GetRow()
if err != nil {
return nil, fmt.Errorf("CypherMapCursor.GetRow:: %s", err)
}
elArr := make([]interface{}, c.columnCount)
for i := 0; i < c.columnCount; i++ {
ent := entities[i]
if ent.GType() == G_MAP_PATH {
elArr[i] = ent
} else {
elArr[i] = ent.(*SimpleEntity).Value()
}
}
return elArr, nil
}
age-PG18-v1.7.0-rc0/drivers/golang/age/age_test.go 0000664 0000000 0000000 00000023746 15134225711 0021420 0 ustar 00root root 0000000 0000000 /*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package age
import (
"fmt"
"reflect"
"testing"
"database/sql"
_ "github.com/lib/pq"
)
var dsn string = "host=127.0.0.1 port=5432 dbname=postgres user=postgres password=agens sslmode=disable"
var graphName string = "testGraph"
func TestAdditional(t *testing.T) {
db, err := sql.Open("postgres", dsn)
if err != nil {
t.Fatal(err)
}
_, err = GetReady(db, graphName)
if err != nil {
t.Fatal(err)
}
cursor, err := db.Begin()
if err != nil {
t.Fatal(err)
}
_, err = ExecCypher(cursor, graphName, 0, "CREATE (n:Person {name: '%s', weight:%f})", "Joe", 67.3)
if err != nil {
t.Fatal(err)
}
_, err = ExecCypher(cursor, graphName, 0, "CREATE (n:Person {name: '%s', weight:77.3, roles:['Dev','marketing']})", "Jack")
if err != nil {
t.Fatal(err)
}
_, err = ExecCypher(cursor, graphName, 0, "CREATE (n:Person {name: '%s', weight:%d})", "Andy", 59)
if err != nil {
t.Fatal(err)
}
cursor.Commit()
cursor, err = db.Begin()
if err != nil {
t.Fatal(err)
}
cypherCursor, err := ExecCypher(cursor, graphName, 1, "MATCH (n:Person) RETURN n")
if err != nil {
t.Fatal(err)
}
for cypherCursor.Next() {
entities, err := cypherCursor.GetRow()
if err != nil {
t.Fatal(err)
}
vertex := entities[0].(*Vertex)
fmt.Println(vertex.Id(), vertex.Label(), vertex.Props())
}
_, err = ExecCypher(cursor, graphName, 0, "MATCH (a:Person), (b:Person) WHERE a.name='%s' AND b.name='%s' CREATE (a)-[r:workWith {weight: %d}]->(b)",
"Jack", "Joe", 3)
if err != nil {
t.Fatal(err)
}
_, err = ExecCypher(cursor, graphName, 0, "MATCH (a:Person {name: '%s'}), (b:Person {name: '%s'}) CREATE (a)-[r:workWith {weight: %d}]->(b)",
"Joe", "Andy", 7)
if err != nil {
t.Fatal(err)
}
cursor.Commit()
cursor, err = db.Begin()
if err != nil {
t.Fatal(err)
}
cypherCursor, err = ExecCypher(cursor, graphName, 1, "MATCH p=()-[:workWith]-() RETURN p")
if err != nil {
t.Fatal(err)
}
for cypherCursor.Next() {
entities, err := cypherCursor.GetRow()
if err != nil {
t.Fatal(err)
}
path := entities[0].(*Path)
vertexStart := path.GetAsVertex(0)
edge := path.GetAsEdge(1)
vertexEnd := path.GetAsVertex(2)
fmt.Println(vertexStart, edge, vertexEnd)
}
_, err = ExecCypher(cursor, graphName, 0, "MATCH (n:Person) DETACH DELETE n RETURN *")
if err != nil {
t.Fatal(err)
}
cursor.Commit()
}
func TestAgeWrapper(t *testing.T) {
ag, err := ConnectAge(graphName, dsn)
if err != nil {
t.Fatal(err)
}
tx, err := ag.Begin()
if err != nil {
t.Fatal(err)
}
_, err = tx.ExecCypher(0, "CREATE (n:Person {name: '%s'})", "Joe")
if err != nil {
t.Fatal(err)
}
_, err = tx.ExecCypher(0, "CREATE (n:Person {name: '%s', age: %d})", "Smith", 10)
if err != nil {
t.Fatal(err)
}
_, err = tx.ExecCypher(0, "CREATE (n:Person {name: '%s', weight:%f})", "Jack", 70.3)
if err != nil {
t.Fatal(err)
}
tx.Commit()
tx, err = ag.Begin()
if err != nil {
t.Fatal(err)
}
cursor, err := tx.ExecCypher(1, "MATCH (n:Person) RETURN n")
if err != nil {
t.Fatal(err)
}
count := 0
for cursor.Next() {
entities, err := cursor.GetRow()
if err != nil {
t.Fatal(err)
}
count++
vertex := entities[0].(*Vertex)
fmt.Println(count, "]", vertex.Id(), vertex.Label(), vertex.Props())
}
fmt.Println("Vertex Count:", count)
_, err = tx.ExecCypher(0, "MATCH (a:Person), (b:Person) WHERE a.name='%s' AND b.name='%s' CREATE (a)-[r:workWith {weight: %d}]->(b)",
"Jack", "Joe", 3)
if err != nil {
t.Fatal(err)
}
_, err = tx.ExecCypher(0, "MATCH (a:Person {name: '%s'}), (b:Person {name: '%s'}) CREATE (a)-[r:workWith {weight: %d}]->(b)",
"Joe", "Smith", 7)
if err != nil {
t.Fatal(err)
}
tx.Commit()
tx, err = ag.Begin()
if err != nil {
t.Fatal(err)
}
cursor, err = tx.ExecCypher(1, "MATCH p=()-[:workWith]-() RETURN p")
if err != nil {
t.Fatal(err)
}
count = 0
for cursor.Next() {
entities, err := cursor.GetRow()
if err != nil {
t.Fatal(err)
}
count++
path := entities[0].(*Path)
fmt.Println(count, "]", path.GetAsVertex(0), path.GetAsEdge(1).props, path.GetAsVertex(2))
}
_, err = tx.ExecCypher(0, "MATCH (n:Person) DETACH DELETE n RETURN *")
if err != nil {
t.Fatal(err)
}
tx.Commit()
}
func TestQueryWithMapper(t *testing.T) {
db, err := sql.Open("postgres", dsn)
if err != nil {
t.Fatal(err)
}
// Confirm graph_path created
_, err = GetReady(db, graphName)
if err != nil {
t.Fatal(err)
}
// Tx begin for execute create vertex
tx, err := db.Begin()
if err != nil {
t.Fatal(err)
}
// Create Vertex
ExecCypher(tx, graphName, 0, "CREATE (n:Person {name: '%s'})", "Joe")
ExecCypher(tx, graphName, 0, "CREATE (n:Person {name: '%s', age: %d})", "Smith", 10)
ExecCypher(tx, graphName, 0, "CREATE (n:Person {name: '%s', weight:%f})", "Jack", 70.3)
tx.Commit()
tx, err = db.Begin()
if err != nil {
t.Fatal(err)
}
// Match
mapCursor, err := ExecCypherMap(tx, graphName, 1, "MATCH (n:Person) RETURN n")
if err != nil {
t.Fatal(err)
}
mapCursor.PutType("Person", reflect.TypeOf(VPerson{}))
count := 0
for mapCursor.Next() {
entities, err := mapCursor.GetRow()
if err != nil {
t.Fatal(err)
}
count++
person := entities[0].(VPerson)
fmt.Println(count, "]", person.Name, person.Age, person.Weight)
}
// Create Path
ExecCypher(tx, graphName, 0, "MATCH (a:Person), (b:Person) WHERE a.name='%s' AND b.name='%s' CREATE (a)-[r:workWith {weight: %d}]->(b)",
"Jack", "Joe", 3)
ExecCypher(tx, graphName, 0, "MATCH (a:Person {name: '%s'}), (b:Person {name: '%s'}) CREATE (a)-[r:workWith {weight: %d}]->(b)",
"Joe", "Smith", 7)
tx.Commit()
tx, err = db.Begin()
if err != nil {
t.Fatal(err)
}
// Query Path
mapCursor, err = ExecCypherMap(tx, graphName, 3, "MATCH (a)-[b:workWith]-(c) RETURN a,b,c")
if err != nil {
t.Fatal(err)
}
mapCursor.PutType("Person", reflect.TypeOf(VPerson{}))
mapCursor.PutType("workWith", reflect.TypeOf(EWorkWith{}))
count = 0
for mapCursor.Next() {
entities, err := mapCursor.GetRow()
if err != nil {
t.Fatal(err)
}
count++
person1 := entities[0].(VPerson)
workWith := entities[1].(EWorkWith)
person2 := entities[2].(VPerson)
fmt.Println(count, "]", person1, workWith, person2)
}
// Clear Data
_, err = ExecCypher(tx, graphName, 0, "MATCH (n:Person) DETACH DELETE n RETURN *")
if err != nil {
t.Fatal(err)
}
tx.Commit()
}
func TestCudReturn(t *testing.T) {
db, err := sql.Open("postgres", dsn)
if err != nil {
t.Fatal(err)
}
// Confirm graph_path created
_, err = GetReady(db, graphName)
if err != nil {
t.Fatal(err)
}
// Tx begin for execute create vertex
tx, err := db.Begin()
if err != nil {
t.Fatal(err)
}
// Create Vertex
cursor, err := ExecCypher(tx, graphName, 1, "CREATE (n:Person {name: '%s'}) RETURN n", "Joe")
if err != nil {
t.Fatal(err)
}
for cursor.Next() {
fmt.Println(cursor.GetRow())
}
cursor, err = ExecCypher(tx, graphName, 1, "CREATE (n:Person {name: '%s', age: %d}) RETURN n", "Smith", 10)
if err != nil {
t.Fatal(err)
}
for cursor.Next() {
fmt.Println(cursor.GetRow())
}
cursor, err = ExecCypher(tx, graphName, 1, "CREATE (n:Person {name: '%s', weight:%f}) RETURN n", "Jack", 70.3)
if err != nil {
t.Fatal(err)
}
for cursor.Next() {
fmt.Println(cursor.GetRow())
}
tx.Commit()
tx, err = db.Begin()
if err != nil {
t.Fatal(err)
}
cursor, err = ExecCypher(tx, graphName, 1, "MATCH (n:Person) RETURN n")
if err != nil {
t.Fatal(err)
}
for cursor.Next() {
fmt.Println(cursor.GetRow())
}
}
func TestQueryManyReturn(t *testing.T) {
ag, err := ConnectAge(graphName, dsn)
if err != nil {
t.Fatal(err)
}
tx, err := ag.Begin()
if err != nil {
t.Fatal(err)
}
// Create Vertex
tx.ExecCypher(0, "CREATE (n:Person {name: '%s'})", "Joe")
tx.ExecCypher(0, "CREATE (n:Person {name: '%s', age: %d})", "Smith", 10)
tx.ExecCypher(0, "CREATE (n:Person {name: '%s', weight:%f})", "Jack", 70.3)
tx.Commit()
tx, err = ag.Begin()
if err != nil {
t.Fatal(err)
}
// Create Path
tx.ExecCypher(0, "MATCH (a:Person), (b:Person) WHERE a.name='%s' AND b.name='%s' CREATE (a)-[r:workWith {weight: %d}]->(b)",
"Jack", "Joe", 3)
tx.ExecCypher(0, "MATCH (a:Person {name: '%s'}), (b:Person {name: '%s'}) CREATE (a)-[r:workWith {weight: %d}]->(b)",
"Joe", "Smith", 7)
tx.Commit()
tx, err = ag.Begin()
if err != nil {
t.Fatal(err)
}
// Query Path1
cursor, err := tx.ExecCypher(3, "MATCH (a:Person)-[l:workWith]-(b:Person) RETURN a, l, b")
if err != nil {
t.Fatal(err)
}
count := 0
for cursor.Next() {
entities, err := cursor.GetRow()
if err != nil {
t.Fatal(err)
}
count++
v1 := entities[0].(*Vertex)
edge := entities[1].(*Edge)
v2 := entities[2].(*Vertex)
fmt.Println("ROW ", count, ">>", "\n\t", v1, "\n\t", edge, "\n\t", v2)
}
// Query Path2
cursor, err = tx.ExecCypher(1, "MATCH p=(a:Person)-[l:workWith]-(b:Person) WHERE a.name = '%s' RETURN p", "Joe")
if err != nil {
t.Fatal(err)
}
count = 0
for cursor.Next() {
entities, err := cursor.GetRow()
if err != nil {
t.Fatal(err)
}
count++
path := entities[0].(*Path)
fmt.Println("ROW ", count, ">>", "\n\t", path.GetAsVertex(0),
"\n\t", path.GetAsEdge(1),
"\n\t", path.GetAsVertex(2))
}
// Clear Data
_, err = tx.ExecCypher(0, "MATCH (n:Person) DETACH DELETE n RETURN *")
if err != nil {
t.Fatal(err)
}
tx.Commit()
}
age-PG18-v1.7.0-rc0/drivers/golang/age/builder.go 0000664 0000000 0000000 00000017305 15134225711 0021245 0 ustar 00root root 0000000 0000000 /*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package age
import (
"fmt"
"math"
"math/big"
"strconv"
"strings"
"github.com/antlr/antlr4/runtime/Go/antlr/v4"
"github.com/apache/age/drivers/golang/parser"
)
const MaxUint = ^uint(0)
const MaxInt = int(MaxUint >> 1)
const MinUint = 0
const MinInt = -MaxInt - 1
type Unmarshaller interface {
unmarshal(text string) (Entity, error)
}
type AGUnmarshaler struct {
Unmarshaller
ageParser *parser.AgeParser
visitor parser.AgeVisitor
errListener *AGErrorListener
vcache map[int64]interface{}
}
func NewAGUnmarshaler() *AGUnmarshaler {
vcache := make(map[int64]interface{})
m := &AGUnmarshaler{ageParser: parser.NewAgeParser(nil),
visitor: &UnmarshalVisitor{vcache: vcache},
errListener: NewAGErrorListener(),
vcache: vcache,
}
m.ageParser.AddErrorListener(m.errListener)
return m
}
func (p *AGUnmarshaler) unmarshal(text string) (Entity, error) {
if len(text) == 0 {
return NewSimpleEntity(nil), nil
}
input := antlr.NewInputStream(text)
lexer := parser.NewAgeLexer(input)
stream := antlr.NewCommonTokenStream(lexer, 0)
p.ageParser.SetInputStream(stream)
tree := p.ageParser.Ageout()
rst := tree.Accept(p.visitor)
if len(p.errListener.errList) > 0 {
var ape *AgeParseError = nil
errs := make([]string, len(p.errListener.errList))
for idx, re := range p.errListener.errList {
errs[idx] = re.GetMessage()
fmt.Println(re)
}
p.errListener.clearErrs()
ape = &AgeParseError{msg: "Cypher query:" + text, errors: errs}
return nil, ape
}
if !IsEntity(rst) {
rst = NewSimpleEntity(rst)
}
return rst.(Entity), nil
}
type AGErrorListener struct {
*antlr.DefaultErrorListener
errList []antlr.RecognitionException
}
func NewAGErrorListener() *AGErrorListener {
return &AGErrorListener{DefaultErrorListener: &antlr.DefaultErrorListener{}, errList: []antlr.RecognitionException{}}
}
func (el *AGErrorListener) SyntaxError(recognizer antlr.Recognizer, offendingSymbol interface{}, line, column int, msg string, e antlr.RecognitionException) {
el.errList = append(el.errList, e)
}
func (el *AGErrorListener) getErrs() []antlr.RecognitionException {
return el.errList
}
func (el *AGErrorListener) clearErrs() {
el.errList = []antlr.RecognitionException{}
}
type UnmarshalVisitor struct {
parser.AgeVisitor
vcache map[int64]interface{}
}
func (v *UnmarshalVisitor) Visit(tree antlr.ParseTree) interface{} { return nil }
func (v *UnmarshalVisitor) VisitChildren(node antlr.RuleNode) interface{} {
var rtn interface{}
for _, c := range node.GetChildren() {
pt := c.(antlr.ParseTree)
rtn = pt.Accept(v)
}
return rtn
}
func (v *UnmarshalVisitor) VisitTerminal(node antlr.TerminalNode) interface{} { return nil }
func (v *UnmarshalVisitor) VisitErrorNode(node antlr.ErrorNode) interface{} { return nil }
func (v *UnmarshalVisitor) VisitAgeout(ctx *parser.AgeoutContext) interface{} {
rtn := v.VisitChildren(ctx)
return rtn
}
// Visit a parse tree produced by AgeParser#vertex.
func (v *UnmarshalVisitor) VisitVertex(ctx *parser.VertexContext) interface{} {
propCtx := ctx.Properties()
props := propCtx.Accept(v).(map[string]interface{})
// fmt.Println(" * VisitVertex:", props)
vid := int64(props["id"].(int64))
vertex, ok := v.vcache[vid]
if !ok {
vertex = NewVertex(vid, props["label"].(string), props["properties"].(map[string]interface{}))
v.vcache[vid] = vertex
}
return vertex
}
// Visit a parse tree produced by AgeParser#edge.
func (v *UnmarshalVisitor) VisitEdge(ctx *parser.EdgeContext) interface{} {
propCtx := ctx.Properties()
props := propCtx.Accept(v).(map[string]interface{})
// fmt.Println(" * VisitEdge:", props)
edge := NewEdge(int64(props["id"].(int64)), props["label"].(string),
int64(props["start_id"].(int64)), int64(props["end_id"].(int64)),
props["properties"].(map[string]interface{}))
return edge
}
// Visit a parse tree produced by AgeParser#path.
func (v *UnmarshalVisitor) VisitPath(ctx *parser.PathContext) interface{} {
entities := []Entity{}
for _, child := range ctx.GetChildren() {
switch child.(type) {
case *parser.VertexContext:
v := child.(*parser.VertexContext).Accept(v)
// fmt.Println(v)
entities = append(entities, v.(Entity))
case *parser.EdgeContext:
e := child.(*parser.EdgeContext).Accept(v)
// fmt.Println(e)
entities = append(entities, e.(Entity))
default:
}
}
path := NewPath(entities)
return path
}
// Visit a parse tree produced by AgeParser#value.
func (v *UnmarshalVisitor) VisitValue(ctx *parser.ValueContext) interface{} {
child := ctx.GetChild(0)
switch child.(type) {
case *antlr.TerminalNodeImpl:
rtn, err := unmarshalTerm(child.(*antlr.TerminalNodeImpl))
if err != nil {
panic(err)
}
return rtn
default:
return child.(antlr.ParserRuleContext).Accept(v)
}
}
// Visit a parse tree produced by AgeParser#properties.
func (v *UnmarshalVisitor) VisitProperties(ctx *parser.PropertiesContext) interface{} {
props := make(map[string]interface{})
for _, pairCtx := range ctx.AllPair() {
pairCtx.Accept(v)
pair := pairCtx.(*parser.PairContext)
key := strings.Trim(pair.STRING().GetText(), "\"")
// fmt.Println("Pair KEY:", key)
value := pair.Value().Accept(v)
props[key] = value
}
return props
}
// Visit a parse tree produced by AgeParser#pair.
func (v *UnmarshalVisitor) VisitPair(ctx *parser.PairContext) interface{} {
return nil
}
// Visit a parse tree produced by AgeParser#arr.
func (v *UnmarshalVisitor) VisitArr(ctx *parser.ArrContext) interface{} {
var arr []interface{}
for _, child := range ctx.GetChildren() {
switch child.(type) {
case *antlr.TerminalNodeImpl:
// skip
break
default:
el := child.(antlr.ParserRuleContext).Accept(v)
arr = append(arr, el)
}
}
return arr
}
func unmarshalTerm(ctx *antlr.TerminalNodeImpl) (interface{}, error) {
txt := ctx.GetText()
switch ctx.GetSymbol().GetTokenType() {
case parser.AgeLexerSTRING:
return strings.Trim(txt, "\""), nil
case parser.AgeLexerNUMERIC:
numStr := txt[:len(txt)-9]
// fmt.Println("txt ", txt)
// fmt.Println("numStr", numStr)
if strings.Contains(numStr, ".") {
bi := new(big.Float)
bi, ok := bi.SetString(numStr)
if !ok {
return nil, &AgeParseError{msg: "Parse big float " + txt}
}
return bi, nil
} else {
bi := new(big.Int)
bi, ok := bi.SetString(numStr, 10)
if !ok {
return nil, &AgeParseError{msg: "Parse big int " + txt}
}
return bi, nil
}
case parser.AgeLexerNUMBER:
if strings.Contains(txt, ".") {
return strconv.ParseFloat(txt, 64)
} else {
return strconv.ParseInt(txt, 10, 64)
}
case parser.AgeLexerFLOAT_EXPR:
switch txt {
case "NaN":
return math.NaN(), nil
case "-Infinity":
return math.Inf(-1), nil
case "Infinity":
return math.Inf(1), nil
default:
return nil, &AgeParseError{msg: "Unknown float expression" + txt}
}
case parser.AgeLexerBOOL:
s, err := strconv.ParseBool(txt)
if err != nil {
return nil, err
} else {
return s, nil
}
case parser.AgeLexerNULL:
return nil, nil
default:
return nil, nil
}
}
age-PG18-v1.7.0-rc0/drivers/golang/age/builder_test.go 0000664 0000000 0000000 00000016346 15134225711 0022310 0 ustar 00root root 0000000 0000000 /*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package age
import (
"fmt"
"math"
"math/big"
"testing"
"github.com/stretchr/testify/assert"
)
func TestPathParsing(t *testing.T) {
rstStr1 := `[{"id": 2251799813685425, "label": "Person", "properties": {"name": "Smith"}}::vertex,
{"id": 2533274790396576, "label": "workWith", "end_id": 2251799813685425, "start_id": 2251799813685424,
"properties": {"weight": 3, "bigFloat":123456789123456789123456789.12345::numeric}}::edge,
{"id": 2251799813685424, "label": "Person", "properties": {"name": "Joe"}}::vertex]::path`
rstStr2 := `[{"id": 2251799813685424, "label": "Person", "properties": {"name": "Joe"}}::vertex,
{"id": 2533274790396576, "label": "workWith", "end_id": 2251799813685425, "start_id": 2251799813685424, "properties": {"weight": 3}}::edge,
{"id": 2251799813685425, "label": "Person", "properties": {"name": "Smith"}}::vertex]::path`
rstStr3 := `[{"id": 2251799813685424, "label": "Person", "properties": {"name": "Joe"}}::vertex,
{"id": 2533274790396579, "label": "workWith", "end_id": 2251799813685426, "start_id": 2251799813685424, "properties": {"weight": 5}}::edge,
{"id": 2251799813685426, "label": "Person", "properties": {"name": "Jack", "arrVal":["A","B"]}}::vertex]::path`
unmarshaler := NewAGUnmarshaler()
entity1, _ := unmarshaler.unmarshal(rstStr1)
entity2, _ := unmarshaler.unmarshal(rstStr2)
entity3, _ := unmarshaler.unmarshal(rstStr3)
assert.Equal(t, entity1.GType(), entity2.GType(), "Type Check")
p1 := entity1.(*Path)
p2 := entity2.(*Path)
p3 := entity3.(*Path)
assert.Equal(t, p1.GetAsVertex(0).props["name"], p2.GetAsVertex(2).props["name"])
assert.Equal(t, p2.GetAsVertex(0).props["name"], p3.GetAsVertex(0).props["name"])
bf := new(big.Float)
bf, _ = bf.SetString("123456789123456789123456789.12345")
bigFloat := p1.GetAsEdge(1).props["bigFloat"]
assert.Equal(t, bf, bigFloat)
fmt.Println(entity1)
fmt.Println(entity2)
fmt.Println(entity3)
}
func TestVertexParsing(t *testing.T) {
rstStr := `{"id": 2251799813685425, "label": "Person",
"properties": {"name": "Smith", "numInt":123, "numIntBig":12345678901235555555555555555::numeric, "numFloat": 384.23424,
"yn":true, "nullVal": null}}::vertex`
unmarshaler := NewAGUnmarshaler()
entity, _ := unmarshaler.unmarshal(rstStr)
// fmt.Println(entity)
assert.Equal(t, G_VERTEX, entity.GType())
v := entity.(*Vertex)
assert.Equal(t, "Smith", v.props["name"])
assert.True(t, (int64(123) == v.props["numInt"]))
assert.Equal(t, int64(123), v.props["numInt"])
bi := new(big.Int)
bi, ok := bi.SetString("12345678901235555555555555555", 10)
if !ok {
fmt.Println("Cannot reach this line. ")
}
assert.Equal(t, bi, v.props["numIntBig"])
assert.True(t, (384.23424 == v.props["numFloat"]))
assert.Equal(t, float64(384.23424), v.props["numFloat"])
assert.Equal(t, true, v.props["yn"])
assert.Nil(t, v.props["nullVal"])
}
func TestNormalValueParsing(t *testing.T) {
mapStr := `{"name": "Smith", "num":123, "yn":true}`
arrStr := `["name", "Smith", "num", 123, "yn", true]`
strStr := `"abcd"`
intStr := `1234`
floatStr := `1234.56789`
floatStr2 := `6.45161290322581e+46`
numericStr1 := `12345678901234567890123456.789::numeric`
numericStr2 := `12345678901234567890123456::numeric`
boolStr := `true`
nullStr := ""
nanStr := "NaN"
infpStr := "Infinity"
infnStr := "-Infinity"
unmarshaler := NewAGUnmarshaler()
mapv, _ := unmarshaler.unmarshal(mapStr)
arrv, _ := unmarshaler.unmarshal(arrStr)
str2, _ := unmarshaler.unmarshal(strStr)
intv, _ := unmarshaler.unmarshal(intStr)
fl, _ := unmarshaler.unmarshal(floatStr)
fl2, _ := unmarshaler.unmarshal(floatStr2)
numeric1, _ := unmarshaler.unmarshal(numericStr1)
numeric2, _ := unmarshaler.unmarshal(numericStr2)
b, _ := unmarshaler.unmarshal(boolStr)
nullVal, _ := unmarshaler.unmarshal(nullStr)
nanVal, _ := unmarshaler.unmarshal(nanStr)
infpVal, _ := unmarshaler.unmarshal(infpStr)
infnVal, _ := unmarshaler.unmarshal(infnStr)
// fmt.Println("intv", intv.GType(), reflect.TypeOf(intv.(*SimpleEntity).Value()), intv)
assert.Equal(t, G_MAP, mapv.GType())
assert.Equal(t, G_ARR, arrv.GType())
assert.Equal(t, G_STR, str2.GType())
assert.Equal(t, G_INT, intv.GType())
assert.Equal(t, G_FLOAT, fl.GType())
assert.Equal(t, G_FLOAT, fl2.GType())
assert.Equal(t, G_FLOATBIG, numeric1.GType())
assert.Equal(t, G_INTBIG, numeric2.GType())
assert.Equal(t, G_BOOL, b.GType())
assert.Equal(t, G_NULL, nullVal.GType())
assert.Equal(t, G_FLOAT, nanVal.GType())
assert.Equal(t, G_FLOAT, infpVal.GType())
assert.Equal(t, G_FLOAT, infnVal.GType())
assert.Equal(t, map[string]interface{}{"name": "Smith", "num": int64(123), "yn": true}, mapv.(*SimpleEntity).Value())
assert.Equal(t, []interface{}{"name", "Smith", "num", int64(123), "yn", true}, arrv.(*SimpleEntity).Value())
assert.Equal(t, "abcd", str2.(*SimpleEntity).Value())
assert.Equal(t, int64(1234), intv.(*SimpleEntity).Value())
assert.Equal(t, 1234.56789, fl.(*SimpleEntity).Value())
assert.Equal(t, 6.45161290322581e+46, fl2.(*SimpleEntity).Value())
assert.Equal(t, true, b.(*SimpleEntity).Value())
assert.Equal(t, nil, nullVal.(*SimpleEntity).Value())
assert.True(t, math.IsNaN(nanVal.(*SimpleEntity).Value().(float64)))
assert.Equal(t, math.Inf(1), infpVal.(*SimpleEntity).Value())
assert.Equal(t, math.Inf(-1), infnVal.(*SimpleEntity).Value())
bf := new(big.Float)
bf, _ = bf.SetString("12345678901234567890123456.789")
assert.Equal(t, bf, numeric1.(*SimpleEntity).Value())
bi := new(big.Int)
bi, _ = bi.SetString("12345678901234567890123456", 10)
assert.Equal(t, bi, numeric2.(*SimpleEntity).Value())
}
func TestMap(t *testing.T) {
mapStr := `{"name": "Smith", "num":123, "yn":true, "arr":["A","B",1], "map":{"a":1, "b":"bv"}}`
unmarshaler := NewAGUnmarshaler()
mapv, _ := unmarshaler.unmarshal(mapStr)
assert.Equal(t, G_MAP, mapv.GType())
mapValue := mapv.(*SimpleEntity).Value().(map[string]interface{})
assert.Equal(t, "Smith", mapValue["name"])
assert.Equal(t, []interface{}{"A", "B", int64(1)}, mapValue["arr"])
assert.Equal(t, map[string]interface{}{"a": int64(1), "b": "bv"}, mapValue["map"])
}
func TestArray(t *testing.T) {
arrayStr := `[ "Smith", 123, true, ["A","B",1], {"a":1, "b":"bv"}]`
unmarshaler := NewAGUnmarshaler()
arrayv, _ := unmarshaler.unmarshal(arrayStr)
assert.Equal(t, G_ARR, arrayv.GType())
arrValue := arrayv.(*SimpleEntity).Value().([]interface{})
assert.Equal(t, "Smith", arrValue[0])
assert.Equal(t, []interface{}{"A", "B", int64(1)}, arrValue[3])
assert.Equal(t, map[string]interface{}{"a": int64(1), "b": "bv"}, arrValue[4])
}
age-PG18-v1.7.0-rc0/drivers/golang/age/errors.go 0000664 0000000 0000000 00000002461 15134225711 0021130 0 ustar 00root root 0000000 0000000 /*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package age
import (
"bytes"
"fmt"
)
type AgeError struct {
cause error
msg string
}
func (e *AgeError) Error() string {
if e.cause != nil {
return fmt.Sprintf("%s >> Cause:%s", e.msg, e.cause.Error())
}
return e.msg
}
type AgeParseError struct {
msg string
errors []string
}
func (e *AgeParseError) Error() string {
var buf bytes.Buffer
buf.WriteString(e.msg)
buf.WriteString(" >> Causes:\n")
for _, err := range e.errors {
buf.WriteString(err)
buf.WriteString("\n")
}
return buf.String()
}
age-PG18-v1.7.0-rc0/drivers/golang/age/mapper.go 0000664 0000000 0000000 00000011355 15134225711 0021102 0 ustar 00root root 0000000 0000000 /*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package age
import (
"fmt"
"reflect"
"strings"
"github.com/antlr/antlr4/runtime/Go/antlr/v4"
"github.com/apache/age/drivers/golang/parser"
)
type AGMapper struct {
AGUnmarshaler
}
func NewAGMapper(typeMap map[string]reflect.Type) *AGMapper {
vcache := make(map[int64]interface{})
if typeMap == nil {
typeMap = make(map[string]reflect.Type)
}
m := AGUnmarshaler{ageParser: parser.NewAgeParser(nil),
visitor: &MapperVisitor{UnmarshalVisitor: UnmarshalVisitor{vcache: vcache},
typeMap: typeMap},
errListener: NewAGErrorListener(),
vcache: vcache,
}
agm := &AGMapper{AGUnmarshaler: m}
agm.ageParser.AddErrorListener(agm.errListener)
return agm
}
func (m *AGMapper) PutType(label string, tp reflect.Type) {
m.visitor.(*MapperVisitor).PutType(label, tp)
}
type MapperVisitor struct {
UnmarshalVisitor
typeMap map[string]reflect.Type
}
func (v *MapperVisitor) PutType(label string, tp reflect.Type) {
v.typeMap[label] = tp
}
func (v *MapperVisitor) VisitAgeout(ctx *parser.AgeoutContext) interface{} {
rtn := v.VisitChildren(ctx)
return rtn
}
func (v *MapperVisitor) VisitChildren(node antlr.RuleNode) interface{} {
var rtn interface{}
for _, c := range node.GetChildren() {
pt := c.(antlr.ParseTree)
rtn = pt.Accept(v)
}
return rtn
}
func (v *MapperVisitor) VisitPath(ctx *parser.PathContext) interface{} {
entities := []interface{}{}
for _, child := range ctx.GetChildren() {
switch child.(type) {
case *parser.VertexContext:
v := child.(*parser.VertexContext).Accept(v)
// fmt.Println(v)
entities = append(entities, v)
case *parser.EdgeContext:
e := child.(*parser.EdgeContext).Accept(v)
// fmt.Println(e)
entities = append(entities, e)
default:
}
}
// vctxArr := ctx.AllVertex()
// start := vctxArr[0].Accept(v)
// rel := ctx.Edge().Accept(v)
// end := vctxArr[1].Accept(v)
// fmt.Println("VisitPath:", reflect.TypeOf(start), reflect.TypeOf(rel), reflect.TypeOf(rel))
path := NewMapPath(entities)
return path
}
func (v *MapperVisitor) VisitVertex(ctx *parser.VertexContext) interface{} {
propCtx := ctx.Properties()
props := propCtx.Accept(v).(map[string]interface{})
vid := int64(props["id"].(int64))
vertex, ok := v.vcache[vid]
var err error
if !ok {
vertex, err = v.mapVertex(vid, props["label"].(string), props["properties"].(map[string]interface{}))
if err != nil {
panic(err)
}
v.vcache[vid] = vertex
}
// fmt.Println(" * VisitVertex:", vertex)
return vertex
}
// Visit a parse tree produced by AgeParser#edge.
func (v *MapperVisitor) VisitEdge(ctx *parser.EdgeContext) interface{} {
propCtx := ctx.Properties()
props := propCtx.Accept(v).(map[string]interface{})
vid := props["id"].(int64)
edge, ok := v.vcache[vid]
var err error
if !ok {
edge, err = v.mapEdge(vid, props["label"].(string), props["start_id"].(int64), props["end_id"].(int64),
props["properties"].(map[string]interface{}))
if err != nil {
panic(err)
}
v.vcache[vid] = edge
}
return edge
}
func (v *MapperVisitor) mapVertex(vid int64, label string, properties map[string]interface{}) (interface{}, error) {
tp, ok := v.typeMap[label]
if !ok {
return NewVertex(vid, label, properties), nil
}
return mapStruct(tp, properties)
}
func (v *MapperVisitor) mapEdge(vid int64, label string, start int64, end int64, properties map[string]interface{}) (interface{}, error) {
tp, ok := v.typeMap[label]
if !ok {
return NewEdge(vid, label, start, end, properties), nil
}
return mapStruct(tp, properties)
}
func mapStruct(tp reflect.Type, properties map[string]interface{}) (interface{}, error) {
value := reflect.New(tp).Elem()
for k, v := range properties {
k = strings.Title(k)
f, ok := tp.FieldByName(k)
if ok {
field := value.FieldByIndex(f.Index)
val := reflect.ValueOf(v)
if field.Type().ConvertibleTo(val.Type()) {
field.Set(val)
} else {
return nil, fmt.Errorf("Property[%s] value[%v] type is not convertable to %v", k, v, field.Type())
}
}
}
return value.Interface(), nil
}
age-PG18-v1.7.0-rc0/drivers/golang/age/mapper_test.go 0000664 0000000 0000000 00000005466 15134225711 0022147 0 ustar 00root root 0000000 0000000 /*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package age
import (
"fmt"
"reflect"
"testing"
"github.com/stretchr/testify/assert"
)
type VPerson struct {
Name string
Age int64
Weight float64
}
type EWorkWith struct {
Weight int64
}
func TestPathMapping(t *testing.T) {
rstStr1 := `[{"id": 2251799813685425, "label": "Person", "properties": {"name": "Smith"}}::vertex,
{"id": 2533274790396576, "label": "workWith", "end_id": 2251799813685425, "start_id": 2251799813685424, "properties": {"weight": 3}}::edge,
{"id": 2251799813685424, "label": "Person", "properties": {"name": "Joe"}}::vertex]::path`
rstStr2 := `[{"id": 2251799813685424, "label": "Person", "properties": {"name": "Joe"}}::vertex,
{"id": 2533274790396576, "label": "workWith", "end_id": 2251799813685425, "start_id": 2251799813685424, "properties": {"weight": 3}}::edge,
{"id": 2251799813685425, "label": "Person", "properties": {"name": "Smith"}}::vertex]::path`
rstStr3 := `[{"id": 2251799813685424, "label": "Person", "properties": {"name": "Joe"}}::vertex,
{"id": 2533274790396579, "label": "workWith", "end_id": 2251799813685426, "start_id": 2251799813685424, "properties": {"weight": 5}}::edge,
{"id": 2251799813685426, "label": "Person", "properties": {"name": "Jack"}}::vertex]::path`
mapper := NewAGMapper(nil)
mapper.PutType("Person", reflect.TypeOf(VPerson{}))
mapper.PutType("workWith", reflect.TypeOf(EWorkWith{}))
entity1, _ := mapper.unmarshal(rstStr1)
entity2, _ := mapper.unmarshal(rstStr2)
entity3, _ := mapper.unmarshal(rstStr3)
fmt.Println(" **** ", entity1)
fmt.Println(" **** ", entity2)
fmt.Println(" **** ", entity3)
assert.Equal(t, entity1.GType(), entity2.GType(), "Type Check")
p1 := entity1.(*MapPath)
p2 := entity2.(*MapPath)
p3 := entity3.(*MapPath)
assert.Equal(t, p1.Get(2).(VPerson).Name, p2.Get(0).(VPerson).Name)
assert.Equal(t, p2.Get(0).(VPerson).Name, p3.Get(0).(VPerson).Name)
assert.Equal(t, p1.Get(1).(EWorkWith).Weight, int64(3))
assert.Equal(t, p2.Get(1).(EWorkWith).Weight, int64(3))
assert.Equal(t, p3.Get(1).(EWorkWith).Weight, int64(5))
}
age-PG18-v1.7.0-rc0/drivers/golang/age/models.go 0000664 0000000 0000000 00000015151 15134225711 0021077 0 ustar 00root root 0000000 0000000 /*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package age
import (
"bytes"
"fmt"
"math/big"
"reflect"
)
// GTYPE representing entity types for AGE result data : Vertex, Edge, Path and SimpleEntity
type GTYPE uint8
const (
G_OTHER GTYPE = 1 + iota
G_VERTEX
G_EDGE
G_PATH
G_MAP_PATH
G_STR
G_INT
G_INTBIG
G_FLOAT
G_FLOATBIG
G_BOOL
G_NULL
G_MAP
G_ARR
)
var _TpV = reflect.TypeOf(&Vertex{})
var _TpE = reflect.TypeOf(&Edge{})
var _TpP = reflect.TypeOf(&Path{})
var _TpMP = reflect.TypeOf(&MapPath{})
var _TpStr = reflect.TypeOf(string(""))
var _TpInt = reflect.TypeOf(int64(0))
var _TpIntBig = reflect.TypeOf(big.NewInt(0))
var _TpFloat = reflect.TypeOf(float64(0))
var _TpFloatBig = reflect.TypeOf(big.NewFloat(0))
var _TpBool = reflect.TypeOf(bool(false))
var _TpMap = reflect.TypeOf(map[string]interface{}{})
var _TpArr = reflect.TypeOf([]interface{}{})
// Entity object interface for parsed AGE result data : Vertex, Edge, Path and SimpleEntity
type Entity interface {
GType() GTYPE
String() string
}
func IsEntity(v interface{}) bool {
_, ok := v.(Entity)
return ok
}
type SimpleEntity struct {
Entity
typ GTYPE
value interface{}
}
func NewSimpleEntity(value interface{}) *SimpleEntity {
if value == nil {
return &SimpleEntity{typ: G_NULL, value: nil}
}
switch value.(type) {
case string:
return &SimpleEntity{typ: G_STR, value: value}
case int64:
return &SimpleEntity{typ: G_INT, value: value}
case *big.Int:
return &SimpleEntity{typ: G_INTBIG, value: value}
case float64:
return &SimpleEntity{typ: G_FLOAT, value: value}
case *big.Float:
return &SimpleEntity{typ: G_FLOATBIG, value: value}
case bool:
return &SimpleEntity{typ: G_BOOL, value: value}
case map[string]interface{}:
return &SimpleEntity{typ: G_MAP, value: value}
case []interface{}:
return &SimpleEntity{typ: G_ARR, value: value}
default:
return &SimpleEntity{typ: G_OTHER, value: value}
}
}
func (e *SimpleEntity) GType() GTYPE {
return e.typ
}
func (e *SimpleEntity) IsNull() bool {
return e.value == nil
}
func (e *SimpleEntity) Value() interface{} {
return e.value
}
func (e *SimpleEntity) String() string {
return fmt.Sprintf("%v", e.value)
}
func (e *SimpleEntity) AsStr() string {
return e.value.(string)
}
func (e *SimpleEntity) AsInt() int {
return e.value.(int)
}
func (e *SimpleEntity) AsInt64() int64 {
return e.value.(int64)
}
func (e *SimpleEntity) AsBigInt() *big.Int {
return e.value.(*big.Int)
}
func (e *SimpleEntity) AsFloat() float64 {
return e.value.(float64)
}
func (e *SimpleEntity) AsBigFloat() *big.Float {
return e.value.(*big.Float)
}
func (e *SimpleEntity) AsBool() bool {
return e.value.(bool)
}
func (e *SimpleEntity) AsMap() map[string]interface{} {
return e.value.(map[string]interface{})
}
func (e *SimpleEntity) AsArr() []interface{} {
return e.value.([]interface{})
}
type LabeledEntity struct {
Entity
id int64
label string
props map[string]interface{}
}
func newLabeledEntity(id int64, label string, props map[string]interface{}) *LabeledEntity {
return &LabeledEntity{id: id, label: label, props: props}
}
func (n *LabeledEntity) Id() int64 {
return n.id
}
func (n *LabeledEntity) Label() string {
return n.label
}
func (n *LabeledEntity) Prop(key string) interface{} {
return n.props[key]
}
// return properties
func (n *LabeledEntity) Props() map[string]interface{} {
return n.props
}
type Vertex struct {
*LabeledEntity
}
func NewVertex(id int64, label string, props map[string]interface{}) *Vertex {
return &Vertex{newLabeledEntity(id, label, props)}
}
func (v *Vertex) GType() GTYPE {
return G_VERTEX
}
func (v *Vertex) String() string {
return fmt.Sprintf("V{id:%d, label:%s, props:%v}", v.id, v.label, v.props)
}
type Edge struct {
*LabeledEntity
start_id int64
end_id int64
}
func NewEdge(id int64, label string, start int64, end int64, props map[string]interface{}) *Edge {
return &Edge{LabeledEntity: newLabeledEntity(id, label, props), start_id: start, end_id: end}
}
func (e *Edge) GType() GTYPE {
return G_EDGE
}
func (e *Edge) StartId() int64 {
return e.start_id
}
func (e *Edge) EndId() int64 {
return e.end_id
}
func (e *Edge) String() string {
return fmt.Sprintf("E{id:%d, label:%s, start:%d, end:%d, props:%v}",
e.id, e.label, e.start_id, e.end_id, e.props)
}
type Path struct {
Entity
entities []Entity
}
func NewPath(entities []Entity) *Path {
return &Path{entities: entities}
}
func (e *Path) GType() GTYPE {
return G_PATH
}
func (e *Path) Size() int {
return len(e.entities)
}
func (e *Path) Get(index int) Entity {
if index < 0 && index >= len(e.entities) {
panic(fmt.Errorf("Entity index[%d] is out of range (%d) ", index, len(e.entities)))
}
return e.entities[index]
}
func (e *Path) GetAsVertex(index int) *Vertex {
v := e.Get(index)
if v.GType() != G_VERTEX {
panic(fmt.Errorf("Entity[%d] is not Vertex", index))
}
return v.(*Vertex)
}
func (e *Path) GetAsEdge(index int) *Edge {
v := e.Get(index)
if v.GType() != G_EDGE {
panic(fmt.Errorf("Entity[%d] is not Edge", index))
}
return v.(*Edge)
}
func (p *Path) String() string {
var buf bytes.Buffer
buf.WriteString("P[")
for _, e := range p.entities {
buf.WriteString(e.String())
buf.WriteString(",")
}
buf.WriteString("]")
return buf.String()
}
type MapPath struct {
Entity
entities []interface{}
}
func NewMapPath(entities []interface{}) *MapPath {
return &MapPath{entities: entities}
}
func (e *MapPath) GType() GTYPE {
return G_MAP_PATH
}
func (e *MapPath) Size() int {
return len(e.entities)
}
func (e *MapPath) Get(index int) interface{} {
if index < 0 && index >= len(e.entities) {
panic(fmt.Errorf("Entity index[%d] is out of range (%d) ", index, len(e.entities)))
}
return e.entities[index]
}
func (p *MapPath) String() string {
var buf bytes.Buffer
buf.WriteString("P[")
for _, e := range p.entities {
buf.WriteString(fmt.Sprintf("%v", e))
buf.WriteString(",")
}
buf.WriteString("]")
return buf.String()
}
age-PG18-v1.7.0-rc0/drivers/golang/go.mod 0000664 0000000 0000000 00000002402 15134225711 0017632 0 ustar 00root root 0000000 0000000 // /*
// * Licensed to the Apache Software Foundation (ASF) under one
// * or more contributor license agreements. See the NOTICE file
// * distributed with this work for additional information
// * regarding copyright ownership. The ASF licenses this file
// * to you under the Apache License, Version 2.0 (the
// * "License"); you may not use this file except in compliance
// * with the License. You may obtain a copy of the License at
// *
// * http://www.apache.org/licenses/LICENSE-2.0
// *
// * Unless required by applicable law or agreed to in writing,
// * software distributed under the License is distributed on an
// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// * KIND, either express or implied. See the License for the
// * specific language governing permissions and limitations
// * under the License.
// */
module github.com/apache/age/drivers/golang
go 1.19
require (
github.com/antlr/antlr4/runtime/Go/antlr/v4 v4.0.0-20230321174746-8dcc6526cfb1
github.com/lib/pq v1.10.9
github.com/stretchr/testify v1.7.0
)
require (
github.com/davecgh/go-spew v1.1.0 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
golang.org/x/exp v0.0.0-20240205201215-2c58cdc269a3 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
age-PG18-v1.7.0-rc0/drivers/golang/go.sum 0000664 0000000 0000000 00000003242 15134225711 0017662 0 ustar 00root root 0000000 0000000 github.com/antlr/antlr4/runtime/Go/antlr/v4 v4.0.0-20230321174746-8dcc6526cfb1 h1:X8MJ0fnN5FPdcGF5Ij2/OW+HgiJrRg3AfHAx1PJtIzM=
github.com/antlr/antlr4/runtime/Go/antlr/v4 v4.0.0-20230321174746-8dcc6526cfb1/go.mod h1:pSwJ0fSY5KhvocuWSx4fz3BA8OrA1bQn+K1Eli3BRwM=
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw=
github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
golang.org/x/exp v0.0.0-20240205201215-2c58cdc269a3 h1:/RIbNt/Zr7rVhIkQhooTxCxFcdWLGIKnZA4IXNFSrvo=
golang.org/x/exp v0.0.0-20240205201215-2c58cdc269a3/go.mod h1:idGWGoKP1toJGkd5/ig9ZLuPcZBC3ewk7SzmH0uou08=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
age-PG18-v1.7.0-rc0/drivers/golang/install.bat 0000664 0000000 0000000 00000006430 15134225711 0020667 0 ustar 00root root 0000000 0000000 @echo off
rem Install Java Development Kit (JDK)
echo Installing JDK...
if not exist "%ProgramFiles%\Java\jdk-19\" (
mkdir C:\temp
cd C:\temp
powershell Invoke-WebRequest -Uri "https://download.oracle.com/java/19/archive/jdk-19.0.2_windows-x64_bin.exe" -OutFile jdk-19.0.2_windows-x64_bin.exe
start /wait jdk-19.0.2_windows-x64_bin.exe /s ADDLOCAL="ToolsFeature" /s
del /f jdk-19.0.2_windows-x64_bin.exe
setx /M JAVA_HOME "C:\Program Files\Java\jdk-19.0.2"
setx /M PATH "%PATH%;%JAVA_HOME%\bin"
) else (
echo JDK already installed.
)
rem Install Apache Maven
echo Installing Apache Maven...
if not exist "%ProgramFiles%\Apache Maven\apache-maven-3.9.0\" (
mkdir C:\temp
cd C:\temp
powershell Invoke-WebRequest -Uri "https://dlcdn.apache.org/maven/maven-3/3.9.0/binaries/apache-maven-3.9.0-bin.zip" -OutFile apache-maven-3.9.0-bin.zip
powershell Expand-Archive apache-maven-3.9.0-bin.zip -DestinationPath \"%ProgramFiles%\Apache Maven\"
del /f apache-maven-3.9.0-bin.zip
setx /M PATH "%PATH%;%ProgramFiles%\Apache Maven\apache-maven-3.9.0-bin\bin"
) else (
echo Apache Maven already installed.
)
rem Download and install ANTLR
echo Downloading ANTLR...
if not exist "%ProgramFiles%\ANTLR" (
mkdir "%ProgramFiles%\ANTLR"
cd "%ProgramFiles%\ANTLR"
powershell Invoke-WebRequest -Uri "https://www.antlr.org/download/antlr-4.11.1-complete.jar" -OutFile "antlr-4.11.1-complete.jar"
setx /M PATH "%PATH%;%ProgramFiles%\ANTLR\"
setx /M CLASSPATH ".;%ProgramFiles%\ANTLR\antlr-4.11.1-complete.jar;%CLASSPATH%"
)
echo ANTLR installation complete.
rem Checking Compatibility for Golang
echo Checking if current version of Golang >= Go 1.18.....
set "minimum_version=1.18"
set "installed_version="
set "download_url=https://go.dev/dl/go1.19.7.windows-amd64.msi"
:: Check if Go is installed and get its version
set "go_path="
for %%i in (go.exe) do set "go_path=%%~$PATH:i"
if defined go_path (
for /f "tokens=3" %%v in ('go version 2^>^&1') do set "installed_version=%%v"
)
:: If Go is not installed or the version is less than 1.18, prompt the user to install a new version
if not defined installed_version (
echo installing Go
:: Download and install the latest version of Go
powershell -Command "& {Invoke-WebRequest -Uri "%download_url%" -OutFile '%TEMP%\go-minimum-version.msi'}"
start /wait msiexec /i "%TEMP%\go-minimum-version.msi"
for /f "tokens=3" %%v in ('go version 2^>^&1') do set "installed_version=%%v"
) else if "%installed_version%" lss "%minimum_version%" (
set /p "install_new_version=Go version %minimum_version% or higher is required. Would you like to install the latest version? (y/n)"
if /i "%install_new_version%"=="y" (
:: Download and install the latest version of Go
powershell -Command "& {Invoke-WebRequest -Uri "%download_url%" -OutFile '%TEMP%\go-minimum-version.msi'}"
start /wait msiexec /i "%TEMP%\go-minimum_version.msi"
for /f "tokens=3" %%v in ('go version 2^>^&1') do set "installed_version=%%v"
) else (
echo Please update Go version before installing driver.
goto skip
)
)
rem Installing Driver
echo --^> Generating ANTLR parser ^& lexer ^for Golang%
java org.antlr.v4.Tool -Dlanguage=Go -visitor Age.g4 -o parser/
echo --^> Installing Driver
go get -u ./...
goto end
:skip
echo Aborted
:end
pause
endlocal age-PG18-v1.7.0-rc0/drivers/golang/install.sh 0000775 0000000 0000000 00000006407 15134225711 0020542 0 ustar 00root root 0000000 0000000 #!/bin/sh
# get OS
os=$(uname)
# get architecture
arch=$(uname -m)
# Check Java installation
echo "Checking for minimum Java installation..."
java_version=$(java -version 2>&1 | awk -F '"' '/version/ {print $2}')
if [ ! -z $java_version ]; then
echo "Java version $java_version"
else
echo "Java not found. Please install Java."
fi
# Get Java version
java_major=$(echo $java_version | cut -d '.' -f1)
java_minor=$(echo $java_version | cut -d '.' -f2)
java_patch=$(echo $java_version | cut -d '.' -f3)
# Check Java version
java_version_flag=0
if [ $java_major -lt 11 ]; then
java_version_flag=0
elif [ $java_minor -lt 0 ]; then
java_version_flag=0
elif [ $java_patch -lt 0 ]; then
java_version_flag=0
else
java_version_flag=1
fi
if [ $java_version_flag -eq 0 ]; then
echo "Java version less than 11.0.0"
echo "NOTE: If a newer version of Java is installed, but not set as "
echo " the current version, exit and select it before continuing."
exit 0
else
echo "Java is installed."
echo ""
fi
# Check ANTLR installation
echo "Checking for minimum ANTLR installation..."
jar xf /usr/local/antlr/antlr-*-complete.jar META-INF/MANIFEST.MF >/dev/null 2>&1
antlr_version=$(grep 'Implementation-Version' META-INF/MANIFEST.MF | cut -d ' ' -f 2)
rm -rf META-INF
if [ ! -z $antlr_version ]; then
echo "ANTLR version $antlr_version"
else
echo "ANTLR not found. Please install ANTLR."
exit 0
fi
# Check ANTLR version
antlr_version_flag=0
antlr_major=$(echo $antlr_version | cut -d '.' -f 1)
antlr_minor=$(echo $antlr_version | cut -d '.' -f 2)
antlr_patch=$(echo $antlr_version | cut -d '.' -f 3 | sed 's/\r//')
if [ $antlr_major -lt 4 ]; then
antlr_version_flag=0
elif [ $antlr_minor -lt 11 ]; then
antlr_version_flag=0
elif [ $antlr_patch -lt 1 ]; then
antlr_version_flag=0
else
antlr_version_flag=1
fi
if [ $antlr_version_flag -eq 0 ]; then
echo "ANTLR version less than 4.11.1"
exit 0
else
echo "ANTLR is installed."
echo ""
fi
# Check Go installation
echo "Checking for minimum Golang installation..."
go_version=$(go version 2>&1 | cut -d' ' -f3)
if [ ! -z $go_version ]; then
echo "Golang version $go_version"
else
echo "Golang not found. Please install Golang."
exit 0
fi
# Check Go version
go_version_flag=0
go_major=$(echo $go_version | cut -d '.' -f1 | cut -d 'o' -f 2)
go_minor=$(echo $go_version | cut -d '.' -f2)
go_patch=$(echo $go_version | cut -d '.' -f3)
if [ $go_major -lt 1 ]; then
go_version_flag=0
elif [ $go_minor -lt 18 ]; then
go_version_flag=0
elif [ $go_patch -lt 0 ]; then
go_version_flag=0
else
go_version_flag=1
fi
if [ $go_version_flag -eq 0 ]; then
echo "Golang version less than 1.19.0"
exit 0
else
echo "Golang is installed."
echo ""
fi
# Check CLASSPATH
echo "Checking for ANTLR in CLASSPATH..."
test_classpath=$(echo $CLASSPATH | grep antlr)
if [ ! -z $test_classpath ]; then
echo "CLASSPATH = $CLASSPATH"
echo ""
else
echo "ANTLR not set in CLASSPATH. Please set up CLASSPATH."
exit 0
fi
# Generate Parser and Lexer
echo "Generating Parser & Lexer..."
java -Xmx500M org.antlr.v4.Tool -Dlanguage=Go -visitor parser/Age.g4
# Install Golang driver
echo "Installing Driver..."
go get -u ./...
echo "Successfully Installed Driver!"
exit 0
age-PG18-v1.7.0-rc0/drivers/golang/parser/ 0000775 0000000 0000000 00000000000 15134225711 0020022 5 ustar 00root root 0000000 0000000 age-PG18-v1.7.0-rc0/drivers/golang/parser/Age.g4 0000664 0000000 0000000 00000004221 15134225711 0020751 0 ustar 00root root 0000000 0000000 /*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
/* Apache AGE output data grammar */
grammar Age;
ageout
: value
| vertex
| edge
| path
;
vertex
: properties KW_VERTEX
;
edge
: properties KW_EDGE
;
path
: '[' vertex (',' edge ',' vertex)* ']' KW_PATH
;
//Keywords
KW_VERTEX : '::vertex';
KW_EDGE : '::edge';
KW_PATH : '::path';
KW_NUMERIC : '::numeric';
// Common Values Rule
value
: STRING
| NUMBER
| NUMERIC
| FLOAT_EXPR
| BOOL
| NULL
| properties
| arr
;
properties
: '{' pair (',' pair)* '}'
| '{' '}'
;
pair
: STRING ':' value
;
arr
: '[' value (',' value)* ']'
| '[' ']'
;
STRING
: '"' (ESC | SAFECODEPOINT)* '"'
;
BOOL
: 'true'|'false'
;
NULL
: 'null'
;
fragment ESC
: '\\' (["\\/bfnrt] | UNICODE)
;
fragment UNICODE
: 'u' HEX HEX HEX HEX
;
fragment HEX
: [0-9a-fA-F]
;
fragment SAFECODEPOINT
: ~ ["\\\u0000-\u001F]
;
NUMBER
: '-'? INT ('.' [0-9] +)? EXP?
;
FLOAT_EXPR
: 'NaN' | '-Infinity' | 'Infinity'
;
NUMERIC
: '-'? INT ('.' [0-9] +)? EXP? KW_NUMERIC
;
fragment INT
: '0' | [1-9] [0-9]*
;
// no leading zeros
fragment EXP
: [Ee] [+\-]? INT
;
// \- since - means "range" inside [...]
WS
: [ \t\n\r] + -> skip
;
age-PG18-v1.7.0-rc0/drivers/golang/parser/age_base_listener.go 0000664 0000000 0000000 00000005173 15134225711 0024012 0 ustar 00root root 0000000 0000000 // Code generated from java-escape by ANTLR 4.11.1. DO NOT EDIT.
package parser // Age
import "github.com/antlr/antlr4/runtime/Go/antlr/v4"
// BaseAgeListener is a complete listener for a parse tree produced by AgeParser.
type BaseAgeListener struct{}
var _ AgeListener = &BaseAgeListener{}
// VisitTerminal is called when a terminal node is visited.
func (s *BaseAgeListener) VisitTerminal(node antlr.TerminalNode) {}
// VisitErrorNode is called when an error node is visited.
func (s *BaseAgeListener) VisitErrorNode(node antlr.ErrorNode) {}
// EnterEveryRule is called when any rule is entered.
func (s *BaseAgeListener) EnterEveryRule(ctx antlr.ParserRuleContext) {}
// ExitEveryRule is called when any rule is exited.
func (s *BaseAgeListener) ExitEveryRule(ctx antlr.ParserRuleContext) {}
// EnterAgeout is called when production ageout is entered.
func (s *BaseAgeListener) EnterAgeout(ctx *AgeoutContext) {}
// ExitAgeout is called when production ageout is exited.
func (s *BaseAgeListener) ExitAgeout(ctx *AgeoutContext) {}
// EnterVertex is called when production vertex is entered.
func (s *BaseAgeListener) EnterVertex(ctx *VertexContext) {}
// ExitVertex is called when production vertex is exited.
func (s *BaseAgeListener) ExitVertex(ctx *VertexContext) {}
// EnterEdge is called when production edge is entered.
func (s *BaseAgeListener) EnterEdge(ctx *EdgeContext) {}
// ExitEdge is called when production edge is exited.
func (s *BaseAgeListener) ExitEdge(ctx *EdgeContext) {}
// EnterPath is called when production path is entered.
func (s *BaseAgeListener) EnterPath(ctx *PathContext) {}
// ExitPath is called when production path is exited.
func (s *BaseAgeListener) ExitPath(ctx *PathContext) {}
// EnterValue is called when production value is entered.
func (s *BaseAgeListener) EnterValue(ctx *ValueContext) {}
// ExitValue is called when production value is exited.
func (s *BaseAgeListener) ExitValue(ctx *ValueContext) {}
// EnterProperties is called when production properties is entered.
func (s *BaseAgeListener) EnterProperties(ctx *PropertiesContext) {}
// ExitProperties is called when production properties is exited.
func (s *BaseAgeListener) ExitProperties(ctx *PropertiesContext) {}
// EnterPair is called when production pair is entered.
func (s *BaseAgeListener) EnterPair(ctx *PairContext) {}
// ExitPair is called when production pair is exited.
func (s *BaseAgeListener) ExitPair(ctx *PairContext) {}
// EnterArr is called when production arr is entered.
func (s *BaseAgeListener) EnterArr(ctx *ArrContext) {}
// ExitArr is called when production arr is exited.
func (s *BaseAgeListener) ExitArr(ctx *ArrContext) {}
age-PG18-v1.7.0-rc0/drivers/golang/parser/age_base_visitor.go 0000664 0000000 0000000 00000001767 15134225711 0023671 0 ustar 00root root 0000000 0000000 // Code generated from java-escape by ANTLR 4.11.1. DO NOT EDIT.
package parser // Age
import "github.com/antlr/antlr4/runtime/Go/antlr/v4"
type BaseAgeVisitor struct {
*antlr.BaseParseTreeVisitor
}
func (v *BaseAgeVisitor) VisitAgeout(ctx *AgeoutContext) interface{} {
return v.VisitChildren(ctx)
}
func (v *BaseAgeVisitor) VisitVertex(ctx *VertexContext) interface{} {
return v.VisitChildren(ctx)
}
func (v *BaseAgeVisitor) VisitEdge(ctx *EdgeContext) interface{} {
return v.VisitChildren(ctx)
}
func (v *BaseAgeVisitor) VisitPath(ctx *PathContext) interface{} {
return v.VisitChildren(ctx)
}
func (v *BaseAgeVisitor) VisitValue(ctx *ValueContext) interface{} {
return v.VisitChildren(ctx)
}
func (v *BaseAgeVisitor) VisitProperties(ctx *PropertiesContext) interface{} {
return v.VisitChildren(ctx)
}
func (v *BaseAgeVisitor) VisitPair(ctx *PairContext) interface{} {
return v.VisitChildren(ctx)
}
func (v *BaseAgeVisitor) VisitArr(ctx *ArrContext) interface{} {
return v.VisitChildren(ctx)
}
age-PG18-v1.7.0-rc0/drivers/golang/parser/age_lexer.go 0000664 0000000 0000000 00000024546 15134225711 0022317 0 ustar 00root root 0000000 0000000 // Code generated from java-escape by ANTLR 4.11.1. DO NOT EDIT.
package parser
import (
"fmt"
"sync"
"unicode"
"github.com/antlr/antlr4/runtime/Go/antlr/v4"
)
// Suppress unused import error
var _ = fmt.Printf
var _ = sync.Once{}
var _ = unicode.IsLetter
type AgeLexer struct {
*antlr.BaseLexer
channelNames []string
modeNames []string
// TODO: EOF string
}
var agelexerLexerStaticData struct {
once sync.Once
serializedATN []int32
channelNames []string
modeNames []string
literalNames []string
symbolicNames []string
ruleNames []string
predictionContextCache *antlr.PredictionContextCache
atn *antlr.ATN
decisionToDFA []*antlr.DFA
}
func agelexerLexerInit() {
staticData := &agelexerLexerStaticData
staticData.channelNames = []string{
"DEFAULT_TOKEN_CHANNEL", "HIDDEN",
}
staticData.modeNames = []string{
"DEFAULT_MODE",
}
staticData.literalNames = []string{
"", "'['", "','", "']'", "'{'", "'}'", "':'", "'::vertex'", "'::edge'",
"'::path'", "'::numeric'", "", "", "'null'",
}
staticData.symbolicNames = []string{
"", "", "", "", "", "", "", "KW_VERTEX", "KW_EDGE", "KW_PATH", "KW_NUMERIC",
"STRING", "BOOL", "NULL", "NUMBER", "FLOAT_EXPR", "NUMERIC", "WS",
}
staticData.ruleNames = []string{
"T__0", "T__1", "T__2", "T__3", "T__4", "T__5", "KW_VERTEX", "KW_EDGE",
"KW_PATH", "KW_NUMERIC", "STRING", "BOOL", "NULL", "ESC", "UNICODE",
"HEX", "SAFECODEPOINT", "NUMBER", "FLOAT_EXPR", "NUMERIC", "INT", "EXP",
"WS",
}
staticData.predictionContextCache = antlr.NewPredictionContextCache()
staticData.serializedATN = []int32{
4, 0, 17, 210, 6, -1, 2, 0, 7, 0, 2, 1, 7, 1, 2, 2, 7, 2, 2, 3, 7, 3, 2,
4, 7, 4, 2, 5, 7, 5, 2, 6, 7, 6, 2, 7, 7, 7, 2, 8, 7, 8, 2, 9, 7, 9, 2,
10, 7, 10, 2, 11, 7, 11, 2, 12, 7, 12, 2, 13, 7, 13, 2, 14, 7, 14, 2, 15,
7, 15, 2, 16, 7, 16, 2, 17, 7, 17, 2, 18, 7, 18, 2, 19, 7, 19, 2, 20, 7,
20, 2, 21, 7, 21, 2, 22, 7, 22, 1, 0, 1, 0, 1, 1, 1, 1, 1, 2, 1, 2, 1,
3, 1, 3, 1, 4, 1, 4, 1, 5, 1, 5, 1, 6, 1, 6, 1, 6, 1, 6, 1, 6, 1, 6, 1,
6, 1, 6, 1, 6, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 8, 1, 8, 1,
8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 9, 1, 9, 1, 9, 1, 9, 1, 9, 1, 9, 1, 9, 1,
9, 1, 9, 1, 9, 1, 10, 1, 10, 1, 10, 5, 10, 96, 8, 10, 10, 10, 12, 10, 99,
9, 10, 1, 10, 1, 10, 1, 11, 1, 11, 1, 11, 1, 11, 1, 11, 1, 11, 1, 11, 1,
11, 1, 11, 3, 11, 112, 8, 11, 1, 12, 1, 12, 1, 12, 1, 12, 1, 12, 1, 13,
1, 13, 1, 13, 3, 13, 122, 8, 13, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 1,
14, 1, 15, 1, 15, 1, 16, 1, 16, 1, 17, 3, 17, 135, 8, 17, 1, 17, 1, 17,
1, 17, 4, 17, 140, 8, 17, 11, 17, 12, 17, 141, 3, 17, 144, 8, 17, 1, 17,
3, 17, 147, 8, 17, 1, 18, 1, 18, 1, 18, 1, 18, 1, 18, 1, 18, 1, 18, 1,
18, 1, 18, 1, 18, 1, 18, 1, 18, 1, 18, 1, 18, 1, 18, 1, 18, 1, 18, 1, 18,
1, 18, 1, 18, 3, 18, 169, 8, 18, 1, 19, 3, 19, 172, 8, 19, 1, 19, 1, 19,
1, 19, 4, 19, 177, 8, 19, 11, 19, 12, 19, 178, 3, 19, 181, 8, 19, 1, 19,
3, 19, 184, 8, 19, 1, 19, 1, 19, 1, 20, 1, 20, 1, 20, 5, 20, 191, 8, 20,
10, 20, 12, 20, 194, 9, 20, 3, 20, 196, 8, 20, 1, 21, 1, 21, 3, 21, 200,
8, 21, 1, 21, 1, 21, 1, 22, 4, 22, 205, 8, 22, 11, 22, 12, 22, 206, 1,
22, 1, 22, 0, 0, 23, 1, 1, 3, 2, 5, 3, 7, 4, 9, 5, 11, 6, 13, 7, 15, 8,
17, 9, 19, 10, 21, 11, 23, 12, 25, 13, 27, 0, 29, 0, 31, 0, 33, 0, 35,
14, 37, 15, 39, 16, 41, 0, 43, 0, 45, 17, 1, 0, 8, 8, 0, 34, 34, 47, 47,
92, 92, 98, 98, 102, 102, 110, 110, 114, 114, 116, 116, 3, 0, 48, 57, 65,
70, 97, 102, 3, 0, 0, 31, 34, 34, 92, 92, 1, 0, 48, 57, 1, 0, 49, 57, 2,
0, 69, 69, 101, 101, 2, 0, 43, 43, 45, 45, 3, 0, 9, 10, 13, 13, 32, 32,
221, 0, 1, 1, 0, 0, 0, 0, 3, 1, 0, 0, 0, 0, 5, 1, 0, 0, 0, 0, 7, 1, 0,
0, 0, 0, 9, 1, 0, 0, 0, 0, 11, 1, 0, 0, 0, 0, 13, 1, 0, 0, 0, 0, 15, 1,
0, 0, 0, 0, 17, 1, 0, 0, 0, 0, 19, 1, 0, 0, 0, 0, 21, 1, 0, 0, 0, 0, 23,
1, 0, 0, 0, 0, 25, 1, 0, 0, 0, 0, 35, 1, 0, 0, 0, 0, 37, 1, 0, 0, 0, 0,
39, 1, 0, 0, 0, 0, 45, 1, 0, 0, 0, 1, 47, 1, 0, 0, 0, 3, 49, 1, 0, 0, 0,
5, 51, 1, 0, 0, 0, 7, 53, 1, 0, 0, 0, 9, 55, 1, 0, 0, 0, 11, 57, 1, 0,
0, 0, 13, 59, 1, 0, 0, 0, 15, 68, 1, 0, 0, 0, 17, 75, 1, 0, 0, 0, 19, 82,
1, 0, 0, 0, 21, 92, 1, 0, 0, 0, 23, 111, 1, 0, 0, 0, 25, 113, 1, 0, 0,
0, 27, 118, 1, 0, 0, 0, 29, 123, 1, 0, 0, 0, 31, 129, 1, 0, 0, 0, 33, 131,
1, 0, 0, 0, 35, 134, 1, 0, 0, 0, 37, 168, 1, 0, 0, 0, 39, 171, 1, 0, 0,
0, 41, 195, 1, 0, 0, 0, 43, 197, 1, 0, 0, 0, 45, 204, 1, 0, 0, 0, 47, 48,
5, 91, 0, 0, 48, 2, 1, 0, 0, 0, 49, 50, 5, 44, 0, 0, 50, 4, 1, 0, 0, 0,
51, 52, 5, 93, 0, 0, 52, 6, 1, 0, 0, 0, 53, 54, 5, 123, 0, 0, 54, 8, 1,
0, 0, 0, 55, 56, 5, 125, 0, 0, 56, 10, 1, 0, 0, 0, 57, 58, 5, 58, 0, 0,
58, 12, 1, 0, 0, 0, 59, 60, 5, 58, 0, 0, 60, 61, 5, 58, 0, 0, 61, 62, 5,
118, 0, 0, 62, 63, 5, 101, 0, 0, 63, 64, 5, 114, 0, 0, 64, 65, 5, 116,
0, 0, 65, 66, 5, 101, 0, 0, 66, 67, 5, 120, 0, 0, 67, 14, 1, 0, 0, 0, 68,
69, 5, 58, 0, 0, 69, 70, 5, 58, 0, 0, 70, 71, 5, 101, 0, 0, 71, 72, 5,
100, 0, 0, 72, 73, 5, 103, 0, 0, 73, 74, 5, 101, 0, 0, 74, 16, 1, 0, 0,
0, 75, 76, 5, 58, 0, 0, 76, 77, 5, 58, 0, 0, 77, 78, 5, 112, 0, 0, 78,
79, 5, 97, 0, 0, 79, 80, 5, 116, 0, 0, 80, 81, 5, 104, 0, 0, 81, 18, 1,
0, 0, 0, 82, 83, 5, 58, 0, 0, 83, 84, 5, 58, 0, 0, 84, 85, 5, 110, 0, 0,
85, 86, 5, 117, 0, 0, 86, 87, 5, 109, 0, 0, 87, 88, 5, 101, 0, 0, 88, 89,
5, 114, 0, 0, 89, 90, 5, 105, 0, 0, 90, 91, 5, 99, 0, 0, 91, 20, 1, 0,
0, 0, 92, 97, 5, 34, 0, 0, 93, 96, 3, 27, 13, 0, 94, 96, 3, 33, 16, 0,
95, 93, 1, 0, 0, 0, 95, 94, 1, 0, 0, 0, 96, 99, 1, 0, 0, 0, 97, 95, 1,
0, 0, 0, 97, 98, 1, 0, 0, 0, 98, 100, 1, 0, 0, 0, 99, 97, 1, 0, 0, 0, 100,
101, 5, 34, 0, 0, 101, 22, 1, 0, 0, 0, 102, 103, 5, 116, 0, 0, 103, 104,
5, 114, 0, 0, 104, 105, 5, 117, 0, 0, 105, 112, 5, 101, 0, 0, 106, 107,
5, 102, 0, 0, 107, 108, 5, 97, 0, 0, 108, 109, 5, 108, 0, 0, 109, 110,
5, 115, 0, 0, 110, 112, 5, 101, 0, 0, 111, 102, 1, 0, 0, 0, 111, 106, 1,
0, 0, 0, 112, 24, 1, 0, 0, 0, 113, 114, 5, 110, 0, 0, 114, 115, 5, 117,
0, 0, 115, 116, 5, 108, 0, 0, 116, 117, 5, 108, 0, 0, 117, 26, 1, 0, 0,
0, 118, 121, 5, 92, 0, 0, 119, 122, 7, 0, 0, 0, 120, 122, 3, 29, 14, 0,
121, 119, 1, 0, 0, 0, 121, 120, 1, 0, 0, 0, 122, 28, 1, 0, 0, 0, 123, 124,
5, 117, 0, 0, 124, 125, 3, 31, 15, 0, 125, 126, 3, 31, 15, 0, 126, 127,
3, 31, 15, 0, 127, 128, 3, 31, 15, 0, 128, 30, 1, 0, 0, 0, 129, 130, 7,
1, 0, 0, 130, 32, 1, 0, 0, 0, 131, 132, 8, 2, 0, 0, 132, 34, 1, 0, 0, 0,
133, 135, 5, 45, 0, 0, 134, 133, 1, 0, 0, 0, 134, 135, 1, 0, 0, 0, 135,
136, 1, 0, 0, 0, 136, 143, 3, 41, 20, 0, 137, 139, 5, 46, 0, 0, 138, 140,
7, 3, 0, 0, 139, 138, 1, 0, 0, 0, 140, 141, 1, 0, 0, 0, 141, 139, 1, 0,
0, 0, 141, 142, 1, 0, 0, 0, 142, 144, 1, 0, 0, 0, 143, 137, 1, 0, 0, 0,
143, 144, 1, 0, 0, 0, 144, 146, 1, 0, 0, 0, 145, 147, 3, 43, 21, 0, 146,
145, 1, 0, 0, 0, 146, 147, 1, 0, 0, 0, 147, 36, 1, 0, 0, 0, 148, 149, 5,
78, 0, 0, 149, 150, 5, 97, 0, 0, 150, 169, 5, 78, 0, 0, 151, 152, 5, 45,
0, 0, 152, 153, 5, 73, 0, 0, 153, 154, 5, 110, 0, 0, 154, 155, 5, 102,
0, 0, 155, 156, 5, 105, 0, 0, 156, 157, 5, 110, 0, 0, 157, 158, 5, 105,
0, 0, 158, 159, 5, 116, 0, 0, 159, 169, 5, 121, 0, 0, 160, 161, 5, 73,
0, 0, 161, 162, 5, 110, 0, 0, 162, 163, 5, 102, 0, 0, 163, 164, 5, 105,
0, 0, 164, 165, 5, 110, 0, 0, 165, 166, 5, 105, 0, 0, 166, 167, 5, 116,
0, 0, 167, 169, 5, 121, 0, 0, 168, 148, 1, 0, 0, 0, 168, 151, 1, 0, 0,
0, 168, 160, 1, 0, 0, 0, 169, 38, 1, 0, 0, 0, 170, 172, 5, 45, 0, 0, 171,
170, 1, 0, 0, 0, 171, 172, 1, 0, 0, 0, 172, 173, 1, 0, 0, 0, 173, 180,
3, 41, 20, 0, 174, 176, 5, 46, 0, 0, 175, 177, 7, 3, 0, 0, 176, 175, 1,
0, 0, 0, 177, 178, 1, 0, 0, 0, 178, 176, 1, 0, 0, 0, 178, 179, 1, 0, 0,
0, 179, 181, 1, 0, 0, 0, 180, 174, 1, 0, 0, 0, 180, 181, 1, 0, 0, 0, 181,
183, 1, 0, 0, 0, 182, 184, 3, 43, 21, 0, 183, 182, 1, 0, 0, 0, 183, 184,
1, 0, 0, 0, 184, 185, 1, 0, 0, 0, 185, 186, 3, 19, 9, 0, 186, 40, 1, 0,
0, 0, 187, 196, 5, 48, 0, 0, 188, 192, 7, 4, 0, 0, 189, 191, 7, 3, 0, 0,
190, 189, 1, 0, 0, 0, 191, 194, 1, 0, 0, 0, 192, 190, 1, 0, 0, 0, 192,
193, 1, 0, 0, 0, 193, 196, 1, 0, 0, 0, 194, 192, 1, 0, 0, 0, 195, 187,
1, 0, 0, 0, 195, 188, 1, 0, 0, 0, 196, 42, 1, 0, 0, 0, 197, 199, 7, 5,
0, 0, 198, 200, 7, 6, 0, 0, 199, 198, 1, 0, 0, 0, 199, 200, 1, 0, 0, 0,
200, 201, 1, 0, 0, 0, 201, 202, 3, 41, 20, 0, 202, 44, 1, 0, 0, 0, 203,
205, 7, 7, 0, 0, 204, 203, 1, 0, 0, 0, 205, 206, 1, 0, 0, 0, 206, 204,
1, 0, 0, 0, 206, 207, 1, 0, 0, 0, 207, 208, 1, 0, 0, 0, 208, 209, 6, 22,
0, 0, 209, 46, 1, 0, 0, 0, 18, 0, 95, 97, 111, 121, 134, 141, 143, 146,
168, 171, 178, 180, 183, 192, 195, 199, 206, 1, 6, 0, 0,
}
deserializer := antlr.NewATNDeserializer(nil)
staticData.atn = deserializer.Deserialize(staticData.serializedATN)
atn := staticData.atn
staticData.decisionToDFA = make([]*antlr.DFA, len(atn.DecisionToState))
decisionToDFA := staticData.decisionToDFA
for index, state := range atn.DecisionToState {
decisionToDFA[index] = antlr.NewDFA(state, index)
}
}
// AgeLexerInit initializes any static state used to implement AgeLexer. By default the
// static state used to implement the lexer is lazily initialized during the first call to
// NewAgeLexer(). You can call this function if you wish to initialize the static state ahead
// of time.
func AgeLexerInit() {
staticData := &agelexerLexerStaticData
staticData.once.Do(agelexerLexerInit)
}
// NewAgeLexer produces a new lexer instance for the optional input antlr.CharStream.
func NewAgeLexer(input antlr.CharStream) *AgeLexer {
AgeLexerInit()
l := new(AgeLexer)
l.BaseLexer = antlr.NewBaseLexer(input)
staticData := &agelexerLexerStaticData
l.Interpreter = antlr.NewLexerATNSimulator(l, staticData.atn, staticData.decisionToDFA, staticData.predictionContextCache)
l.channelNames = staticData.channelNames
l.modeNames = staticData.modeNames
l.RuleNames = staticData.ruleNames
l.LiteralNames = staticData.literalNames
l.SymbolicNames = staticData.symbolicNames
l.GrammarFileName = "Age.g4"
// TODO: l.EOF = antlr.TokenEOF
return l
}
// AgeLexer tokens.
const (
AgeLexerT__0 = 1
AgeLexerT__1 = 2
AgeLexerT__2 = 3
AgeLexerT__3 = 4
AgeLexerT__4 = 5
AgeLexerT__5 = 6
AgeLexerKW_VERTEX = 7
AgeLexerKW_EDGE = 8
AgeLexerKW_PATH = 9
AgeLexerKW_NUMERIC = 10
AgeLexerSTRING = 11
AgeLexerBOOL = 12
AgeLexerNULL = 13
AgeLexerNUMBER = 14
AgeLexerFLOAT_EXPR = 15
AgeLexerNUMERIC = 16
AgeLexerWS = 17
)
age-PG18-v1.7.0-rc0/drivers/golang/parser/age_listener.go 0000664 0000000 0000000 00000003275 15134225711 0023021 0 ustar 00root root 0000000 0000000 // Code generated from java-escape by ANTLR 4.11.1. DO NOT EDIT.
package parser // Age
import "github.com/antlr/antlr4/runtime/Go/antlr/v4"
// AgeListener is a complete listener for a parse tree produced by AgeParser.
type AgeListener interface {
antlr.ParseTreeListener
// EnterAgeout is called when entering the ageout production.
EnterAgeout(c *AgeoutContext)
// EnterVertex is called when entering the vertex production.
EnterVertex(c *VertexContext)
// EnterEdge is called when entering the edge production.
EnterEdge(c *EdgeContext)
// EnterPath is called when entering the path production.
EnterPath(c *PathContext)
// EnterValue is called when entering the value production.
EnterValue(c *ValueContext)
// EnterProperties is called when entering the properties production.
EnterProperties(c *PropertiesContext)
// EnterPair is called when entering the pair production.
EnterPair(c *PairContext)
// EnterArr is called when entering the arr production.
EnterArr(c *ArrContext)
// ExitAgeout is called when exiting the ageout production.
ExitAgeout(c *AgeoutContext)
// ExitVertex is called when exiting the vertex production.
ExitVertex(c *VertexContext)
// ExitEdge is called when exiting the edge production.
ExitEdge(c *EdgeContext)
// ExitPath is called when exiting the path production.
ExitPath(c *PathContext)
// ExitValue is called when exiting the value production.
ExitValue(c *ValueContext)
// ExitProperties is called when exiting the properties production.
ExitProperties(c *PropertiesContext)
// ExitPair is called when exiting the pair production.
ExitPair(c *PairContext)
// ExitArr is called when exiting the arr production.
ExitArr(c *ArrContext)
}
age-PG18-v1.7.0-rc0/drivers/golang/parser/age_parser.go 0000664 0000000 0000000 00000100675 15134225711 0022472 0 ustar 00root root 0000000 0000000 // Code generated from java-escape by ANTLR 4.11.1. DO NOT EDIT.
package parser // Age
import (
"fmt"
"strconv"
"sync"
"github.com/antlr/antlr4/runtime/Go/antlr/v4"
)
// Suppress unused import errors
var _ = fmt.Printf
var _ = strconv.Itoa
var _ = sync.Once{}
type AgeParser struct {
*antlr.BaseParser
}
var ageParserStaticData struct {
once sync.Once
serializedATN []int32
literalNames []string
symbolicNames []string
ruleNames []string
predictionContextCache *antlr.PredictionContextCache
atn *antlr.ATN
decisionToDFA []*antlr.DFA
}
func ageParserInit() {
staticData := &ageParserStaticData
staticData.literalNames = []string{
"", "'['", "','", "']'", "'{'", "'}'", "':'", "'::vertex'", "'::edge'",
"'::path'", "'::numeric'", "", "", "'null'",
}
staticData.symbolicNames = []string{
"", "", "", "", "", "", "", "KW_VERTEX", "KW_EDGE", "KW_PATH", "KW_NUMERIC",
"STRING", "BOOL", "NULL", "NUMBER", "FLOAT_EXPR", "NUMERIC", "WS",
}
staticData.ruleNames = []string{
"ageout", "vertex", "edge", "path", "value", "properties", "pair", "arr",
}
staticData.predictionContextCache = antlr.NewPredictionContextCache()
staticData.serializedATN = []int32{
4, 1, 17, 88, 2, 0, 7, 0, 2, 1, 7, 1, 2, 2, 7, 2, 2, 3, 7, 3, 2, 4, 7,
4, 2, 5, 7, 5, 2, 6, 7, 6, 2, 7, 7, 7, 1, 0, 1, 0, 1, 0, 1, 0, 3, 0, 21,
8, 0, 1, 1, 1, 1, 1, 1, 1, 2, 1, 2, 1, 2, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3,
1, 3, 1, 3, 5, 3, 36, 8, 3, 10, 3, 12, 3, 39, 9, 3, 1, 3, 1, 3, 1, 3, 1,
4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 3, 4, 52, 8, 4, 1, 5, 1, 5,
1, 5, 1, 5, 5, 5, 58, 8, 5, 10, 5, 12, 5, 61, 9, 5, 1, 5, 1, 5, 1, 5, 1,
5, 3, 5, 67, 8, 5, 1, 6, 1, 6, 1, 6, 1, 6, 1, 7, 1, 7, 1, 7, 1, 7, 5, 7,
77, 8, 7, 10, 7, 12, 7, 80, 9, 7, 1, 7, 1, 7, 1, 7, 1, 7, 3, 7, 86, 8,
7, 1, 7, 0, 0, 8, 0, 2, 4, 6, 8, 10, 12, 14, 0, 0, 94, 0, 20, 1, 0, 0,
0, 2, 22, 1, 0, 0, 0, 4, 25, 1, 0, 0, 0, 6, 28, 1, 0, 0, 0, 8, 51, 1, 0,
0, 0, 10, 66, 1, 0, 0, 0, 12, 68, 1, 0, 0, 0, 14, 85, 1, 0, 0, 0, 16, 21,
3, 8, 4, 0, 17, 21, 3, 2, 1, 0, 18, 21, 3, 4, 2, 0, 19, 21, 3, 6, 3, 0,
20, 16, 1, 0, 0, 0, 20, 17, 1, 0, 0, 0, 20, 18, 1, 0, 0, 0, 20, 19, 1,
0, 0, 0, 21, 1, 1, 0, 0, 0, 22, 23, 3, 10, 5, 0, 23, 24, 5, 7, 0, 0, 24,
3, 1, 0, 0, 0, 25, 26, 3, 10, 5, 0, 26, 27, 5, 8, 0, 0, 27, 5, 1, 0, 0,
0, 28, 29, 5, 1, 0, 0, 29, 37, 3, 2, 1, 0, 30, 31, 5, 2, 0, 0, 31, 32,
3, 4, 2, 0, 32, 33, 5, 2, 0, 0, 33, 34, 3, 2, 1, 0, 34, 36, 1, 0, 0, 0,
35, 30, 1, 0, 0, 0, 36, 39, 1, 0, 0, 0, 37, 35, 1, 0, 0, 0, 37, 38, 1,
0, 0, 0, 38, 40, 1, 0, 0, 0, 39, 37, 1, 0, 0, 0, 40, 41, 5, 3, 0, 0, 41,
42, 5, 9, 0, 0, 42, 7, 1, 0, 0, 0, 43, 52, 5, 11, 0, 0, 44, 52, 5, 14,
0, 0, 45, 52, 5, 16, 0, 0, 46, 52, 5, 15, 0, 0, 47, 52, 5, 12, 0, 0, 48,
52, 5, 13, 0, 0, 49, 52, 3, 10, 5, 0, 50, 52, 3, 14, 7, 0, 51, 43, 1, 0,
0, 0, 51, 44, 1, 0, 0, 0, 51, 45, 1, 0, 0, 0, 51, 46, 1, 0, 0, 0, 51, 47,
1, 0, 0, 0, 51, 48, 1, 0, 0, 0, 51, 49, 1, 0, 0, 0, 51, 50, 1, 0, 0, 0,
52, 9, 1, 0, 0, 0, 53, 54, 5, 4, 0, 0, 54, 59, 3, 12, 6, 0, 55, 56, 5,
2, 0, 0, 56, 58, 3, 12, 6, 0, 57, 55, 1, 0, 0, 0, 58, 61, 1, 0, 0, 0, 59,
57, 1, 0, 0, 0, 59, 60, 1, 0, 0, 0, 60, 62, 1, 0, 0, 0, 61, 59, 1, 0, 0,
0, 62, 63, 5, 5, 0, 0, 63, 67, 1, 0, 0, 0, 64, 65, 5, 4, 0, 0, 65, 67,
5, 5, 0, 0, 66, 53, 1, 0, 0, 0, 66, 64, 1, 0, 0, 0, 67, 11, 1, 0, 0, 0,
68, 69, 5, 11, 0, 0, 69, 70, 5, 6, 0, 0, 70, 71, 3, 8, 4, 0, 71, 13, 1,
0, 0, 0, 72, 73, 5, 1, 0, 0, 73, 78, 3, 8, 4, 0, 74, 75, 5, 2, 0, 0, 75,
77, 3, 8, 4, 0, 76, 74, 1, 0, 0, 0, 77, 80, 1, 0, 0, 0, 78, 76, 1, 0, 0,
0, 78, 79, 1, 0, 0, 0, 79, 81, 1, 0, 0, 0, 80, 78, 1, 0, 0, 0, 81, 82,
5, 3, 0, 0, 82, 86, 1, 0, 0, 0, 83, 84, 5, 1, 0, 0, 84, 86, 5, 3, 0, 0,
85, 72, 1, 0, 0, 0, 85, 83, 1, 0, 0, 0, 86, 15, 1, 0, 0, 0, 7, 20, 37,
51, 59, 66, 78, 85,
}
deserializer := antlr.NewATNDeserializer(nil)
staticData.atn = deserializer.Deserialize(staticData.serializedATN)
atn := staticData.atn
staticData.decisionToDFA = make([]*antlr.DFA, len(atn.DecisionToState))
decisionToDFA := staticData.decisionToDFA
for index, state := range atn.DecisionToState {
decisionToDFA[index] = antlr.NewDFA(state, index)
}
}
// AgeParserInit initializes any static state used to implement AgeParser. By default the
// static state used to implement the parser is lazily initialized during the first call to
// NewAgeParser(). You can call this function if you wish to initialize the static state ahead
// of time.
func AgeParserInit() {
staticData := &ageParserStaticData
staticData.once.Do(ageParserInit)
}
// NewAgeParser produces a new parser instance for the optional input antlr.TokenStream.
func NewAgeParser(input antlr.TokenStream) *AgeParser {
AgeParserInit()
this := new(AgeParser)
this.BaseParser = antlr.NewBaseParser(input)
staticData := &ageParserStaticData
this.Interpreter = antlr.NewParserATNSimulator(this, staticData.atn, staticData.decisionToDFA, staticData.predictionContextCache)
this.RuleNames = staticData.ruleNames
this.LiteralNames = staticData.literalNames
this.SymbolicNames = staticData.symbolicNames
this.GrammarFileName = "java-escape"
return this
}
// AgeParser tokens.
const (
AgeParserEOF = antlr.TokenEOF
AgeParserT__0 = 1
AgeParserT__1 = 2
AgeParserT__2 = 3
AgeParserT__3 = 4
AgeParserT__4 = 5
AgeParserT__5 = 6
AgeParserKW_VERTEX = 7
AgeParserKW_EDGE = 8
AgeParserKW_PATH = 9
AgeParserKW_NUMERIC = 10
AgeParserSTRING = 11
AgeParserBOOL = 12
AgeParserNULL = 13
AgeParserNUMBER = 14
AgeParserFLOAT_EXPR = 15
AgeParserNUMERIC = 16
AgeParserWS = 17
)
// AgeParser rules.
const (
AgeParserRULE_ageout = 0
AgeParserRULE_vertex = 1
AgeParserRULE_edge = 2
AgeParserRULE_path = 3
AgeParserRULE_value = 4
AgeParserRULE_properties = 5
AgeParserRULE_pair = 6
AgeParserRULE_arr = 7
)
// IAgeoutContext is an interface to support dynamic dispatch.
type IAgeoutContext interface {
antlr.ParserRuleContext
// GetParser returns the parser.
GetParser() antlr.Parser
// IsAgeoutContext differentiates from other interfaces.
IsAgeoutContext()
}
type AgeoutContext struct {
*antlr.BaseParserRuleContext
parser antlr.Parser
}
func NewEmptyAgeoutContext() *AgeoutContext {
var p = new(AgeoutContext)
p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(nil, -1)
p.RuleIndex = AgeParserRULE_ageout
return p
}
func (*AgeoutContext) IsAgeoutContext() {}
func NewAgeoutContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *AgeoutContext {
var p = new(AgeoutContext)
p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(parent, invokingState)
p.parser = parser
p.RuleIndex = AgeParserRULE_ageout
return p
}
func (s *AgeoutContext) GetParser() antlr.Parser { return s.parser }
func (s *AgeoutContext) Value() IValueContext {
var t antlr.RuleContext
for _, ctx := range s.GetChildren() {
if _, ok := ctx.(IValueContext); ok {
t = ctx.(antlr.RuleContext)
break
}
}
if t == nil {
return nil
}
return t.(IValueContext)
}
func (s *AgeoutContext) Vertex() IVertexContext {
var t antlr.RuleContext
for _, ctx := range s.GetChildren() {
if _, ok := ctx.(IVertexContext); ok {
t = ctx.(antlr.RuleContext)
break
}
}
if t == nil {
return nil
}
return t.(IVertexContext)
}
func (s *AgeoutContext) Edge() IEdgeContext {
var t antlr.RuleContext
for _, ctx := range s.GetChildren() {
if _, ok := ctx.(IEdgeContext); ok {
t = ctx.(antlr.RuleContext)
break
}
}
if t == nil {
return nil
}
return t.(IEdgeContext)
}
func (s *AgeoutContext) Path() IPathContext {
var t antlr.RuleContext
for _, ctx := range s.GetChildren() {
if _, ok := ctx.(IPathContext); ok {
t = ctx.(antlr.RuleContext)
break
}
}
if t == nil {
return nil
}
return t.(IPathContext)
}
func (s *AgeoutContext) GetRuleContext() antlr.RuleContext {
return s
}
func (s *AgeoutContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string {
return antlr.TreesStringTree(s, ruleNames, recog)
}
func (s *AgeoutContext) EnterRule(listener antlr.ParseTreeListener) {
if listenerT, ok := listener.(AgeListener); ok {
listenerT.EnterAgeout(s)
}
}
func (s *AgeoutContext) ExitRule(listener antlr.ParseTreeListener) {
if listenerT, ok := listener.(AgeListener); ok {
listenerT.ExitAgeout(s)
}
}
func (s *AgeoutContext) Accept(visitor antlr.ParseTreeVisitor) interface{} {
switch t := visitor.(type) {
case AgeVisitor:
return t.VisitAgeout(s)
default:
return t.VisitChildren(s)
}
}
func (p *AgeParser) Ageout() (localctx IAgeoutContext) {
this := p
_ = this
localctx = NewAgeoutContext(p, p.GetParserRuleContext(), p.GetState())
p.EnterRule(localctx, 0, AgeParserRULE_ageout)
defer func() {
p.ExitRule()
}()
defer func() {
if err := recover(); err != nil {
if v, ok := err.(antlr.RecognitionException); ok {
localctx.SetException(v)
p.GetErrorHandler().ReportError(p, v)
p.GetErrorHandler().Recover(p, v)
} else {
panic(err)
}
}
}()
p.SetState(20)
p.GetErrorHandler().Sync(p)
switch p.GetInterpreter().AdaptivePredict(p.GetTokenStream(), 0, p.GetParserRuleContext()) {
case 1:
p.EnterOuterAlt(localctx, 1)
{
p.SetState(16)
p.Value()
}
case 2:
p.EnterOuterAlt(localctx, 2)
{
p.SetState(17)
p.Vertex()
}
case 3:
p.EnterOuterAlt(localctx, 3)
{
p.SetState(18)
p.Edge()
}
case 4:
p.EnterOuterAlt(localctx, 4)
{
p.SetState(19)
p.Path()
}
}
return localctx
}
// IVertexContext is an interface to support dynamic dispatch.
type IVertexContext interface {
antlr.ParserRuleContext
// GetParser returns the parser.
GetParser() antlr.Parser
// IsVertexContext differentiates from other interfaces.
IsVertexContext()
}
type VertexContext struct {
*antlr.BaseParserRuleContext
parser antlr.Parser
}
func NewEmptyVertexContext() *VertexContext {
var p = new(VertexContext)
p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(nil, -1)
p.RuleIndex = AgeParserRULE_vertex
return p
}
func (*VertexContext) IsVertexContext() {}
func NewVertexContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *VertexContext {
var p = new(VertexContext)
p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(parent, invokingState)
p.parser = parser
p.RuleIndex = AgeParserRULE_vertex
return p
}
func (s *VertexContext) GetParser() antlr.Parser { return s.parser }
func (s *VertexContext) Properties() IPropertiesContext {
var t antlr.RuleContext
for _, ctx := range s.GetChildren() {
if _, ok := ctx.(IPropertiesContext); ok {
t = ctx.(antlr.RuleContext)
break
}
}
if t == nil {
return nil
}
return t.(IPropertiesContext)
}
func (s *VertexContext) KW_VERTEX() antlr.TerminalNode {
return s.GetToken(AgeParserKW_VERTEX, 0)
}
func (s *VertexContext) GetRuleContext() antlr.RuleContext {
return s
}
func (s *VertexContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string {
return antlr.TreesStringTree(s, ruleNames, recog)
}
func (s *VertexContext) EnterRule(listener antlr.ParseTreeListener) {
if listenerT, ok := listener.(AgeListener); ok {
listenerT.EnterVertex(s)
}
}
func (s *VertexContext) ExitRule(listener antlr.ParseTreeListener) {
if listenerT, ok := listener.(AgeListener); ok {
listenerT.ExitVertex(s)
}
}
func (s *VertexContext) Accept(visitor antlr.ParseTreeVisitor) interface{} {
switch t := visitor.(type) {
case AgeVisitor:
return t.VisitVertex(s)
default:
return t.VisitChildren(s)
}
}
func (p *AgeParser) Vertex() (localctx IVertexContext) {
this := p
_ = this
localctx = NewVertexContext(p, p.GetParserRuleContext(), p.GetState())
p.EnterRule(localctx, 2, AgeParserRULE_vertex)
defer func() {
p.ExitRule()
}()
defer func() {
if err := recover(); err != nil {
if v, ok := err.(antlr.RecognitionException); ok {
localctx.SetException(v)
p.GetErrorHandler().ReportError(p, v)
p.GetErrorHandler().Recover(p, v)
} else {
panic(err)
}
}
}()
p.EnterOuterAlt(localctx, 1)
{
p.SetState(22)
p.Properties()
}
{
p.SetState(23)
p.Match(AgeParserKW_VERTEX)
}
return localctx
}
// IEdgeContext is an interface to support dynamic dispatch.
type IEdgeContext interface {
antlr.ParserRuleContext
// GetParser returns the parser.
GetParser() antlr.Parser
// IsEdgeContext differentiates from other interfaces.
IsEdgeContext()
}
type EdgeContext struct {
*antlr.BaseParserRuleContext
parser antlr.Parser
}
func NewEmptyEdgeContext() *EdgeContext {
var p = new(EdgeContext)
p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(nil, -1)
p.RuleIndex = AgeParserRULE_edge
return p
}
func (*EdgeContext) IsEdgeContext() {}
func NewEdgeContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *EdgeContext {
var p = new(EdgeContext)
p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(parent, invokingState)
p.parser = parser
p.RuleIndex = AgeParserRULE_edge
return p
}
func (s *EdgeContext) GetParser() antlr.Parser { return s.parser }
func (s *EdgeContext) Properties() IPropertiesContext {
var t antlr.RuleContext
for _, ctx := range s.GetChildren() {
if _, ok := ctx.(IPropertiesContext); ok {
t = ctx.(antlr.RuleContext)
break
}
}
if t == nil {
return nil
}
return t.(IPropertiesContext)
}
func (s *EdgeContext) KW_EDGE() antlr.TerminalNode {
return s.GetToken(AgeParserKW_EDGE, 0)
}
func (s *EdgeContext) GetRuleContext() antlr.RuleContext {
return s
}
func (s *EdgeContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string {
return antlr.TreesStringTree(s, ruleNames, recog)
}
func (s *EdgeContext) EnterRule(listener antlr.ParseTreeListener) {
if listenerT, ok := listener.(AgeListener); ok {
listenerT.EnterEdge(s)
}
}
func (s *EdgeContext) ExitRule(listener antlr.ParseTreeListener) {
if listenerT, ok := listener.(AgeListener); ok {
listenerT.ExitEdge(s)
}
}
func (s *EdgeContext) Accept(visitor antlr.ParseTreeVisitor) interface{} {
switch t := visitor.(type) {
case AgeVisitor:
return t.VisitEdge(s)
default:
return t.VisitChildren(s)
}
}
func (p *AgeParser) Edge() (localctx IEdgeContext) {
this := p
_ = this
localctx = NewEdgeContext(p, p.GetParserRuleContext(), p.GetState())
p.EnterRule(localctx, 4, AgeParserRULE_edge)
defer func() {
p.ExitRule()
}()
defer func() {
if err := recover(); err != nil {
if v, ok := err.(antlr.RecognitionException); ok {
localctx.SetException(v)
p.GetErrorHandler().ReportError(p, v)
p.GetErrorHandler().Recover(p, v)
} else {
panic(err)
}
}
}()
p.EnterOuterAlt(localctx, 1)
{
p.SetState(25)
p.Properties()
}
{
p.SetState(26)
p.Match(AgeParserKW_EDGE)
}
return localctx
}
// IPathContext is an interface to support dynamic dispatch.
type IPathContext interface {
antlr.ParserRuleContext
// GetParser returns the parser.
GetParser() antlr.Parser
// IsPathContext differentiates from other interfaces.
IsPathContext()
}
type PathContext struct {
*antlr.BaseParserRuleContext
parser antlr.Parser
}
func NewEmptyPathContext() *PathContext {
var p = new(PathContext)
p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(nil, -1)
p.RuleIndex = AgeParserRULE_path
return p
}
func (*PathContext) IsPathContext() {}
func NewPathContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *PathContext {
var p = new(PathContext)
p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(parent, invokingState)
p.parser = parser
p.RuleIndex = AgeParserRULE_path
return p
}
func (s *PathContext) GetParser() antlr.Parser { return s.parser }
func (s *PathContext) AllVertex() []IVertexContext {
children := s.GetChildren()
len := 0
for _, ctx := range children {
if _, ok := ctx.(IVertexContext); ok {
len++
}
}
tst := make([]IVertexContext, len)
i := 0
for _, ctx := range children {
if t, ok := ctx.(IVertexContext); ok {
tst[i] = t.(IVertexContext)
i++
}
}
return tst
}
func (s *PathContext) Vertex(i int) IVertexContext {
var t antlr.RuleContext
j := 0
for _, ctx := range s.GetChildren() {
if _, ok := ctx.(IVertexContext); ok {
if j == i {
t = ctx.(antlr.RuleContext)
break
}
j++
}
}
if t == nil {
return nil
}
return t.(IVertexContext)
}
func (s *PathContext) KW_PATH() antlr.TerminalNode {
return s.GetToken(AgeParserKW_PATH, 0)
}
func (s *PathContext) AllEdge() []IEdgeContext {
children := s.GetChildren()
len := 0
for _, ctx := range children {
if _, ok := ctx.(IEdgeContext); ok {
len++
}
}
tst := make([]IEdgeContext, len)
i := 0
for _, ctx := range children {
if t, ok := ctx.(IEdgeContext); ok {
tst[i] = t.(IEdgeContext)
i++
}
}
return tst
}
func (s *PathContext) Edge(i int) IEdgeContext {
var t antlr.RuleContext
j := 0
for _, ctx := range s.GetChildren() {
if _, ok := ctx.(IEdgeContext); ok {
if j == i {
t = ctx.(antlr.RuleContext)
break
}
j++
}
}
if t == nil {
return nil
}
return t.(IEdgeContext)
}
func (s *PathContext) GetRuleContext() antlr.RuleContext {
return s
}
func (s *PathContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string {
return antlr.TreesStringTree(s, ruleNames, recog)
}
func (s *PathContext) EnterRule(listener antlr.ParseTreeListener) {
if listenerT, ok := listener.(AgeListener); ok {
listenerT.EnterPath(s)
}
}
func (s *PathContext) ExitRule(listener antlr.ParseTreeListener) {
if listenerT, ok := listener.(AgeListener); ok {
listenerT.ExitPath(s)
}
}
func (s *PathContext) Accept(visitor antlr.ParseTreeVisitor) interface{} {
switch t := visitor.(type) {
case AgeVisitor:
return t.VisitPath(s)
default:
return t.VisitChildren(s)
}
}
func (p *AgeParser) Path() (localctx IPathContext) {
this := p
_ = this
localctx = NewPathContext(p, p.GetParserRuleContext(), p.GetState())
p.EnterRule(localctx, 6, AgeParserRULE_path)
var _la int
defer func() {
p.ExitRule()
}()
defer func() {
if err := recover(); err != nil {
if v, ok := err.(antlr.RecognitionException); ok {
localctx.SetException(v)
p.GetErrorHandler().ReportError(p, v)
p.GetErrorHandler().Recover(p, v)
} else {
panic(err)
}
}
}()
p.EnterOuterAlt(localctx, 1)
{
p.SetState(28)
p.Match(AgeParserT__0)
}
{
p.SetState(29)
p.Vertex()
}
p.SetState(37)
p.GetErrorHandler().Sync(p)
_la = p.GetTokenStream().LA(1)
for _la == AgeParserT__1 {
{
p.SetState(30)
p.Match(AgeParserT__1)
}
{
p.SetState(31)
p.Edge()
}
{
p.SetState(32)
p.Match(AgeParserT__1)
}
{
p.SetState(33)
p.Vertex()
}
p.SetState(39)
p.GetErrorHandler().Sync(p)
_la = p.GetTokenStream().LA(1)
}
{
p.SetState(40)
p.Match(AgeParserT__2)
}
{
p.SetState(41)
p.Match(AgeParserKW_PATH)
}
return localctx
}
// IValueContext is an interface to support dynamic dispatch.
type IValueContext interface {
antlr.ParserRuleContext
// GetParser returns the parser.
GetParser() antlr.Parser
// IsValueContext differentiates from other interfaces.
IsValueContext()
}
type ValueContext struct {
*antlr.BaseParserRuleContext
parser antlr.Parser
}
func NewEmptyValueContext() *ValueContext {
var p = new(ValueContext)
p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(nil, -1)
p.RuleIndex = AgeParserRULE_value
return p
}
func (*ValueContext) IsValueContext() {}
func NewValueContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *ValueContext {
var p = new(ValueContext)
p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(parent, invokingState)
p.parser = parser
p.RuleIndex = AgeParserRULE_value
return p
}
func (s *ValueContext) GetParser() antlr.Parser { return s.parser }
func (s *ValueContext) STRING() antlr.TerminalNode {
return s.GetToken(AgeParserSTRING, 0)
}
func (s *ValueContext) NUMBER() antlr.TerminalNode {
return s.GetToken(AgeParserNUMBER, 0)
}
func (s *ValueContext) NUMERIC() antlr.TerminalNode {
return s.GetToken(AgeParserNUMERIC, 0)
}
func (s *ValueContext) FLOAT_EXPR() antlr.TerminalNode {
return s.GetToken(AgeParserFLOAT_EXPR, 0)
}
func (s *ValueContext) BOOL() antlr.TerminalNode {
return s.GetToken(AgeParserBOOL, 0)
}
func (s *ValueContext) NULL() antlr.TerminalNode {
return s.GetToken(AgeParserNULL, 0)
}
func (s *ValueContext) Properties() IPropertiesContext {
var t antlr.RuleContext
for _, ctx := range s.GetChildren() {
if _, ok := ctx.(IPropertiesContext); ok {
t = ctx.(antlr.RuleContext)
break
}
}
if t == nil {
return nil
}
return t.(IPropertiesContext)
}
func (s *ValueContext) Arr() IArrContext {
var t antlr.RuleContext
for _, ctx := range s.GetChildren() {
if _, ok := ctx.(IArrContext); ok {
t = ctx.(antlr.RuleContext)
break
}
}
if t == nil {
return nil
}
return t.(IArrContext)
}
func (s *ValueContext) GetRuleContext() antlr.RuleContext {
return s
}
func (s *ValueContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string {
return antlr.TreesStringTree(s, ruleNames, recog)
}
func (s *ValueContext) EnterRule(listener antlr.ParseTreeListener) {
if listenerT, ok := listener.(AgeListener); ok {
listenerT.EnterValue(s)
}
}
func (s *ValueContext) ExitRule(listener antlr.ParseTreeListener) {
if listenerT, ok := listener.(AgeListener); ok {
listenerT.ExitValue(s)
}
}
func (s *ValueContext) Accept(visitor antlr.ParseTreeVisitor) interface{} {
switch t := visitor.(type) {
case AgeVisitor:
return t.VisitValue(s)
default:
return t.VisitChildren(s)
}
}
func (p *AgeParser) Value() (localctx IValueContext) {
this := p
_ = this
localctx = NewValueContext(p, p.GetParserRuleContext(), p.GetState())
p.EnterRule(localctx, 8, AgeParserRULE_value)
defer func() {
p.ExitRule()
}()
defer func() {
if err := recover(); err != nil {
if v, ok := err.(antlr.RecognitionException); ok {
localctx.SetException(v)
p.GetErrorHandler().ReportError(p, v)
p.GetErrorHandler().Recover(p, v)
} else {
panic(err)
}
}
}()
p.SetState(51)
p.GetErrorHandler().Sync(p)
switch p.GetTokenStream().LA(1) {
case AgeParserSTRING:
p.EnterOuterAlt(localctx, 1)
{
p.SetState(43)
p.Match(AgeParserSTRING)
}
case AgeParserNUMBER:
p.EnterOuterAlt(localctx, 2)
{
p.SetState(44)
p.Match(AgeParserNUMBER)
}
case AgeParserNUMERIC:
p.EnterOuterAlt(localctx, 3)
{
p.SetState(45)
p.Match(AgeParserNUMERIC)
}
case AgeParserFLOAT_EXPR:
p.EnterOuterAlt(localctx, 4)
{
p.SetState(46)
p.Match(AgeParserFLOAT_EXPR)
}
case AgeParserBOOL:
p.EnterOuterAlt(localctx, 5)
{
p.SetState(47)
p.Match(AgeParserBOOL)
}
case AgeParserNULL:
p.EnterOuterAlt(localctx, 6)
{
p.SetState(48)
p.Match(AgeParserNULL)
}
case AgeParserT__3:
p.EnterOuterAlt(localctx, 7)
{
p.SetState(49)
p.Properties()
}
case AgeParserT__0:
p.EnterOuterAlt(localctx, 8)
{
p.SetState(50)
p.Arr()
}
default:
panic(antlr.NewNoViableAltException(p, nil, nil, nil, nil, nil))
}
return localctx
}
// IPropertiesContext is an interface to support dynamic dispatch.
type IPropertiesContext interface {
antlr.ParserRuleContext
// GetParser returns the parser.
GetParser() antlr.Parser
// IsPropertiesContext differentiates from other interfaces.
IsPropertiesContext()
}
type PropertiesContext struct {
*antlr.BaseParserRuleContext
parser antlr.Parser
}
func NewEmptyPropertiesContext() *PropertiesContext {
var p = new(PropertiesContext)
p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(nil, -1)
p.RuleIndex = AgeParserRULE_properties
return p
}
func (*PropertiesContext) IsPropertiesContext() {}
func NewPropertiesContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *PropertiesContext {
var p = new(PropertiesContext)
p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(parent, invokingState)
p.parser = parser
p.RuleIndex = AgeParserRULE_properties
return p
}
func (s *PropertiesContext) GetParser() antlr.Parser { return s.parser }
func (s *PropertiesContext) AllPair() []IPairContext {
children := s.GetChildren()
len := 0
for _, ctx := range children {
if _, ok := ctx.(IPairContext); ok {
len++
}
}
tst := make([]IPairContext, len)
i := 0
for _, ctx := range children {
if t, ok := ctx.(IPairContext); ok {
tst[i] = t.(IPairContext)
i++
}
}
return tst
}
func (s *PropertiesContext) Pair(i int) IPairContext {
var t antlr.RuleContext
j := 0
for _, ctx := range s.GetChildren() {
if _, ok := ctx.(IPairContext); ok {
if j == i {
t = ctx.(antlr.RuleContext)
break
}
j++
}
}
if t == nil {
return nil
}
return t.(IPairContext)
}
func (s *PropertiesContext) GetRuleContext() antlr.RuleContext {
return s
}
func (s *PropertiesContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string {
return antlr.TreesStringTree(s, ruleNames, recog)
}
func (s *PropertiesContext) EnterRule(listener antlr.ParseTreeListener) {
if listenerT, ok := listener.(AgeListener); ok {
listenerT.EnterProperties(s)
}
}
func (s *PropertiesContext) ExitRule(listener antlr.ParseTreeListener) {
if listenerT, ok := listener.(AgeListener); ok {
listenerT.ExitProperties(s)
}
}
func (s *PropertiesContext) Accept(visitor antlr.ParseTreeVisitor) interface{} {
switch t := visitor.(type) {
case AgeVisitor:
return t.VisitProperties(s)
default:
return t.VisitChildren(s)
}
}
func (p *AgeParser) Properties() (localctx IPropertiesContext) {
this := p
_ = this
localctx = NewPropertiesContext(p, p.GetParserRuleContext(), p.GetState())
p.EnterRule(localctx, 10, AgeParserRULE_properties)
var _la int
defer func() {
p.ExitRule()
}()
defer func() {
if err := recover(); err != nil {
if v, ok := err.(antlr.RecognitionException); ok {
localctx.SetException(v)
p.GetErrorHandler().ReportError(p, v)
p.GetErrorHandler().Recover(p, v)
} else {
panic(err)
}
}
}()
p.SetState(66)
p.GetErrorHandler().Sync(p)
switch p.GetInterpreter().AdaptivePredict(p.GetTokenStream(), 4, p.GetParserRuleContext()) {
case 1:
p.EnterOuterAlt(localctx, 1)
{
p.SetState(53)
p.Match(AgeParserT__3)
}
{
p.SetState(54)
p.Pair()
}
p.SetState(59)
p.GetErrorHandler().Sync(p)
_la = p.GetTokenStream().LA(1)
for _la == AgeParserT__1 {
{
p.SetState(55)
p.Match(AgeParserT__1)
}
{
p.SetState(56)
p.Pair()
}
p.SetState(61)
p.GetErrorHandler().Sync(p)
_la = p.GetTokenStream().LA(1)
}
{
p.SetState(62)
p.Match(AgeParserT__4)
}
case 2:
p.EnterOuterAlt(localctx, 2)
{
p.SetState(64)
p.Match(AgeParserT__3)
}
{
p.SetState(65)
p.Match(AgeParserT__4)
}
}
return localctx
}
// IPairContext is an interface to support dynamic dispatch.
type IPairContext interface {
antlr.ParserRuleContext
// GetParser returns the parser.
GetParser() antlr.Parser
// IsPairContext differentiates from other interfaces.
IsPairContext()
}
type PairContext struct {
*antlr.BaseParserRuleContext
parser antlr.Parser
}
func NewEmptyPairContext() *PairContext {
var p = new(PairContext)
p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(nil, -1)
p.RuleIndex = AgeParserRULE_pair
return p
}
func (*PairContext) IsPairContext() {}
func NewPairContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *PairContext {
var p = new(PairContext)
p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(parent, invokingState)
p.parser = parser
p.RuleIndex = AgeParserRULE_pair
return p
}
func (s *PairContext) GetParser() antlr.Parser { return s.parser }
func (s *PairContext) STRING() antlr.TerminalNode {
return s.GetToken(AgeParserSTRING, 0)
}
func (s *PairContext) Value() IValueContext {
var t antlr.RuleContext
for _, ctx := range s.GetChildren() {
if _, ok := ctx.(IValueContext); ok {
t = ctx.(antlr.RuleContext)
break
}
}
if t == nil {
return nil
}
return t.(IValueContext)
}
func (s *PairContext) GetRuleContext() antlr.RuleContext {
return s
}
func (s *PairContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string {
return antlr.TreesStringTree(s, ruleNames, recog)
}
func (s *PairContext) EnterRule(listener antlr.ParseTreeListener) {
if listenerT, ok := listener.(AgeListener); ok {
listenerT.EnterPair(s)
}
}
func (s *PairContext) ExitRule(listener antlr.ParseTreeListener) {
if listenerT, ok := listener.(AgeListener); ok {
listenerT.ExitPair(s)
}
}
func (s *PairContext) Accept(visitor antlr.ParseTreeVisitor) interface{} {
switch t := visitor.(type) {
case AgeVisitor:
return t.VisitPair(s)
default:
return t.VisitChildren(s)
}
}
func (p *AgeParser) Pair() (localctx IPairContext) {
this := p
_ = this
localctx = NewPairContext(p, p.GetParserRuleContext(), p.GetState())
p.EnterRule(localctx, 12, AgeParserRULE_pair)
defer func() {
p.ExitRule()
}()
defer func() {
if err := recover(); err != nil {
if v, ok := err.(antlr.RecognitionException); ok {
localctx.SetException(v)
p.GetErrorHandler().ReportError(p, v)
p.GetErrorHandler().Recover(p, v)
} else {
panic(err)
}
}
}()
p.EnterOuterAlt(localctx, 1)
{
p.SetState(68)
p.Match(AgeParserSTRING)
}
{
p.SetState(69)
p.Match(AgeParserT__5)
}
{
p.SetState(70)
p.Value()
}
return localctx
}
// IArrContext is an interface to support dynamic dispatch.
type IArrContext interface {
antlr.ParserRuleContext
// GetParser returns the parser.
GetParser() antlr.Parser
// IsArrContext differentiates from other interfaces.
IsArrContext()
}
type ArrContext struct {
*antlr.BaseParserRuleContext
parser antlr.Parser
}
func NewEmptyArrContext() *ArrContext {
var p = new(ArrContext)
p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(nil, -1)
p.RuleIndex = AgeParserRULE_arr
return p
}
func (*ArrContext) IsArrContext() {}
func NewArrContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *ArrContext {
var p = new(ArrContext)
p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(parent, invokingState)
p.parser = parser
p.RuleIndex = AgeParserRULE_arr
return p
}
func (s *ArrContext) GetParser() antlr.Parser { return s.parser }
func (s *ArrContext) AllValue() []IValueContext {
children := s.GetChildren()
len := 0
for _, ctx := range children {
if _, ok := ctx.(IValueContext); ok {
len++
}
}
tst := make([]IValueContext, len)
i := 0
for _, ctx := range children {
if t, ok := ctx.(IValueContext); ok {
tst[i] = t.(IValueContext)
i++
}
}
return tst
}
func (s *ArrContext) Value(i int) IValueContext {
var t antlr.RuleContext
j := 0
for _, ctx := range s.GetChildren() {
if _, ok := ctx.(IValueContext); ok {
if j == i {
t = ctx.(antlr.RuleContext)
break
}
j++
}
}
if t == nil {
return nil
}
return t.(IValueContext)
}
func (s *ArrContext) GetRuleContext() antlr.RuleContext {
return s
}
func (s *ArrContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string {
return antlr.TreesStringTree(s, ruleNames, recog)
}
func (s *ArrContext) EnterRule(listener antlr.ParseTreeListener) {
if listenerT, ok := listener.(AgeListener); ok {
listenerT.EnterArr(s)
}
}
func (s *ArrContext) ExitRule(listener antlr.ParseTreeListener) {
if listenerT, ok := listener.(AgeListener); ok {
listenerT.ExitArr(s)
}
}
func (s *ArrContext) Accept(visitor antlr.ParseTreeVisitor) interface{} {
switch t := visitor.(type) {
case AgeVisitor:
return t.VisitArr(s)
default:
return t.VisitChildren(s)
}
}
func (p *AgeParser) Arr() (localctx IArrContext) {
this := p
_ = this
localctx = NewArrContext(p, p.GetParserRuleContext(), p.GetState())
p.EnterRule(localctx, 14, AgeParserRULE_arr)
var _la int
defer func() {
p.ExitRule()
}()
defer func() {
if err := recover(); err != nil {
if v, ok := err.(antlr.RecognitionException); ok {
localctx.SetException(v)
p.GetErrorHandler().ReportError(p, v)
p.GetErrorHandler().Recover(p, v)
} else {
panic(err)
}
}
}()
p.SetState(85)
p.GetErrorHandler().Sync(p)
switch p.GetInterpreter().AdaptivePredict(p.GetTokenStream(), 6, p.GetParserRuleContext()) {
case 1:
p.EnterOuterAlt(localctx, 1)
{
p.SetState(72)
p.Match(AgeParserT__0)
}
{
p.SetState(73)
p.Value()
}
p.SetState(78)
p.GetErrorHandler().Sync(p)
_la = p.GetTokenStream().LA(1)
for _la == AgeParserT__1 {
{
p.SetState(74)
p.Match(AgeParserT__1)
}
{
p.SetState(75)
p.Value()
}
p.SetState(80)
p.GetErrorHandler().Sync(p)
_la = p.GetTokenStream().LA(1)
}
{
p.SetState(81)
p.Match(AgeParserT__2)
}
case 2:
p.EnterOuterAlt(localctx, 2)
{
p.SetState(83)
p.Match(AgeParserT__0)
}
{
p.SetState(84)
p.Match(AgeParserT__2)
}
}
return localctx
}
age-PG18-v1.7.0-rc0/drivers/golang/parser/age_visitor.go 0000664 0000000 0000000 00000002011 15134225711 0022656 0 ustar 00root root 0000000 0000000 // Code generated from java-escape by ANTLR 4.11.1. DO NOT EDIT.
package parser // Age
import "github.com/antlr/antlr4/runtime/Go/antlr/v4"
// A complete Visitor for a parse tree produced by AgeParser.
type AgeVisitor interface {
antlr.ParseTreeVisitor
// Visit a parse tree produced by AgeParser#ageout.
VisitAgeout(ctx *AgeoutContext) interface{}
// Visit a parse tree produced by AgeParser#vertex.
VisitVertex(ctx *VertexContext) interface{}
// Visit a parse tree produced by AgeParser#edge.
VisitEdge(ctx *EdgeContext) interface{}
// Visit a parse tree produced by AgeParser#path.
VisitPath(ctx *PathContext) interface{}
// Visit a parse tree produced by AgeParser#value.
VisitValue(ctx *ValueContext) interface{}
// Visit a parse tree produced by AgeParser#properties.
VisitProperties(ctx *PropertiesContext) interface{}
// Visit a parse tree produced by AgeParser#pair.
VisitPair(ctx *PairContext) interface{}
// Visit a parse tree produced by AgeParser#arr.
VisitArr(ctx *ArrContext) interface{}
}
age-PG18-v1.7.0-rc0/drivers/golang/parser/generate.go 0000664 0000000 0000000 00000000054 15134225711 0022142 0 ustar 00root root 0000000 0000000 package parser
//go:generate ./generate.sh
age-PG18-v1.7.0-rc0/drivers/golang/parser/generate.sh 0000775 0000000 0000000 00000000712 15134225711 0022153 0 ustar 00root root 0000000 0000000 #!/bin/sh
#
# Please be aware that this is used by the CI scripts
#
GRAMMAR_LOC="$(dirname $(pwd))/parser"
mkdir -p ~/tmp/antlr
cd ~/tmp/antlr
curl -LO "https://www.antlr.org/download/antlr-4.11.1-complete.jar"
echo "ANTLR installation complete."
echo "Generating Parser & Lexer..."
java -Xmx500M -cp "$HOME/tmp/antlr/antlr-4.11.1-complete.jar:$HOME/tmp/antlr/antlr-4.11.1-complete.jar" org.antlr.v4.Tool -Dlanguage=Go -visitor $GRAMMAR_LOC/Age.g4
exit 0
age-PG18-v1.7.0-rc0/drivers/golang/samples/ 0000775 0000000 0000000 00000000000 15134225711 0020172 5 ustar 00root root 0000000 0000000 age-PG18-v1.7.0-rc0/drivers/golang/samples/age_wrapper_sample.go 0000664 0000000 0000000 00000006345 15134225711 0024366 0 ustar 00root root 0000000 0000000 /*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package main
import (
"fmt"
"github.com/apache/age/drivers/golang/age"
)
// Do cypher query to AGE with Age API
func doWithAgeWrapper(dsn string, graphName string) {
ag, err := age.ConnectAge(graphName, dsn)
if err != nil {
panic(err)
}
tx, err := ag.Begin()
if err != nil {
panic(err)
}
_, err = tx.ExecCypher(0, "CREATE (n:Person {name: '%s'})", "Joe")
if err != nil {
panic(err)
}
_, err = tx.ExecCypher(0, "CREATE (n:Person {name: '%s', age: %d})", "Smith", 10)
if err != nil {
panic(err)
}
_, err = tx.ExecCypher(0, "CREATE (n:Person {name: '%s', weight:%f})", "Jack", 70.3)
if err != nil {
panic(err)
}
tx.Commit()
tx, err = ag.Begin()
if err != nil {
panic(err)
}
cursor, err := tx.ExecCypher(1, "MATCH (n:Person) RETURN n")
if err != nil {
panic(err)
}
count := 0
for cursor.Next() {
entities, err := cursor.GetRow()
if err != nil {
panic(err)
}
count++
vertex := entities[0].(*age.Vertex)
fmt.Println(count, "]", vertex.Id(), vertex.Label(), vertex.Props())
}
fmt.Println("Vertex Count:", count)
_, err = tx.ExecCypher(0, "MATCH (a:Person), (b:Person) WHERE a.name='%s' AND b.name='%s' CREATE (a)-[r:workWith {weight: %d}]->(b)",
"Jack", "Joe", 3)
if err != nil {
panic(err)
}
_, err = tx.ExecCypher(0, "MATCH (a:Person {name: '%s'}), (b:Person {name: '%s'}) CREATE (a)-[r:workWith {weight: %d}]->(b)",
"Joe", "Smith", 7)
if err != nil {
panic(err)
}
tx.Commit()
tx, err = ag.Begin()
if err != nil {
panic(err)
}
cursor, err = tx.ExecCypher(1, "MATCH p=()-[:workWith]-() RETURN p")
if err != nil {
panic(err)
}
count = 0
for cursor.Next() {
entities, err := cursor.GetRow()
if err != nil {
panic(err)
}
count++
path := entities[0].(*age.Path)
vertexStart := path.GetAsVertex(0)
edge := path.GetAsEdge(1)
vertexEnd := path.GetAsVertex(2)
fmt.Println(count, "]", vertexStart, edge.Props(), vertexEnd)
}
// Query with return many columns
cursor, err = tx.ExecCypher(3, "MATCH (a:Person)-[l:workWith]-(b:Person) RETURN a, l, b")
if err != nil {
panic(err)
}
count = 0
for cursor.Next() {
row, err := cursor.GetRow()
if err != nil {
panic(err)
}
count++
v1 := row[0].(*age.Vertex)
edge := row[1].(*age.Edge)
v2 := row[2].(*age.Vertex)
fmt.Println("ROW ", count, ">>", "\n\t", v1, "\n\t", edge, "\n\t", v2)
}
_, err = tx.ExecCypher(0, "MATCH (n:Person) DETACH DELETE n RETURN *")
if err != nil {
panic(err)
}
tx.Commit()
}
age-PG18-v1.7.0-rc0/drivers/golang/samples/main.go 0000664 0000000 0000000 00000002650 15134225711 0021450 0 ustar 00root root 0000000 0000000 /*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package main
import (
"fmt"
_ "github.com/lib/pq"
)
// var dsn string = "host={host} port={port} dbname={dbname} user={username} password={password} sslmode=disable"
var dsn string = "host=127.0.0.1 port=5432 dbname=postgres user=postgres password=agens sslmode=disable"
// var graphName string = "{graph_path}"
var graphName string = "testGraph"
func main() {
// Do cypher query to AGE with database/sql Tx API transaction control
fmt.Println("# Do cypher query with SQL API")
doWithSqlAPI(dsn, graphName)
// Do cypher query to AGE with Age API
fmt.Println("# Do cypher query with Age API")
doWithAgeWrapper(dsn, graphName)
}
age-PG18-v1.7.0-rc0/drivers/golang/samples/sql_api_sample.go 0000664 0000000 0000000 00000007321 15134225711 0023515 0 ustar 00root root 0000000 0000000 /*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package main
import (
"database/sql"
"fmt"
"github.com/apache/age/drivers/golang/age"
)
// Do cypher query to AGE with database/sql Tx API transaction control
func doWithSqlAPI(dsn string, graphName string) {
// Connect to PostgreSQL
db, err := sql.Open("postgres", dsn)
if err != nil {
panic(err)
}
// Confirm graph_path created
_, err = age.GetReady(db, graphName)
if err != nil {
panic(err)
}
// Tx begin for execute create vertex
tx, err := db.Begin()
if err != nil {
panic(err)
}
// Create vertices with Cypher
_, err = age.ExecCypher(tx, graphName, 0, "CREATE (n:Person {name: '%s', weight:%f})", "Joe", 67.3)
if err != nil {
panic(err)
}
_, err = age.ExecCypher(tx, graphName, 0, "CREATE (n:Person {name: '%s', weight:77.3, roles:['Dev','marketing']})", "Jack")
if err != nil {
panic(err)
}
_, err = age.ExecCypher(tx, graphName, 0, "CREATE (n:Person {name: '%s', weight:%d})", "Andy", 59)
if err != nil {
panic(err)
}
// Commit Tx
tx.Commit()
// Tx begin for queries
tx, err = db.Begin()
if err != nil {
panic(err)
}
// Query cypher
cypherCursor, err := age.ExecCypher(tx, graphName, 1, "MATCH (n:Person) RETURN n")
if err != nil {
panic(err)
}
// Unmarshal result data to Vertex row by row
for cypherCursor.Next() {
row, err := cypherCursor.GetRow()
if err != nil {
panic(err)
}
vertex := row[0].(*age.Vertex)
fmt.Println(vertex.Id(), vertex.Label(), vertex.Props())
}
// Create Paths (Edges)
_, err = age.ExecCypher(tx, graphName, 0, "MATCH (a:Person), (b:Person) WHERE a.name='%s' AND b.name='%s' CREATE (a)-[r:workWith {weight: %d}]->(b)", "Jack", "Joe", 3)
if err != nil {
panic(err)
}
_, err = age.ExecCypher(tx, graphName, 0, "MATCH (a:Person {name: '%s'}), (b:Person {name: '%s'}) CREATE (a)-[r:workWith {weight: %d}]->(b)", "Joe", "Andy", 7)
if err != nil {
panic(err)
}
tx.Commit()
tx, err = db.Begin()
if err != nil {
panic(err)
}
// Query Paths with Cypher
cypherCursor, err = age.ExecCypher(tx, graphName, 1, "MATCH p=()-[:workWith]-() RETURN p")
if err != nil {
panic(err)
}
for cypherCursor.Next() {
row, err := cypherCursor.GetRow()
if err != nil {
panic(err)
}
path := row[0].(*age.Path)
vertexStart := path.GetAsVertex(0)
edge := path.GetAsEdge(1)
vertexEnd := path.GetAsVertex(2)
fmt.Println(vertexStart, edge, vertexEnd)
}
// Query with return many columns
cursor, err := age.ExecCypher(tx, graphName, 3, "MATCH (a:Person)-[l:workWith]-(b:Person) RETURN a, l, b")
if err != nil {
panic(err)
}
count := 0
for cursor.Next() {
row, err := cursor.GetRow()
if err != nil {
panic(err)
}
count++
v1 := row[0].(*age.Vertex)
edge := row[1].(*age.Edge)
v2 := row[2].(*age.Vertex)
fmt.Println("ROW ", count, ">>", "\n\t", v1, "\n\t", edge, "\n\t", v2)
}
// Delete Vertices
_, err = age.ExecCypher(tx, graphName, 0, "MATCH (n:Person) DETACH DELETE n RETURN *")
if err != nil {
panic(err)
}
tx.Commit()
}
age-PG18-v1.7.0-rc0/drivers/jdbc/ 0000775 0000000 0000000 00000000000 15134225711 0016161 5 ustar 00root root 0000000 0000000 age-PG18-v1.7.0-rc0/drivers/jdbc/.gitattributes 0000664 0000000 0000000 00000001462 15134225711 0021057 0 ustar 00root root 0000000 0000000 # Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
*.bat text eol=crlf
age-PG18-v1.7.0-rc0/drivers/jdbc/.gitignore 0000664 0000000 0000000 00000001665 15134225711 0020161 0 ustar 00root root 0000000 0000000 # Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
# Ignore Gradle Wapper
gradle/wrapper/gradle-wrapper.jar
# Ignore Gradle project-specific cache directory
.gradle
# Ignore Gradle build output directory
build
age-PG18-v1.7.0-rc0/drivers/jdbc/README.md 0000664 0000000 0000000 00000007317 15134225711 0017450 0 ustar 00root root 0000000 0000000 # **AGE AGType parser and driver support for Java**
AGType parser and driver support for [Apache AGE](https://age.apache.org/), graph extension for PostgreSQL.
## Prerequisites
You should have installed following jar files and packages.
- [gradle](https://gradle.org/install/) build tool
- [postgres JDBC driver](https://jdbc.postgresql.org/download/)
- [antlr4-4.9.2-complete](https://repo1.maven.org/maven2/org/antlr/antlr4/4.9.2/)
- [common-lang3](http://www.java2s.com/Code/Jar/c/Downloadcommonlang3jar.htm)
- [commons-text-1.6](http://www.java2s.com/ref/jar/download-commonstext16jar-file.html)
Kindly unzip the jars if they are zipped before using them.
## Build from source
```bash
git clone https://github.com/apache/age.git
cd age/drivers/jdbc
gradle assemble
```
After the build completes successfully, a jar file will be created at path `age/drivers/jdbc/lib/build/libs/lib.jar`. Now add this JAR file to class path for your java project.
## Getting Started
* Install AGE on your machine. [https://age.apache.org/age-manual/master/index.html](https://age.apache.org/age-manual/master/index.html)
* Add the downloaded jar files to class path.
* Connect to the postgres server using pg JDBC drivers.
Lets say we have a graph named `demo_graph` having some nodes. In order to extract its nodes we can try following steps. To create some more graphs. [https://github.com/apache/age#quick-start](https://github.com/apache/age#quick-start). Following sample code shows how to return query result as `Agtype`.
```java
import org.apache.age.jdbc.base.Agtype;
import org.postgresql.jdbc.PgConnection;
import java.sql.*;
public class Sample {
static final String DB_URL = "jdbc:postgresql://localhost:5432/demo";
static final String USER = "postgres";
static final String PASS = "pass";
public static void main(String[] args) {
// Open a connection
try {
PgConnection connection = DriverManager.getConnection(DB_URL, USER, PASS).unwrap(PgConnection.class);
connection.addDataType("agtype", Agtype.class);
// configure AGE
Statement stmt = connection.createStatement();
stmt.execute("CREATE EXTENSION IF NOT EXISTS age;");
stmt.execute("LOAD 'age'");
stmt.execute("SET search_path = ag_catalog, \"$user\", public;");
// Run cypher
ResultSet rs = stmt.executeQuery("SELECT * from cypher('demo_graph', $$ MATCH (n) RETURN n $$) as (n agtype);");
while (rs.next()) {
// Returning Result as Agtype
Agtype returnedAgtype = rs.getObject(1, Agtype.class);
String nodeLabel = returnedAgtype.getMap().getObject("label").toString();
String nodeProp = returnedAgtype.getMap().getObject("properties").toString();
System.out.println("Vertex : " + nodeLabel + ", \tProps : " + nodeProp);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
```
Output
```
Vertex : Person, Props : {bornIn=Pakistan, name=imran}
Vertex : Person, Props : {bornIn=Pakistan, name=ali}
Vertex : Person, Props : {bornIn=US, name=james}
Vertex : Person, Props : {bornIn=Pakistan, name=ali}
Vertex : Person, Props : {bornIn=Pakistan, name=usama}
Vertex : Person, Props : {bornIn=Pakistan, name=akabr}
Vertex : Country, Props : {name=Pakistan}
Vertex : Country, Props : {name=US}
```
## For more information about [Apache AGE](https://age.apache.org/)
- Apache Age : [https://age.apache.org/](https://age.apache.org/)
- GitHub : [https://github.com/apache/age](https://github.com/apache/age)
- Document : [https://age.apache.org/age-manual/master/index.html](https://age.apache.org/age-manual/master/index.html)
age-PG18-v1.7.0-rc0/drivers/jdbc/gradle/ 0000775 0000000 0000000 00000000000 15134225711 0017417 5 ustar 00root root 0000000 0000000 age-PG18-v1.7.0-rc0/drivers/jdbc/gradle/wrapper/ 0000775 0000000 0000000 00000000000 15134225711 0021077 5 ustar 00root root 0000000 0000000 age-PG18-v1.7.0-rc0/drivers/jdbc/gradle/wrapper/gradle-wrapper.properties 0000664 0000000 0000000 00000001733 15134225711 0026135 0 ustar 00root root 0000000 0000000 # Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.0-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
age-PG18-v1.7.0-rc0/drivers/jdbc/gradlew 0000775 0000000 0000000 00000013477 15134225711 0017550 0 ustar 00root root 0000000 0000000 #!/usr/bin/env sh
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
##############################################################################
##
## Gradle start up script for UN*X
##
##############################################################################
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
PRG="$0"
# Need this for relative symlinks.
while [ -h "$PRG" ] ; do
ls=`ls -ld "$PRG"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
PRG="$link"
else
PRG=`dirname "$PRG"`"/$link"
fi
done
SAVED="`pwd`"
cd "`dirname \"$PRG\"`/" >/dev/null
APP_HOME="`pwd -P`"
cd "$SAVED" >/dev/null
APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
warn () {
echo "$*"
}
die () {
echo
echo "$*"
echo
exit 1
}
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
nonstop=false
case "`uname`" in
CYGWIN* )
cygwin=true
;;
Darwin* )
darwin=true
;;
MINGW* )
msys=true
;;
NONSTOP* )
nonstop=true
;;
esac
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD="$JAVA_HOME/jre/sh/java"
else
JAVACMD="$JAVA_HOME/bin/java"
fi
if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
else
JAVACMD="java"
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
# Increase the maximum file descriptors if we can.
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
MAX_FD_LIMIT=`ulimit -H -n`
if [ $? -eq 0 ] ; then
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
MAX_FD="$MAX_FD_LIMIT"
fi
ulimit -n $MAX_FD
if [ $? -ne 0 ] ; then
warn "Could not set maximum file descriptor limit: $MAX_FD"
fi
else
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
fi
fi
# For Darwin, add options to specify how the application appears in the dock
if $darwin; then
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
fi
# For Cygwin or MSYS, switch paths to Windows format before running java
if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
JAVACMD=`cygpath --unix "$JAVACMD"`
# We build the pattern for arguments to be converted via cygpath
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
SEP=""
for dir in $ROOTDIRSRAW ; do
ROOTDIRS="$ROOTDIRS$SEP$dir"
SEP="|"
done
OURCYGPATTERN="(^($ROOTDIRS))"
# Add a user-defined pattern to the cygpath arguments
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
fi
# Now convert the arguments - kludge to limit ourselves to /bin/sh
i=0
for arg in "$@" ; do
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
else
eval `echo args$i`="\"$arg\""
fi
i=`expr $i + 1`
done
case $i in
0) set -- ;;
1) set -- "$args0" ;;
2) set -- "$args0" "$args1" ;;
3) set -- "$args0" "$args1" "$args2" ;;
4) set -- "$args0" "$args1" "$args2" "$args3" ;;
5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
esac
fi
# Escape application args
save () {
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
echo " "
}
APP_ARGS=`save "$@"`
# Collect all arguments for the java command, following the shell quoting and substitution rules
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
exec "$JAVACMD" "$@"
age-PG18-v1.7.0-rc0/drivers/jdbc/gradlew.bat 0000664 0000000 0000000 00000005624 15134225711 0020305 0 ustar 00root root 0000000 0000000 @rem
@rem Licensed to the Apache Software Foundation (ASF) under one
@rem or more contributor license agreements. See the NOTICE file
@rem distributed with this work for additional information
@rem regarding copyright ownership. The ASF licenses this file
@rem to you under the Apache License, Version 2.0 (the
@rem "License"); you may not use this file except in compliance
@rem with the License. You may obtain a copy of the License at
@rem
@rem http://www.apache.org/licenses/LICENSE-2.0
@rem
@rem Unless required by applicable law or agreed to in writing,
@rem software distributed under the License is distributed on an
@rem "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
@rem KIND, either express or implied. See the License for the
@rem specific language governing permissions and limitations
@rem under the License.
@rem
@if "%DEBUG%" == "" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@rem
@rem ##########################################################################
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto execute
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto execute
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:execute
@rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
:end
@rem End local scope for the variables with windows NT shell
if "%ERRORLEVEL%"=="0" goto mainEnd
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
exit /b 1
:mainEnd
if "%OS%"=="Windows_NT" endlocal
:omega
age-PG18-v1.7.0-rc0/drivers/jdbc/lib/ 0000775 0000000 0000000 00000000000 15134225711 0016727 5 ustar 00root root 0000000 0000000 age-PG18-v1.7.0-rc0/drivers/jdbc/lib/build.gradle.kts 0000664 0000000 0000000 00000004464 15134225711 0022016 0 ustar 00root root 0000000 0000000 /*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import org.gradle.api.tasks.testing.logging.TestExceptionFormat
import org.gradle.api.tasks.testing.logging.TestLogEvent
plugins {
`java-library`
antlr
}
repositories {
mavenCentral()
}
dependencies {
implementation("org.postgresql:postgresql:42.6.0")
api("org.apache.commons:commons-text:1.10.0")
antlr("org.antlr:antlr4:4.12.0")
testImplementation("org.junit.jupiter:junit-jupiter-api:5.9.3")
testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine")
testRuntimeOnly("org.junit.platform:junit-platform-launcher")
testImplementation("org.testcontainers:testcontainers:1.18.0")
testImplementation("org.postgresql:postgresql:42.6.0")
testImplementation("org.slf4j:slf4j-api:2.0.7")
testImplementation("org.slf4j:slf4j-simple:2.0.7")
}
tasks.generateGrammarSource {
maxHeapSize = "64m"
source = project.objects
.sourceDirectorySet("antlr", "antlr")
.srcDir("${projectDir}/../../").apply {
include("*.g4")
}
arguments.addAll(arrayOf("-package", "org.apache.age.jdbc.antlr4"))
outputDirectory = file("$outputDirectory/org/apache/age/jdbc/antlr4")
}
tasks.test {
useJUnitPlatform();
testLogging {
// set options for log level LIFECYCLE
events(TestLogEvent.FAILED,
TestLogEvent.PASSED,
TestLogEvent.SKIPPED,
TestLogEvent.STANDARD_OUT)
exceptionFormat = TestExceptionFormat.FULL
showExceptions = true
showCauses = true
showStackTraces = true
}
}
age-PG18-v1.7.0-rc0/drivers/jdbc/lib/src/ 0000775 0000000 0000000 00000000000 15134225711 0017516 5 ustar 00root root 0000000 0000000 age-PG18-v1.7.0-rc0/drivers/jdbc/lib/src/main/ 0000775 0000000 0000000 00000000000 15134225711 0020442 5 ustar 00root root 0000000 0000000 age-PG18-v1.7.0-rc0/drivers/jdbc/lib/src/main/java/ 0000775 0000000 0000000 00000000000 15134225711 0021363 5 ustar 00root root 0000000 0000000 age-PG18-v1.7.0-rc0/drivers/jdbc/lib/src/main/java/org/ 0000775 0000000 0000000 00000000000 15134225711 0022152 5 ustar 00root root 0000000 0000000 age-PG18-v1.7.0-rc0/drivers/jdbc/lib/src/main/java/org/apache/ 0000775 0000000 0000000 00000000000 15134225711 0023373 5 ustar 00root root 0000000 0000000 age-PG18-v1.7.0-rc0/drivers/jdbc/lib/src/main/java/org/apache/age/ 0000775 0000000 0000000 00000000000 15134225711 0024127 5 ustar 00root root 0000000 0000000 age-PG18-v1.7.0-rc0/drivers/jdbc/lib/src/main/java/org/apache/age/jdbc/ 0000775 0000000 0000000 00000000000 15134225711 0025031 5 ustar 00root root 0000000 0000000 age-PG18-v1.7.0-rc0/drivers/jdbc/lib/src/main/java/org/apache/age/jdbc/AgtypeUnrecognizedList.java 0000664 0000000 0000000 00000002505 15134225711 0032340 0 ustar 00root root 0000000 0000000 /*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.age.jdbc;
import org.apache.age.jdbc.base.type.AgtypeAnnotation;
import org.apache.age.jdbc.base.type.AgtypeListImpl;
import org.apache.age.jdbc.base.type.UnrecognizedObject;
public class AgtypeUnrecognizedList extends AgtypeListImpl implements UnrecognizedObject,
AgtypeAnnotation {
private String annotation;
@Override
public String getAnnotation() {
return this.annotation;
}
@Override
public void setAnnotation(String annotation) {
this.annotation = annotation;
}
}
age-PG18-v1.7.0-rc0/drivers/jdbc/lib/src/main/java/org/apache/age/jdbc/AgtypeUnrecognizedMap.java 0000664 0000000 0000000 00000002502 15134225711 0032137 0 ustar 00root root 0000000 0000000 /*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.age.jdbc;
import org.apache.age.jdbc.base.type.AgtypeAnnotation;
import org.apache.age.jdbc.base.type.AgtypeMapImpl;
import org.apache.age.jdbc.base.type.UnrecognizedObject;
public class AgtypeUnrecognizedMap extends AgtypeMapImpl implements UnrecognizedObject,
AgtypeAnnotation {
private String annotation;
@Override
public String getAnnotation() {
return this.annotation;
}
@Override
public void setAnnotation(String annotation) {
this.annotation = annotation;
}
}
age-PG18-v1.7.0-rc0/drivers/jdbc/lib/src/main/java/org/apache/age/jdbc/base/ 0000775 0000000 0000000 00000000000 15134225711 0025743 5 ustar 00root root 0000000 0000000 age-PG18-v1.7.0-rc0/drivers/jdbc/lib/src/main/java/org/apache/age/jdbc/base/Agtype.java 0000664 0000000 0000000 00000016304 15134225711 0030043 0 ustar 00root root 0000000 0000000 /*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.age.jdbc.base;
import java.sql.SQLException;
import org.apache.age.jdbc.base.type.AgtypeAnnotation;
import org.apache.age.jdbc.base.type.AgtypeList;
import org.apache.age.jdbc.base.type.AgtypeMap;
import org.postgresql.util.PGobject;
import org.postgresql.util.PSQLException;
import org.postgresql.util.PSQLState;
/**
* Stores values of various kinds in a single object for use in PostgreSQL. The text representation
* is built on top of the JSON format
* specification. The goal of the text representation is making it compatible with JSON as much
* as possible so that valid JSON values can be parsed without effort.
*
* Valid Agtypes:
*
*
null
*
int
*
long
*
double
*
boolean
*
String
*
{@link AgtypeList}
*
{@link AgtypeMap}
*
*/
public class Agtype extends PGobject implements Cloneable {
private Object obj;
/**
* Public constructor for Agtype. Do not call directly, use the AgtypeFactory when creating
* Agtype objects on the client-side and casting the received object in the ResultSet when the
* object is created on the server-side.
*/
public Agtype() {
super.setType("ag_catalog.agtype");
}
Agtype(Object obj) {
this();
this.obj = obj;
}
/**
* TODO: need to define for PreparedStatement.
*/
@Override
public String getValue() {
if (value == null) {
value = AgtypeUtil.serializeAgtype(obj);
}
return value;
}
/**
* Parses the serialized value to it's Agtype value. {@inheritDoc}
*
* @param value Serialized representation of Agtype value.
* @throws SQLException throws if the String value cannot be parsed to a valid Agtype.
* @see AgtypeUtil#parse(String)
*/
@Override
public void setValue(String value) throws SQLException {
try {
obj = AgtypeUtil.parse(value);
} catch (Exception e) {
throw new PSQLException("Parsing AgType failed", PSQLState.DATA_ERROR, e);
}
super.setValue(value);
}
/**
* Returns the value stored in Agtype as a String. Attempts to perform an implicit conversion of
* types stored as non-strings values.
*
* @return value stored in Agtype as a String.
* @throws InvalidAgtypeException Throws if the stored Agtype value cannot be represented as a
* String.
* @see AgtypeUtil#getString(Object)
*/
public String getString() throws InvalidAgtypeException {
return AgtypeUtil.getString(obj);
}
/**
* Returns the value stored in Agtype as a generic object.
*
* @return value stored in Agtype as a generic object.
*/
public Object getObject() throws InvalidAgtypeException {
return obj;
}
/**
* Returns the value stored in Agtype as an int. Attempts to perform an implicit conversion of
* types stored as non-int values.
*
* @return value stored in Agtype as an int.
* @throws InvalidAgtypeException Throws if the stored Agtype value cannot be represented as an
* int.
* @see AgtypeUtil#getInt(Object)
*/
public int getInt() throws InvalidAgtypeException {
return AgtypeUtil.getInt(obj);
}
/**
* Returns the value stored in Agtype as a long. Attempts to perform an implicit conversion of
* types stored as non-long values.
*
* @return value stored in Agtype as a long.
* @throws InvalidAgtypeException Throws if the stored Agtype value cannot be represented as an
* long.
* @see AgtypeUtil#getLong(Object)
*/
public long getLong() throws InvalidAgtypeException {
return AgtypeUtil.getLong(obj);
}
/**
* Returns the value stored in Agtype as a double. Attempts to perform an implicit conversion of
* types stored as non-double values.
*
* @return value stored in Agtype as a double.
* @throws InvalidAgtypeException Throws if the stored Agtype value cannot be represented as an
* double.
* @see AgtypeUtil#getDouble(Object)
*/
public double getDouble() throws InvalidAgtypeException {
return AgtypeUtil.getDouble(obj);
}
/**
* Returns the value stored in Agtype as a boolean. Attempts to perform an implicit conversion
* of types stored as non-boolean values.
*
* @return value stored in Agtype as a long.
* @throws InvalidAgtypeException Throws if the stored Agtype value cannot be represented as an
* boolean.
* @see AgtypeUtil#getBoolean(Object)
*/
public boolean getBoolean() throws InvalidAgtypeException {
return AgtypeUtil.getBoolean(obj);
}
/**
* Returns the value stored in Agtype as an AgtypeList.
*
* @return value stored in Agtype as an AgtypeList.
* @throws InvalidAgtypeException Throws if the stored Agtype value cannot be represented as an
* AgtypeList.
* @see AgtypeUtil#getList(Object)
*/
public AgtypeList getList() throws InvalidAgtypeException {
return AgtypeUtil.getList(obj);
}
/**
* Returns the value stored in Agtype as an AgtypeMap.
*
* @return value stored in Agtype as an AgtypeMap.
* @throws InvalidAgtypeException Throws if the stored Agtype value cannot be represented as an
* AgtypeMap.
* @see AgtypeUtil#getMap(Object)
*/
public AgtypeMap getMap() throws InvalidAgtypeException {
return AgtypeUtil.getMap(obj);
}
/**
* Returns whether stored is Agtype Null.
*
* @return true if the value is Agtype null, false otherwise.
*/
public boolean isNull() {
return obj == null;
}
/**
* Returns a string representation of this Agtype object.
*
* @return a string representation of this Agtype object.
*/
@Override
public String toString() {
if (obj != null && obj instanceof AgtypeAnnotation) {
return obj
+ (type != null ? "::" + ((AgtypeAnnotation) obj).getAnnotation() : "");
}
return (obj != null ? obj.toString() : "null")
+ (type != null ? "::" + type : "");
}
}
age-PG18-v1.7.0-rc0/drivers/jdbc/lib/src/main/java/org/apache/age/jdbc/base/AgtypeFactory.java 0000664 0000000 0000000 00000004325 15134225711 0031373 0 ustar 00root root 0000000 0000000 /*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.age.jdbc.base;
import org.apache.age.jdbc.base.type.AgtypeList;
import org.apache.age.jdbc.base.type.AgtypeMap;
/**
* Factory for creating Agtype objects.
*
* @see Agtype
*/
public class AgtypeFactory {
/**
* Creates an Agtype object.
*
* @param obj Object to store in the an Agtype Object.
* @return new Agtype Object
* @throws InvalidAgtypeException Thrown if the object passed is not a {@link Agtype valid
* Agtype}
*/
public static Agtype create(Object obj) throws InvalidAgtypeException {
if (obj == null) {
return new Agtype(null);
} else if (obj instanceof Integer) {
return new Agtype(((Integer) obj).longValue());
} else if (obj instanceof Long) {
return new Agtype(obj);
} else if (obj instanceof String) {
return new Agtype(obj);
} else if (obj instanceof Boolean) {
return new Agtype(obj);
} else if (obj instanceof Double) {
return new Agtype(obj);
} else if (obj instanceof AgtypeList) {
return new Agtype(obj);
} else if (obj instanceof AgtypeMap) {
return new Agtype(obj);
} else {
String s = String
.format("%s is not a valid Agtype value", obj.getClass().getSimpleName());
throw new InvalidAgtypeException(s);
}
}
}
age-PG18-v1.7.0-rc0/drivers/jdbc/lib/src/main/java/org/apache/age/jdbc/base/AgtypeListener.java 0000664 0000000 0000000 00000015415 15134225711 0031553 0 ustar 00root root 0000000 0000000 /*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.age.jdbc.base;
import java.util.Stack;
import org.apache.age.jdbc.AgtypeUnrecognizedList;
import org.apache.age.jdbc.AgtypeUnrecognizedMap;
import org.apache.age.jdbc.antlr4.AgtypeBaseListener;
import org.apache.age.jdbc.antlr4.AgtypeParser.AgTypeContext;
import org.apache.age.jdbc.antlr4.AgtypeParser.ArrayValueContext;
import org.apache.age.jdbc.antlr4.AgtypeParser.FalseBooleanContext;
import org.apache.age.jdbc.antlr4.AgtypeParser.FloatValueContext;
import org.apache.age.jdbc.antlr4.AgtypeParser.IntegerValueContext;
import org.apache.age.jdbc.antlr4.AgtypeParser.NullValueContext;
import org.apache.age.jdbc.antlr4.AgtypeParser.ObjectValueContext;
import org.apache.age.jdbc.antlr4.AgtypeParser.PairContext;
import org.apache.age.jdbc.antlr4.AgtypeParser.StringValueContext;
import org.apache.age.jdbc.antlr4.AgtypeParser.TrueBooleanContext;
import org.apache.age.jdbc.antlr4.AgtypeParser.TypeAnnotationContext;
import org.apache.age.jdbc.base.type.AgtypeList;
import org.apache.age.jdbc.base.type.AgtypeListImpl;
import org.apache.age.jdbc.base.type.AgtypeMap;
import org.apache.age.jdbc.base.type.AgtypeMapImpl;
import org.apache.age.jdbc.base.type.AgtypeObject;
import org.apache.age.jdbc.base.type.UnrecognizedObject;
import org.apache.commons.text.StringEscapeUtils;
public class AgtypeListener extends AgtypeBaseListener {
// Will have List or Map
private final Stack objectStack = new Stack<>();
private final Stack annotationMap = new Stack<>();
Object rootObject;
Object lastValue;
boolean lastValueUndefined = true;
private long objectStackLength = 0;
private void pushObjectStack(AgtypeObject o) {
objectStackLength++;
this.objectStack.push(o);
}
private AgtypeObject popObjectStack() {
objectStackLength--;
return objectStack.pop();
}
private AgtypeObject peekObjectStack() {
return objectStack.peek();
}
private void mergeObjectIfTargetIsArray() {
if (objectStackLength >= 2) {
AgtypeObject firstObject = popObjectStack();
AgtypeObject secondObject = popObjectStack();
if (secondObject instanceof AgtypeListImpl) {
((AgtypeListImpl) secondObject).add(firstObject);
pushObjectStack(secondObject);
} else {
pushObjectStack(secondObject);
pushObjectStack(firstObject);
}
}
}
private void mergeObjectIfTargetIsMap(String key, Object value) {
AgtypeMapImpl agtypeMap = (AgtypeMapImpl) peekObjectStack();
agtypeMap.put(key, value);
}
private void addObjectValue() {
if (objectStackLength != 0) {
AgtypeObject currentObject = peekObjectStack();
if (currentObject instanceof AgtypeListImpl) {
((AgtypeListImpl) currentObject).add(this.lastValue);
lastValueUndefined = true;
return;
}
}
lastValueUndefined = false;
}
@Override
public void exitStringValue(StringValueContext ctx) {
this.lastValue = identString(ctx.STRING().getText());
addObjectValue();
}
@Override
public void exitIntegerValue(IntegerValueContext ctx) {
this.lastValue = Long.parseLong(ctx.INTEGER().getText());
addObjectValue();
}
@Override
public void exitFloatValue(FloatValueContext ctx) {
this.lastValue = Double.parseDouble(ctx.floatLiteral().getText());
addObjectValue();
}
@Override
public void exitTrueBoolean(TrueBooleanContext ctx) {
this.lastValue = true;
addObjectValue();
}
@Override
public void exitFalseBoolean(FalseBooleanContext ctx) {
this.lastValue = false;
addObjectValue();
}
@Override
public void exitNullValue(NullValueContext ctx) {
this.lastValue = null;
addObjectValue();
}
@Override
public void enterObjectValue(ObjectValueContext ctx) {
AgtypeMap agtypeMap = new AgtypeUnrecognizedMap();
pushObjectStack(agtypeMap);
}
@Override
public void exitObjectValue(ObjectValueContext ctx) {
mergeObjectIfTargetIsArray();
}
@Override
public void enterArrayValue(ArrayValueContext ctx) {
AgtypeList agtypeList = new AgtypeUnrecognizedList();
pushObjectStack(agtypeList);
}
@Override
public void exitArrayValue(ArrayValueContext ctx) {
mergeObjectIfTargetIsArray();
}
@Override
public void exitPair(PairContext ctx) {
String name = identString(ctx.STRING().getText());
if (!lastValueUndefined) {
mergeObjectIfTargetIsMap(name, this.lastValue);
lastValueUndefined = true;
} else {
Object lastValue = popObjectStack();
Object currentHeaderObject = peekObjectStack();
if (currentHeaderObject instanceof AgtypeListImpl) {
((AgtypeListImpl) currentHeaderObject).add(lastValue);
} else {
mergeObjectIfTargetIsMap(name, lastValue);
}
}
}
@Override
public void exitAgType(AgTypeContext ctx) {
if (objectStack.empty()) {
this.rootObject = this.lastValue;
return;
}
this.rootObject = popObjectStack();
}
@Override
public void enterTypeAnnotation(TypeAnnotationContext ctx) {
annotationMap.push(ctx.IDENT().getText());
}
@Override
public void exitTypeAnnotation(TypeAnnotationContext ctx) {
String annotation = annotationMap.pop();
Object currentObject = peekObjectStack();
if (currentObject instanceof UnrecognizedObject) {
((UnrecognizedObject) currentObject).setAnnotation(annotation);
}
}
private String identString(String quotesString) {
return StringEscapeUtils.unescapeJson(quotesString.substring(1, quotesString.length() - 1));
}
public Object getOutput() {
return this.rootObject;
}
}
age-PG18-v1.7.0-rc0/drivers/jdbc/lib/src/main/java/org/apache/age/jdbc/base/AgtypeUtil.java 0000664 0000000 0000000 00000033550 15134225711 0030703 0 ustar 00root root 0000000 0000000 /*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.age.jdbc.base;
import java.util.StringJoiner;
import org.antlr.v4.runtime.BaseErrorListener;
import org.antlr.v4.runtime.CharStream;
import org.antlr.v4.runtime.CharStreams;
import org.antlr.v4.runtime.CommonTokenStream;
import org.antlr.v4.runtime.RecognitionException;
import org.antlr.v4.runtime.Recognizer;
import org.antlr.v4.runtime.TokenStream;
import org.antlr.v4.runtime.tree.ParseTreeWalker;
import org.apache.age.jdbc.antlr4.AgtypeLexer;
import org.apache.age.jdbc.antlr4.AgtypeParser;
import org.apache.age.jdbc.base.type.AgtypeList;
import org.apache.age.jdbc.base.type.AgtypeListBuilder;
import org.apache.age.jdbc.base.type.AgtypeMap;
import org.apache.age.jdbc.base.type.AgtypeMapBuilder;
import org.apache.commons.text.StringEscapeUtils;
/**
* A set of utility methods to assist in using Agtype.
*/
public class AgtypeUtil {
private static BaseErrorListener baseErrorListener = new BaseErrorListener() {
@Override
public void syntaxError(Recognizer, ?> recognizer, Object offendingSymbol, int line,
int charPositionInLine, String msg, RecognitionException e) {
throw new IllegalStateException(
"Failed to parse at line " + line + " due to " + msg, e);
}
};
/**
* Do not instantiate AgtypeUtil, all methods are static.
*/
private AgtypeUtil() {
}
/**
* Returns to object as a double, if it is a valid double, otherwise will throw an exception.
*
All other values will throw an InvalidAgtypeException
*
*
* @param obj Object to parse
* @return Object as a double
* @throws NumberFormatException if the given object is a number or a string that cannot be
* parsed to a double
* @throws InvalidAgtypeException if the given object is not a number or string and cannot be
* converted to a double
*/
public static double getDouble(Object obj)
throws NumberFormatException, InvalidAgtypeException {
if (obj == null) {
return 0.0;
} else if (obj instanceof Double) {
return (Double) obj;
} else if (obj instanceof Boolean) {
return (Boolean) obj ? 1.0 : 0.0;
} else if (obj instanceof String) {
return Double.parseDouble((String) obj);
} else if (obj instanceof Long) {
return ((Long) obj).doubleValue();
}
throw new InvalidAgtypeException("Not a double: " + obj);
}
/**
* Returns the object as an integer, if it is a valid integer, otherwise will throw an
* exception.
*
Strings - Parsed to its integer value, an Exception will be thrown if its not an
* integer
*
All other values will throw an InvalidAgtypeException
*
*
* @param obj Object to parse
* @return Object as an int
* @throws NumberFormatException if the given object is a number or string that cannot be
* parsed into an Integer
* @throws InvalidAgtypeException if the given object is not a number of a string
*/
public static int getInt(Object obj) throws NumberFormatException, InvalidAgtypeException {
long l;
try {
l = getLong(obj);
if (l >= Integer.MIN_VALUE && l <= Integer.MAX_VALUE) {
return (int) l;
}
} catch (InvalidAgtypeException ex) {
throw new InvalidAgtypeException("Not a int: " + obj, ex);
}
throw new NumberFormatException("Bad value for type int: " + l);
}
/**
* Returns to object as a long, if it is a valid long, otherwise will throw an exception.
*
Strings - Parsed to its integer value, an Exception will be thrown if its not an
* integer
*
All other values will throw an InvalidAgtypeException
*
*
* @param obj Object to parse
* @return Object as an long
* @throws InvalidAgtypeException if the object cannot be converted to a Long
* @throws NumberFormatException if the given object is a number or string that cannot be
* parsed into a double
*/
public static long getLong(Object obj) throws NumberFormatException, InvalidAgtypeException {
if (obj == null) {
return 0;
} else if (obj instanceof Long) {
return (Long) obj;
} else if (obj instanceof String) {
return (long) Double.parseDouble((String) obj);
} else if (obj instanceof Boolean) {
return (boolean) obj ? 1 : 0;
} else if (obj instanceof Double) {
return ((Double) obj).longValue();
}
throw new InvalidAgtypeException("Not a long: " + obj);
}
/**
* Returns to object as a string, if it is a valid string, otherwise will throw an exception.
*
* Rules for converting from other types:
*
*
null - Returns null
*
Long - Returns a String representation of the Long
*
Double - Returns a String representation of the double
*
Boolean - Returns a String representation of the boolean
*
All other values will throw an InvalidAgtypeException
*
*
* @param obj Object to parse to a String
* @return Object as an string
* @throws InvalidAgtypeException if the object cannot be converted to a String
*/
public static String getString(Object obj) throws InvalidAgtypeException {
if (obj == null) {
return null;
} else if (obj instanceof String) {
return (String) obj;
} else if (obj instanceof Long) {
return Long.toString((long) obj);
} else if (obj instanceof Double) {
return Double.toString((double) obj);
} else if (obj instanceof Boolean) {
return Boolean.toString((boolean) obj);
}
throw new InvalidAgtypeException("Not a string: " + obj);
}
/**
* Returns to object as a boolean, if it is a valid boolean, otherwise will throw an exception.
*
* Data Conversions from other types
*
*
null - Returns false
*
Long - Returns false is the value is 0, returns true otherwise.
*
Double - Returns false is the value is 0.0, returns true otherwise.
*
String - Returns false if the length of the String is 0, returns true otherwise.
*
* {@link AgtypeList} - Returns false if the size of the list is 0, returns true otherwise.
*
*
* {@link AgtypeMap} - Returns false if the size of the map is 0, returns true otherwise.
*
*
All other values will throw an InvalidAgtypeException
*
*
* @param obj Object to parse
* @return Object as an boolean
* @throws InvalidAgtypeException if the object cannot be converted to a boolean
*/
public static boolean getBoolean(Object obj) throws InvalidAgtypeException {
if (obj == null) {
return false;
} else if (obj instanceof Boolean) {
return (Boolean) obj;
} else if (obj instanceof String) {
return ((String) obj).length() > 0;
} else if (obj instanceof Long) {
return (Long) obj != 0L;
} else if (obj instanceof Double) {
return (Double) obj != 0.0;
} else if (obj instanceof AgtypeList) {
return ((AgtypeList) obj).size() > 0;
} else if (obj instanceof AgtypeMap) {
return ((AgtypeMap) obj).size() > 0;
}
throw new InvalidAgtypeException("Not a valid Agtype: " + obj);
}
/**
* Returns to object as an {@link AgtypeList}. If this obj is not an AgtypeList, an
* InvalidAgtypeException will be thrown.
*
* @param obj Object to parse and return as an AgtypeList
* @return Object as an agTypeArray
* @throws InvalidAgtypeException if the object cannot be converted to an AgtypeList
*/
public static AgtypeList getList(Object obj) throws InvalidAgtypeException {
if (obj == null) {
return null;
} else if (obj instanceof AgtypeList) {
return (AgtypeList) obj;
}
throw new InvalidAgtypeException("Not an AgtypeList: " + obj);
}
/**
* Returns to object as an {@link AgtypeMap}. If this obj is not an AgtypeMap, an
* InvalidAgtypeException will be thrown.
*
* @param obj Object to parse and return as an AgtypeMap
* @return Object as an AgtypeMap
* @throws InvalidAgtypeException if the object cannot be converted to an AgtypeMap
*/
public static AgtypeMap getMap(Object obj) throws InvalidAgtypeException {
if (obj == null) {
return null;
} else if (obj instanceof AgtypeMap) {
return (AgtypeMap) obj;
}
throw new InvalidAgtypeException("Not an AgtypeMap: " + obj);
}
/**
* Creates a new AgtypeMapBuilder.
*
* @return Newly created AgtypeMapBuilder
*/
public static AgtypeMapBuilder createMapBuilder() {
return new AgtypeMapBuilder();
}
/**
* Creates a new AgtypeListBuilder.
*
* @return Newly created AgtypeListBuilder
*/
public static AgtypeListBuilder createListBuilder() {
return new AgtypeListBuilder();
}
/**
* Converts a serialized Agtype value into it's non-serialized value.
*
* @param strAgtype Serialized Agtype value to be parsed.
* @return Parsed object that can be stored in {@link Agtype}
* @throws IllegalStateException if the value cannot be parsed into an Agtype.
*/
public static Object parse(String strAgtype) throws IllegalStateException {
CharStream charStream = CharStreams.fromString(strAgtype);
AgtypeLexer lexer = new AgtypeLexer(charStream);
TokenStream tokens = new CommonTokenStream(lexer);
AgtypeParser parser = new AgtypeParser(tokens);
lexer.removeErrorListeners();
lexer.addErrorListener(baseErrorListener);
parser.removeErrorListeners();
parser.addErrorListener(baseErrorListener);
AgtypeListener agtypeListener = new AgtypeListener();
ParseTreeWalker walker = new ParseTreeWalker();
walker.walk(agtypeListener, parser.agType());
return agtypeListener.getOutput();
}
/**
* Converts the passed object into its serialized Agtype form.
*
* @param obj Agtype object to convert into its serialized form
* @return Serialized Agtype object
*/
static String serializeAgtype(Object obj) {
if (obj == null) {
return "null";
} else if (obj instanceof String) {
return '"' + StringEscapeUtils.escapeJson((String) obj) + '"';
} else if (obj instanceof AgtypeMap) {
StringJoiner join = new StringJoiner(",", "{", "}");
((AgtypeMap) obj).entrySet()
.stream()
.map((entry) -> new StringJoiner(":")
.add(serializeAgtype(entry.getKey()))
.add(serializeAgtype(entry.getValue()))
)
.forEach(join::merge);
return join.toString();
} else if (obj instanceof AgtypeList) {
StringJoiner join = new StringJoiner(",", "[", "]");
((AgtypeList) obj)
.stream()
.map(AgtypeUtil::serializeAgtype)
.forEach(join::add);
return join.toString();
}
return String.valueOf(obj);
}
}
InvalidAgtypeException.java 0000664 0000000 0000000 00000002222 15134225711 0033144 0 ustar 00root root 0000000 0000000 age-PG18-v1.7.0-rc0/drivers/jdbc/lib/src/main/java/org/apache/age/jdbc/base /*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.age.jdbc.base;
/**
* Runtime exception for when there is an invalid use of Agtype.
*/
public class InvalidAgtypeException extends RuntimeException {
public InvalidAgtypeException(String message) {
super(message);
}
public InvalidAgtypeException(String message, Throwable cause) {
super(message, cause);
}
}
age-PG18-v1.7.0-rc0/drivers/jdbc/lib/src/main/java/org/apache/age/jdbc/base/type/ 0000775 0000000 0000000 00000000000 15134225711 0026724 5 ustar 00root root 0000000 0000000 AgtypeAnnotation.java 0000664 0000000 0000000 00000001622 15134225711 0032775 0 ustar 00root root 0000000 0000000 age-PG18-v1.7.0-rc0/drivers/jdbc/lib/src/main/java/org/apache/age/jdbc/base/type /*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.age.jdbc.base.type;
public interface AgtypeAnnotation {
String getAnnotation();
}
age-PG18-v1.7.0-rc0/drivers/jdbc/lib/src/main/java/org/apache/age/jdbc/base/type/AgtypeList.java 0000664 0000000 0000000 00000016351 15134225711 0031662 0 ustar 00root root 0000000 0000000 /*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.age.jdbc.base.type;
import java.util.Iterator;
import java.util.Spliterator;
import java.util.function.Consumer;
import java.util.stream.Stream;
import org.apache.age.jdbc.base.Agtype;
import org.apache.age.jdbc.base.AgtypeUtil;
import org.apache.age.jdbc.base.InvalidAgtypeException;
/**
* Non-mutable list of Agtype values.
*
* @see AgtypeListBuilder
* @see Agtype
*/
public interface AgtypeList extends AgtypeObject {
/**
* Performs the given action for each element of the Iterable until all elements have been
* processed or the action throws an exception. Unless otherwise specified by the implementing
* class, actions are performed in the order of iteration (if an iteration order is specified).
* Exceptions thrown by the action are relayed to the caller.
*
* @param action The action to be performed for each element
* @throws NullPointerException - if the specified action is null
*/
void forEach(Consumer super Object> action);
/**
* Returns the String value at the specified position in this list. Throws an
* InvalidAgtypeException if the element is not a String.
*
* @param index index of the element to return
* @return the String value at the specified position in this list
* @throws InvalidAgtypeException if the value cannot be converted to a String
* @throws IndexOutOfBoundsException if the index is out of range (index {@literal <} 0 || index
* {@literal >}= size())
* @see AgtypeUtil#getString(Object)
*/
String getString(int index) throws InvalidAgtypeException;
/**
* Returns the int value at the specified position in this list. Throws an
* InvalidAgtypeException if the element is not an int.
*
* @param index index of the element to return
* @return the int value at the specified position in this list
* @throws InvalidAgtypeException if the value cannot be converted to an int
* @throws IndexOutOfBoundsException if the index is out of range (index {@literal <} 0 || index
* {@literal >}= size())
* @see AgtypeUtil#getInt(Object)
*/
int getInt(int index) throws InvalidAgtypeException;
/**
* Returns the long value at the specified position in this list. Throws an
* InvalidAgtypeException if the element is not a long.
*
* @param index index of the element to return
* @return the long value at the specified position in this list
* @throws InvalidAgtypeException if the value cannot be converted to a long
* @throws IndexOutOfBoundsException if the index is out of range (index {@literal <} 0 || index
* {@literal >}= size())
* @see AgtypeUtil#getLong(Object)
*/
long getLong(int index) throws InvalidAgtypeException;
/**
* Returns the double value at the specified position in this list. Throws an
* InvalidAgtypeException if the element is not a double.
*
* @param index index of the element to return
* @return the double value at the specified position in this list
* @throws InvalidAgtypeException if the value cannot be converted to a double
* @throws IndexOutOfBoundsException if the index is out of range (index {@literal <} 0 || index
* {@literal >}= size())
* @see AgtypeUtil#getDouble(Object)
*/
double getDouble(int index) throws InvalidAgtypeException;
/**
* Returns the double value at the specified position in this list. Throws an
* InvalidAgtypeException if the element is not a double.
*
* @param index index of the element to return
* @return the boolean value at the specified position in this list
* @throws InvalidAgtypeException if the value cannot be converted to a boolean
* @throws IndexOutOfBoundsException if the index is out of range (index {@literal <} 0 || index
* {@literal >}= size())
* @see AgtypeUtil#getBoolean(Object)
*/
boolean getBoolean(int index) throws InvalidAgtypeException;
/**
* Returns the AgtypeList at the specified position in this list. Throws an
* InvalidAgtypeException if the element is not an AgtypeList.
*
* @param index index of the element to return
* @return the AgtypeList at the specified position in this list
* @throws InvalidAgtypeException if the value stored at the index is not an AgtypeList
* @throws IndexOutOfBoundsException if the index is out of range (index {@literal <} 0 || index
* {@literal >}= size())
* @see AgtypeUtil#getList(Object)
*/
AgtypeList getList(int index) throws InvalidAgtypeException;
/**
* Returns the AgtypeMap at the specified position in this list. Throws an
* InvalidAgtypeException if the element is not an AgtypeMap.
*
* @param index index of the element to return
* @return the AgtypeList at the specified position in this list
* @throws InvalidAgtypeException if the value stored at the index is not an AgtypeMap
* @throws IndexOutOfBoundsException if the index is out of range (index {@literal <} 0 || index
* {@literal >}= size())
* @see AgtypeUtil#getMap(Object)
*/
AgtypeMap getMap(int index) throws InvalidAgtypeException;
/**
* Returns the object at the specified position in this list.
*
* @param index index of the element to return
* @return the object at the specified position in this list
* @throws IndexOutOfBoundsException if the index is out of range (index {@literal <} 0 || index
* {@literal >}= size())
*/
Object getObject(int index);
/**
* Returns an iterator over the elements.
*
* @return Iterator over the elements
*/
Iterator