diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..485b27d
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,13 @@
+.project
+.classpath
+.checkstyle
+.settings/
+.idea/
+*.log
+*.lck
+*.iml
+target/
+*.DS_Store
+*.patch
+*~
+git.properties
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
new file mode 100644
index 0000000..35eb1dd
--- /dev/null
+++ b/.idea/vcs.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Sample.py b/Sample.py
new file mode 100644
index 0000000..15f3ab4
--- /dev/null
+++ b/Sample.py
@@ -0,0 +1,67 @@
+from entity.document.Document import Document
+from entity.document.DocumentStore import DocumentStore
+from entity.storage.ConnectionManager import ConnectionManager
+from entity.storage.Connection import Connection
+
+
+"""Example for customer may works with Python client"""
+"""Create a connection, get store, insert new document into store"""
+# create a connection by path:user@password
+connection = Connection(ConnectionManager.get_connection(url="ojai:mapr:user@password"))
+
+# Get a store and keep it as DocumentStore object
+store = DocumentStore(connection.get_store(store_name="/test_name"))
+
+# Json string or json map
+json_string = "json string"
+
+# Create new document from json_document
+new_document = connection.new_document(json_string)
+
+# Insert new document into the store
+store.insert_or_replace(new_document)
+
+# close
+store.close()
+connection.close()
+
+
+"""Create a connection, get store, find document by id"""
+# create a connection by path:user@password
+connection = Connection(ConnectionManager.get_connection(url="ojai:mapr:user@password"))
+
+# Get a store and keep it as DocumentStore object
+store = DocumentStore(connection.get_store(store_name="/test_name"))
+
+# Fetch document from store by id
+json_document = store.find_by_id("id_005")
+
+# close
+store.close()
+connection.close()
+
+
+"""Create a connection, get store, create a query, execute find query and got through document stream"""
+# create a connection by path:user@password
+connection = Connection(ConnectionManager.get_connection(url="ojai:mapr:user@password"))
+
+# Get a store and keep it as DocumentStore object
+store = DocumentStore(connection.get_store(store_name="/test_name"))
+
+# Build query
+query = connection.new_query().select("_id", "city").build()
+
+# fetch all document from store by query
+document_stream = store.find_query(query)
+
+# go to fetched records and pritnt them
+for document in document_stream.result:
+ print document
+
+
+# close
+store.close()
+connection.close()
+
+
+
diff --git a/entity/Table.py b/entity/Table.py
new file mode 100644
index 0000000..e69de29
diff --git a/entity/document/Document.py b/entity/document/Document.py
new file mode 100644
index 0000000..e085ebc
--- /dev/null
+++ b/entity/document/Document.py
@@ -0,0 +1,169 @@
+from abc import ABCMeta, abstractmethod
+
+
+class Document:
+ __metaclass__ = ABCMeta
+
+ @abstractmethod
+ def set_id(self, _id):
+ raise NotImplementedError("Should have implemented this")
+
+ @abstractmethod
+ def get_id(self):
+ raise NotImplementedError("Should have implemented this")
+
+ @abstractmethod
+ def get_id_string(self):
+ raise NotImplementedError("Should have implemented this")
+
+ @abstractmethod
+ def get_id_binary(self):
+ raise NotImplementedError("Should have implemented this")
+
+ @abstractmethod
+ def size(self):
+ raise NotImplementedError("Should have implemented this")
+
+ @abstractmethod
+ def empty(self):
+ raise NotImplementedError("Should have implemented this")
+
+ @abstractmethod
+ def set(self, field_path, value):
+ raise NotImplementedError("Should have implemented this")
+
+ @abstractmethod
+ def set_boolean(self, field_path, value):
+ raise NotImplementedError("Should have implemented this")
+
+ @abstractmethod
+ def set_byte(self, field_path, value):
+ raise NotImplementedError("Should have implemented this")
+
+ @abstractmethod
+ def set_long(self, field_path, value):
+ raise NotImplementedError("Should have implemented this")
+
+ @abstractmethod
+ def set_float(self, field_path, value):
+ raise NotImplementedError("Should have implemented this")
+
+ @abstractmethod
+ def set_decimal(self, field_path, value):
+ raise NotImplementedError("Should have implemented this")
+
+ @abstractmethod
+ def set_time(self, field_path, value):
+ raise NotImplementedError("Should have implemented this")
+
+ @abstractmethod
+ def set_date(self, field_path, value):
+ raise NotImplementedError("Should have implemented this")
+
+ @abstractmethod
+ def set_timestamp(self, field_path, value):
+ raise NotImplementedError("Should have implemented this")
+
+ @abstractmethod
+ def set_interval(self, field_path, value):
+ raise NotImplementedError("Should have implemented this")
+
+ @abstractmethod
+ def set_byte_array(self, field_path, value, offset=None, length=None):
+ raise NotImplementedError("Should have implemented this")
+
+ @abstractmethod
+ def set_map(self, field_path, value):
+ raise NotImplementedError("Should have implemented this")
+
+ @abstractmethod
+ def set_document(self, field_path, value):
+ raise NotImplementedError("Should have implemented this")
+
+ @abstractmethod
+ def set_value_obj(self, field_path, value):
+ raise NotImplementedError("Should have implemented this")
+
+ @abstractmethod
+ def set_array(self, field_path, values):
+ raise NotImplementedError("Should have implemented this")
+
+ @abstractmethod
+ def set_null(self, field_path):
+ raise NotImplementedError("Should have implemented this")
+
+ @abstractmethod
+ def delete(self, field_path):
+ raise NotImplementedError("Should have implemented this")
+
+ @abstractmethod
+ def get_string(self, field_path):
+ raise NotImplementedError("Should have implemented this")
+
+ @abstractmethod
+ def get_boolean(self, field_path):
+ raise NotImplementedError("Should have implemented this")
+
+ @abstractmethod
+ def get_byte(self, field_path):
+ raise NotImplementedError("Should have implemented this")
+
+ @abstractmethod
+ def get_int(self, field_path):
+ raise NotImplementedError("Should have implemented this")
+
+ @abstractmethod
+ def get_long(self, field_path):
+ raise NotImplementedError("Should have implemented this")
+
+ @abstractmethod
+ def get_float(self, field_path):
+ raise NotImplementedError("Should have implemented this")
+
+ @abstractmethod
+ def get_double(self, field_path):
+ raise NotImplementedError("Should have implemented this")
+
+ @abstractmethod
+ def get_decimal(self, field_path):
+ raise NotImplementedError("Should have implemented this")
+
+ @abstractmethod
+ def get_time(self, field_path):
+ raise NotImplementedError("Should have implemented this")
+
+ @abstractmethod
+ def get_date(self, field_path):
+ raise NotImplementedError("Should have implemented this")
+
+ @abstractmethod
+ def get_timestamp(self, field_path):
+ raise NotImplementedError("Should have implemented this")
+
+ @abstractmethod
+ def get_binary(self, field_path):
+ raise NotImplementedError("Should have implemented this")
+
+ @abstractmethod
+ def get_interval(self, field_path):
+ raise NotImplementedError("Should have implemented this")
+
+ @abstractmethod
+ def get_value(self, field_path):
+ raise NotImplementedError("Should have implemented this")
+
+ @abstractmethod
+ def get_map(self, field_path):
+ raise NotImplementedError("Should have implemented this")
+
+ @abstractmethod
+ def get_list(self, field_path):
+ raise NotImplementedError("Should have implemented this")
+
+ @abstractmethod
+ def as_reader(self, field_path=None):
+ raise NotImplementedError("Should have implemented this")
+
+ @abstractmethod
+ def as_map(self):
+ raise NotImplementedError("Should have implemented this")
diff --git a/entity/document/DocumentBuilder.py b/entity/document/DocumentBuilder.py
new file mode 100644
index 0000000..4f17faa
--- /dev/null
+++ b/entity/document/DocumentBuilder.py
@@ -0,0 +1,156 @@
+from abc import ABCMeta, abstractmethod
+
+
+class DocumentBuilder:
+ __metaclass__ = ABCMeta
+
+ def __init__(self):
+ pass
+
+ @abstractmethod
+ def put(self, field, value):
+ raise NotImplementedError("Should have implemented this")
+
+ @abstractmethod
+ def put_float(self, field, value):
+ raise NotImplementedError("Should have implemented this")
+
+ @abstractmethod
+ def put_byte(self, field, value):
+ raise NotImplementedError("Should have implemented this")
+
+ @abstractmethod
+ def put_byte_array(self, field, value, offset=None, length=None):
+ raise NotImplementedError("Should have implemented this")
+
+ @abstractmethod
+ def put_date(self, field, value):
+ raise NotImplementedError("Should have implemented this")
+
+ @abstractmethod
+ def put_time(self, field, value):
+ raise NotImplementedError("Should have implemented this")
+
+ @abstractmethod
+ def put_decimal(self, field, value, scale=None):
+ raise NotImplementedError("Should have implemented this")
+
+ @abstractmethod
+ def put_date(self, field, days):
+ raise NotImplementedError("Should have implemented this")
+
+ @abstractmethod
+ def put_time(self, field, millis):
+ raise NotImplementedError("Should have implemented this")
+
+ @abstractmethod
+ def put_timestamp(self, field, time_millis):
+ raise NotImplementedError("Should have implemented this")
+
+ @abstractmethod
+ def put_new_interval(self, field, value):
+ raise NotImplementedError("Should have implemented this")
+
+ @abstractmethod
+ def put_map(self, field, value):
+ raise NotImplementedError("Should have implemented this")
+
+ @abstractmethod
+ def put_new_map(self, field):
+ raise NotImplementedError("Should have implemented this")
+
+ @abstractmethod
+ def put_new_array(self, field):
+ raise NotImplementedError("Should have implemented this")
+
+ @abstractmethod
+ def put_null(self, field):
+ raise NotImplementedError("Should have implemented this")
+
+ @abstractmethod
+ def put_document(self, field, value):
+ raise NotImplementedError("Should have implemented this")
+
+ @abstractmethod
+ def put_value_obj(self, field, value):
+ raise NotImplementedError("Should have implemented this")
+
+ @abstractmethod
+ def set_array_index(self, index):
+ raise NotImplementedError("Should have implemented this")
+
+ @abstractmethod
+ def add(self, value):
+ raise NotImplementedError("Should have implemented this")
+
+ @abstractmethod
+ def add_boolean(self, value):
+ raise NotImplementedError("Should have implemented this")
+
+ @abstractmethod
+ def add_byte(self, value):
+ raise NotImplementedError("Should have implemented this")
+
+ @abstractmethod
+ def add_long(self, value):
+ raise NotImplementedError("Should have implemented this")
+
+ @abstractmethod
+ def add_float(self, value):
+ raise NotImplementedError("Should have implemented this")
+
+ @abstractmethod
+ def add_byte_array(self, value, offset=None, length=None):
+ raise NotImplementedError("Should have implemented this")
+
+ @abstractmethod
+ def add_document(self, value):
+ raise NotImplementedError("Should have implemented this")
+
+ @abstractmethod
+ def add_value_obj(self, value):
+ raise NotImplementedError("Should have implemented this")
+
+ @abstractmethod
+ def add_decimal(self, decimal_value, scale=None):
+ raise NotImplementedError("Should have implemented this")
+
+ @abstractmethod
+ def add_null(self):
+ raise NotImplementedError("Should have implemented this")
+
+ @abstractmethod
+ def add_new_array(self):
+ raise NotImplementedError("Should have implemented this")
+
+ @abstractmethod
+ def add_new_map(self):
+ raise NotImplementedError("Should have implemented this")
+
+ @abstractmethod
+ def add_time(self, millis):
+ raise NotImplementedError("Should have implemented this")
+
+ @abstractmethod
+ def add_date(self, days):
+ raise NotImplementedError("Should have implemented this")
+
+ @abstractmethod
+ def add_timestamp(self, time_millis):
+ raise NotImplementedError("Should have implemented this")
+
+ @abstractmethod
+ def add_interval(self, duration_in_ms):
+ raise NotImplementedError("Should have implemented this")
+
+ @abstractmethod
+ def end_array(self):
+ raise NotImplementedError("Should have implemented this")
+
+ @abstractmethod
+ def add_map(self):
+ raise NotImplementedError("Should have implemented this")
+
+ @abstractmethod
+ def get_document(self):
+ raise NotImplementedError("Should have implemented this")
diff --git a/entity/document/DocumentImpl.py b/entity/document/DocumentImpl.py
new file mode 100644
index 0000000..8ddd265
--- /dev/null
+++ b/entity/document/DocumentImpl.py
@@ -0,0 +1,126 @@
+from Document import Document
+
+
+class DocumentImpl(Document):
+ def get_byte(self, field_path):
+ pass
+
+ def set_boolean(self, field_path, value):
+ pass
+
+ def set_byte_array(self, field_path, value, offset=None, length=None):
+ pass
+
+ def get_map(self, field_path):
+ pass
+
+ def set_time(self, field_path, value):
+ pass
+
+ def get_id(self):
+ pass
+
+ def get_value(self, field_path):
+ pass
+
+ def get_long(self, field_path):
+ pass
+
+ def get_date(self, field_path):
+ pass
+
+ def set_interval(self, field_path, value):
+ pass
+
+ def set_map(self, field_path, value):
+ pass
+
+ def get_boolean(self, field_path):
+ pass
+
+ def set_byte(self, field_path, value):
+ pass
+
+ def get_list(self, field_path):
+ pass
+
+ def size(self):
+ pass
+
+ def get_decimal(self, field_path):
+ pass
+
+ def get_interval(self, field_path):
+ pass
+
+ def get_double(self, field_path):
+ pass
+
+ def empty(self):
+ pass
+
+ def get_int(self, field_path):
+ pass
+
+ def as_map(self):
+ pass
+
+ def get_binary(self, field_path):
+ pass
+
+ def set(self, field_path, value):
+ pass
+
+ def set_value_obj(self, field_path, value):
+ pass
+
+ def set_id(self, _id):
+ pass
+
+ def set_date(self, field_path, value):
+ pass
+
+ def get_time(self, field_path):
+ pass
+
+ def delete(self, field_path):
+ pass
+
+ def set_timestamp(self, field_path, value):
+ pass
+
+ def set_decimal(self, field_path, value):
+ pass
+
+ def get_timestamp(self, field_path):
+ pass
+
+ def get_float(self, field_path):
+ pass
+
+ def set_null(self, field_path):
+ pass
+
+ def set_document(self, field_path, value):
+ pass
+
+ def get_id_binary(self):
+ pass
+
+ def as_reader(self, field_path=None):
+ pass
+
+ def get_id_string(self):
+ pass
+
+ def get_string(self, field_path):
+ pass
+
+ def set_long(self, field_path, value):
+ pass
+
+ def set_array(self, field_path, values):
+ pass
+
+ def set_float(self, field_path, value):
+ pass
diff --git a/entity/document/DocumentListener.py b/entity/document/DocumentListener.py
new file mode 100644
index 0000000..9dab135
--- /dev/null
+++ b/entity/document/DocumentListener.py
@@ -0,0 +1,20 @@
+from abc import ABCMeta, abstractmethod
+
+
+class DocumentListener:
+ __metaclass__ = ABCMeta
+
+ def __init__(self):
+ pass
+
+ @abstractmethod
+ def document_arrived(self, doc):
+ raise NotImplementedError("Should have implemented this")
+
+ @abstractmethod
+ def failed(self, exception):
+ raise NotImplementedError("Should have implemented this")
+
+ @abstractmethod
+ def eos(self):
+ raise NotImplementedError("Should have implemented this")
\ No newline at end of file
diff --git a/entity/document/DocumentMutation.py b/entity/document/DocumentMutation.py
new file mode 100644
index 0000000..06f27e4
--- /dev/null
+++ b/entity/document/DocumentMutation.py
@@ -0,0 +1,209 @@
+from abc import ABCMeta, abstractmethod
+
+
+class DocumentMutation:
+ __metaclass__ = ABCMeta
+
+ def __init__(self):
+ pass
+
+ @abstractmethod
+ def empty(self):
+ raise NotImplementedError("Should have implemented this")
+
+ @abstractmethod
+ def set_null(self, path):
+ raise NotImplementedError("Should have implemented this")
+
+ @abstractmethod
+ def set(self, path, value):
+ raise NotImplementedError("Should have implemented this")
+
+ @abstractmethod
+ def set_string(self, path, value):
+ raise NotImplementedError("Should have implemented this")
+
+ @abstractmethod
+ def set_boolean(self, path, value):
+ raise NotImplementedError("Should have implemented this")
+
+ @abstractmethod
+ def set_byte(self, path, value):
+ raise NotImplementedError("Should have implemented this")
+
+ @abstractmethod
+ def set_long(self, path, value):
+ raise NotImplementedError("Should have implemented this")
+
+ @abstractmethod
+ def set_float(self, path, value):
+ raise NotImplementedError("Should have implemented this")
+
+ @abstractmethod
+ def set_date(self, path, value):
+ raise NotImplementedError("Should have implemented this")
+
+ @abstractmethod
+ def set_time(self, path, value):
+ raise NotImplementedError("Should have implemented this")
+
+ @abstractmethod
+ def set_timestamp(self, path, value):
+ raise NotImplementedError("Should have implemented this")
+
+ @abstractmethod
+ def set_interval(self, path, value):
+ raise NotImplementedError("Should have implemented this")
+
+ @abstractmethod
+ def set_list(self, path, value):
+ raise NotImplementedError("Should have implemented this")
+
+ @abstractmethod
+ def set_map(self, path, value):
+ raise NotImplementedError("Should have implemented this")
+
+ @abstractmethod
+ def set_document(self, path, doc):
+ raise NotImplementedError("Should have implemented this")
+
+ @abstractmethod
+ def set_value_obj(self, path, value):
+ raise NotImplementedError("Should have implemented this")
+
+ @abstractmethod
+ def set_or_replace_null(self, path):
+ raise NotImplementedError("Should have implemented this")
+
+ @abstractmethod
+ def set_or_replace(self, path, value):
+ raise NotImplementedError("Should have implemented this")
+
+ @abstractmethod
+ def set_or_replace_value_obj(self, path, value):
+ raise NotImplementedError("Should have implemented this")
+
+ @abstractmethod
+ def set_or_replace_boolean(self, path, value):
+ raise NotImplementedError("Should have implemented this")
+
+ @abstractmethod
+ def set_or_replace_byte(self, path, value):
+ raise NotImplementedError("Should have implemented this")
+
+ @abstractmethod
+ def set_or_replace_long(self, path, value):
+ raise NotImplementedError("Should have implemented this")
+
+ @abstractmethod
+ def set_or_replace_float(self, path, value):
+ raise NotImplementedError("Should have implemented this")
+
+ @abstractmethod
+ def set_or_replace_string(self, path, value):
+ raise NotImplementedError("Should have implemented this")
+
+ @abstractmethod
+ def set_or_replace_decimal(self, path, value):
+ raise NotImplementedError("Should have implemented this")
+
+ @abstractmethod
+ def set_or_replace_date(self, path, value):
+ raise NotImplementedError("Should have implemented this")
+
+ @abstractmethod
+ def set_or_replace_time(self, path, value):
+ raise NotImplementedError("Should have implemented this")
+
+ @abstractmethod
+ def set_or_replace_timestamp(self, path, value):
+ raise NotImplementedError("Should have implemented this")
+
+ @abstractmethod
+ def set_or_replace_interval(self, path, value):
+ raise NotImplementedError("Should have implemented this")
+
+ @abstractmethod
+ def set_or_replace_list(self, path, value):
+ raise NotImplementedError("Should have implemented this")
+
+ @abstractmethod
+ def set_or_replace_map(self, path, value):
+ raise NotImplementedError("Should have implemented this")
+
+ @abstractmethod
+ def set_or_replace_doc(self, path, value):
+ raise NotImplementedError("Should have implemented this")
+
+ @abstractmethod
+ def append(self, path, value):
+ raise NotImplementedError("Should have implemented this")
+
+ @abstractmethod
+ def append_list(self, path, value):
+ raise NotImplementedError("Should have implemented this")
+
+ @abstractmethod
+ def append_string(self, path, value):
+ raise NotImplementedError("Should have implemented this")
+
+ @abstractmethod
+ def append_byte_array(self, path, value, offset=None, length=None):
+ raise NotImplementedError("Should have implemented this")
+
+ @abstractmethod
+ def merge(self, path, value):
+ raise NotImplementedError("Should have implemented this")
+
+ @abstractmethod
+ def merge_document(self, path, value):
+ raise NotImplementedError("Should have implemented this")
+
+ @abstractmethod
+ def merge_map(self, path, value):
+ raise NotImplementedError("Should have implemented this")
+
+ @abstractmethod
+ def increment(self, path, inc):
+ raise NotImplementedError("Should have implemented this")
+
+ @abstractmethod
+ def increment(self, path, inc):
+ raise NotImplementedError("Should have implemented this")
+
+ @abstractmethod
+ def increment_float(self, path, inc):
+ raise NotImplementedError("Should have implemented this")
+
+ @abstractmethod
+ def increment_byte(self, path, inc):
+ raise NotImplementedError("Should have implemented this")
+
+ @abstractmethod
+ def increment_decimal(self, path, inc):
+ raise NotImplementedError("Should have implemented this")
+
+ @abstractmethod
+ def decrement(self, path, dec):
+ raise NotImplementedError("Should have implemented this")
+
+ @abstractmethod
+ def decrement(self, path, dec):
+ raise NotImplementedError("Should have implemented this")
+
+ @abstractmethod
+ def decrement_float(self, path, dec):
+ raise NotImplementedError("Should have implemented this")
+
+ @abstractmethod
+ def decrement_byte(self, path, dec):
+ raise NotImplementedError("Should have implemented this")
+
+ @abstractmethod
+ def decrement_decimal(self, path, dec):
+ raise NotImplementedError("Should have implemented this")
+
+ @abstractmethod
+ def delete(self, path):
+ raise NotImplementedError("Should have implemented this")
+
diff --git a/entity/document/DocumentReader.py b/entity/document/DocumentReader.py
new file mode 100644
index 0000000..f894c0c
--- /dev/null
+++ b/entity/document/DocumentReader.py
@@ -0,0 +1,9 @@
+from abc import ABCMeta, abstractmethod
+
+
+class DocumentReader:
+ __metaclass__ = ABCMeta
+
+ def __init__(self):
+ pass
+
diff --git a/entity/document/DocumentStore.py b/entity/document/DocumentStore.py
new file mode 100644
index 0000000..6ebe45c
--- /dev/null
+++ b/entity/document/DocumentStore.py
@@ -0,0 +1,120 @@
+from abc import ABCMeta, abstractmethod
+
+
+class DocumentStore:
+ __metaclass__ = ABCMeta
+
+ def __init__(self):
+ pass
+
+ @abstractmethod
+ def is_read_only(self):
+ raise NotImplementedError("Should have implemented this")
+
+ @abstractmethod
+ def flush(self):
+ raise NotImplementedError("Should have implemented this")
+
+ @abstractmethod
+ def begin_tracking_writes(self, previous_writes_context=None):
+ raise NotImplementedError("Should have implemented this")
+
+ @abstractmethod
+ def end_tracking_writes(self):
+ raise NotImplementedError("Should have implemented this")
+
+ @abstractmethod
+ def clear_tracked_writes(self):
+ raise NotImplementedError("Should have implemented this")
+
+ @abstractmethod
+ def find_by_id_value_obj(self, _id, field_paths=None, condition=None):
+ raise NotImplementedError("Should have implemented this")
+
+ @abstractmethod
+ def find_by_id_string(self, _id, field_paths=None, condition=None):
+ raise NotImplementedError("Should have implemented this")
+
+ @abstractmethod
+ def find_by_id(self, _id, field_paths=None, condition=None):
+ raise NotImplementedError("Should have implemented this")
+
+ @abstractmethod
+ def find(self, query=None, field_paths=None, condition=None, query_string=None):
+ raise NotImplementedError("Should have implemented this")
+
+ @abstractmethod
+ def insert_or_replace(self, doc=None, _id=None, field_as_key=None, doc_stream=None):
+ raise NotImplementedError("Should have implemented this")
+
+ @abstractmethod
+ def update(self, _id, mutation):
+ raise NotImplementedError("Should have implemented this")
+
+ @abstractmethod
+ def delete_by_id(self, _id):
+ raise NotImplementedError("Should have implemented this")
+
+ @abstractmethod
+ def delete_document(self, doc=None, field_as_key=None, doc_stream=None):
+ raise NotImplementedError("Should have implemented this")
+
+ @abstractmethod
+ def insert_document_with_id(self, _id, document):
+ raise NotImplementedError("Should have implemented this")
+
+ @abstractmethod
+ def insert_document(self, document, field_as_key=None):
+ raise NotImplementedError("Should have implemented this")
+
+ @abstractmethod
+ def insert_document_stream(self, document_stream, field_as_key=None):
+ raise NotImplementedError("Should have implemented this")
+
+ @abstractmethod
+ def replace_document_with_id(self, _id, document):
+ raise NotImplementedError("Should have implemented this")
+
+ @abstractmethod
+ def replace_document(self, document, field_as_key=None):
+ raise NotImplementedError("Should have implemented this")
+
+ @abstractmethod
+ def replace_document_stream(self, document_stream, field_as_key=None):
+ raise NotImplementedError("Should have implemented this")
+
+ @abstractmethod
+ def increment(self, _id, field, inc):
+ raise NotImplementedError("Should have implemented this")
+
+ @abstractmethod
+ def increment_int(self, _id, field, inc):
+ raise NotImplementedError("Should have implemented this")
+
+ @abstractmethod
+ def increment_float(self, _id, field, inc):
+ raise NotImplementedError("Should have implemented this")
+
+ @abstractmethod
+ def increment_decimal(self, _id, field, inc):
+ raise NotImplementedError("Should have implemented this")
+
+ @abstractmethod
+ def increment_byte(self, _id, field, inc):
+ raise NotImplementedError("Should have implemented this")
+
+ @abstractmethod
+ def check_and_mutate(self, _id, query_condition, mutation):
+ raise NotImplementedError("Should have implemented this")
+
+ @abstractmethod
+ def check_and_delete(self, _id, condition):
+ raise NotImplementedError("Should have implemented this")
+
+ @abstractmethod
+ def check_and_replace(self, _id, condition, doc):
+ raise NotImplementedError("Should have implemented this")
+
+ @abstractmethod
+ def close(self):
+ raise NotImplementedError("Should have implemented this")
\ No newline at end of file
diff --git a/entity/document/DocumentStream.py b/entity/document/DocumentStream.py
new file mode 100644
index 0000000..fedb498
--- /dev/null
+++ b/entity/document/DocumentStream.py
@@ -0,0 +1,35 @@
+from abc import ABCMeta, abstractmethod
+
+
+class DocumentStream:
+ """ A stream of documents.
+ Implements Iterable but only one call is allows to iterator()
+ or readerIterator(). Only one of these iterators can be retrieved
+ from the stream."""
+
+ __metaclass__ = ABCMeta
+
+ @abstractmethod
+ def stream_to(self, doc_listener):
+ """Streams all the documents in this {@code DocumentStream} to the specified
+ listener.
+ doc_listener : a DocumentListener which is notified of JsonDocuments as they arrive"""
+ raise NotImplementedError("Should have implemented this")
+
+ @abstractmethod
+ def iterator(self):
+ """Returns an iterator over a set of JsonDocument"""
+ raise NotImplementedError("Should have implemented this")
+
+ @abstractmethod
+ def document_readers(self):
+ """Returns an Iterable over a set of DocumentReader."""
+ raise NotImplementedError("Should have implemented this")
+
+ @abstractmethod
+ def close(self):
+ raise NotImplementedError("Should have implemented this")
+
+ @abstractmethod
+ def get_query_plan(self):
+ raise NotImplementedError("Should have implemented this")
\ No newline at end of file
diff --git a/entity/document/document_constants.py b/entity/document/document_constants.py
new file mode 100644
index 0000000..46fd7d8
--- /dev/null
+++ b/entity/document/document_constants.py
@@ -0,0 +1,3 @@
+DOCUMENT_KEY = "$$document"
+ID_KEY = "_id"
+ID_FIELD = "" #TODO Implement FieldPath like in OJAI
\ No newline at end of file
diff --git a/entity/exceptions/UnsupportedConstructorException.py b/entity/exceptions/UnsupportedConstructorException.py
new file mode 100644
index 0000000..b00b254
--- /dev/null
+++ b/entity/exceptions/UnsupportedConstructorException.py
@@ -0,0 +1,2 @@
+class UnsupportedConstructorException(Exception):
+ pass
diff --git a/entity/json/Json.py b/entity/json/Json.py
new file mode 100644
index 0000000..c13e33d
--- /dev/null
+++ b/entity/json/Json.py
@@ -0,0 +1,78 @@
+from entity.json.JsonDocument import JsonDocument
+
+from entity.json.JsonDocumentBuilder import JsonDocumentBuilder
+from entity.json.JsonDocumentStream import JsonDocumentStream
+from entity.json.JsonOptions import Options
+from entity.utils.Documents import Documents
+
+
+class Json:
+ def __init__(self):
+ pass
+
+ @staticmethod
+ def new_document(json_string=None, json_map=None):
+ """Returns a new, empty Document or from the specified JSON string or map."""
+ if json_string is None and json_map is None:
+ return JsonDocument()
+ elif json_string is not None and type(json_string) is str:
+ byte_array = bytearray(json_string)
+ # TODO JsonDocumentStream required!!! iterator impl
+ return Json.new_document_stream(input_stream=byte_array).iterator()
+ elif json_map is not None and type(json_map) is map:
+ # TODO JsonValueBuilder required
+ pass
+ else:
+ raise AttributeError
+
+ @staticmethod
+ def get_value_builder():
+ """Returns a ValueBuilder object."""
+ # TODO added implementation after JsonValueBuilder was added.
+ pass
+
+ @staticmethod
+ def new_document_reader(json_string):
+ """Returns a new instance of the JSON DocumentReader."""
+ byte_array = bytearray(json_string)
+ # todo JsonDocumentStream required !!! iterator impl
+ return Json.new_document_stream(input_stream=byte_array).iterator()
+
+ @staticmethod
+ def new_document_builder(options=None):
+ """Returns a new instance of JSON DocumentBuilder."""
+ if options is None:
+ return JsonDocumentBuilder()
+ else:
+ # todo required JsonDocumentBuilder, options!!
+ pass
+
+ @staticmethod
+ def new_document_stream(input_stream=None, field_path_type_map=None, event_delegate=None,
+ fs=None, path=None):
+ # TODO
+ if fs is None and path is None:
+ return JsonDocumentStream(input_stream=input_stream,
+ field_path_type_map=field_path_type_map,
+ event_delegate=event_delegate)
+ elif fs is not None and path is not None:
+ return JsonDocumentStream.new_document_stream(fs=fs, path=path,
+ field_path_type_map=field_path_type_map,
+ event_delegate=event_delegate)
+ else:
+ raise AttributeError("Unexpected input params set")
+
+ # TODO encode method skipped, bean required
+
+ @staticmethod
+ def to_json_string(document=None, options=None, document_reader=None):
+ if document is not None:
+ document_reader = document.as_reader()
+
+ if options is None:
+ options = Options.DEFAULT
+ # TODO JsonDocumentBuilder and DocumentReader required!!!
+
+ @staticmethod
+ def write_reader_to_builder(document_reader, document_builder):
+ Documents.write_reader_to_builder(document_reader=document_reader, document_builder=document_builder)
diff --git a/entity/json/JsonDocument.py b/entity/json/JsonDocument.py
new file mode 100644
index 0000000..9f0da12
--- /dev/null
+++ b/entity/json/JsonDocument.py
@@ -0,0 +1,132 @@
+from entity.document.Document import Document
+from entity.json.JsonValue import JsonValue
+
+
+class JsonDocument(Document):
+ __json_stream_document_reader = None
+
+ def __init__(self, json_value=None):
+ self.json_value = json_value
+
+ def set_id(self, _id):
+ pass
+
+ def get_id(self):
+ pass
+
+ def get_id_string(self):
+ pass
+
+ def get_id_binary(self):
+ pass
+
+ def size(self):
+ pass
+
+ def empty(self):
+ pass
+
+ def set(self, field_path, value):
+ pass
+
+ def set_boolean(self, field_path, value):
+ pass
+
+ def set_byte(self, field_path, value):
+ pass
+
+ def set_long(self, field_path, value):
+ pass
+
+ def set_float(self, field_path, value):
+ pass
+
+ def set_decimal(self, field_path, value):
+ pass
+
+ def set_time(self, field_path, value):
+ pass
+
+ def set_date(self, field_path, value):
+ pass
+
+ def set_timestamp(self, field_path, value):
+ pass
+
+ def set_interval(self, field_path, value):
+ pass
+
+ def set_byte_array(self, field_path, value, offset=None, length=None):
+ pass
+
+ def set_map(self, field_path, value):
+ pass
+
+ def set_document(self, field_path, value):
+ pass
+
+ def set_value_obj(self, field_path, value):
+ pass
+
+ def set_array(self, field_path, values):
+ pass
+
+ def set_null(self, field_path):
+ pass
+
+ def delete(self, field_path):
+ pass
+
+ def get_string(self, field_path):
+ pass
+
+ def get_boolean(self, field_path):
+ pass
+
+ def get_byte(self, field_path):
+ pass
+
+ def get_int(self, field_path):
+ pass
+
+ def get_long(self, field_path):
+ pass
+
+ def get_float(self, field_path):
+ pass
+
+ def get_double(self, field_path):
+ pass
+
+ def get_decimal(self, field_path):
+ pass
+
+ def get_time(self, field_path):
+ pass
+
+ def get_date(self, field_path):
+ pass
+
+ def get_timestamp(self, field_path):
+ pass
+
+ def get_binary(self, field_path):
+ pass
+
+ def get_interval(self, field_path):
+ pass
+
+ def get_value(self, field_path):
+ pass
+
+ def get_map(self, field_path):
+ pass
+
+ def get_list(self, field_path):
+ pass
+
+ def as_reader(self, field_path=None):
+ pass
+
+ def as_map(self):
+ pass
diff --git a/entity/json/JsonDocumentBuilder.py b/entity/json/JsonDocumentBuilder.py
new file mode 100644
index 0000000..d5e7ef7
--- /dev/null
+++ b/entity/json/JsonDocumentBuilder.py
@@ -0,0 +1,6 @@
+from entity.document.DocumentBuilder import DocumentBuilder
+
+
+class JsonDocumentBuilder(DocumentBuilder):
+ def __init__(self):
+ pass
diff --git a/entity/json/JsonDocumentStream.py b/entity/json/JsonDocumentStream.py
new file mode 100644
index 0000000..1b70441
--- /dev/null
+++ b/entity/json/JsonDocumentStream.py
@@ -0,0 +1,34 @@
+from entity.document.DocumentStream import DocumentStream
+
+
+class JsonDocumentStream(DocumentStream):
+
+ __input_stream = None
+ __json_parser = None
+ __read_started = None
+ __iterator_opened = None
+
+ __field_path_type_map = None
+ __event_delegate = None
+
+ def __init__(self, input_stream=None, field_path_type_map=None, event_delegate=None):
+ pass
+
+ def stream_to(self, doc_listener):
+ pass
+
+ def iterator(self):
+ pass
+
+ def document_readers(self):
+ pass
+
+ def close(self):
+ pass
+
+ def get_query_plan(self):
+ pass
+
+ @staticmethod
+ def new_document_stream(fs, path, field_path_type_map=None, event_delegate=None):
+ pass
diff --git a/entity/json/JsonList.py b/entity/json/JsonList.py
new file mode 100644
index 0000000..a9ced7d
--- /dev/null
+++ b/entity/json/JsonList.py
@@ -0,0 +1,5 @@
+
+
+class JsonList(list):
+ def __init__(self, json_value=None):
+ super(JsonList, self).__init__()
diff --git a/entity/json/JsonOptions.py b/entity/json/JsonOptions.py
new file mode 100644
index 0000000..d39ec4d
--- /dev/null
+++ b/entity/json/JsonOptions.py
@@ -0,0 +1,72 @@
+class JsonOptions:
+
+ """This class encapsulates various options to configure a JSON serializer for Documents.
+ Currently, it supports the following options:
+ Pretty Print: off by default.
+ With Tags: on by default"""
+
+ __pretty = False
+ __with_tags = False
+
+ def __init__(self):
+ pass
+
+ def is_pretty(self):
+ return self.__pretty
+
+ # TODO test it careful
+ def __check_mutation_of_constants(self):
+ if Options.DEFAULT == self or Options.WITH_TAGS == self:
+ raise AttributeError
+
+ def set_pretty(self, pretty):
+ self.__check_mutation_of_constants()
+ self.__pretty = pretty
+ return self
+
+ def pretty(self):
+ self.__check_mutation_of_constants()
+ self.__pretty = True
+ return self
+
+ # TODO deprecated???
+ def compact(self):
+ self.__check_mutation_of_constants()
+ self.__pretty = False
+ return self
+
+ def is_with_tags(self, with_tags):
+ self.__check_mutation_of_constants()
+ self.__with_tags = with_tags
+ return self
+
+ def with_tags(self):
+ self.__check_mutation_of_constants()
+ self.__with_tags = True
+ return self
+
+ def without_tags(self):
+ self.__check_mutation_of_constants()
+ self.__with_tags = False
+ return self
+
+ def __str__(self):
+ return "\"pretty\"" + self.__pretty + ", \"with_tags\": " + self.__with_tags
+
+
+class Options:
+
+ def __init__(self):
+ pass
+
+ __DEFAULT = JsonOptions()
+ __WITH_TAGS = JsonOptions().with_tags()
+
+ @property
+ def DEFAULT(self):
+ return self.__DEFAULT
+
+ @property
+ def WITH_TAGS(self):
+ return self.__WITH_TAGS
+
diff --git a/entity/json/JsonUtils.py b/entity/json/JsonUtils.py
new file mode 100644
index 0000000..e69de29
diff --git a/entity/json/JsonValue.py b/entity/json/JsonValue.py
new file mode 100644
index 0000000..c8f819e
--- /dev/null
+++ b/entity/json/JsonValue.py
@@ -0,0 +1,205 @@
+from entity.values.Value import Value, ValueType
+from entity.json.JsonList import JsonList
+from entity.o_types.ODate import ODate
+from entity.o_types.OInterval import OInterval
+from entity.o_types.OTime import OTime
+from entity.o_types.OTimestamp import OTimestamp
+
+
+class JsonValue(Value):
+
+ def __init__(self, value_type=None, json_value=None, obj_value=None):
+ self.value_type = value_type
+ self.json_value = json_value
+ self.obj_value = obj_value
+ self.key = None
+
+ def set_key(self, key):
+ self.key = key
+
+ def get_key(self):
+ return self.key
+
+ def check_type(self, value_type):
+ if self.value_type != value_type:
+ raise TypeError("Value is of type " + self.value_type + " but requested type is " + value_type)
+ return
+
+ def set_prim_value(self, value):
+ self.json_value = value
+
+ def set_obj_value(self, value):
+ # TODO added chat that value is object. Which objects acceptable?
+ # Only ValueType objects? ValueType object don't store as enum in python
+ self.obj_value = value
+
+ def get_obj(self):
+ switcher = {
+ 1: self.obj_value,
+ 2: self.get_boolean(),
+ 3: self.obj_value,
+ 4: self.get_byte(),
+ 5: self.get_int(),
+ 6: self.get_long(),
+ 7: self.get_float(),
+ 8: self.obj_value,
+ 9: self.get_date(),
+ 10: self.get_time(),
+ 11: self.get_timestamp(),
+ 12: self.get_interval(),
+ 13: self.obj_value,
+ 14: self,
+ 15: self
+ }
+ return switcher.get(self.value_type, TypeError("Invalid type " + self.value_type))
+
+ def get_date(self):
+ self.check_type(ValueType.DATE)
+ if self.obj_value is None:
+ self.obj_value = ODate.from_days_since_epoch(self.json_value)
+ return self.obj_value
+
+ def get_map(self):
+ self.check_type(ValueType.MAP)
+ # TODO added get_map implementation after JSONDocument will done
+ # TODO Test it
+ from entity.json.JsonDocument import JsonDocument
+ doc = JsonDocument(json_value=self)
+ return doc
+
+ def get_time_as_int(self):
+ return int(self.json_value)
+
+ def get_type(self):
+ return self.value_type
+
+ def get_interval(self):
+ self.check_type(ValueType.INTERVAL)
+ if self.obj_value is None:
+ self.obj_value = OInterval(self.json_value)
+ return self.obj_value
+
+ def get_list(self):
+ self.check_type(ValueType.ARRAY)
+ # TODO added get_map implementation after JSONList will done
+ # TODO TEST IT
+ json_list = JsonList(json_value=self)
+ return json_list
+
+ def get_byte(self):
+ switcher = {
+ ValueType.BYTE: self.int_to_byte(self.json_value),
+ ValueType.INT: self.get_int(),
+ ValueType.LONG: self.get_long(),
+ ValueType.FLOAT: self.get_float(),
+ # TODO convert decimal to byte
+ ValueType.DECIMAL: self.get_decimal()
+ }
+ return switcher.get(self.value_type, TypeError("Expected a numeric type, found: " + self.value_type))
+
+ def get_time(self):
+ self.check_type(ValueType.TIME)
+ if self.obj_value is None:
+ self.obj_value = OTime.from_millis_of_day(millis_of_day=self.json_value)
+ return self.obj_value
+
+ def get_long(self):
+ switcher = {
+ ValueType.LONG: self.json_value,
+ ValueType.BYTE: self.get_byte(),
+ ValueType.INT: self.get_int(),
+ ValueType.FLOAT: long(self.get_float()),
+ # TODO convert decimal to long
+ ValueType.DECIMAL: long(self.get_decimal())
+ }
+ return switcher.get(self.value_type, TypeError("Expected a numeric type, found: " + self.value_type))
+
+ def get_int(self):
+ switcher = {
+ ValueType.INT: self.byte_to_int(self.json_value),
+ ValueType.BYTE: self.get_byte(),
+ ValueType.FLOAT: int(self.get_float()),
+ # TODO convert decimal to int
+ ValueType.DECIMAL: int(self.get_decimal())
+ }
+ return switcher.get(self.value_type, TypeError("Expected a numeric type, found: " + self.value_type))
+
+ def as_reader(self):
+ # TODO required JsonDOMDocumentReader implementation
+ pass
+
+ def get_date_as_int(self):
+ return int(self.json_value)
+
+ def get_boolean(self):
+ self.check_type(ValueType.BOOLEAN)
+ return self.json_value != 0
+
+ def get_timestamp(self):
+ self.check_type(ValueType.TIMESTAMP)
+ if self.obj_value is None:
+ self.obj_value = OTimestamp(millis_since_epoch=self.json_value)
+ return self.obj_value
+
+ def get_decimal(self):
+ # TODO check and implement get_decimal like java BigDecimal
+ pass
+
+ def get_string(self):
+ self.check_type(ValueType.STRING)
+ return str(self.obj_value)
+
+ def get_float(self):
+ switcher = {
+ # TODO check how to convert long to float
+ ValueType.FLOAT: float(self.json_value),
+ ValueType.BYTE: self.get_byte(),
+ ValueType.INT: float(self.get_int()),
+ ValueType.LONG: float(self.get_long()),
+ # TODO convert decimal to float
+ ValueType.DECIMAL: int(self.get_decimal())
+ }
+ return switcher.get(self.value_type, TypeError("Expected a numeric type, found: " + self.value_type))
+
+ def get_interval_as_long(self):
+ return long(self.json_value)
+
+ def get_timestamp_as_long(self):
+ return self.json_value
+
+ @staticmethod
+ def int_to_byte(value, length):
+ result = []
+ for i in range(0, length):
+ result.append(value >> (i * 8) & 0xff)
+ result.reverse()
+
+ return result
+
+ @staticmethod
+ def byte_to_int(value):
+ result = 0
+
+ for b in value:
+ result = result * 256 + int(b)
+ return result
+
+ # TODO check get_binary and how we can implement it
+
+ # TODO check is shallowCopy method required
+ def shallow_copy(self):
+ pass
+
+ # this OJAI object serialized as JSON string using the default options
+ # TODO options param required JsonOptions implementation
+ def as_json_string(self, options=None):
+ # TODO returns org.ojai.json.JSON.toJsonString implementation.
+ pass
+
+ # TODO required as_json_string method!
+ # def __str__(self):
+ # return self.as_json_string()
+
+ # TODO check eq impl
+ # def __eq__(self, o):
+ # return super(ValueImpl, self).__eq__(o)
diff --git a/entity/json/JsonValueBuilder.py b/entity/json/JsonValueBuilder.py
new file mode 100644
index 0000000..e69de29
diff --git a/entity/o_types/ODate.py b/entity/o_types/ODate.py
new file mode 100644
index 0000000..67503fa
--- /dev/null
+++ b/entity/o_types/ODate.py
@@ -0,0 +1,102 @@
+import datetime
+import dateutil.parser
+
+from entity.exceptions import UnsupportedConstructorException
+
+
+class ODate:
+ serial_version_uid = 0xaffa9a5dfe3ff863L
+
+ __EPOCH_DATE = datetime.datetime(1970, 1, 1)
+ __START_OF_DAY = datetime.time(hour=0, minute=0, second=0)
+
+ def __init__(self, year=None, month=None, day_of_month=None, epoch=None, date=None, days_since_epoch=None):
+ if all([year, month, day_of_month]) and epoch is None and date is None:
+ self.__date = datetime.datetime(year, month, day_of_month)
+ self.__days_since_epoch = (self.__date - self.__EPOCH_DATE).days
+ elif date is not None:
+ if type(date) is not datetime.datetime:
+ raise TypeError("date should be datetime.date type or comparable to it")
+ self.__date = date
+ self.__days_since_epoch = (self.__date - self.__EPOCH_DATE).days
+ elif epoch is not None:
+ self.__date = datetime.datetime.fromtimestamp(epoch)
+ self.__days_since_epoch = (self.__date - self.__EPOCH_DATE).days
+ elif days_since_epoch is not None:
+ self.__date = None
+ self.__days_since_epoch = days_since_epoch
+ else:
+ raise UnsupportedConstructorException
+
+ @property
+ def epoch_date(self):
+ return self.__EPOCH_DATE
+
+ @property
+ def start_of_day(self):
+ return self.__START_OF_DAY
+
+ @property
+ def days_since_epoch(self):
+ return self.__days_since_epoch
+
+ @staticmethod
+ def from_days_since_epoch(days_since_epoch):
+ return ODate(days_since_epoch=days_since_epoch)
+
+ @staticmethod
+ def parse(date_str):
+ return ODate(date=dateutil.parser.parse(date_str))
+
+ def __get_date(self):
+ if self.__date is None:
+ # self.__date = self.__EPOCH_DATE + datetime.datetime.fromtimestamp(self.__days_since_epoch)
+ self.__date = self.__EPOCH_DATE + datetime.timedelta(self.__days_since_epoch)
+ return self.__date
+
+ # Return the years of this datetime
+ def get_year(self):
+ return self.__get_date().year
+
+ # Return the month of this datetime
+ def get_month(self):
+ return self.__get_date().month
+
+ # Return the day of month of this datetime
+ def get_day_of_month(self):
+ return self.__get_date().day
+
+ def to_days_since_epoch(self):
+ return self.__days_since_epoch
+
+ def to_date_str(self):
+ return self.to_string("%Y-%m-%d")
+
+ def to_string(self, pattern):
+ return self.__get_date().strftime(pattern)
+
+ # return date with time set to 0
+ def to_date(self):
+ return datetime.datetime.combine(self.__get_date().date(), self.start_of_day)
+
+ def __str__(self):
+ return self.to_date_str()
+
+ def __cmp__(self, other):
+ if not isinstance(self, type(other)):
+ raise TypeError
+ return self.days_since_epoch - other.days_since_epoch
+
+ def __hash__(self):
+ return self.__days_since_epoch
+
+ def __eq__(self, other):
+ if self is other:
+ return True
+ if other is None:
+ return False
+ if not isinstance(self, type(other)):
+ return False
+ if self.days_since_epoch != other.days_since_epoch:
+ return False
+ return True
diff --git a/entity/o_types/OInterval.py b/entity/o_types/OInterval.py
new file mode 100644
index 0000000..01085f4
--- /dev/null
+++ b/entity/o_types/OInterval.py
@@ -0,0 +1,74 @@
+from entity.exceptions.UnsupportedConstructorException import UnsupportedConstructorException
+from entity.o_types import constants
+
+
+class OInterval:
+ """An immutable class which encapsulates a time interval."""
+
+ __SERIAL_VERSION_UID = 0x228372f2047c1511L
+
+ __APPROX_DAYS_IN_YEAR = ((365 * 4) + 1) / 4.0
+
+ __APPROX_DAYS_IN_MONTH = __APPROX_DAYS_IN_YEAR / 12
+
+ def __init__(self, milli_seconds=None, years=None, months=None, days=None,
+ seconds=None, iso8601DurationPattern=None):
+ if all([milli_seconds, years, months, days, seconds]):
+ self.__milli_seconds = milli_seconds
+ self.__seconds = seconds
+ self.__days = days
+ self.__months = months
+ self.__years = years
+ total_days = long(((years * self.__APPROX_DAYS_IN_YEAR) + (months + self.__APPROX_DAYS_IN_MONTH) + days))
+ self.__time_duration = constants.MILLISECONDS_PER_DAY * total_days + seconds * 1000 + milli_seconds
+ elif milli_seconds is not None and years is None and months is None and days is None and seconds is None:
+ self.__time_duration = long(milli_seconds)
+ self.__milli_seconds = int(milli_seconds % 1000)
+ self.__seconds = int((milli_seconds % constants.MILLISECONDS_PER_DAY) / 1000)
+ self.__days = int(milli_seconds / constants.MILLISECONDS_PER_DAY)
+ self.__months = 0
+ self.__years = 0
+ elif iso8601DurationPattern is not None:
+ # FIXME: parse the string as per ISO 8601 duration and time stamps format
+ self.__init__(0, 0, 0, 0, 0)
+ else:
+ raise UnsupportedConstructorException("This params set is not supported for the OInterval init")
+
+ @property
+ def years(self):
+ return self.__years
+
+ @property
+ def months(self):
+ return self.__months
+
+ @property
+ def days(self):
+ return self.__days
+
+ @property
+ def seconds(self):
+ return self.__seconds
+
+ @property
+ def milli_seconds(self):
+ return self.__milli_seconds
+
+ @property
+ def time_duration(self):
+ return self.__time_duration
+
+ def __hash__(self):
+ __result = 31 * 1 * int(self.time_duration ^ (self.time_duration >> 2))
+ return __result
+
+ def __eq__(self, other):
+ if self is other:
+ return True
+ if other is None:
+ return False
+ if not isinstance(self, type(other)):
+ return False
+ if self.time_duration != other.time_duration:
+ return False
+ return True
diff --git a/entity/o_types/OTime.py b/entity/o_types/OTime.py
new file mode 100644
index 0000000..00b1bdc
--- /dev/null
+++ b/entity/o_types/OTime.py
@@ -0,0 +1,116 @@
+import datetime
+import dateutil.parser
+
+from entity.exceptions import UnsupportedConstructorException
+
+
+class OTime:
+
+ __serial_version_uid = 0xaffa9a5dfe3ff863L
+ __EPOCH_DATE = datetime.datetime(1970, 1, 1)
+
+ def __init__(self, epoch=None, hour_of_day=None, minutes=None,
+ seconds=None, ms=None, date=None, millis_of_day=None):
+ if epoch is not None:
+ self.__time = datetime.datetime.fromtimestamp(epoch).time()
+ self.__millis_of_day = long((self.__time.hour * 60 * 60 + self.__time.second)
+ * 1000 + self.__time.microsecond / 1000.0)
+ # elif all([hour_of_day, minutes, seconds]) is not None:
+ elif hour_of_day is not None and minutes is not None and seconds is not None:
+ if ms is None:
+ self.__time = datetime.time(hour=hour_of_day, minute=minutes, second=seconds, microsecond=0)
+ else:
+ self.__time = datetime.time(hour=hour_of_day, minute=minutes, second=seconds, microsecond=ms)
+ self.__millis_of_day = long((self.__time.hour * 60 * 60 + self.__time.second)
+ * 1000 + self.__time.microsecond / 1000.0)
+ elif date is not None:
+ if not isinstance(type(date), type(datetime.datetime)):
+ raise TypeError
+ self.__time = date.time()
+ self.__millis_of_day = long((self.__time.hour * 60 * 60 + self.__time.second)
+ * 1000 + self.__time.microsecond / 1000.0)
+ elif millis_of_day is not None:
+ self.__time = None
+ self.__millis_of_day = millis_of_day
+ else:
+ raise UnsupportedConstructorException
+
+ @property
+ def epoch_date(self):
+ return self.__EPOCH_DATE
+
+ @property
+ def time(self):
+ return self.__time
+
+ @property
+ def millis_of_day(self):
+ return self.__millis_of_day
+
+ @staticmethod
+ def parse(time_str):
+ return OTime(date=dateutil.parser.parse("1970-01-01 " + time_str))
+
+ @staticmethod
+ def from_millis_of_day(millis_of_day):
+ return OTime(millis_of_day=millis_of_day)
+
+ def __get_time(self):
+ if self.time is None:
+ self.__time = datetime.datetime.fromtimestamp(self.millis_of_day).time()
+ return self.__time
+
+ def get_hour(self):
+ return self.__get_time().hour
+
+ def get_minute(self):
+ return self.__get_time().minute
+
+ def get_second(self):
+ return self.__get_time().second
+
+ def get_millis(self):
+ return self.__get_time().microsecond / 1000
+
+ def to_date(self):
+ return datetime.datetime.combine(self.__EPOCH_DATE.date(), self.__time)
+
+ def to_time_in_millis(self):
+ return self.__millis_of_day
+
+ def time_to_str(self):
+ if self.millis_of_day % 1000 == 0:
+ return self.to_str("%H:%M:%S")
+ else:
+ return self.to_str("%H:%M:%S:%f")
+
+ def to_str(self, pattern):
+ return self.__get_time().strftime(pattern)
+
+ def __str__(self):
+ self.time_to_str()
+
+ def __hash__(self):
+ return self.millis_of_day
+
+ def __cmp__(self, other):
+ if type(other) is not self:
+ raise TypeError
+ return self.millis_of_day - other.millis_of_day
+
+ def __eq__(self, other):
+ if self is other:
+ return True
+ if other is None:
+ return False
+ if not isinstance(self, type(other)):
+ return False
+ if self.millis_of_day != other.millis_of_day:
+ return False
+ return True
+
+
+
+
+
+
diff --git a/entity/o_types/OTimestamp.py b/entity/o_types/OTimestamp.py
new file mode 100644
index 0000000..8784491
--- /dev/null
+++ b/entity/o_types/OTimestamp.py
@@ -0,0 +1,119 @@
+import datetime
+import dateutil.parser
+
+from entity.exceptions import UnsupportedConstructorException
+
+
+class OTimestamp:
+ __serial_version_uid = 0x3800c3b7b7f0e008L
+ __epoch = datetime.datetime.utcfromtimestamp(0)
+ # TODO Is UTC_CHRONOLOGY must return current time in UTC time zone? and must be created only once with instance?
+ __UTC_CHRONOLOGY = datetime.datetime.utcfromtimestamp(0)
+
+ """ Two types of OTimestamp init:
+ First params set:
+ year - the year
+ month_of_year - the month of the year, from 1 to 12
+ day_of_month - the day of the month, from 1 to 31
+ hour_of_day - the hour of the day, from 0 to 23
+ minute_of_hour - the minute of the hour, from 0 to 59
+ second_of_minute - the second of the minute, from 0 to 59
+ millis_of_second - the millisecond of the second, from 0 to 999
+ Second:
+ date - the Date to extract fields from"""
+
+ def __init__(self, year=None, month_of_year=None, day_of_month=None, hour_of_day=None, minute_of_hour=None,
+ second_of_minute=None, millis_of_second=None, date=None, millis_since_epoch=None):
+ # if all([year, month_of_year, day_of_month, hour_of_day,
+ # minute_of_hour, second_of_minute, millis_of_second]) is not None:
+ if (year is not None and month_of_year is not None and day_of_month is not None and hour_of_day is not None
+ and minute_of_hour is not None and second_of_minute is not None and millis_of_second is not None):
+ self.__date_time = datetime.datetime(year=year, month=month_of_year, day=day_of_month,
+ hour=hour_of_day, minute=minute_of_hour, second=second_of_minute,
+ microsecond=millis_of_second * 1000)
+ self.__millis_since_epoch = (self.__date_time - self.__epoch).total_seconds() * 1000.0
+ elif millis_since_epoch is not None:
+ self.__date_time = None
+ self.__millis_since_epoch = millis_since_epoch
+ elif date is not None:
+ if not isinstance(type(date), type(datetime.datetime)):
+ raise TypeError
+ self.__date_time = date
+ self.__millis_since_epoch = (self.__date_time - self.__epoch).total_seconds() * 1000.0
+ else:
+ raise UnsupportedConstructorException
+
+ @property
+ def millis_since_epoch(self):
+ return self.__millis_since_epoch
+
+ @property
+ def date_time(self):
+ return self.__date_time
+
+ def get_year(self):
+ return (self.__UTC_CHRONOLOGY + datetime.timedelta(milliseconds=self.millis_since_epoch)).year
+
+ def get_month(self):
+ return (self.__UTC_CHRONOLOGY + datetime.timedelta(milliseconds=self.millis_since_epoch)).month
+
+ def get_day_of_month(self):
+ return (self.__UTC_CHRONOLOGY + datetime.timedelta(milliseconds=self.millis_since_epoch)).day
+
+ def get_hour(self):
+ return (self.__UTC_CHRONOLOGY + datetime.timedelta(milliseconds=self.millis_since_epoch)).hour
+
+ def get_minute(self):
+ return (self.__UTC_CHRONOLOGY + datetime.timedelta(milliseconds=self.millis_since_epoch)).minute
+
+ def get_second(self):
+ return (self.__UTC_CHRONOLOGY + datetime.timedelta(milliseconds=self.millis_since_epoch)).second
+
+ def get_millis(self):
+ return (self.__UTC_CHRONOLOGY + datetime.timedelta(milliseconds=self.millis_since_epoch)).microsecond / 1000
+
+ def __get_date_time(self):
+ if self.__date_time is None:
+ self.__date_time = self.__UTC_CHRONOLOGY + datetime.timedelta(milliseconds=self.millis_since_epoch)
+ return self.date_time
+
+ # Create datetime object from millis since epoch
+ def to_date(self):
+ return datetime.datetime.fromtimestamp(self.millis_since_epoch / 1000.0)
+
+ # Returns the ISO8601 format timestamp string in UTC.
+ def to_utc_str(self):
+ return self.__get_date_time().utcnow().isoformat()
+
+ # Returns the ISO8601 format timestamp string in local time zone.
+ def to_local_str(self):
+ return self.__get_date_time().now().isoformat()
+
+ def to_str(self, pattern):
+ return self.__get_date_time().strftime(pattern)
+
+ @staticmethod
+ def parse(date_time_str):
+ return OTimestamp(date=dateutil.parser.parse(date_time_str))
+
+ def __str__(self):
+ return self.to_utc_str()
+
+ def __cmp__(self, other):
+ if type(other) is not self or type(other) is not type(datetime.datetime):
+ raise TypeError
+ return self.millis_since_epoch - other.millis_since_epoch
+
+ def __hash__(self):
+ return int(self.millis_since_epoch ^ (self.millis_since_epoch >> 32))
+
+ def __eq__(self, other):
+ if self is other:
+ return True
+ if other is None:
+ return False
+ if not isinstance(self, type(other)):
+ return False
+ if self.millis_since_epoch != other.millis_since_epoch:
+ return False
+ return True
diff --git a/entity/o_types/constants.py b/entity/o_types/constants.py
new file mode 100644
index 0000000..d09d4ed
--- /dev/null
+++ b/entity/o_types/constants.py
@@ -0,0 +1,12 @@
+
+# A long value equal to the number of milliseconds in a second
+MILLISECONDS_PER_SECOND = 1000
+
+# A long value equal to the number of milliseconds in a minute.
+MILLISECONDS_PER_MINUTE = 60 * MILLISECONDS_PER_SECOND
+
+# A long value equal to the number of milliseconds in an hour.
+MILLISECONDS_PER_HOUR = 60 * MILLISECONDS_PER_MINUTE
+
+# A long value equal to the number of milliseconds in a day.
+MILLISECONDS_PER_DAY = 24 * MILLISECONDS_PER_HOUR
diff --git a/entity/storage/Connection.py b/entity/storage/Connection.py
new file mode 100644
index 0000000..8582a52
--- /dev/null
+++ b/entity/storage/Connection.py
@@ -0,0 +1,44 @@
+from abc import ABCMeta, abstractmethod
+
+
+class Connection:
+ __metaclass__ = ABCMeta
+
+ def __init__(self):
+ pass
+
+ @abstractmethod
+ def get_store(self, store_name, options=None):
+ raise NotImplementedError("Should have implemented this")
+
+ @abstractmethod
+ def get_value_buffer(self):
+ raise NotImplementedError("Should have implemented this")
+
+ @abstractmethod
+ def new_document(self, json_string=None, json_map=None, obj=None):
+ raise NotImplementedError("Should have implemented this")
+
+ @abstractmethod
+ def new_document_builder(self):
+ raise NotImplementedError("Should have implemented this")
+
+ @abstractmethod
+ def new_mutation(self):
+ raise NotImplementedError("Should have implemented this")
+
+ @abstractmethod
+ def new_condition(self):
+ raise NotImplementedError("Should have implemented this")
+
+ @abstractmethod
+ def new_query(self, query_json=None):
+ raise NotImplementedError("Should have implemented this")
+
+ @abstractmethod
+ def get_driver(self):
+ raise NotImplementedError("Should have implemented this")
+
+ @abstractmethod
+ def close(self):
+ raise NotImplementedError("Should have implemented this")
diff --git a/entity/storage/ConnectionManager.py b/entity/storage/ConnectionManager.py
new file mode 100644
index 0000000..0510792
--- /dev/null
+++ b/entity/storage/ConnectionManager.py
@@ -0,0 +1,16 @@
+from abc import ABCMeta, abstractmethod
+
+
+class ConnectionManager:
+ __metaclass__ = ABCMeta
+
+ def __init__(self):
+ pass
+
+ @abstractmethod
+ def get_connection(self, url, options=None):
+ raise NotImplementedError("Should have implemented this")
+
+ @abstractmethod
+ def check_url(self, url):
+ raise NotImplementedError("Should have implemented this")
\ No newline at end of file
diff --git a/entity/utils/Documents.py b/entity/utils/Documents.py
new file mode 100644
index 0000000..e2cfc49
--- /dev/null
+++ b/entity/utils/Documents.py
@@ -0,0 +1,13 @@
+
+class Documents:
+
+ def __init__(self):
+ pass
+
+ @staticmethod
+ def write_reader_to_builder(document_reader, document_builder):
+ pass
+
+ @staticmethod
+ def equals(document1, document2):
+ pass
diff --git a/entity/values/Value.py b/entity/values/Value.py
new file mode 100644
index 0000000..68a46b6
--- /dev/null
+++ b/entity/values/Value.py
@@ -0,0 +1,157 @@
+from abc import ABCMeta, abstractmethod
+from aenum import Enum
+
+
+class Value:
+ __metaclass__ = ABCMeta
+
+ @abstractmethod
+ def get_type(self):
+ raise NotImplementedError("Should have implemented this")
+
+ @abstractmethod
+ def get_byte(self):
+ raise NotImplementedError("Should have implemented this")
+
+ @abstractmethod
+ def get_int(self):
+ raise NotImplementedError("Should have implemented this")
+
+ @abstractmethod
+ def get_long(self):
+ raise NotImplementedError("Should have implemented this")
+
+ @abstractmethod
+ def get_float(self):
+ raise NotImplementedError("Should have implemented this")
+
+ @abstractmethod
+ def get_decimal(self):
+ raise NotImplementedError("Should have implemented this")
+
+ @abstractmethod
+ def get_boolean(self):
+ raise NotImplementedError("Should have implemented this")
+
+ @abstractmethod
+ def get_string(self):
+ raise NotImplementedError("Should have implemented this")
+
+ @abstractmethod
+ def get_timestamp(self):
+ raise NotImplementedError("Should have implemented this")
+
+ @abstractmethod
+ def get_timestamp_as_long(self):
+ raise NotImplementedError("Should have implemented this")
+
+ @abstractmethod
+ def get_date(self):
+ raise NotImplementedError("Should have implemented this")
+
+ @abstractmethod
+ def get_date_as_int(self):
+ raise NotImplementedError("Should have implemented this")
+
+ @abstractmethod
+ def get_time(self):
+ raise NotImplementedError("Should have implemented this")
+
+ @abstractmethod
+ def get_time_as_int(self):
+ raise NotImplementedError("Should have implemented this")
+
+ @abstractmethod
+ def get_interval(self):
+ raise NotImplementedError("Should have implemented this")
+
+ @abstractmethod
+ def get_interval_as_long(self):
+ raise NotImplementedError("Should have implemented this")
+
+ @abstractmethod
+ def get_map(self):
+ raise NotImplementedError("Should have implemented this")
+
+ @abstractmethod
+ def get_list(self):
+ raise NotImplementedError("Should have implemented this")
+
+ @abstractmethod
+ def get_obj(self):
+ raise NotImplementedError("Should have implemented this")
+
+ @abstractmethod
+ def as_reader(self):
+ raise NotImplementedError("Should have implemented this")
+
+ # TODO investigate is we can add binary analog (java.nia.ByteBuffer)
+ # @abstractmethod
+ # def get_binary(self):
+ # raise NotImplementedError("Should have implemented this")
+
+
+# TODO Python2 doesn't have enum. Impelement method for convert ValueType numeric field to string like 2 -> "BOOLEAN"
+class ValueType(Enum):
+ # NULL = Value.type_code_null
+ NULL = 1
+
+ # BOOLEAN = Value.type_code_boolean
+ BOOLEAN = 2
+
+ # STRING = Value.type_code_string
+ STRING = 3
+
+ # BYTE = Value.type_code_byte
+ BYTE = 4
+
+ # INT = Value.type_code_int
+ INT = 5
+
+ # LONG = Value.type_code_long
+ LONG = 6
+
+ # FLOAT = Value.type_code_float
+ FLOAT = 7
+
+ # DECIMAL = Value.type_code_decimal
+ DECIMAL = 8
+
+ # DATE = Value.type_code_date
+ DATE = 9
+
+ # TIME = Value.type_code_time
+ TIME = 10
+
+ # TIMESTAMP = Value.get_timestamp
+ TIMESTAMP = 11
+
+ # INTERVAL = Value.type_code_interval
+ INTERVAL = 12
+
+ # BINARY = Value.type_code_binary
+ BINARY = 13
+
+ # MAP = Value.type_code_map
+ MAP = 14
+
+ # ARRAY = Value.type_code_array
+ ARRAY = 15
+
+ @staticmethod
+ def __check_value(value_type):
+ value_dict = {ValueType.NULL: 1, ValueType.BOOLEAN: 2, ValueType.STRING: 3, ValueType.BYTE: 4, ValueType.INT: 5,
+ ValueType.LONG: 6, ValueType.FLOAT: 7, ValueType.DECIMAL: 8, ValueType.DATE: 9,
+ ValueType.TIME: 10, ValueType.TIMESTAMP: 11, ValueType.INTERVAL: 12,
+ ValueType.BINARY: 13, ValueType.MAP: 14, ValueType.ARRAY: 15}
+ return value_dict[value_type]
+
+ @staticmethod
+ def is_scalar(value):
+ return ValueType.__check_value(value) != ValueType.__check_value(ValueType.MAP)\
+ and ValueType.__check_value(value) != ValueType.__check_value(ValueType.ARRAY)
+
+ @staticmethod
+ def is_numeric(value):
+ return ValueType.__check_value(ValueType.BYTE) <= ValueType.__check_value(value)\
+ <= ValueType.__check_value(ValueType.DECIMAL)
diff --git a/entity/values/ValueBuilder.py b/entity/values/ValueBuilder.py
new file mode 100644
index 0000000..291898c
--- /dev/null
+++ b/entity/values/ValueBuilder.py
@@ -0,0 +1,5 @@
+from abc import ABCMeta, abstractmethod
+
+
+class ValueBuilder:
+ __metaclass__ = ABCMeta
\ No newline at end of file
diff --git a/test/json/test_jsonvalue.py b/test/json/test_jsonvalue.py
new file mode 100644
index 0000000..25abbc1
--- /dev/null
+++ b/test/json/test_jsonvalue.py
@@ -0,0 +1,11 @@
+from __future__ import unicode_literals
+
+from entity.o_types.OInterval import OInterval
+from entity.values import Value
+from entity.values.Value import ValueType
+
+try:
+ import unittest2 as unittest
+except ImportError:
+ import unittest
+
diff --git a/test/o_types_test/test_odate.py b/test/o_types_test/test_odate.py
new file mode 100644
index 0000000..b4422b7
--- /dev/null
+++ b/test/o_types_test/test_odate.py
@@ -0,0 +1,75 @@
+from __future__ import unicode_literals
+
+from entity.o_types.ODate import ODate
+
+try:
+ import unittest2 as unittest
+except ImportError:
+ import unittest
+
+
+class ODateTest(unittest.TestCase):
+
+ def test_days_from_epoch(self):
+ days = 99
+ o_date = ODate(days_since_epoch=days)
+ o_date_clone = ODate(days_since_epoch=days)
+ self.assertTrue(o_date.__eq__(o_date_clone))
+ self.assertEqual(o_date.__cmp__(o_date_clone), 0)
+ self.assertEqual(o_date.__hash__(), o_date_clone.__hash__())
+ self.assertEqual(o_date.to_date_str(), "1970-04-10")
+ self.assertEqual(o_date.get_year(), 1970)
+ self.assertEqual(o_date.get_month(), 4)
+ self.assertEqual(o_date.get_day_of_month(), 10)
+ self.assertEqual(o_date.to_date().time().hour, 0)
+ self.assertEqual(o_date.to_date().time().minute, 0)
+ self.assertEqual(o_date.to_date().time().second, 0)
+
+ def test_o_date_parse(self):
+ o_date = ODate.parse("1970-04-10")
+ self.assertEqual(o_date.days_since_epoch, 99)
+ self.assertEqual(o_date.get_year(), 1970)
+ self.assertEqual(o_date.get_month(), 4)
+ self.assertEqual(o_date.get_day_of_month(), 10)
+ self.assertEqual(o_date.to_date().time().hour, 0)
+ self.assertEqual(o_date.to_date().time().minute, 0)
+ self.assertEqual(o_date.to_date().time().second, 0)
+
+ def test_concrete_date(self):
+ o_date = ODate(year=1970, month=4, day_of_month=10)
+ self.assertEqual(o_date.days_since_epoch, 99)
+ self.assertEqual(o_date.get_year(), 1970)
+ self.assertEqual(o_date.get_month(), 4)
+ self.assertEqual(o_date.get_day_of_month(), 10)
+ self.assertEqual(o_date.to_date().time().hour, 0)
+ self.assertEqual(o_date.to_date().time().minute, 0)
+ self.assertEqual(o_date.to_date().time().second, 0)
+
+ def test_o_date_epoch(self):
+ epoch = 8546400
+ o_date = ODate(epoch=epoch)
+ days = 99
+ o_date_clone = ODate(days_since_epoch=days)
+ self.assertTrue(o_date.__eq__(o_date_clone))
+ self.assertEqual(o_date.__cmp__(o_date_clone), 0)
+ self.assertEqual(o_date.__hash__(), o_date_clone.__hash__())
+ self.assertEqual(o_date.get_year(), o_date_clone.get_year())
+ self.assertEqual(o_date.get_month(), o_date_clone.get_month())
+ self.assertEqual(o_date.get_day_of_month(), o_date_clone.get_day_of_month())
+
+ def test_o_date_datetime(self):
+ import datetime
+ date = datetime.datetime(year=1970, month=4, day=10, hour=5, minute=15, second=55)
+ o_date = ODate(date=date)
+ self.assertEqual(o_date.days_since_epoch, 99)
+ self.assertEqual(o_date.get_year(), 1970)
+ self.assertEqual(o_date.get_month(), 4)
+ self.assertEqual(o_date.get_day_of_month(), 10)
+ self.assertEqual(o_date.to_date().time().hour, 0)
+ self.assertEqual(o_date.to_date().time().minute, 0)
+ self.assertEqual(o_date.to_date().time().second, 0)
+
+
+if __name__ == '__main__':
+ suite = unittest.TestLoader().loadTestsFromTestCase(ODateTest)
+ unittest.TextTestRunner(verbosity=2).run(suite)
diff --git a/test/o_types_test/test_ointerval.py b/test/o_types_test/test_ointerval.py
new file mode 100644
index 0000000..91570da
--- /dev/null
+++ b/test/o_types_test/test_ointerval.py
@@ -0,0 +1,47 @@
+from __future__ import unicode_literals
+
+from entity.o_types.OInterval import OInterval
+
+try:
+ import unittest2 as unittest
+except ImportError:
+ import unittest
+
+
+class OIntervalTest(unittest.TestCase):
+
+ def test_instance_millis(self):
+ # check than 2 instance with the same constructor are equals
+ instance1 = OInterval(milli_seconds=86754099)
+ instance2 = OInterval(milli_seconds=86754099)
+ self.assertTrue(instance1.__eq__(instance2))
+
+ self.assertEqual(instance1.time_duration, long(86754099))
+ from entity.o_types.constants import MILLISECONDS_PER_DAY
+ self.assertEqual(instance1.seconds, int((86754099 % MILLISECONDS_PER_DAY) / 1000))
+ self.assertEqual(instance1.days, int(86754099 / MILLISECONDS_PER_DAY))
+ self.assertEqual(instance1.years, 0)
+ self.assertEqual(instance1.months, 0)
+
+ def test_instance_full(self):
+ instance = OInterval(milli_seconds=999, years=3, months=4, days=6, seconds=59)
+
+ self.assertEqual(instance.milli_seconds, 999)
+ self.assertEqual(instance.years, 3)
+ self.assertEqual(instance.months, 4)
+ self.assertEqual(instance.days, 6)
+ self.assertEqual(instance.seconds, 59)
+
+ # Test check that __hash__ works correct
+ def test_instance_hash(self):
+ instance1 = OInterval(milli_seconds=86754099)
+ instance2 = OInterval(milli_seconds=86754099)
+ instance3 = OInterval(milli_seconds=86754098)
+
+ self.assertEqual(instance1.__hash__(), instance2.__hash__())
+ self.assertFalse(instance1.__hash__() == instance3.__hash__())
+
+
+if __name__ == '__main__':
+ suite = unittest.TestLoader().loadTestsFromTestCase(OIntervalTest)
+ unittest.TextTestRunner(verbosity=2).run(suite)
diff --git a/test/o_types_test/test_otime.py b/test/o_types_test/test_otime.py
new file mode 100644
index 0000000..84b06b8
--- /dev/null
+++ b/test/o_types_test/test_otime.py
@@ -0,0 +1,60 @@
+from __future__ import unicode_literals
+
+from entity.o_types.OTime import OTime
+
+try:
+ import unittest2 as unittest
+except ImportError:
+ import unittest
+
+
+class OTimeTest(unittest.TestCase):
+
+ def test_days_from_epoch(self):
+ epoch = 8587555
+ o_time = OTime(epoch=epoch)
+ self.assertEqual(o_time.get_hour(), 12)
+ self.assertEqual(o_time.get_minute(), 25)
+ self.assertEqual(o_time.get_second(), 55)
+ self.assertEqual(o_time.get_millis(), 0)
+ parse_o_time = OTime.parse(time_str="12:25:55")
+ self.assertEqual(parse_o_time.get_hour(), o_time.get_hour())
+ self.assertEqual(parse_o_time.get_minute(), o_time.get_minute())
+ self.assertEqual(parse_o_time.get_second(), o_time.get_second())
+ self.assertTrue(o_time.__eq__(parse_o_time))
+ self.assertEqual(o_time.to_str("%H:%M:%S"), "12:25:55")
+ self.assertEqual(o_time.time_to_str(), "12:25:55")
+
+ def test_o_time_from_time(self):
+ o_time = OTime(hour_of_day=12, minutes=25, seconds=55)
+ self.assertEqual(o_time.get_hour(), 12)
+ self.assertEqual(o_time.get_minute(), 25)
+ self.assertEqual(o_time.get_second(), 55)
+ self.assertEqual(o_time.get_millis(), 0)
+ parse_o_time = OTime.parse(time_str="12:25:55")
+ self.assertEqual(parse_o_time.get_hour(), o_time.get_hour())
+ self.assertEqual(parse_o_time.get_minute(), o_time.get_minute())
+ self.assertEqual(parse_o_time.get_second(), o_time.get_second())
+ self.assertTrue(o_time.__eq__(parse_o_time))
+ self.assertEqual(o_time.to_str("%H:%M:%S"), "12:25:55")
+ self.assertEqual(o_time.time_to_str(), "12:25:55")
+
+ def test_o_time_from_date(self):
+ import datetime
+ o_time = OTime(date=datetime.datetime(year=1970, month=1, day=1, hour=12, minute=25, second=55))
+ self.assertEqual(o_time.get_hour(), 12)
+ self.assertEqual(o_time.get_minute(), 25)
+ self.assertEqual(o_time.get_second(), 55)
+ self.assertEqual(o_time.get_millis(), 0)
+ parse_o_time = OTime.parse(time_str="12:25:55")
+ self.assertEqual(parse_o_time.get_hour(), o_time.get_hour())
+ self.assertEqual(parse_o_time.get_minute(), o_time.get_minute())
+ self.assertEqual(parse_o_time.get_second(), o_time.get_second())
+ self.assertTrue(o_time.__eq__(parse_o_time))
+ self.assertEqual(o_time.to_str("%H:%M:%S"), "12:25:55")
+ self.assertEqual(o_time.time_to_str(), "12:25:55")
+
+
+if __name__ == '__main__':
+ suite = unittest.TestLoader().loadTestsFromTestCase(OTimeTest)
+ unittest.TextTestRunner(verbosity=2).run(suite)
diff --git a/test/o_types_test/test_otimestamp.py b/test/o_types_test/test_otimestamp.py
new file mode 100644
index 0000000..0bdd028
--- /dev/null
+++ b/test/o_types_test/test_otimestamp.py
@@ -0,0 +1,60 @@
+from __future__ import unicode_literals
+
+from entity.o_types.OTimestamp import OTimestamp
+
+try:
+ import unittest2 as unittest
+except ImportError:
+ import unittest
+
+
+class OTimestampTest(unittest.TestCase):
+
+ def test_days_from_epoch(self):
+ o_timestamp = OTimestamp(year=1970, month_of_year=4, day_of_month=10, hour_of_day=12,
+ minute_of_hour=25, second_of_minute=55, millis_of_second=600)
+ o_timestamp_clone = OTimestamp(year=1970, month_of_year=4, day_of_month=10, hour_of_day=12,
+ minute_of_hour=25, second_of_minute=55, millis_of_second=600)
+
+ self.assertEqual(o_timestamp.get_year(), 1970)
+ self.assertEqual(o_timestamp.get_month(), 4)
+ self.assertEqual(o_timestamp.get_day_of_month(), 10)
+ self.assertEqual(o_timestamp.get_hour(), 12)
+ self.assertEqual(o_timestamp.get_minute(), 25)
+ self.assertEqual(o_timestamp.get_second(), 55)
+ self.assertEqual(o_timestamp.get_millis(), 600)
+ self.assertTrue(o_timestamp.__eq__(o_timestamp_clone))
+
+ def test_o_timestamp_from_millis_epoch(self):
+ o_timestamp = OTimestamp(millis_since_epoch=8598355000)
+ self.assertEqual(o_timestamp.get_year(), 1970)
+ self.assertEqual(o_timestamp.get_month(), 4)
+ self.assertEqual(o_timestamp.get_day_of_month(), 10)
+ self.assertEqual(o_timestamp.get_hour(), 12)
+ self.assertEqual(o_timestamp.get_minute(), 25)
+ self.assertEqual(o_timestamp.get_second(), 55)
+
+ def test_o_timestamp_from_date(self):
+ import datetime
+ date = datetime.datetime(year=1970, month=4, day=10, hour=12, minute=25, second=55)
+ o_timestamp = OTimestamp(date=date)
+ self.assertEqual(o_timestamp.get_year(), 1970)
+ self.assertEqual(o_timestamp.get_month(), 4)
+ self.assertEqual(o_timestamp.get_day_of_month(), 10)
+ self.assertEqual(o_timestamp.get_hour(), 12)
+ self.assertEqual(o_timestamp.get_minute(), 25)
+ self.assertEqual(o_timestamp.get_second(), 55)
+
+ def test_parse_timestamp_to_o_timestamp(self):
+ o_timestamp = OTimestamp.parse("April 10 1970 12:25:55")
+ self.assertEqual(o_timestamp.get_year(), 1970)
+ self.assertEqual(o_timestamp.get_month(), 4)
+ self.assertEqual(o_timestamp.get_day_of_month(), 10)
+ self.assertEqual(o_timestamp.get_hour(), 12)
+ self.assertEqual(o_timestamp.get_minute(), 25)
+ self.assertEqual(o_timestamp.get_second(), 55)
+
+
+if __name__ == '__main__':
+ suite = unittest.TestLoader().loadTestsFromTestCase(OTimestampTest)
+ unittest.TextTestRunner(verbosity=2).run(suite)
diff --git a/test/values/test_type.py b/test/values/test_type.py
new file mode 100644
index 0000000..445ff8a
--- /dev/null
+++ b/test/values/test_type.py
@@ -0,0 +1,41 @@
+from __future__ import unicode_literals
+
+from entity.o_types.OInterval import OInterval
+from entity.values import Value
+from entity.values.Value import ValueType
+
+try:
+ import unittest2 as unittest
+except ImportError:
+ import unittest
+
+
+class ValueTypeTest(unittest.TestCase):
+
+ def test_value_type(self):
+ self.assertFalse(ValueType.is_numeric(ValueType.NULL))
+ self.assertFalse(ValueType.is_numeric(ValueType.BOOLEAN))
+ self.assertFalse(ValueType.is_numeric(ValueType.STRING))
+ self.assertTrue(ValueType.is_numeric(ValueType.BYTE))
+ self.assertTrue(ValueType.is_numeric(ValueType.INT))
+ self.assertTrue(ValueType.is_numeric(ValueType.LONG))
+ self.assertTrue(ValueType.is_numeric(ValueType.FLOAT))
+ self.assertTrue(ValueType.is_numeric(ValueType.DECIMAL))
+ self.assertFalse(ValueType.is_numeric(ValueType.DATE))
+ self.assertFalse(ValueType.is_numeric(ValueType.TIME))
+ self.assertFalse(ValueType.is_numeric(ValueType.TIMESTAMP))
+ self.assertFalse(ValueType.is_numeric(ValueType.INTERVAL))
+ self.assertFalse(ValueType.is_numeric(ValueType.BINARY))
+ self.assertFalse(ValueType.is_numeric(ValueType.MAP))
+ self.assertFalse(ValueType.is_numeric(ValueType.ARRAY))
+
+ self.assertFalse(ValueType.is_scalar(ValueType.MAP))
+ self.assertFalse(ValueType.is_scalar(ValueType.ARRAY))
+
+ self.assertEqual(ValueType.ARRAY, ValueType.ARRAY)
+ self.assertNotEqual(ValueType.ARRAY, ValueType.MAP)
+
+
+if __name__ == '__main__':
+ suite = unittest.TestLoader().loadTestsFromTestCase(ValueTypeTest)
+ unittest.TextTestRunner(verbosity=2).run(suite)