diff --git a/.github/workflows/integration-test-cluster-neo4j-5.yml b/.github/workflows/integration-test-cluster-neo4j-5.yml index eb8317cb..bab2e12a 100644 --- a/.github/workflows/integration-test-cluster-neo4j-5.yml +++ b/.github/workflows/integration-test-cluster-neo4j-5.yml @@ -12,8 +12,8 @@ jobs: tests: runs-on: ubuntu-latest env: - CONNECTION: neo4j://neo4j:testtest@localhost:7688 - name: "Running on PHP 8.0 with a Neo4j 5.6.0-enterprise cluster" + CONNECTION: neo4j://neo4j:testtest@localhost:7687 + name: "Running on PHP 8.0 with a Neo4j 5.10-enterprise cluster" steps: - uses: actions/checkout@v2 @@ -38,72 +38,84 @@ jobs: services: server1: - image: neo4j:5.6.0-enterprise + image: neo4j:5.10-enterprise ports: - - 7688:7688 - - 7475:7475 + - 7687:7687 + - 7473:7473 + - 7474:7474 env: NEO4J_initial_server_mode__constraint: PRIMARY NEO4J_dbms_cluster_discovery_endpoints: server1:5000,server2:5000,server3:5000 NEO4J_ACCEPT_LICENSE_AGREEMENT: yes - NEO4j_server_bolt_advertised_address: localhost:7688 - NEO4j_server_http_advertised_address: localhost:7478 + NEO4j_server_bolt_advertised_address: localhost:7687 + NEO4j_server_http_advertised_address: localhost:7474 + NEO4J_PLUGINS: '["apoc"]' NEO4J_AUTH: neo4j/testtest options: >- + --hostname server1 --health-cmd "wget -q --method=HEAD http://localhost:7474 || exit 1" --health-start-period "60s" --health-interval "30s" --health-timeout "15s" --health-retries "5" server2: - image: neo4j:5.6.0-enterprise + image: neo4j:5.10-enterprise ports: - - 7689:7689 - - 7476:7476 + - 8687:7687 + - 8473:7473 + - 8474:7474 env: NEO4J_initial_server_mode__constraint: PRIMARY NEO4J_dbms_cluster_discovery_endpoints: server1:5000,server2:5000,server3:5000 NEO4J_ACCEPT_LICENSE_AGREEMENT: yes - NEO4j_server_bolt_advertised_address: localhost:7689 - NEO4j_server_http_advertised_address: server2:7476 + NEO4j_server_bolt_advertised_address: localhost:8687 + NEO4j_server_http_advertised_address: localhost:8474 + NEO4J_PLUGINS: '["apoc"]' NEO4J_AUTH: neo4j/testtest options: >- + --hostname server2 --health-cmd "wget -q --method=HEAD http://localhost:7474 || exit 1" --health-start-period "60s" --health-interval "30s" --health-timeout "15s" --health-retries "5" server3: - image: neo4j:5.6.0-enterprise + image: neo4j:5.10-enterprise ports: - - 7690:7690 - - 7477:7477 + - 9474:7474 + - 9473:7473 + - 9687:7687 env: NEO4J_initial_server_mode__constraint: PRIMARY NEO4J_dbms_cluster_discovery_endpoints: server1:5000,server2:5000,server3:5000 NEO4J_ACCEPT_LICENSE_AGREEMENT: yes - NEO4j_server_bolt_advertised_address: localhost:7690 - NEO4j_server_http_advertised_address: server3:7477 + NEO4j_server_bolt_advertised_address: localhost:9687 + NEO4j_server_http_advertised_address: localhost:9474 + NEO4J_PLUGINS: '["apoc"]' NEO4J_AUTH: neo4j/testtest options: >- + --hostname server3 --health-cmd "wget -q --method=HEAD http://localhost:7474 || exit 1" --health-start-period "60s" --health-interval "30s" --health-timeout "15s" --health-retries "5" read-server4: - image: neo4j:5.6.0-enterprise + image: neo4j:5.10-enterprise ports: - - 7691:7691 - - 7478:7478 + - 10474:7474 + - 10473:7473 + - 10687:7687 env: - NEO4J_initial_server_mode__constraint: PRIMARY + NEO4J_initial_server_mode__constraint: SECONDARY NEO4J_dbms_cluster_discovery_endpoints: server1:5000,server2:5000,server3:5000 NEO4J_ACCEPT_LICENSE_AGREEMENT: yes - NEO4j_server_bolt_advertised_address: localhost:7691 - NEO4j_server_http_advertised_address: localhost:7478 + NEO4j_server_bolt_advertised_address: localhost:10687 + NEO4j_server_http_advertised_address: localhost:10474 + NEO4J_PLUGINS: '["apoc"]' NEO4J_AUTH: neo4j/testtest options: >- + --hostname read-server4 --health-cmd "wget -q --method=HEAD http://localhost:7474 || exit 1" --health-start-period "60s" --health-interval "30s" diff --git a/.github/workflows/integration-test-single-server.yml b/.github/workflows/integration-test-single-server.yml index e97b90a9..671c1a6b 100644 --- a/.github/workflows/integration-test-single-server.yml +++ b/.github/workflows/integration-test-single-server.yml @@ -11,11 +11,11 @@ on: jobs: tests: runs-on: ubuntu-latest - name: "Running on PHP 8.2 with a Neo4j 5.5 instance connecting over all available protocols" + name: "Running on PHP 8.2 with a Neo4j 5 instance connecting over all available protocols" services: neo4j: - image: neo4j:5.5 + image: neo4j:5 env: NEO4J_AUTH: neo4j/testtest NEO4JLABS_PLUGINS: '["apoc"]' diff --git a/README.md b/README.md index 5337b582..5d2ea688 100644 --- a/README.md +++ b/README.md @@ -19,13 +19,18 @@ ## See the driver in action -An example project exists on the [neo4j github](https://github.com/neo4j-examples/movies-neo4j-php-client). It uses Slim and neo4j-php-client to build an API for the classic movie's example of neo4j. + - [An implementation of the class movie database](https://github.com/neo4j-examples/movies-neo4j-php-client). It uses Slim and neo4j-php-client to build an API for the classic movie's example of neo4j. + - [An complete implementation of the realworld example](https://github.com/neo4j-examples/php-laravel-neo4j-realworld-example). It uses Laravel to implement the [real world example](https://github.com/gothinkster/realworld) project, _the mother of all demo apps_. + - [The friends api](https://github.com/neo4j-examples/friends-php-client) for the world's most corny example project leveraging the power of Neo4j. -### Follow along on the livestream +For some more detailed write-ups you can refer to these blogposts: -We are currently running a biweekly neo4j + laravel livestream were we are building the RealWorld example app. + - [How to build a JSON RESTful API with Neo4j, PHP and Open API](https://medium.com/neo4j/how-to-build-a-json-restful-api-with-neo4j-php-and-openapi-e45bf0a8956) + - [Building a Web App with Neo4j, AuraDB and PHP](https://medium.com/neo4j/building-a-web-app-with-neo4j-auradb-and-php-990deca0d213) + - [Connect to Neo4j with PHP](https://medium.com/neo4j/connect-to-neo4j-with-php-e10e24afedff) + - [Enterprise level PHP and Neo4j](https://medium.com/neo4j/enterprise-level-php-and-neo4j-e467a789e6b4) -The [github repostiory can be found here](https://github.com/neo4j-examples/php-laravel-neo4j-realworld-example), there are also [recordings](https://www.youtube.com/playlist?list=PL9Hl4pk2FsvViI9wmdDpRS7tZ8V6j4uJs). The live stream usually starts at 5 PM Brussels time on Wednesday, but you can [follow Florent on twitter](https://twitter.com/fbiville) for live updates in case the schedule changes. +Or watch any of these [videos](https://www.youtube.com/watch?v=qwz5XVtbfSY&list=PL9Hl4pk2FsvViI9wmdDpRS7tZ8V6j4uJs). ## Start your driving experience in three easy steps @@ -70,10 +75,47 @@ echo $result; // echos 'z' ## Decide how to send your Cypher queries You can control the driver using three different approaches: -- *Transaction functions* (recommended and portable) - *Auto committed queries* (easiest and most intuitive) +- *Transaction functions* (most portable) - *Unmanaged transactions* (for the highest degree of control) + +### Auto committed queries + +Auto committed queries are the most straightforward and most intuitive but have many drawbacks when running complex business logic or within a high availability environment. + +#### Run a simple cypher query + +```php +$client->run( + 'MERGE (user {email: $email})', //The query is a required parameter + ['email' => 'abc@hotmail.com'], //Requests can be optionally added + 'backup' //The default connection can be overridden +); +``` + +#### Run a statement object: + +```php +use Laudis\Neo4j\Databags\Statement; + +$statement = new Statement('MERGE (user {email: $email})', ['email' => 'abc@hotmail.com']); +$client->runStatement($statement, 'default'); +``` + +#### Running multiple queries at once + +The `runStatements` method will run all the statements at once. This method is an essential tool to reduce the number of database calls, especially when using the HTTP protocol. + +```php +use Laudis\Neo4j\Databags\Statement; + +$results = $client->runStatements([ + Statement::create('MATCH (x) RETURN x LIMIT 100'), + Statement::create('MERGE (x:Person {email: $email})', ['email' => 'abc@hotmail.com']) +]); +``` + ### Transaction functions Transaction functions are the **de facto** standard when using the driver. It is the most portable as it is resistant to a lot of the pitfalls when first developing with high availability solutions such as [Neo4j aura](https://neo4j.com/blog/neo4j-aura-enterprise-ga-release/) or a [cluster](https://neo4j.com/docs/operations-manual/current/clustering/). @@ -116,42 +158,6 @@ $client->writeTransaction(static function (TransactionInterface $tsx) use ($id) $externalCounter->incrementNodesCreated(); ``` -### Auto committed queries - -Auto committed queries are the most straightforward and most intuitive but have many drawbacks when running complex business logic or within a high availability environment. - -#### Run a simple cypher query - -```php -$client->run( - 'MERGE (user {email: $email})', //The query is a required parameter - ['email' => 'abc@hotmail.com'], //Requests can be optionally added - 'backup' //The default connection can be overridden -); -``` - -#### Run a statement object: - -```php -use Laudis\Neo4j\Databags\Statement; - -$statement = new Statement('MERGE (user {email: $email})', ['email' => 'abc@hotmail.com']); -$client->runStatement($statement, 'default'); -``` - -#### Running multiple queries at once - -The `runStatements` method will run all the statements at once. This method is an essential tool to reduce the number of database calls, especially when using the HTTP protocol. - -```php -use Laudis\Neo4j\Databags\Statement; - -$results = $client->runStatements([ - Statement::create('MATCH (x) RETURN x LIMIT 100'), - Statement::create('MERGE (x:Person {email: $email})', ['email' => 'abc@hotmail.com']) -]); -``` - ### Unmanaged transactions If you need lower-level access to the drivers' capabilities, then you want unmanaged transactions. They allow for completely controllable commits and rollbacks. @@ -261,22 +267,24 @@ $client->run('MATCH (x) WHERE x.slug in $listOrMap RETURN x', ['listOrMap' => [] ### Neo4j Version Support -| **Version** | **Tested** | -|-------------|-------------| -| 3.0 + | Yes | -| 4.0 + | Yes | +| **Version** | **Tested** | +|-------------|------------| +| 3.0 + | Yes | +| 4.0 + | Yes | +| 5.0 + | Yes | ### Neo4j Feature Support | **Feature** | **Supported?** | |----------------------|----------------| -| Authentication | Yes | -| Transactions | Yes | -| Http Protocol | Yes | -| Bolt Protocol | Yes | -| Cluster | Yes | -| Aura | Yes | -| Jolt Protocol | Roadmap | +| Authentication | Yes | +| Transactions | Yes | +| Http Protocol | Yes | +| Bolt Protocol | Yes | +| Cluster | Yes | +| Aura | Yes | +| Jolt Protocol | Yes | +| Bookmarks | Yes | ## In-depth requirements diff --git a/docker-compose.yml b/docker-compose.yml index cefb5747..096e8e73 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -8,17 +8,15 @@ x-definitions: x-shared-cluster-env: &common-cluster-env <<: *common-env - NEO4J_EDITION: 'enterprise' NEO4J_ACCEPT_LICENSE_AGREEMENT: 'yes' - EXTENDED_CONF: 'yes' + NEO4J_dbms_cluster_discovery_endpoints: server1:5000,server2:5000,server3:5000 x-shared-core-env: &common-core-env <<: *common-cluster-env NEO4J_initial_server_mode__constraint: 'PRIMARY' x-common: &common - image: neo4j:5.5 - user: ${USER_ID}:${GROUP_ID} + image: neo4j:5-enterprise healthcheck: test: [ "CMD-SHELL", "wget --no-verbose --tries=1 --spider localhost:7474 || exit 1" ] env_file: @@ -29,7 +27,6 @@ x-definitions: context: . dockerfile: Dockerfile image: neo4j-php-client:latest - user: ${USER_ID}:${GROUP_ID} volumes: - .:/opt/project x-common-cluster: @@ -38,8 +35,6 @@ x-definitions: image: neo4j:5-enterprise networks: neo4j-cluster: - aliases: - - neo4j-network networks: neo4j: @@ -57,95 +52,63 @@ services: - .env neo4j: <<: *common + image: neo4j:5.10-community hostname: neo4j networks: - neo4j - - neo4j-cluster ports: - - "7687:7687" - - "7474:7474" + - "11687:7687" + - "11474:7474" environment: <<: *common-env - NEO4J_EDITION: community - volumes: - - ./neo4j/neo4j.conf:/conf/neo4j.conf - - ./neo4j/data/neo4j:/var/lib/neo4j/data - - ./neo4j/logs/neo4j:/var/lib/neo4j/logs - - ./neo4j/conf/neo4j:/var/lib/neo4j/conf - - ./neo4j/import/neo4j:/var/lib/neo4j/import - - ./neo4j/metrics/neo4j:/var/lib/neo4j/metrics - - ./neo4j/licenses/neo4j:/var/lib/neo4j/licenses - - ./neo4j/ssl/neo4j:/var/lib/neo4j/ssl + NEO4j_server_bolt_advertised_address: localhost:11687 + NEO4j_server_http_advertised_address: localhost:11474 server1: <<: *common-cluster hostname: server1 ports: - - "7688:7687" - - "7475:7474" - volumes: - - ./neo4j/neo4j-cluster.conf:/conf/neo4j.conf - - ./neo4j/data/server1:/var/lib/neo4j/data - - ./neo4j/logs/server1:/var/lib/neo4j/logs - - ./neo4j/conf/server1:/var/lib/neo4j/conf - - ./neo4j/import/server1:/var/lib/neo4j/import - - ./neo4j/metrics/server1:/var/lib/neo4j/metrics - - ./neo4j/licenses/server1:/var/lib/neo4j/licenses - - ./neo4j/ssl/server1:/var/lib/neo4j/ssl + - "7687:7687" + - "7473:7473" + - "7474:7474" environment: <<: *common-core-env + NEO4j_server_bolt_advertised_address: localhost:7687 + NEO4j_server_http_advertised_address: localhost:7474 server2: <<: *common-cluster hostname: server2 ports: - - "7689:7687" - - "7476:7474" + - "8687:7687" + - "8473:7473" + - "8474:7474" environment: <<: *common-core-env - volumes: - - ./neo4j/neo4j-cluster.conf:/conf/neo4j.conf - - ./neo4j/data/server2:/var/lib/neo4j/data - - ./neo4j/logs/server2:/var/lib/neo4j/logs - - ./neo4j/conf/server2:/var/lib/neo4j/conf - - ./neo4j/import/server2:/var/lib/neo4j/import - - ./neo4j/metrics/server2:/var/lib/neo4j/metrics - - ./neo4j/licenses/server2:/var/lib/neo4j/licenses - - ./neo4j/ssl/server2:/var/lib/neo4j/ssl + NEO4j_server_bolt_advertised_address: localhost:8687 + NEO4j_server_http_advertised_address: localhost:8474 server3: <<: *common-cluster hostname: server3 ports: - - "7690:7687" - - "7477:7474" + - "9474:7474" + - "9473:7473" + - "9687:7687" environment: <<: *common-core-env - volumes: - - ./neo4j/neo4j-cluster.conf:/conf/neo4j.conf - - ./neo4j/data/server3:/var/lib/neo4j/data - - ./neo4j/logs/server3:/var/lib/neo4j/logs - - ./neo4j/conf/server3:/var/lib/neo4j/conf - - ./neo4j/import/server3:/var/lib/neo4j/import - - ./neo4j/metrics/server3:/var/lib/neo4j/metrics - - ./neo4j/licenses/server3:/var/lib/neo4j/licenses - - ./neo4j/ssl/server3:/var/lib/neo4j/ssl + NEO4j_server_bolt_advertised_address: localhost:9687 + NEO4j_server_http_advertised_address: localhost:9474 server4: <<: *common-cluster hostname: server4 ports: - - "7691:7687" - - "7478:7474" + - "10474:7474" + - "10473:7473" + - "10687:7687" environment: <<: *common-cluster-env NEO4J_initial_server_mode__constraint: 'SECONDARY' - volumes: - - ./neo4j/neo4j-cluster.conf:/conf/neo4j.conf - - ./neo4j/data/server4:/var/lib/neo4j/data - - ./neo4j/logs/server4:/var/lib/neo4j/logs - - ./neo4j/conf/server4:/var/lib/neo4j/conf - - ./neo4j/import/server4:/var/lib/neo4j/import - - ./neo4j/metrics/server4:/var/lib/neo4j/metrics - - ./neo4j/licenses/server4:/var/lib/neo4j/licenses - - ./neo4j/ssl/server4:/var/lib/neo4j/ssl + NEO4j_server_bolt_advertised_address: localhost:10687 + NEO4j_server_http_advertised_address: localhost:10474 diff --git a/neo4j/conf/neo4j/.gitignore b/neo4j/conf/neo4j/.gitignore deleted file mode 100644 index d6b7ef32..00000000 --- a/neo4j/conf/neo4j/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -* -!.gitignore diff --git a/neo4j/conf/server1/.gitignore b/neo4j/conf/server1/.gitignore deleted file mode 100644 index d6b7ef32..00000000 --- a/neo4j/conf/server1/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -* -!.gitignore diff --git a/neo4j/conf/server2/.gitignore b/neo4j/conf/server2/.gitignore deleted file mode 100644 index d6b7ef32..00000000 --- a/neo4j/conf/server2/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -* -!.gitignore diff --git a/neo4j/conf/server3/.gitignore b/neo4j/conf/server3/.gitignore deleted file mode 100644 index d6b7ef32..00000000 --- a/neo4j/conf/server3/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -* -!.gitignore diff --git a/neo4j/conf/server4/.gitignore b/neo4j/conf/server4/.gitignore deleted file mode 100644 index d6b7ef32..00000000 --- a/neo4j/conf/server4/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -* -!.gitignore diff --git a/neo4j/data/neo4j/.gitignore b/neo4j/data/neo4j/.gitignore deleted file mode 100644 index d6b7ef32..00000000 --- a/neo4j/data/neo4j/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -* -!.gitignore diff --git a/neo4j/data/server1/.gitignore b/neo4j/data/server1/.gitignore deleted file mode 100644 index d6b7ef32..00000000 --- a/neo4j/data/server1/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -* -!.gitignore diff --git a/neo4j/data/server2/.gitignore b/neo4j/data/server2/.gitignore deleted file mode 100644 index d6b7ef32..00000000 --- a/neo4j/data/server2/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -* -!.gitignore diff --git a/neo4j/data/server3/.gitignore b/neo4j/data/server3/.gitignore deleted file mode 100644 index d6b7ef32..00000000 --- a/neo4j/data/server3/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -* -!.gitignore diff --git a/neo4j/data/server4/.gitignore b/neo4j/data/server4/.gitignore deleted file mode 100644 index 48bbb6c2..00000000 --- a/neo4j/data/server4/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ - -* -!.gitignore diff --git a/neo4j/import/neo4j/.gitignore b/neo4j/import/neo4j/.gitignore deleted file mode 100755 index d6b7ef32..00000000 --- a/neo4j/import/neo4j/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -* -!.gitignore diff --git a/neo4j/import/server1/.gitignore b/neo4j/import/server1/.gitignore deleted file mode 100755 index d6b7ef32..00000000 --- a/neo4j/import/server1/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -* -!.gitignore diff --git a/neo4j/import/server2/.gitignore b/neo4j/import/server2/.gitignore deleted file mode 100755 index d6b7ef32..00000000 --- a/neo4j/import/server2/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -* -!.gitignore diff --git a/neo4j/import/server3/.gitignore b/neo4j/import/server3/.gitignore deleted file mode 100755 index d6b7ef32..00000000 --- a/neo4j/import/server3/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -* -!.gitignore diff --git a/neo4j/import/server4/.gitignore b/neo4j/import/server4/.gitignore deleted file mode 100755 index d6b7ef32..00000000 --- a/neo4j/import/server4/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -* -!.gitignore diff --git a/neo4j/licenses/neo4j/.gitignore b/neo4j/licenses/neo4j/.gitignore deleted file mode 100755 index d6b7ef32..00000000 --- a/neo4j/licenses/neo4j/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -* -!.gitignore diff --git a/neo4j/licenses/server1/.gitignore b/neo4j/licenses/server1/.gitignore deleted file mode 100755 index d6b7ef32..00000000 --- a/neo4j/licenses/server1/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -* -!.gitignore diff --git a/neo4j/licenses/server2/.gitignore b/neo4j/licenses/server2/.gitignore deleted file mode 100755 index d6b7ef32..00000000 --- a/neo4j/licenses/server2/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -* -!.gitignore diff --git a/neo4j/licenses/server3/.gitignore b/neo4j/licenses/server3/.gitignore deleted file mode 100755 index d6b7ef32..00000000 --- a/neo4j/licenses/server3/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -* -!.gitignore diff --git a/neo4j/licenses/server4/.gitignore b/neo4j/licenses/server4/.gitignore deleted file mode 100755 index d6b7ef32..00000000 --- a/neo4j/licenses/server4/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -* -!.gitignore diff --git a/neo4j/logs/neo4j/.gitignore b/neo4j/logs/neo4j/.gitignore deleted file mode 100644 index d6b7ef32..00000000 --- a/neo4j/logs/neo4j/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -* -!.gitignore diff --git a/neo4j/logs/server1/.gitignore b/neo4j/logs/server1/.gitignore deleted file mode 100644 index d6b7ef32..00000000 --- a/neo4j/logs/server1/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -* -!.gitignore diff --git a/neo4j/logs/server2/.gitignore b/neo4j/logs/server2/.gitignore deleted file mode 100644 index d6b7ef32..00000000 --- a/neo4j/logs/server2/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -* -!.gitignore diff --git a/neo4j/logs/server3/.gitignore b/neo4j/logs/server3/.gitignore deleted file mode 100644 index d6b7ef32..00000000 --- a/neo4j/logs/server3/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -* -!.gitignore diff --git a/neo4j/logs/server4/.gitignore b/neo4j/logs/server4/.gitignore deleted file mode 100644 index d6b7ef32..00000000 --- a/neo4j/logs/server4/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -* -!.gitignore diff --git a/neo4j/metrics/neo4j/.gitignore b/neo4j/metrics/neo4j/.gitignore deleted file mode 100755 index d6b7ef32..00000000 --- a/neo4j/metrics/neo4j/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -* -!.gitignore diff --git a/neo4j/metrics/server1/.gitignore b/neo4j/metrics/server1/.gitignore deleted file mode 100755 index d6b7ef32..00000000 --- a/neo4j/metrics/server1/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -* -!.gitignore diff --git a/neo4j/metrics/server2/.gitignore b/neo4j/metrics/server2/.gitignore deleted file mode 100755 index d6b7ef32..00000000 --- a/neo4j/metrics/server2/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -* -!.gitignore diff --git a/neo4j/metrics/server3/.gitignore b/neo4j/metrics/server3/.gitignore deleted file mode 100755 index d6b7ef32..00000000 --- a/neo4j/metrics/server3/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -* -!.gitignore diff --git a/neo4j/metrics/server4/.gitignore b/neo4j/metrics/server4/.gitignore deleted file mode 100755 index d6b7ef32..00000000 --- a/neo4j/metrics/server4/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -* -!.gitignore diff --git a/neo4j/neo4j-cluster.conf b/neo4j/neo4j-cluster.conf deleted file mode 100644 index e3e4dac5..00000000 --- a/neo4j/neo4j-cluster.conf +++ /dev/null @@ -1,35 +0,0 @@ -dbms.security.allow_csv_import_from_file_urls=true -server.memory.pagecache.size=100M -server.memory.heap.initial_size=100M - -# The behavior of the initial discovery is determined by the parameters `dbms.cluster.discovery.type` and `dbms.cluster.discovery.endpoints`. -# The DNS strategy fetches the IP addresses of the cluster members using the DNS A records. -dbms.cluster.discovery.type=DNS - -# The value of `dbms.cluster.discovery.endpoints` should be set to a single domain name and the port of the discovery service. -# The domain name returns an A record for every server in the cluster when a DNS lookup is performed. -# Each A record returned by DNS should contain the IP address of the server in the cluster. -# The configured server uses all the IP addresses from the A records to join or form a cluster. -# The discovery port must be the same on all servers when using this configuration. -dbms.cluster.discovery.endpoints=neo4j-network:5000 - -# Address (the public hostname/IP address of the machine) -# and port setting that specifies where this instance advertises for discovery protocol messages from other members of the cluster. -server.discovery.advertised_address=$(hostname -i) - -# Address (the public hostname/IP address of the machine) -# and port setting that specifies where this instance advertises for Raft messages within the cluster. -server.cluster.raft.advertised_address=$(hostname) - - # Address (the public hostname/IP address of the machine) - # and port setting that specifies where this instance advertises for requests for transactions in the transaction-shipping catchup protocol. -server.cluster.advertised_address=$(hostname) - -# Enable server-side routing -dbms.routing.enabled=true - -# Use server-side routing for neo4j:// protocol connections. -dbms.routing.default_router=SERVER - -# The advertised address for the intra-cluster routing connector. -server.routing.advertised_address=$(hostname) diff --git a/neo4j/neo4j.conf b/neo4j/neo4j.conf deleted file mode 100644 index 47da851d..00000000 --- a/neo4j/neo4j.conf +++ /dev/null @@ -1,3 +0,0 @@ -dbms.security.allow_csv_import_from_file_urls=true -server.memory.pagecache.size=100M -server.memory.heap.initial_size=100M diff --git a/neo4j/ssl/neo4j/.gitignore b/neo4j/ssl/neo4j/.gitignore deleted file mode 100755 index d6b7ef32..00000000 --- a/neo4j/ssl/neo4j/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -* -!.gitignore diff --git a/neo4j/ssl/server1/.gitignore b/neo4j/ssl/server1/.gitignore deleted file mode 100755 index d6b7ef32..00000000 --- a/neo4j/ssl/server1/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -* -!.gitignore diff --git a/neo4j/ssl/server2/.gitignore b/neo4j/ssl/server2/.gitignore deleted file mode 100755 index d6b7ef32..00000000 --- a/neo4j/ssl/server2/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -* -!.gitignore diff --git a/neo4j/ssl/server3/.gitignore b/neo4j/ssl/server3/.gitignore deleted file mode 100755 index d6b7ef32..00000000 --- a/neo4j/ssl/server3/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -* -!.gitignore diff --git a/neo4j/ssl/server4/.gitignore b/neo4j/ssl/server4/.gitignore deleted file mode 100755 index d6b7ef32..00000000 --- a/neo4j/ssl/server4/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -* -!.gitignore diff --git a/src/Basic/Client.php b/src/Basic/Client.php index e3afc0ff..4a9dd018 100644 --- a/src/Basic/Client.php +++ b/src/Basic/Client.php @@ -14,7 +14,6 @@ namespace Laudis\Neo4j\Basic; use Laudis\Neo4j\Contracts\ClientInterface; -use Laudis\Neo4j\Contracts\DriverInterface; use Laudis\Neo4j\Databags\Statement; use Laudis\Neo4j\Databags\SummarizedResult; use Laudis\Neo4j\Databags\TransactionConfiguration; @@ -53,9 +52,19 @@ public function beginTransaction(?iterable $statements = null, ?string $alias = return new UnmanagedTransaction($this->client->beginTransaction($statements, $alias, $config)); } - public function getDriver(?string $alias): DriverInterface + public function getDriver(?string $alias): Driver { - return $this->client->getDriver($alias); + $driver = $this->client->getDriver($alias); + if ($driver instanceof Driver) { + return $driver; + } + + return new Driver($driver); + } + + public function hasDriver(string $alias): bool + { + return $this->client->hasDriver($alias); } public function writeTransaction(callable $tsxHandler, ?string $alias = null, ?TransactionConfiguration $config = null) diff --git a/src/Client.php b/src/Client.php index 53a31855..5a3e4b4e 100644 --- a/src/Client.php +++ b/src/Client.php @@ -153,6 +153,11 @@ public function verifyConnectivity(?string $driver = null): bool return $this->driverSetups->verifyConnectivity($this->defaultSessionConfiguration, $driver); } + public function hasDriver(string $alias): bool + { + return $this->driverSetups->hasDriver($alias); + } + public function bindTransaction(?string $alias = null, ?TransactionConfiguration $config = null): void { $alias ??= $this->driverSetups->getDefaultAlias(); diff --git a/src/Common/DriverSetupManager.php b/src/Common/DriverSetupManager.php index 8b9a6ec0..f954df67 100644 --- a/src/Common/DriverSetupManager.php +++ b/src/Common/DriverSetupManager.php @@ -77,6 +77,11 @@ public function withSetup(DriverSetup $setup, ?string $alias = null, ?int $prior return $tbr; } + public function hasDriver(string $alias): bool + { + return array_key_exists($alias, $this->driverSetups); + } + /** * @return DriverInterface */ diff --git a/src/Contracts/ClientInterface.php b/src/Contracts/ClientInterface.php index 7185ebf6..5a5f1d4c 100644 --- a/src/Contracts/ClientInterface.php +++ b/src/Contracts/ClientInterface.php @@ -76,6 +76,11 @@ public function beginTransaction(?iterable $statements = null, ?string $alias = */ public function getDriver(?string $alias): DriverInterface; + /** + * Checks to see if the Client has the driver registered with the provided alias. + */ + public function hasDriver(string $alias): bool; + /** * @template U * diff --git a/tests/Integration/OGMFormatterIntegrationTest.php b/tests/Integration/OGMFormatterIntegrationTest.php index 6c7f3e89..3a4b50ec 100644 --- a/tests/Integration/OGMFormatterIntegrationTest.php +++ b/tests/Integration/OGMFormatterIntegrationTest.php @@ -70,8 +70,8 @@ public function testMap(): void { $map = $this->getSession()->transaction(static fn (TransactionInterface $tsx) => $tsx->run('RETURN {a: "b", c: "d"} as map')->first()->get('map')); self::assertInstanceOf(CypherMap::class, $map); - self::assertEquals(['a' => 'b', 'c' => 'd'], $map->toArray()); - self::assertEquals(json_encode(['a' => 'b', 'c' => 'd'], JSON_THROW_ON_ERROR), json_encode($map, JSON_THROW_ON_ERROR)); + self::assertEqualsCanonicalizing(['a' => 'b', 'c' => 'd'], $map->toArray()); + self::assertEqualsCanonicalizing(json_encode(['a' => 'b', 'c' => 'd'], JSON_THROW_ON_ERROR), json_encode($map, JSON_THROW_ON_ERROR)); } public function testBoolean(): void