Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ edges.insert({"_from": "students/03", "_to": "lectures/CSC101"})
# Traverse the graph in outbound direction, breath-first.
query = """
FOR v, e, p IN 1..3 OUTBOUND 'students/01' GRAPH 'school'
OPTIONS { bfs: true, uniqueVertices: 'global' }
OPTIONS { order: 'bfs', uniqueVertices: 'global' }
RETURN {vertex: v, edge: e, path: p}
"""
cursor = db.aql.execute(query)
Expand Down
157 changes: 10 additions & 147 deletions arango/collection.py
Original file line number Diff line number Diff line change
Expand Up @@ -866,6 +866,9 @@ def find_near(
:rtype: arango.cursor.Cursor
:raises arango.exceptions.DocumentGetError: If retrieval fails.
"""
m = "find_near is deprecated in ArangoDB 4.0"
warn(m, DeprecationWarning, stacklevel=2)

assert isinstance(latitude, Number), "latitude must be a number"
assert isinstance(longitude, Number), "longitude must be a number"
assert is_none_or_int(limit), "limit must be a non-negative int"
Expand Down Expand Up @@ -988,6 +991,9 @@ def find_in_radius(
:rtype: arango.cursor.Cursor
:raises arango.exceptions.DocumentGetError: If retrieval fails.
"""
m = "find_in_radius is deprecated in ArangoDB 4.0"
warn(m, DeprecationWarning, stacklevel=2)

assert isinstance(latitude, Number), "latitude must be a number"
assert isinstance(longitude, Number), "longitude must be a number"
assert isinstance(radius, Number), "radius must be a number"
Expand Down Expand Up @@ -1335,112 +1341,6 @@ def response_handler(resp: Response) -> Json:

return self._execute(request, response_handler)

def add_hash_index(
self,
fields: Sequence[str],
unique: Optional[bool] = None,
sparse: Optional[bool] = None,
deduplicate: Optional[bool] = None,
name: Optional[str] = None,
in_background: Optional[bool] = None,
) -> Result[Json]:
"""Create a new hash index.

.. warning::

The index types `hash` and `skiplist` are aliases for the persistent
index type and should no longer be used to create new indexes. The
aliases will be removed in a future version.

:param fields: Document fields to index.
:type fields: [str]
:param unique: Whether the index is unique.
:type unique: bool | None
:param sparse: If set to True, documents with None in the field
are also indexed. If set to False, they are skipped.
:type sparse: bool | None
:param deduplicate: If set to True, inserting duplicate index values
from the same document triggers unique constraint errors.
:type deduplicate: bool | None
:param name: Optional name for the index.
:type name: str | None
:param in_background: Do not hold the collection lock.
:type in_background: bool | None
:return: New index details.
:rtype: dict
:raise arango.exceptions.IndexCreateError: If create fails.
"""
m = "add_hash_index is deprecated. Using add_index with {'type': 'hash'} instead." # noqa: E501
warn(m, DeprecationWarning, stacklevel=2)

data: Json = {"type": "hash", "fields": fields}

if unique is not None:
data["unique"] = unique
if sparse is not None:
data["sparse"] = sparse
if deduplicate is not None:
data["deduplicate"] = deduplicate
if name is not None:
data["name"] = name
if in_background is not None:
data["inBackground"] = in_background

return self.add_index(data, formatter=True)

def add_skiplist_index(
self,
fields: Sequence[str],
unique: Optional[bool] = None,
sparse: Optional[bool] = None,
deduplicate: Optional[bool] = None,
name: Optional[str] = None,
in_background: Optional[bool] = None,
) -> Result[Json]:
"""Create a new skiplist index.

.. warning::

The index types `hash` and `skiplist` are aliases for the persistent
index type and should no longer be used to create new indexes. The
aliases will be removed in a future version.

:param fields: Document fields to index.
:type fields: [str]
:param unique: Whether the index is unique.
:type unique: bool | None
:param sparse: If set to True, documents with None in the field
are also indexed. If set to False, they are skipped.
:type sparse: bool | None
:param deduplicate: If set to True, inserting duplicate index values
from the same document triggers unique constraint errors.
:type deduplicate: bool | None
:param name: Optional name for the index.
:type name: str | None
:param in_background: Do not hold the collection lock.
:type in_background: bool | None
:return: New index details.
:rtype: dict
:raise arango.exceptions.IndexCreateError: If create fails.
"""
m = "add_skiplist_index is deprecated. Using add_index with {'type': 'skiplist'} instead." # noqa: E501
warn(m, DeprecationWarning, stacklevel=2)

data: Json = {"type": "skiplist", "fields": fields}

if unique is not None:
data["unique"] = unique
if sparse is not None:
data["sparse"] = sparse
if deduplicate is not None:
data["deduplicate"] = deduplicate
if name is not None:
data["name"] = name
if in_background is not None:
data["inBackground"] = in_background

return self.add_index(data, formatter=True)

def add_geo_index(
self,
fields: Fields,
Expand Down Expand Up @@ -1487,45 +1387,6 @@ def add_geo_index(

return self.add_index(data, formatter=True)

def add_fulltext_index(
self,
fields: Sequence[str],
min_length: Optional[int] = None,
name: Optional[str] = None,
in_background: Optional[bool] = None,
) -> Result[Json]:
"""Create a new fulltext index.

.. warning::
This method is deprecated since ArangoDB 3.10 and will be removed
in a future version of the driver.

:param fields: Document fields to index.
:type fields: [str]
:param min_length: Minimum number of characters to index.
:type min_length: int | None
:param name: Optional name for the index.
:type name: str | None
:param in_background: Do not hold the collection lock.
:type in_background: bool | None
:return: New index details.
:rtype: dict
:raise arango.exceptions.IndexCreateError: If create fails.
"""
m = "add_fulltext_index is deprecated. Using add_index with {'type': 'fulltext'} instead." # noqa: E501
warn(m, DeprecationWarning, stacklevel=2)

data: Json = {"type": "fulltext", "fields": fields}

if min_length is not None:
data["minLength"] = min_length
if name is not None:
data["name"] = name
if in_background is not None:
data["inBackground"] = in_background

return self.add_index(data, formatter=True)

def add_persistent_index(
self,
fields: Sequence[str],
Expand Down Expand Up @@ -1790,7 +1651,8 @@ def insert_many(
can be used to save resources.
:type silent: bool
:param overwrite: If set to True, operation does not fail on duplicate
keys and the existing documents are replaced.
keys and the existing documents are replaced. **Removed** in ArangoDB
v4.0.0. Use overwrite_mode instead.
:type overwrite: bool
:param return_old: Include body of the old documents if replaced.
Applies only when value of **overwrite** is set to True.
Expand Down Expand Up @@ -2611,7 +2473,8 @@ def insert(
can be used to save resources.
:type silent: bool
:param overwrite: If set to True, operation does not fail on duplicate
key and existing document is overwritten (replace-insert).
key and existing document is overwritten (replace-insert). **Removed**
in ArangoDB v4.0.0. Use overwrite_mode instead.
:type overwrite: bool
:param return_old: Include body of the old document if overwritten.
Ignored if parameter **silent** is set to True.
Expand Down
6 changes: 4 additions & 2 deletions arango/database.py
Original file line number Diff line number Diff line change
Expand Up @@ -573,6 +573,9 @@ def required_db_version(self) -> Result[str]:
:rtype: str
:raise arango.exceptions.ServerRequiredDBVersionError: If retrieval fails.
"""
m = "target-version is removed in ArangoDB 4.0"
warn(m, DeprecationWarning, stacklevel=2)

request = Request(method="get", endpoint="/_admin/database/target-version")

def response_handler(resp: Response) -> str:
Expand Down Expand Up @@ -1115,7 +1118,7 @@ def metrics(self) -> Result[str]:
:rtype: str
:raise arango.exceptions.ServerMetricsError: If operation fails.
"""
request = Request(method="get", endpoint="/_admin/metrics/v2")
request = Request(method="get", endpoint="/_admin/metrics")

def response_handler(resp: Response) -> str:
if resp.is_success:
Expand Down Expand Up @@ -1554,7 +1557,6 @@ def response_handler(resp: Response) -> Jsons:
"name": col["name"],
"system": col["isSystem"],
"type": StandardCollection.types[col["type"]],
"status": StandardCollection.statuses[col["status"]],
}
for col in resp.body["result"]
]
Expand Down
4 changes: 4 additions & 0 deletions arango/replication.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
__all__ = ["Replication"]

from typing import Optional, Sequence
from warnings import warn

from arango.api import ApiGroup
from arango.exceptions import (
Expand Down Expand Up @@ -325,6 +326,9 @@ def logger_first_tick(self) -> Result[str]:
:rtype: str
:raise arango.exceptions.ReplicationLoggerFirstTickError: If retrieval fails.
"""
m = "/_api/replication/logger-first-tick endpoint is removed in ArangoDB v4.0"
warn(m, DeprecationWarning, stacklevel=2)

request = Request(
method="get",
endpoint="/_api/replication/logger-first-tick",
Expand Down
18 changes: 15 additions & 3 deletions arango/wal.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
__all__ = ["WAL"]

from typing import Optional
from warnings import warn

from arango.api import ApiGroup
from arango.exceptions import (
Expand Down Expand Up @@ -28,12 +29,15 @@ class WAL(ApiGroup): # pragma: no cover
"""WAL (Write-Ahead Log) API wrapper."""

def properties(self) -> Result[Json]:
"""Return WAL properties.
"""Return WAL properties. **Removed** in ArangoDB v4.0.0.

:return: WAL properties.
:rtype: dict
:raise arango.exceptions.WALPropertiesError: If retrieval fails.
"""
m = "/_admin/wal/properties was removed in ArangoDB v4.0.0."
warn(m, DeprecationWarning, stacklevel=2)

request = Request(method="get", endpoint="/_admin/wal/properties")

def response_handler(resp: Response) -> Json:
Expand All @@ -52,7 +56,7 @@ def configure(
throttle_wait: Optional[int] = None,
throttle_limit: Optional[int] = None,
) -> Result[Json]:
"""Configure WAL properties.
"""Configure WAL properties. **Removed in ArangoDB v4.0.0.

:param oversized_ops: If set to True, operations bigger than a single
log file are allowed to be executed and stored.
Expand All @@ -74,6 +78,9 @@ def configure(
:rtype: dict
:raise arango.exceptions.WALConfigureError: If operation fails.
"""
m = "/_admin/wal/properties was removed in ArangoDB v4.0.0."
warn(m, DeprecationWarning, stacklevel=2)

data: Json = {}
if oversized_ops is not None:
data["allowOversizeEntries"] = oversized_ops
Expand All @@ -98,7 +105,9 @@ def response_handler(resp: Response) -> Json:
return self._execute(request, response_handler)

def transactions(self) -> Result[Json]:
"""Return details on currently running WAL transactions.
"""**Removed** in ArangoDB v4.0.0.

Return details on currently running WAL transactions.

Fields in the returned details are as follows:

Expand All @@ -118,6 +127,9 @@ def transactions(self) -> Result[Json]:
:rtype: dict
:raise arango.exceptions.WALTransactionListError: If retrieval fails.
"""
m = "/_admin/wal/transactions was removed in ArangoDB v4.0.0."
warn(m, DeprecationWarning, stacklevel=2)

request = Request(method="get", endpoint="/_admin/wal/transactions")

def response_handler(resp: Response) -> Json:
Expand Down
2 changes: 1 addition & 1 deletion docs/graph.rst
Original file line number Diff line number Diff line change
Expand Up @@ -377,7 +377,7 @@ over edges and vertices using various algorithms.
# AQL to perform a graph traversal
query = """
FOR v, e, p IN 1..3 OUTBOUND 'teachers/jon' GRAPH 'school'
OPTIONS { bfs: true, uniqueVertices: 'global' }
OPTIONS { order: 'bfs', uniqueVertices: 'global' }
RETURN {vertex: v, edge: e, path: p}
"""

Expand Down
18 changes: 10 additions & 8 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,7 @@ def pytest_configure(config):
)

db_version = sys_db.version()
global_data.db_version = version.parse(db_version.split("-")[0])

# Create a user and non-system database for testing.
username = generate_username()
Expand All @@ -161,8 +162,9 @@ def pytest_configure(config):
col_name = generate_col_name()
tst_col = tst_db.create_collection(col_name, edge=False)

tst_col.add_index({"type": "skiplist", "fields": ["val"]})
tst_col.add_index({"type": "fulltext", "fields": ["text"]})
tst_col.add_index({"type": "persistent", "fields": ["val"]})
if global_data.db_version < version.parse("4.0.0"):
tst_col.add_index({"type": "fulltext", "fields": ["text"]})
geo_index = tst_col.add_index({"type": "geo", "fields": ["loc"]})

# Create a legacy edge collection for testing.
Expand All @@ -189,7 +191,6 @@ def pytest_configure(config):
global_data.username = username
global_data.password = password
global_data.db_name = tst_db_name
global_data.db_version = version.parse(db_version.split("-")[0])
global_data.sys_db = sys_db
global_data.tst_db = tst_db
global_data.bad_db = bad_db
Expand Down Expand Up @@ -220,11 +221,12 @@ def pytest_unconfigure(*_): # pragma: no cover
# Remove all test async jobs.
sys_db.clear_async_jobs()

# Remove all test tasks.
for task in sys_db.tasks():
task_name = task["name"]
if task_name.startswith("test_task"):
sys_db.delete_task(task_name, ignore_missing=True)
if global_data.db_version < version.parse("4.0.0"):
# Remove all test tasks.
for task in sys_db.tasks():
task_name = task["name"]
if task_name.startswith("test_task"):
sys_db.delete_task(task_name, ignore_missing=True)

# Remove all test users.
for user in sys_db.users():
Expand Down
5 changes: 4 additions & 1 deletion tests/test_aql.py
Original file line number Diff line number Diff line change
Expand Up @@ -284,7 +284,10 @@ def test_aql_query_force_one_shard_attribute_value(db, skip_tests, cluster):
assert len(results) == 0


def test_aql_function_management(db, bad_db):
def test_aql_function_management(db, bad_db, db_version):
if db_version >= version.parse("4.0.0"):
pytest.skip("Javascript is not available in ArangoDB v4.0")

fn_group = "functions::temperature"
fn_name_1 = "functions::temperature::celsius_to_fahrenheit"
fn_body_1 = "function (celsius) { return celsius * 1.8 + 32; }"
Expand Down
4 changes: 3 additions & 1 deletion tests/test_cluster.py
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,9 @@ def test_cluster_server_engine(sys_db, bad_db, cluster):
assert err.value.error_code in {FORBIDDEN, DATABASE_NOT_FOUND}


def test_cluster_server_statistics(sys_db, bad_db, cluster):
def test_cluster_server_statistics(sys_db, bad_db, cluster, db_version):
if db_version >= version.parse("4.0.0"):
pytest.skip("Server statistics endpoint is removed in ArangoDB v4.0")
if not cluster:
pytest.skip("Only tested in a cluster setup")

Expand Down
Loading
Loading