Skip to content

Commit d49d8a6

Browse files
committed
Merge branch 'upstream-main'
2 parents 13c8f21 + ab6b2ab commit d49d8a6

69 files changed

Lines changed: 6806 additions & 253 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

bindings/python/scripts/verify_wheel_platform_tag.py

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -80,10 +80,19 @@ def parse_wheel_tag(wheel_path: Path) -> tuple[tuple[int, int], str]:
8080

8181

8282
def main() -> int:
83-
parser = argparse.ArgumentParser(description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter)
83+
parser = argparse.ArgumentParser(
84+
description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter
85+
)
8486
parser.add_argument("wheel", nargs="?", type=Path, help="Path to the .whl file")
85-
parser.add_argument("jre", nargs="?", type=Path, help="Path to the bundled JRE/JDK directory")
86-
parser.add_argument("--jre", dest="jre_only", type=Path, help="Inspect a JRE only and print its required tag")
87+
parser.add_argument(
88+
"jre", nargs="?", type=Path, help="Path to the bundled JRE/JDK directory"
89+
)
90+
parser.add_argument(
91+
"--jre",
92+
dest="jre_only",
93+
type=Path,
94+
help="Inspect a JRE only and print its required tag",
95+
)
8796
args = parser.parse_args()
8897

8998
if args.jre_only is not None:

bindings/python/tests/test_wheel_platform_tag.py

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,15 @@
1919

2020
import pytest
2121

22-
23-
SCRIPT_PATH = Path(__file__).resolve().parents[1] / "scripts" / "verify_wheel_platform_tag.py"
22+
SCRIPT_PATH = (
23+
Path(__file__).resolve().parents[1] / "scripts" / "verify_wheel_platform_tag.py"
24+
)
2425

2526

2627
def _load_verifier():
27-
spec = importlib.util.spec_from_file_location("verify_wheel_platform_tag", SCRIPT_PATH)
28+
spec = importlib.util.spec_from_file_location(
29+
"verify_wheel_platform_tag", SCRIPT_PATH
30+
)
2831
module = importlib.util.module_from_spec(spec)
2932
assert spec.loader is not None
3033
spec.loader.exec_module(module)
@@ -62,7 +65,9 @@ def test_parse_wheel_tag_extracts_version_and_arch(tmp_path: Path) -> None:
6265
assert arch == "x86_64"
6366

6467

65-
def test_main_succeeds_when_tag_matches(tmp_path: Path, capsys: pytest.CaptureFixture[str]) -> None:
68+
def test_main_succeeds_when_tag_matches(
69+
tmp_path: Path, capsys: pytest.CaptureFixture[str]
70+
) -> None:
6671
verifier = _load_verifier()
6772
jre_dir = tmp_path / "jre"
6873
jre_dir.mkdir()
@@ -76,7 +81,9 @@ def test_main_succeeds_when_tag_matches(tmp_path: Path, capsys: pytest.CaptureFi
7681
assert "OK" in capsys.readouterr().out
7782

7883

79-
def test_main_fails_when_tag_higher_than_jre(tmp_path: Path, capsys: pytest.CaptureFixture[str]) -> None:
84+
def test_main_fails_when_tag_higher_than_jre(
85+
tmp_path: Path, capsys: pytest.CaptureFixture[str]
86+
) -> None:
8087
"""Reproduces issue #4037: wheel tagged manylinux_2_35 but JRE only needs GLIBC_2.34."""
8188
verifier = _load_verifier()
8289
jre_dir = tmp_path / "jre"
@@ -93,7 +100,9 @@ def test_main_fails_when_tag_higher_than_jre(tmp_path: Path, capsys: pytest.Capt
93100
assert "manylinux_2_35" in captured.err or "manylinux_2_34" in captured.err
94101

95102

96-
def test_main_fails_when_tag_lower_than_jre(tmp_path: Path, capsys: pytest.CaptureFixture[str]) -> None:
103+
def test_main_fails_when_tag_lower_than_jre(
104+
tmp_path: Path, capsys: pytest.CaptureFixture[str]
105+
) -> None:
97106
"""A too-low tag would let the wheel install on systems where the JRE cannot run."""
98107
verifier = _load_verifier()
99108
jre_dir = tmp_path / "jre"

bolt/src/main/java/com/arcadedb/bolt/BoltNetworkExecutor.java

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -41,13 +41,13 @@
4141
import com.arcadedb.index.Index;
4242
import com.arcadedb.index.TypeIndex;
4343
import com.arcadedb.log.LogManager;
44+
import com.arcadedb.query.sql.executor.Result;
45+
import com.arcadedb.query.sql.executor.ResultSet;
4446
import com.arcadedb.schema.DocumentType;
4547
import com.arcadedb.schema.EdgeType;
4648
import com.arcadedb.schema.Property;
4749
import com.arcadedb.schema.Schema;
4850
import com.arcadedb.schema.VertexType;
49-
import com.arcadedb.query.sql.executor.Result;
50-
import com.arcadedb.query.sql.executor.ResultSet;
5151
import com.arcadedb.server.ArcadeDBServer;
5252
import com.arcadedb.server.security.ServerSecurityException;
5353
import com.arcadedb.server.security.ServerSecurityUser;
@@ -252,9 +252,9 @@ private boolean performHandshake() throws IOException {
252252
if (magic[0] == 0x16 && magic[1] == 0x03)
253253
LogManager.instance().log(this, Level.WARNING,
254254
"""
255-
TLS/SSL connection attempted on BOLT port but TLS is disabled. \
256-
Configure arcadedb.bolt.ssl=OPTIONAL or REQUIRED to enable TLS, \
257-
or use bolt:// (unencrypted) on the client""");
255+
TLS/SSL connection attempted on BOLT port but TLS is disabled. \
256+
Configure arcadedb.bolt.ssl=OPTIONAL or REQUIRED to enable TLS, \
257+
or use bolt:// (unencrypted) on the client""");
258258
else
259259
LogManager.instance().log(this, Level.WARNING,
260260
"Invalid BOLT magic bytes: [%d, %d, %d, %d]", magic[0], magic[1], magic[2], magic[3]);
@@ -1083,7 +1083,8 @@ private boolean handleSystemQuery(final String query) throws IOException {
10831083
|| normalized.startsWith("show point index")
10841084
|| normalized.startsWith("show lookup index")
10851085
|| normalized.startsWith("show fulltext index")
1086-
|| normalized.startsWith("show vector index")) {
1086+
|| normalized.startsWith("show vector index")
1087+
|| normalized.startsWith("show sparse_vector index")) {
10871088
// SHOW INDEXES / SHOW ... INDEXES - list indexes from ArcadeDB schema
10881089
currentFields = List.of("id", "name", "state", "populationPercent", "type", "entityType",
10891090
"labelsOrTypes", "properties", "indexProvider", "owningConstraint", "lastRead", "readCount");
@@ -1266,6 +1267,7 @@ private static String mapIndexTypeToNeo4j(final Schema.INDEX_TYPE type) {
12661267
case HASH -> "HASH";
12671268
case FULL_TEXT -> "FULLTEXT";
12681269
case LSM_VECTOR -> "VECTOR";
1270+
case LSM_SPARSE_VECTOR -> "SPARSE_VECTOR";
12691271
case GEOSPATIAL -> "POINT";
12701272
};
12711273
}
@@ -1278,6 +1280,7 @@ private static String mapIndexTypeToProvider(final Schema.INDEX_TYPE type) {
12781280
case HASH -> "hash-1.0";
12791281
case FULL_TEXT -> "fulltext-1.0";
12801282
case LSM_VECTOR -> "vector-2.0";
1283+
case LSM_SPARSE_VECTOR -> "sparse-vector-2.0";
12811284
case GEOSPATIAL -> "point-1.0";
12821285
};
12831286
}
@@ -1295,6 +1298,8 @@ private static boolean indexTypeMatchesFilter(final String filter, final String
12951298
return "FULLTEXT".equals(neoType);
12961299
if (filter.startsWith("show vector index"))
12971300
return "VECTOR".equals(neoType);
1301+
if (filter.startsWith("show sparse_vector index"))
1302+
return "SPARSE_VECTOR".equals(neoType);
12981303
return true;
12991304
}
13001305

bolt/src/test/java/com/arcadedb/bolt/BoltProtocolIT.java

Lines changed: 36 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -23,14 +23,21 @@
2323
import com.arcadedb.schema.Schema;
2424
import com.arcadedb.schema.Type;
2525
import com.arcadedb.test.BaseGraphServerTest;
26-
2726
import org.assertj.core.data.Offset;
2827
import org.junit.jupiter.api.AfterEach;
2928
import org.junit.jupiter.api.Test;
30-
import org.neo4j.driver.*;
29+
import org.neo4j.driver.AuthTokens;
30+
import org.neo4j.driver.Config;
31+
import org.neo4j.driver.Driver;
32+
import org.neo4j.driver.GraphDatabase;
33+
import org.neo4j.driver.Record;
34+
import org.neo4j.driver.Result;
35+
import org.neo4j.driver.Session;
36+
import org.neo4j.driver.SessionConfig;
37+
import org.neo4j.driver.Transaction;
38+
import org.neo4j.driver.Values;
3139
import org.neo4j.driver.exceptions.ClientException;
3240
import org.neo4j.driver.summary.ResultSummary;
33-
import org.neo4j.driver.Values;
3441

3542
import java.io.BufferedReader;
3643
import java.io.DataInputStream;
@@ -44,20 +51,18 @@
4451
import java.nio.ByteBuffer;
4552
import java.nio.charset.StandardCharsets;
4653
import java.security.MessageDigest;
47-
import java.util.Base64;
48-
import java.util.concurrent.CompletableFuture;
49-
import java.util.concurrent.CompletionStage;
50-
import java.util.concurrent.TimeUnit;
5154
import java.util.ArrayList;
55+
import java.util.Base64;
5256
import java.util.HashMap;
5357
import java.util.List;
5458
import java.util.Map;
59+
import java.util.concurrent.CompletableFuture;
60+
import java.util.concurrent.CompletionStage;
61+
import java.util.concurrent.TimeUnit;
5562

5663
import static org.assertj.core.api.Assertions.assertThat;
5764
import static org.assertj.core.api.Assertions.assertThatThrownBy;
5865

59-
import org.neo4j.driver.Record;
60-
6166
/**
6267
* Integration tests for BOLT protocol using Neo4j Java driver.
6368
*/
@@ -161,7 +166,8 @@ void createAndMatchEdge() {
161166
session.run("CREATE (a:EdgePerson {name: 'EdgeAlice'}), (b:EdgePerson {name: 'EdgeBob'})");
162167

163168
// Create edge
164-
session.run("MATCH (a:EdgePerson {name: 'EdgeAlice'}), (b:EdgePerson {name: 'EdgeBob'}) CREATE (a)-[:KNOWS {since: 2020}]->(b)");
169+
session.run(
170+
"MATCH (a:EdgePerson {name: 'EdgeAlice'}), (b:EdgePerson {name: 'EdgeBob'}) CREATE (a)-[:KNOWS {since: 2020}]->(b)");
165171

166172
// Query edge
167173
final Result result = session.run(
@@ -877,7 +883,8 @@ void concurrentSessions() throws Exception {
877883

878884
// Check for errors
879885
if (!errors.isEmpty()) {
880-
throw new AssertionError("Concurrent test failed with " + errors.size() + " errors: " + errors.get(0).getMessage(), errors.get(0));
886+
throw new AssertionError("Concurrent test failed with " + errors.size() + " errors: " + errors.get(0).getMessage(),
887+
errors.get(0));
881888
}
882889
}
883890

@@ -957,7 +964,8 @@ void largeParameterMap() {
957964
// Build a query that uses all parameters
958965
StringBuilder query = new StringBuilder("RETURN ");
959966
for (int i = 0; i < 50; i++) {
960-
if (i > 0) query.append(" + ");
967+
if (i > 0)
968+
query.append(" + ");
961969
query.append("$param").append(i);
962970
}
963971
query.append(" AS sum");
@@ -1103,7 +1111,8 @@ void httpDiscoveryOnBoltPort() throws Exception {
11031111
@Test
11041112
void systemDatabaseDbmsComponents() {
11051113
// Neo4j Desktop queries the "system" database for version info
1106-
try (final Driver driver = GraphDatabase.driver("bolt://localhost:7687", AuthTokens.basic("root", DEFAULT_PASSWORD_FOR_TESTS))) {
1114+
try (final Driver driver = GraphDatabase.driver("bolt://localhost:7687",
1115+
AuthTokens.basic("root", DEFAULT_PASSWORD_FOR_TESTS))) {
11071116
try (final Session session = driver.session(SessionConfig.forDatabase("system"))) {
11081117
final var result = session.run("CALL dbms.components()");
11091118
assertThat(result.hasNext()).isTrue();
@@ -1615,4 +1624,18 @@ void showVectorIndexesReturnsEmptyWithoutVectorIndexes() {
16151624
}
16161625
}
16171626
}
1627+
1628+
@Test
1629+
void showSparseVectorIndexesReturnsEmptyWithoutSparseVectorIndexes() {
1630+
try (Driver driver = getDriver()) {
1631+
try (Session session = driver.session(SessionConfig.forDatabase(getDatabaseName()))) {
1632+
final Result result = session.run("SHOW SPARSE_VECTOR INDEXES");
1633+
assertThat(result.keys()).containsExactly("id", "name", "state", "populationPercent", "type",
1634+
"entityType", "labelsOrTypes", "properties", "indexProvider", "owningConstraint", "lastRead", "readCount");
1635+
final List<Record> rows = result.list();
1636+
for (final Record r : rows)
1637+
assertThat(r.get("type").asString()).isEqualTo("SPARSE_VECTOR");
1638+
}
1639+
}
1640+
}
16181641
}

console/pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030
</parent>
3131

3232
<properties>
33-
<jline.version>4.0.12</jline.version>
33+
<jline.version>4.0.14</jline.version>
3434
</properties>
3535

3636
<artifactId>arcadedb-console</artifactId>

e2e-csharp/.gitignore

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
bin/
2+
obj/
3+
*.user
4+
*.suo
5+
.vs/
6+
TestResults/
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
<!--
2+
Copyright © 2021-present Arcade Data Ltd (info@arcadedata.com)
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
-->
16+
<Project Sdk="Microsoft.NET.Sdk">
17+
<PropertyGroup>
18+
<TargetFramework>net10.0</TargetFramework>
19+
<Nullable>enable</Nullable>
20+
<ImplicitUsings>enable</ImplicitUsings>
21+
<IsPackable>false</IsPackable>
22+
</PropertyGroup>
23+
24+
<ItemGroup>
25+
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="18.5.1" />
26+
<PackageReference Include="xunit" Version="2.9.3" />
27+
<PackageReference Include="xunit.runner.visualstudio" Version="2.8.2">
28+
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
29+
<PrivateAssets>all</PrivateAssets>
30+
</PackageReference>
31+
<PackageReference Include="Testcontainers" Version="4.11.0" />
32+
<PackageReference Include="Npgsql" Version="10.0.2" />
33+
</ItemGroup>
34+
</Project>
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
/*
2+
* Copyright © 2021-present Arcade Data Ltd (info@arcadedata.com)
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
using System.Net;
18+
using System.Net.Http.Headers;
19+
using System.Text;
20+
using DotNet.Testcontainers.Builders;
21+
using DotNet.Testcontainers.Containers;
22+
using Npgsql;
23+
using Xunit;
24+
25+
namespace ArcadeDB.E2ETests;
26+
27+
[CollectionDefinition("ArcadeDB")]
28+
public class ArcadeDbCollection : ICollectionFixture<ArcadeDbFixture> { }
29+
30+
public class ArcadeDbFixture : IAsyncLifetime
31+
{
32+
private const string RootUser = "root";
33+
private const string RootPassword = "playwithdata";
34+
35+
private IContainer _container = null!;
36+
public NpgsqlDataSource DataSource { get; private set; } = null!;
37+
38+
public async Task InitializeAsync()
39+
{
40+
var imageEnv = Environment.GetEnvironmentVariable("ARCADEDB_DOCKER_IMAGE");
41+
var image = string.IsNullOrWhiteSpace(imageEnv) ? "arcadedata/arcadedb:latest" : imageEnv;
42+
43+
_container = new ContainerBuilder(image)
44+
.WithPortBinding(2480, true)
45+
.WithPortBinding(5432, true)
46+
.WithEnvironment("JAVA_OPTS",
47+
$"-Darcadedb.server.rootPassword={RootPassword} " +
48+
"-Darcadedb.server.plugins=PostgresProtocolPlugin")
49+
.WithWaitStrategy(Wait.ForUnixContainer()
50+
.UntilHttpRequestIsSucceeded(r => r
51+
.ForPort(2480)
52+
.ForPath("/api/v1/ready")
53+
.ForStatusCode(HttpStatusCode.NoContent)))
54+
.Build();
55+
56+
await _container.StartAsync();
57+
58+
var httpPort = _container.GetMappedPublicPort(2480);
59+
var authHeader = new AuthenticationHeaderValue(
60+
"Basic", Convert.ToBase64String(Encoding.UTF8.GetBytes($"{RootUser}:{RootPassword}")));
61+
62+
using var http = new HttpClient();
63+
http.DefaultRequestHeaders.Authorization = authHeader;
64+
using var response = await http.PostAsync(
65+
$"http://{_container.Hostname}:{httpPort}/api/v1/server",
66+
new StringContent(
67+
"{\"command\":\"create database NpgsqlE2ETest\"}",
68+
Encoding.UTF8,
69+
"application/json"));
70+
response.EnsureSuccessStatusCode();
71+
72+
using var createTypeResponse = await http.PostAsync(
73+
$"http://{_container.Hostname}:{httpPort}/api/v1/command/NpgsqlE2ETest",
74+
new StringContent(
75+
"{\"language\":\"sql\",\"command\":\"CREATE DOCUMENT TYPE NpgsqlTest\"}",
76+
Encoding.UTF8,
77+
"application/json"));
78+
createTypeResponse.EnsureSuccessStatusCode();
79+
80+
var pgPort = _container.GetMappedPublicPort(5432);
81+
DataSource = NpgsqlDataSource.Create(
82+
$"Host={_container.Hostname};Port={pgPort};Database=NpgsqlE2ETest;" +
83+
$"Username={RootUser};Password={RootPassword};SSL Mode=Disable;" +
84+
"Server Compatibility Mode=NoTypeLoading;No Reset On Close=true");
85+
}
86+
87+
public async Task DisposeAsync()
88+
{
89+
if (DataSource is not null)
90+
await DataSource.DisposeAsync();
91+
if (_container is not null)
92+
await _container.DisposeAsync();
93+
}
94+
}

0 commit comments

Comments
 (0)