Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RDBC-781 Python client - various tests #208

Draft
wants to merge 3 commits into
base: v5.2
Choose a base branch
from
Draft
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: 2 additions & 0 deletions ravendb/documents/session/document_session.py
Original file line number Diff line number Diff line change
Expand Up @@ -456,6 +456,8 @@ def counters_for_entity(self, entity: object) -> SessionDocumentCounters:
return SessionDocumentCounters(self, entity)

def time_series_for(self, document_id: str, name: str = None) -> SessionDocumentTimeSeries:
if not isinstance(document_id, str):
raise TypeError("Method time_series_for expects a string. Did you want to call time_series_for_entity?")
return SessionDocumentTimeSeries(self, document_id, name)

def time_series_for_entity(self, entity: object, name: str = None) -> SessionDocumentTimeSeries:
Expand Down
38 changes: 22 additions & 16 deletions ravendb/documents/session/loaders/include.py
Original file line number Diff line number Diff line change
Expand Up @@ -358,23 +358,29 @@ def include_all_counters(self) -> SubscriptionIncludeBuilder:
self._include_all_counters("")
return self

def include_time_series_by_range_type_and_time(
self, name: str, ts_type: TimeSeriesRangeType, time: TimeValue
) -> SubscriptionIncludeBuilder:
self._include_time_series_by_range_type_and_time("", name, ts_type, time)
return self

def include_time_series_by_range_type_and_count(
self, name: str, ts_type: TimeSeriesRangeType, count: int
) -> SubscriptionIncludeBuilder:
self._include_time_series_by_range_type_and_count("", name, ts_type, count)
return self

def include_all_time_series_by_range_type_and_count(
self, ts_type: TimeSeriesRangeType, count: int
) -> SubscriptionIncludeBuilder:
self._include_time_series_by_range_type_and_count("", constants.TimeSeries.ALL, ts_type, count)
return self

# def include_time_series(
# self,
# name:str,
# ts_type: TimeSeriesRangeType,
# time: TimeValue
# ) -> SubscriptionIncludeBuilder:
# self._include_time_series_by_range_type_and_time("", name, ts_type, time)
# return self
#
# def include_time_series_by_range_type_and_count(
# self,
# name:str,
# ts_type: TimeSeriesRangeType,
# time: TimeValue
# ) -> SubscriptionIncludeBuilder:
# self._include_time_series_by_range_type_and_count("", name, type, count)
def include_all_time_series_by_range_type_and_time(
self, ts_type: TimeSeriesRangeType, time: TimeValue
) -> SubscriptionIncludeBuilder:
self._include_time_series_by_range_type_and_time("", constants.TimeSeries.ALL, ts_type, time)
return self


class TimeSeriesIncludeBuilder(IncludeBuilderBase):
Expand Down
75 changes: 38 additions & 37 deletions ravendb/documents/subscriptions/document_subscriptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
from typing import Optional, Type, TypeVar, Dict, List, TYPE_CHECKING

from ravendb.documents.operations.ongoing_tasks import ToggleOngoingTaskStateOperation, OngoingTaskType
from ravendb.documents.session.tokens.query_tokens.definitions import CounterIncludesToken, TimeSeriesIncludesToken
from ravendb.documents.session.tokens.query_tokens.query_token import QueryToken
from ravendb.documents.session.utils.includes_util import IncludesUtil
from ravendb.documents.commands.subscriptions import (
Expand Down Expand Up @@ -96,11 +97,11 @@ def ensure_criteria(self, criteria: SubscriptionCreationOptions, object_type: Ty

number_of_includes_added = 0

if builder._documents_to_include is not None and not len(builder._documents_to_include) == 0:
if builder.documents_to_include is not None and not len(builder.documents_to_include) == 0:
query_builder.append(os.linesep)
query_builder.append("include ")

for inc in builder._documents_to_include:
for inc in builder.documents_to_include:
include = "doc." + inc
if number_of_includes_added > 0:
query_builder.append(",")
Expand All @@ -115,41 +116,41 @@ def ensure_criteria(self, criteria: SubscriptionCreationOptions, object_type: Ty
query_builder.append(f"'{include}'" if QueryToken.is_keyword(include) else include)

number_of_includes_added += 1
# todo: uncomment on Counters and TimeSeries development
# if builder._is_all_counters:
# if number_of_includes_added == 0:
# query_builder.append(os.linesep)
# query_builder.append("include ")
#
# token = CountersIncludesToken.all("")
# token.write_to(query_builder)
# number_of_includes_added += 1
#
# elif builder._counters_to_include:
# if number_of_includes_added:
# query_builder.append(os.linesep)
# query_builder.append("include ")
#
# for counter_name in builder._counters_to_include:
# if number_of_includes_added > 0:
# query_builder.append(",")
#
# token = CountersToIncludeToken.create("", counter_name)
# token.write_to(query_builder)
#
# number_of_includes_added += 1
#
# if builder._time_series_to_include:
# for time_series_range in builder._time_series_to_include:
# if number_of_includes_added == 0:
# query_builder.append(os.linesep)
# query_builder.append("include ")
#
# if number_of_includes_added > 0:
# query_builder.append(",")
#
# token = TimeSeriesIncludeToken.create("", time_series_range)
# token.write_to(query_builder)

if builder.is_all_counters:
if number_of_includes_added == 0:
query_builder.append(os.linesep)
query_builder.append("include ")

token = CounterIncludesToken.all("")
token.write_to(query_builder)
number_of_includes_added += 1

elif builder.counters_to_include:
if number_of_includes_added:
query_builder.append(os.linesep)
query_builder.append("include ")

for counter_name in builder.counters_to_include:
if number_of_includes_added > 0:
query_builder.append(",")

token = CounterIncludesToken.create("", counter_name)
token.write_to(query_builder)

number_of_includes_added += 1

if builder.time_series_to_include:
for time_series_range in builder.time_series_to_include:
if number_of_includes_added == 0:
query_builder.append(os.linesep)
query_builder.append("include ")

if number_of_includes_added > 0:
query_builder.append(",")

token = TimeSeriesIncludesToken.create("", time_series_range)
token.write_to(query_builder)

criteria.query = "".join(query_builder)
return criteria
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
from datetime import datetime, timedelta

from ravendb import GetStatisticsOperation
from ravendb.documents.smuggler.common import DatabaseItemType
from ravendb.infrastructure.entities import User
from ravendb.infrastructure.operations import CreateSampleDataOperation
from ravendb.tests.test_base import TestBase

Expand Down Expand Up @@ -74,3 +77,17 @@ def test_can_get_stats(self):
self.assertIsNotNone(index_information.type)

self.assertIsNotNone(index_information.last_indexing_time)

def test_can_get_stats_for_counters_and_time_series(self):
with self.store.open_session() as session:
session.store(User(), "users/1")
session.counters_for("users/1").increment("c1")
session.counters_for("users/1").increment("c2")
tsf = session.time_series_for("users/1", "Heartrate")
tsf.append(datetime.now(), [70])
tsf.append(datetime.now() + timedelta(minutes=1), [20])
session.save_changes()

db_statistics = self.store.maintenance.send(GetStatisticsOperation())
self.assertEqual(1, db_statistics.count_of_counter_entries)
self.assertEqual(1, db_statistics.count_of_time_series_segments)
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
from typing import Optional, List

from ravendb.documents.session.event_args import BeforeRequestEventArgs
from ravendb.documents.session.time_series import TimeSeriesRangeType
from ravendb.documents.subscriptions.options import (
SubscriptionCreationOptions,
SubscriptionWorkerOptions,
Expand All @@ -20,7 +21,9 @@
)
from ravendb.infrastructure.entities import User
from ravendb.infrastructure.orders import Company
from ravendb.primitives.time_series import TimeValue
from ravendb.tests.test_base import TestBase
from ravendb.tools.raven_test_helper import RavenTestHelper


class TestBasicSubscription(TestBase):
Expand Down Expand Up @@ -585,3 +588,47 @@ def __subscription_callback(x: SubscriptionBatch):

subscription.run(__subscription_callback)
third_user_processed.wait(timeout=5)

def test_can_create_subscription_with_include_time_series_last_range_by_time(self):
now = RavenTestHelper.utc_today()

subscription_creation_options = SubscriptionCreationOptions()
subscription_creation_options.includes = lambda b: b.include_time_series_by_range_type_and_time(
"stock_price", TimeSeriesRangeType.LAST, TimeValue.of_months(1)
)

name = self.store.subscriptions.create_for_options_autocomplete_query(Company, subscription_creation_options)

with self.store.subscriptions.get_subscription_worker_by_name(name, Company) as worker:
event = Event()

def __subscription_callback(batch: SubscriptionBatch[Company]):
with batch.open_session() as session:
self.assertEqual(0, session.advanced.number_of_requests)
company = session.load("companies/1", Company)
self.assertEqual(0, session.advanced.number_of_requests)

time_series = session.time_series_for_entity(company, "stock_price")
time_series_entries = time_series.get(now - datetime.timedelta(days=7), None)

self.assertEqual(1, len(time_series_entries))
self.assertEqual(now, time_series_entries[0].timestamp)
self.assertEqual(10, time_series_entries[0].value)

self.assertEqual(0, session.advanced.number_of_requests)

event.set()

worker.run(__subscription_callback)

with self.store.open_session() as session:
company = Company()
company.Id = "companies/1"
company.name = "HR"

session.store(company)

session.time_series_for_entity(company, "stock_price").append_single(now, 10)
session.save_changes()

self.assertTrue(event.wait(30))
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
from ravendb.infrastructure.orders import Company, Order
from ravendb.primitives.constants import int_max
from ravendb.primitives.time_series import TimeValue
from ravendb.tests.test_base import TestBase, User
from ravendb.tests.test_base import TestBase

document_id = "users/gracjan"
company_id = "companies/1-A"
Expand All @@ -17,6 +17,13 @@
tag3 = "watches/bitfit"


class User:
def __init__(self, Id: str = None, name: str = None, works_at: str = None):
self.Id = Id
self.name = name
self.works_at = works_at


class TestTimeSeriesIncludes(TestBase):
def setUp(self):
super(TestTimeSeriesIncludes, self).setUp()
Expand Down Expand Up @@ -1184,3 +1191,69 @@ def test_should_throw_on_including_time_series_with_negative_count(self):
TimeSeriesRangeType.LAST, -1024
),
)

def test_include_time_series_and_documents_and_counters(self):
with self.store.open_session() as session:
user = User()
user.name = "Oren"
user.works_at = "companies/1"
session.store(user, "users/ayende")

company = Company(name="HR")
session.store(company, "companies/1")

session.save_changes()

with self.store.open_session() as session:
tsf = session.time_series_for("users/ayende", "Heartrate")

for i in range(360):
tsf.append_single(base_line + timedelta(seconds=i * 10), 67, "watches/fitbit")

session.counters_for("users/ayende").increment("likes", 100)
session.counters_for("users/ayende").increment("dislikes", 5)
session.save_changes()

with self.store.open_session() as session:
user = session.load(
"users/ayende",
User,
lambda i: i.include_documents("works_at")
.include_time_series("Heartrate", base_line, base_line + timedelta(minutes=30))
.include_counter("likes")
.include_counter("dislikes"),
)

self.assertEqual(1, session.advanced.number_of_requests)

self.assertEqual("Oren", user.name)

# should not go to server

company = session.load(user.works_at, Company)
self.assertEqual(1, session.advanced.number_of_requests)

self.assertEqual("HR", company.name)

# should not go to server
vals = session.time_series_for("users/ayende", "Heartrate").get(
base_line, base_line + timedelta(minutes=30)
)
self.assertEqual(1, session.advanced.number_of_requests)

self.assertEqual(181, len(vals))

self.assertEqual(base_line, vals[0].timestamp)
self.assertEqual("watches/fitbit", vals[0].tag)
self.assertEqual(67, vals[0].values[0])
self.assertEqual(base_line + timedelta(minutes=30), vals[180].timestamp)

# should not go to server
counters = session.counters_for("users/ayende").get_all()

self.assertEqual(1, session.advanced.number_of_requests)

counter = counters.get("likes")
self.assertEqual(100, counter)
counter = counters.get("dislikes")
self.assertEqual(5, counter)
Loading