diff --git a/Cargo.lock b/Cargo.lock index f97fc10..b65421d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -293,7 +293,7 @@ dependencies = [ [[package]] name = "gxtdb-rs" -version = "0.1.0" +version = "0.0.1" dependencies = [ "chrono", "futures", diff --git a/Makefile b/Makefile index 6795232..032639d 100644 --- a/Makefile +++ b/Makefile @@ -21,7 +21,7 @@ fix-clj: cljfmt kibit fix-rs: rsfmt clippy proto: - protoc --clojure_out=grpc-client,grpc-server:src --proto_path=resources resources/transactions.proto resources/service.proto + protoc --clojure_out=grpc-client,grpc-server:src --proto_path=resources resources/common.proto resources/transactions.proto resources/entity.proto resources/service.proto all: proto fix diff --git a/gxtdb-rs/tests/mock.rs b/gxtdb-rs/tests/mock.rs index b0c5cbe..9d2720d 100644 --- a/gxtdb-rs/tests/mock.rs +++ b/gxtdb-rs/tests/mock.rs @@ -21,6 +21,13 @@ impl GrpcApi for ServerMock { ) -> Result, tonic::Status> { todo!() } + + async fn entity_tx( + &self, + _request: tonic::Request, + ) -> Result, tonic::Status> { + todo!() + } } pub async fn client() -> gxtdb_rs::Client { diff --git a/kreya/grpc/com/xtdb/protos/GrpcApi/EntityTx-request.json b/kreya/grpc/com/xtdb/protos/GrpcApi/EntityTx-request.json new file mode 100644 index 0000000..713f040 --- /dev/null +++ b/kreya/grpc/com/xtdb/protos/GrpcApi/EntityTx-request.json @@ -0,0 +1,14 @@ +{ + "idType": "Keyword", + "entityId": "id1", + "openSnapshot": false, + "txId": { + "none": {} + }, + "validTime": { + "none": {} + }, + "txTime": { + "none": {} + } +} \ No newline at end of file diff --git a/kreya/grpc/com/xtdb/protos/GrpcApi/EntityTx.krop b/kreya/grpc/com/xtdb/protos/GrpcApi/EntityTx.krop new file mode 100644 index 0000000..7a154b8 --- /dev/null +++ b/kreya/grpc/com/xtdb/protos/GrpcApi/EntityTx.krop @@ -0,0 +1,12 @@ +{ + "details": { + "methodFqn": "com.xtdb.protos.GrpcApi.EntityTx" + }, + "requests": [ + { + "location": "EntityTx-request.json" + } + ], + "operationType": "unary", + "invokerName": "grpc" +} \ No newline at end of file diff --git a/kreya/grpc/com/xtdb/protos/GrpcApi/SubmitTx-request.json b/kreya/grpc/com/xtdb/protos/GrpcApi/SubmitTx-request.json index 7b0faeb..ff872e6 100644 --- a/kreya/grpc/com/xtdb/protos/GrpcApi/SubmitTx-request.json +++ b/kreya/grpc/com/xtdb/protos/GrpcApi/SubmitTx-request.json @@ -7,8 +7,5 @@ "document": {"key": "value"} } } - ], - "txTime": { - "some": "2023-06-12T21:32:44.717-05:00" - } + ] } \ No newline at end of file diff --git a/resources/common.proto b/resources/common.proto index a3756df..36b7535 100644 --- a/resources/common.proto +++ b/resources/common.proto @@ -2,8 +2,22 @@ syntax = "proto3"; package com.xtdb.protos; +enum IdType { + Uuid = 0; + Keyword = 1; + String = 2; + Int = 3; +} + message Empty {} +message OptionInt64 { + oneof value { + Empty none = 1; + int64 some = 2; + } +} + message OptionString { oneof value { Empty none = 1; diff --git a/resources/entity.proto b/resources/entity.proto new file mode 100644 index 0000000..a3e47a8 --- /dev/null +++ b/resources/entity.proto @@ -0,0 +1,21 @@ +syntax = "proto3"; + +package com.xtdb.protos; +import "common.proto"; + +message EntityTxResponse { + string xt_id = 1; + string content_hash = 2; + string valid_time = 3; + string tx_time = 4; + int64 tx_id = 5; +} + +message EntityTxRequest { + IdType id_type = 1; + string entity_id = 2; + bool open_snapshot = 3; + OptionInt64 tx_id = 4; + OptionDatetime valid_time = 5; + OptionDatetime tx_time = 6; +} \ No newline at end of file diff --git a/resources/service.proto b/resources/service.proto index c57aed2..77e4903 100644 --- a/resources/service.proto +++ b/resources/service.proto @@ -3,6 +3,7 @@ syntax = "proto3"; package com.xtdb.protos; import "transactions.proto"; +import "entity.proto"; import "common.proto"; @@ -20,4 +21,6 @@ service GrpcApi { rpc Status(Empty) returns (StatusResponse); rpc SubmitTx(com.xtdb.protos.SubmitRequest) returns (com.xtdb.protos.SubmitResponse); + rpc EntityTx(com.xtdb.protos.EntityTxRequest) + returns (com.xtdb.protos.EntityTxResponse); } diff --git a/resources/transactions.proto b/resources/transactions.proto index 1673b73..e0d4ab3 100644 --- a/resources/transactions.proto +++ b/resources/transactions.proto @@ -13,15 +13,6 @@ message Transaction { } } -enum IdType { - Uuid = 0; - Keyword = 1; - String = 2; - Int = 3; -} - - - message Put { IdType id_type = 1; string xt_id = 2; diff --git a/src/com/google/protobuf.cljc b/src/com/google/protobuf.cljc deleted file mode 100644 index 04fc5e4..0000000 --- a/src/com/google/protobuf.cljc +++ /dev/null @@ -1,714 +0,0 @@ -;;;---------------------------------------------------------------------------------- -;;; Generated by protoc-gen-clojure. DO NOT EDIT -;;; -;;; Message Implementation of package com.google.protobuf -;;;---------------------------------------------------------------------------------- -(ns com.google.protobuf - (:require [protojure.protobuf.protocol :as pb] - [protojure.protobuf.serdes.core :as serdes.core] - [protojure.protobuf.serdes.complex :as serdes.complex] - [protojure.protobuf.serdes.utils :refer [tag-map]] - [protojure.protobuf.serdes.stream :as serdes.stream] - [com.google.protobuf :as com.google.protobuf] - [clojure.set :as set] - [clojure.spec.alpha :as s])) - -;;---------------------------------------------------------------------------------- -;;---------------------------------------------------------------------------------- -;; Forward declarations -;;---------------------------------------------------------------------------------- -;;---------------------------------------------------------------------------------- - -(declare cis->ListValue) -(declare ecis->ListValue) -(declare new-ListValue) -(declare cis->Empty) -(declare ecis->Empty) -(declare new-Empty) -(declare cis->Struct) -(declare ecis->Struct) -(declare new-Struct) -(declare cis->StatusResponse) -(declare ecis->StatusResponse) -(declare new-StatusResponse) -(declare cis->Evict) -(declare ecis->Evict) -(declare new-Evict) -(declare cis->Struct-FieldsEntry) -(declare ecis->Struct-FieldsEntry) -(declare new-Struct-FieldsEntry) -(declare cis->Put) -(declare ecis->Put) -(declare new-Put) -(declare cis->Delete) -(declare ecis->Delete) -(declare new-Delete) -(declare cis->SubmitRequest) -(declare ecis->SubmitRequest) -(declare new-SubmitRequest) -(declare cis->SubmitResponse) -(declare ecis->SubmitResponse) -(declare new-SubmitResponse) -(declare cis->Value) -(declare ecis->Value) -(declare new-Value) -(declare cis->Transaction) -(declare ecis->Transaction) -(declare new-Transaction) -(declare cis->OptionString) -(declare ecis->OptionString) -(declare new-OptionString) - -;;---------------------------------------------------------------------------------- -;;---------------------------------------------------------------------------------- -;; Enumerations -;;---------------------------------------------------------------------------------- -;;---------------------------------------------------------------------------------- - -;----------------------------------------------------------------------------- -; NullValue -;----------------------------------------------------------------------------- -(def NullValue-default :null-value) - -(def NullValue-val2label {0 :null-value}) - -(def NullValue-label2val (set/map-invert NullValue-val2label)) - -(defn cis->NullValue [is] - (let [val (serdes.core/cis->Enum is)] - (get NullValue-val2label val val))) - -(defn- get-NullValue [value] - {:pre [(or (int? value) (contains? NullValue-label2val value))]} - (get NullValue-label2val value value)) - -(defn write-NullValue - ([tag value os] (write-NullValue tag {:optimize false} value os)) - ([tag options value os] - (serdes.core/write-Enum tag options (get-NullValue value) os))) - -;;---------------------------------------------------------------------------------- -;;---------------------------------------------------------------------------------- -;; Value-kind's oneof Implementations -;;---------------------------------------------------------------------------------- -;;---------------------------------------------------------------------------------- - -(defn convert-Value-kind [origkeyval] - (cond - (get-in origkeyval [:kind :null-value]) origkeyval - (get-in origkeyval [:kind :number-value]) origkeyval - (get-in origkeyval [:kind :string-value]) origkeyval - (get-in origkeyval [:kind :bool-value]) origkeyval - (get-in origkeyval [:kind :struct-value]) (update-in origkeyval [:kind :struct-value] new-Struct) - (get-in origkeyval [:kind :list-value]) (update-in origkeyval [:kind :list-value] new-ListValue) - :default origkeyval)) - -(defn write-Value-kind [kind os] - (let [field (first kind) - k (when-not (nil? field) (key field)) - v (when-not (nil? field) (val field))] - (case k - :null-value (write-NullValue 1 {:optimize false} v os) - :number-value (serdes.core/write-Double 2 {:optimize false} v os) - :string-value (serdes.core/write-String 3 {:optimize false} v os) - :bool-value (serdes.core/write-Bool 4 {:optimize false} v os) - :struct-value (serdes.core/write-embedded 5 v os) - :list-value (serdes.core/write-embedded 6 v os) - nil))) - -;;---------------------------------------------------------------------------------- -;;---------------------------------------------------------------------------------- -;; Transaction-transaction-type's oneof Implementations -;;---------------------------------------------------------------------------------- -;;---------------------------------------------------------------------------------- - -(defn convert-Transaction-transaction-type [origkeyval] - (cond - (get-in origkeyval [:transaction-type :put]) (update-in origkeyval [:transaction-type :put] new-Put) - (get-in origkeyval [:transaction-type :delete]) (update-in origkeyval [:transaction-type :delete] new-Delete) - (get-in origkeyval [:transaction-type :evict]) (update-in origkeyval [:transaction-type :evict] new-Evict) - :default origkeyval)) - -(defn write-Transaction-transaction-type [transaction-type os] - (let [field (first transaction-type) - k (when-not (nil? field) (key field)) - v (when-not (nil? field) (val field))] - (case k - :put (serdes.core/write-embedded 1 v os) - :delete (serdes.core/write-embedded 2 v os) - :evict (serdes.core/write-embedded 3 v os) - nil))) - -;;---------------------------------------------------------------------------------- -;;---------------------------------------------------------------------------------- -;; OptionString-value's oneof Implementations -;;---------------------------------------------------------------------------------- -;;---------------------------------------------------------------------------------- - -(defn convert-OptionString-value [origkeyval] - (cond - (get-in origkeyval [:value :none]) (update-in origkeyval [:value :none] new-Empty) - (get-in origkeyval [:value :some]) origkeyval - :default origkeyval)) - -(defn write-OptionString-value [value os] - (let [field (first value) - k (when-not (nil? field) (key field)) - v (when-not (nil? field) (val field))] - (case k - :none (serdes.core/write-embedded 1 v os) - :some (serdes.core/write-String 2 {:optimize false} v os) - nil))) - -;;---------------------------------------------------------------------------------- -;;---------------------------------------------------------------------------------- -;; Message Implementations -;;---------------------------------------------------------------------------------- -;;---------------------------------------------------------------------------------- - -;----------------------------------------------------------------------------- -; ListValue -;----------------------------------------------------------------------------- -(defrecord ListValue-record [values] - pb/Writer - (serialize [this os] - (serdes.complex/write-repeated serdes.core/write-embedded 1 (:values this) os)) - pb/TypeReflection - (gettype [this] - "com.google.protobuf.ListValue")) - -(s/def ::ListValue-spec (s/keys :opt-un [])) -(def ListValue-defaults {:values []}) - -(defn cis->ListValue - "CodedInputStream to ListValue" - [is] - (map->ListValue-record (tag-map ListValue-defaults (fn [tag index] (case index 1 [:values (serdes.complex/cis->repeated ecis->Value is)] [index (serdes.core/cis->undefined tag is)])) is))) - -(defn ecis->ListValue - "Embedded CodedInputStream to ListValue" - [is] - (serdes.core/cis->embedded cis->ListValue is)) - -(defn new-ListValue - "Creates a new instance from a map, similar to map->ListValue except that - it properly accounts for nested messages, when applicable. - " - [init] - {:pre [(if (s/valid? ::ListValue-spec init) true (throw (ex-info "Invalid input" (s/explain-data ::ListValue-spec init))))]} - (-> (merge ListValue-defaults init) - (cond-> (some? (get init :values)) (update :values #(map new-Value %))) - (map->ListValue-record))) - -(defn pb->ListValue - "Protobuf to ListValue" - [input] - (cis->ListValue (serdes.stream/new-cis input))) - -(def ^:protojure.protobuf.any/record ListValue-meta {:type "com.google.protobuf.ListValue" :decoder pb->ListValue}) - -;----------------------------------------------------------------------------- -; Empty -;----------------------------------------------------------------------------- -(defrecord Empty-record [] - pb/Writer - (serialize [this os]) - pb/TypeReflection - (gettype [this] - "com.google.protobuf.Empty")) - -(s/def ::Empty-spec (s/keys :opt-un [])) -(def Empty-defaults {}) - -(defn cis->Empty - "CodedInputStream to Empty" - [is] - (map->Empty-record (tag-map Empty-defaults (fn [tag index] (case index [index (serdes.core/cis->undefined tag is)])) is))) - -(defn ecis->Empty - "Embedded CodedInputStream to Empty" - [is] - (serdes.core/cis->embedded cis->Empty is)) - -(defn new-Empty - "Creates a new instance from a map, similar to map->Empty except that - it properly accounts for nested messages, when applicable. - " - [init] - {:pre [(if (s/valid? ::Empty-spec init) true (throw (ex-info "Invalid input" (s/explain-data ::Empty-spec init))))]} - (map->Empty-record (merge Empty-defaults init))) - -(defn pb->Empty - "Protobuf to Empty" - [input] - (cis->Empty (serdes.stream/new-cis input))) - -(def ^:protojure.protobuf.any/record Empty-meta {:type "com.google.protobuf.Empty" :decoder pb->Empty}) - -;----------------------------------------------------------------------------- -; Struct -;----------------------------------------------------------------------------- -(defrecord Struct-record [fields] - pb/Writer - (serialize [this os] - (serdes.complex/write-map new-Struct-FieldsEntry 1 (:fields this) os)) - pb/TypeReflection - (gettype [this] - "com.google.protobuf.Struct")) - -(s/def ::Struct-spec (s/keys :opt-un [])) -(def Struct-defaults {:fields []}) - -(defn cis->Struct - "CodedInputStream to Struct" - [is] - (map->Struct-record (tag-map Struct-defaults (fn [tag index] (case index 1 [:fields (serdes.complex/cis->map ecis->Struct-FieldsEntry is)] [index (serdes.core/cis->undefined tag is)])) is))) - -(defn ecis->Struct - "Embedded CodedInputStream to Struct" - [is] - (serdes.core/cis->embedded cis->Struct is)) - -(defn new-Struct - "Creates a new instance from a map, similar to map->Struct except that - it properly accounts for nested messages, when applicable. - " - [init] - {:pre [(if (s/valid? ::Struct-spec init) true (throw (ex-info "Invalid input" (s/explain-data ::Struct-spec init))))]} - (map->Struct-record (merge Struct-defaults init))) - -(defn pb->Struct - "Protobuf to Struct" - [input] - (cis->Struct (serdes.stream/new-cis input))) - -(def ^:protojure.protobuf.any/record Struct-meta {:type "com.google.protobuf.Struct" :decoder pb->Struct}) - -;----------------------------------------------------------------------------- -; StatusResponse -;----------------------------------------------------------------------------- -(defrecord StatusResponse-record [version index-version kv-store estimate-num-keys size revision consumer-state] - pb/Writer - (serialize [this os] - (serdes.core/write-String 1 {:optimize true} (:version this) os) - (serdes.core/write-Int32 2 {:optimize true} (:index-version this) os) - (serdes.core/write-String 3 {:optimize true} (:kv-store this) os) - (serdes.core/write-Int32 4 {:optimize true} (:estimate-num-keys this) os) - (serdes.core/write-Int64 5 {:optimize true} (:size this) os) - (serdes.core/write-embedded 6 (:revision this) os) - (serdes.core/write-embedded 7 (:consumer-state this) os)) - pb/TypeReflection - (gettype [this] - "com.google.protobuf.StatusResponse")) - -(s/def :com.google.protobuf.StatusResponse/version string?) -(s/def :com.google.protobuf.StatusResponse/index-version int?) -(s/def :com.google.protobuf.StatusResponse/kv-store string?) -(s/def :com.google.protobuf.StatusResponse/estimate-num-keys int?) -(s/def :com.google.protobuf.StatusResponse/size int?) - -(s/def ::StatusResponse-spec (s/keys :opt-un [:com.google.protobuf.StatusResponse/version :com.google.protobuf.StatusResponse/index-version :com.google.protobuf.StatusResponse/kv-store :com.google.protobuf.StatusResponse/estimate-num-keys :com.google.protobuf.StatusResponse/size])) -(def StatusResponse-defaults {:version "" :index-version 0 :kv-store "" :estimate-num-keys 0 :size 0}) - -(defn cis->StatusResponse - "CodedInputStream to StatusResponse" - [is] - (map->StatusResponse-record (tag-map StatusResponse-defaults (fn [tag index] (case index 1 [:version (serdes.core/cis->String is)] 2 [:index-version (serdes.core/cis->Int32 is)] 3 [:kv-store (serdes.core/cis->String is)] 4 [:estimate-num-keys (serdes.core/cis->Int32 is)] 5 [:size (serdes.core/cis->Int64 is)] 6 [:revision (ecis->OptionString is)] 7 [:consumer-state (ecis->OptionString is)] [index (serdes.core/cis->undefined tag is)])) is))) - -(defn ecis->StatusResponse - "Embedded CodedInputStream to StatusResponse" - [is] - (serdes.core/cis->embedded cis->StatusResponse is)) - -(defn new-StatusResponse - "Creates a new instance from a map, similar to map->StatusResponse except that - it properly accounts for nested messages, when applicable. - " - [init] - {:pre [(if (s/valid? ::StatusResponse-spec init) true (throw (ex-info "Invalid input" (s/explain-data ::StatusResponse-spec init))))]} - (-> (merge StatusResponse-defaults init) - (cond-> (some? (get init :revision)) (update :revision new-OptionString)) - (cond-> (some? (get init :consumer-state)) (update :consumer-state new-OptionString)) - (map->StatusResponse-record))) - -(defn pb->StatusResponse - "Protobuf to StatusResponse" - [input] - (cis->StatusResponse (serdes.stream/new-cis input))) - -(def ^:protojure.protobuf.any/record StatusResponse-meta {:type "com.google.protobuf.StatusResponse" :decoder pb->StatusResponse}) - -;----------------------------------------------------------------------------- -; Evict -;----------------------------------------------------------------------------- -(defrecord Evict-record [document-id] - pb/Writer - (serialize [this os] - (serdes.core/write-String 1 {:optimize true} (:document-id this) os)) - pb/TypeReflection - (gettype [this] - "com.google.protobuf.Evict")) - -(s/def :com.google.protobuf.Evict/document-id string?) -(s/def ::Evict-spec (s/keys :opt-un [:com.google.protobuf.Evict/document-id])) -(def Evict-defaults {:document-id ""}) - -(defn cis->Evict - "CodedInputStream to Evict" - [is] - (map->Evict-record (tag-map Evict-defaults (fn [tag index] (case index 1 [:document-id (serdes.core/cis->String is)] [index (serdes.core/cis->undefined tag is)])) is))) - -(defn ecis->Evict - "Embedded CodedInputStream to Evict" - [is] - (serdes.core/cis->embedded cis->Evict is)) - -(defn new-Evict - "Creates a new instance from a map, similar to map->Evict except that - it properly accounts for nested messages, when applicable. - " - [init] - {:pre [(if (s/valid? ::Evict-spec init) true (throw (ex-info "Invalid input" (s/explain-data ::Evict-spec init))))]} - (map->Evict-record (merge Evict-defaults init))) - -(defn pb->Evict - "Protobuf to Evict" - [input] - (cis->Evict (serdes.stream/new-cis input))) - -(def ^:protojure.protobuf.any/record Evict-meta {:type "com.google.protobuf.Evict" :decoder pb->Evict}) - -;----------------------------------------------------------------------------- -; Struct-FieldsEntry -;----------------------------------------------------------------------------- -(defrecord Struct-FieldsEntry-record [key value] - pb/Writer - (serialize [this os] - (serdes.core/write-String 1 {:optimize true} (:key this) os) - (serdes.core/write-embedded 2 (:value this) os)) - pb/TypeReflection - (gettype [this] - "com.google.protobuf.Struct-FieldsEntry")) - -(s/def :com.google.protobuf.Struct-FieldsEntry/key string?) - -(s/def ::Struct-FieldsEntry-spec (s/keys :opt-un [:com.google.protobuf.Struct-FieldsEntry/key])) -(def Struct-FieldsEntry-defaults {:key ""}) - -(defn cis->Struct-FieldsEntry - "CodedInputStream to Struct-FieldsEntry" - [is] - (map->Struct-FieldsEntry-record (tag-map Struct-FieldsEntry-defaults (fn [tag index] (case index 1 [:key (serdes.core/cis->String is)] 2 [:value (ecis->Value is)] [index (serdes.core/cis->undefined tag is)])) is))) - -(defn ecis->Struct-FieldsEntry - "Embedded CodedInputStream to Struct-FieldsEntry" - [is] - (serdes.core/cis->embedded cis->Struct-FieldsEntry is)) - -(defn new-Struct-FieldsEntry - "Creates a new instance from a map, similar to map->Struct-FieldsEntry except that - it properly accounts for nested messages, when applicable. - " - [init] - {:pre [(if (s/valid? ::Struct-FieldsEntry-spec init) true (throw (ex-info "Invalid input" (s/explain-data ::Struct-FieldsEntry-spec init))))]} - (-> (merge Struct-FieldsEntry-defaults init) - (cond-> (some? (get init :value)) (update :value new-Value)) - (map->Struct-FieldsEntry-record))) - -(defn pb->Struct-FieldsEntry - "Protobuf to Struct-FieldsEntry" - [input] - (cis->Struct-FieldsEntry (serdes.stream/new-cis input))) - -(def ^:protojure.protobuf.any/record Struct-FieldsEntry-meta {:type "com.google.protobuf.Struct-FieldsEntry" :decoder pb->Struct-FieldsEntry}) - -;----------------------------------------------------------------------------- -; Put -;----------------------------------------------------------------------------- -(defrecord Put-record [xt-id document] - pb/Writer - (serialize [this os] - (serdes.core/write-String 1 {:optimize true} (:xt-id this) os) - (serdes.core/write-embedded 2 (:document this) os)) - pb/TypeReflection - (gettype [this] - "com.google.protobuf.Put")) - -(s/def :com.google.protobuf.Put/xt-id string?) - -(s/def ::Put-spec (s/keys :opt-un [:com.google.protobuf.Put/xt-id])) -(def Put-defaults {:xt-id ""}) - -(defn cis->Put - "CodedInputStream to Put" - [is] - (map->Put-record (tag-map Put-defaults (fn [tag index] (case index 1 [:xt-id (serdes.core/cis->String is)] 2 [:document (ecis->Value is)] [index (serdes.core/cis->undefined tag is)])) is))) - -(defn ecis->Put - "Embedded CodedInputStream to Put" - [is] - (serdes.core/cis->embedded cis->Put is)) - -(defn new-Put - "Creates a new instance from a map, similar to map->Put except that - it properly accounts for nested messages, when applicable. - " - [init] - {:pre [(if (s/valid? ::Put-spec init) true (throw (ex-info "Invalid input" (s/explain-data ::Put-spec init))))]} - (-> (merge Put-defaults init) - (cond-> (some? (get init :document)) (update :document new-Value)) - (map->Put-record))) - -(defn pb->Put - "Protobuf to Put" - [input] - (cis->Put (serdes.stream/new-cis input))) - -(def ^:protojure.protobuf.any/record Put-meta {:type "com.google.protobuf.Put" :decoder pb->Put}) - -;----------------------------------------------------------------------------- -; Delete -;----------------------------------------------------------------------------- -(defrecord Delete-record [document-id] - pb/Writer - (serialize [this os] - (serdes.core/write-String 1 {:optimize true} (:document-id this) os)) - pb/TypeReflection - (gettype [this] - "com.google.protobuf.Delete")) - -(s/def :com.google.protobuf.Delete/document-id string?) -(s/def ::Delete-spec (s/keys :opt-un [:com.google.protobuf.Delete/document-id])) -(def Delete-defaults {:document-id ""}) - -(defn cis->Delete - "CodedInputStream to Delete" - [is] - (map->Delete-record (tag-map Delete-defaults (fn [tag index] (case index 1 [:document-id (serdes.core/cis->String is)] [index (serdes.core/cis->undefined tag is)])) is))) - -(defn ecis->Delete - "Embedded CodedInputStream to Delete" - [is] - (serdes.core/cis->embedded cis->Delete is)) - -(defn new-Delete - "Creates a new instance from a map, similar to map->Delete except that - it properly accounts for nested messages, when applicable. - " - [init] - {:pre [(if (s/valid? ::Delete-spec init) true (throw (ex-info "Invalid input" (s/explain-data ::Delete-spec init))))]} - (map->Delete-record (merge Delete-defaults init))) - -(defn pb->Delete - "Protobuf to Delete" - [input] - (cis->Delete (serdes.stream/new-cis input))) - -(def ^:protojure.protobuf.any/record Delete-meta {:type "com.google.protobuf.Delete" :decoder pb->Delete}) - -;----------------------------------------------------------------------------- -; SubmitRequest -;----------------------------------------------------------------------------- -(defrecord SubmitRequest-record [tx-ops] - pb/Writer - (serialize [this os] - (serdes.complex/write-repeated serdes.core/write-embedded 1 (:tx-ops this) os)) - pb/TypeReflection - (gettype [this] - "com.google.protobuf.SubmitRequest")) - -(s/def ::SubmitRequest-spec (s/keys :opt-un [])) -(def SubmitRequest-defaults {:tx-ops []}) - -(defn cis->SubmitRequest - "CodedInputStream to SubmitRequest" - [is] - (map->SubmitRequest-record (tag-map SubmitRequest-defaults (fn [tag index] (case index 1 [:tx-ops (serdes.complex/cis->repeated ecis->Transaction is)] [index (serdes.core/cis->undefined tag is)])) is))) - -(defn ecis->SubmitRequest - "Embedded CodedInputStream to SubmitRequest" - [is] - (serdes.core/cis->embedded cis->SubmitRequest is)) - -(defn new-SubmitRequest - "Creates a new instance from a map, similar to map->SubmitRequest except that - it properly accounts for nested messages, when applicable. - " - [init] - {:pre [(if (s/valid? ::SubmitRequest-spec init) true (throw (ex-info "Invalid input" (s/explain-data ::SubmitRequest-spec init))))]} - (-> (merge SubmitRequest-defaults init) - (cond-> (some? (get init :tx-ops)) (update :tx-ops #(map new-Transaction %))) - (map->SubmitRequest-record))) - -(defn pb->SubmitRequest - "Protobuf to SubmitRequest" - [input] - (cis->SubmitRequest (serdes.stream/new-cis input))) - -(def ^:protojure.protobuf.any/record SubmitRequest-meta {:type "com.google.protobuf.SubmitRequest" :decoder pb->SubmitRequest}) - -;----------------------------------------------------------------------------- -; SubmitResponse -;----------------------------------------------------------------------------- -(defrecord SubmitResponse-record [tx-time tx-id] - pb/Writer - (serialize [this os] - (serdes.core/write-String 1 {:optimize true} (:tx-time this) os) - (serdes.core/write-Int64 2 {:optimize true} (:tx-id this) os)) - pb/TypeReflection - (gettype [this] - "com.google.protobuf.SubmitResponse")) - -(s/def :com.google.protobuf.SubmitResponse/tx-time string?) -(s/def :com.google.protobuf.SubmitResponse/tx-id int?) -(s/def ::SubmitResponse-spec (s/keys :opt-un [:com.google.protobuf.SubmitResponse/tx-time :com.google.protobuf.SubmitResponse/tx-id])) -(def SubmitResponse-defaults {:tx-time "" :tx-id 0}) - -(defn cis->SubmitResponse - "CodedInputStream to SubmitResponse" - [is] - (map->SubmitResponse-record (tag-map SubmitResponse-defaults (fn [tag index] (case index 1 [:tx-time (serdes.core/cis->String is)] 2 [:tx-id (serdes.core/cis->Int64 is)] [index (serdes.core/cis->undefined tag is)])) is))) - -(defn ecis->SubmitResponse - "Embedded CodedInputStream to SubmitResponse" - [is] - (serdes.core/cis->embedded cis->SubmitResponse is)) - -(defn new-SubmitResponse - "Creates a new instance from a map, similar to map->SubmitResponse except that - it properly accounts for nested messages, when applicable. - " - [init] - {:pre [(if (s/valid? ::SubmitResponse-spec init) true (throw (ex-info "Invalid input" (s/explain-data ::SubmitResponse-spec init))))]} - (map->SubmitResponse-record (merge SubmitResponse-defaults init))) - -(defn pb->SubmitResponse - "Protobuf to SubmitResponse" - [input] - (cis->SubmitResponse (serdes.stream/new-cis input))) - -(def ^:protojure.protobuf.any/record SubmitResponse-meta {:type "com.google.protobuf.SubmitResponse" :decoder pb->SubmitResponse}) - -;----------------------------------------------------------------------------- -; Value -;----------------------------------------------------------------------------- -(defrecord Value-record [kind] - pb/Writer - (serialize [this os] - (write-Value-kind (:kind this) os)) - pb/TypeReflection - (gettype [this] - "com.google.protobuf.Value")) - -(s/def ::Value-spec (s/keys :opt-un [])) -(def Value-defaults {}) - -(defn cis->Value - "CodedInputStream to Value" - [is] - (map->Value-record (tag-map Value-defaults (fn [tag index] (case index 1 [:kind {:null-value (cis->NullValue is)}] 2 [:kind {:number-value (serdes.core/cis->Double is)}] 3 [:kind {:string-value (serdes.core/cis->String is)}] 4 [:kind {:bool-value (serdes.core/cis->Bool is)}] 5 [:kind {:struct-value (ecis->Struct is)}] 6 [:kind {:list-value (ecis->ListValue is)}] [index (serdes.core/cis->undefined tag is)])) is))) - -(defn ecis->Value - "Embedded CodedInputStream to Value" - [is] - (serdes.core/cis->embedded cis->Value is)) - -(defn new-Value - "Creates a new instance from a map, similar to map->Value except that - it properly accounts for nested messages, when applicable. - " - [init] - {:pre [(if (s/valid? ::Value-spec init) true (throw (ex-info "Invalid input" (s/explain-data ::Value-spec init))))]} - (-> (merge Value-defaults init) - (convert-Value-kind) - (map->Value-record))) - -(defn pb->Value - "Protobuf to Value" - [input] - (cis->Value (serdes.stream/new-cis input))) - -(def ^:protojure.protobuf.any/record Value-meta {:type "com.google.protobuf.Value" :decoder pb->Value}) - -;----------------------------------------------------------------------------- -; Transaction -;----------------------------------------------------------------------------- -(defrecord Transaction-record [transaction-type] - pb/Writer - (serialize [this os] - (write-Transaction-transaction-type (:transaction-type this) os)) - pb/TypeReflection - (gettype [this] - "com.google.protobuf.Transaction")) - -(s/def ::Transaction-spec (s/keys :opt-un [])) -(def Transaction-defaults {}) - -(defn cis->Transaction - "CodedInputStream to Transaction" - [is] - (map->Transaction-record (tag-map Transaction-defaults (fn [tag index] (case index 1 [:transaction-type {:put (ecis->Put is)}] 2 [:transaction-type {:delete (ecis->Delete is)}] 3 [:transaction-type {:evict (ecis->Evict is)}] [index (serdes.core/cis->undefined tag is)])) is))) - -(defn ecis->Transaction - "Embedded CodedInputStream to Transaction" - [is] - (serdes.core/cis->embedded cis->Transaction is)) - -(defn new-Transaction - "Creates a new instance from a map, similar to map->Transaction except that - it properly accounts for nested messages, when applicable. - " - [init] - {:pre [(if (s/valid? ::Transaction-spec init) true (throw (ex-info "Invalid input" (s/explain-data ::Transaction-spec init))))]} - (-> (merge Transaction-defaults init) - (convert-Transaction-transaction-type) - (map->Transaction-record))) - -(defn pb->Transaction - "Protobuf to Transaction" - [input] - (cis->Transaction (serdes.stream/new-cis input))) - -(def ^:protojure.protobuf.any/record Transaction-meta {:type "com.google.protobuf.Transaction" :decoder pb->Transaction}) - -;----------------------------------------------------------------------------- -; OptionString -;----------------------------------------------------------------------------- -(defrecord OptionString-record [value] - pb/Writer - (serialize [this os] - (write-OptionString-value (:value this) os)) - pb/TypeReflection - (gettype [this] - "com.google.protobuf.OptionString")) - -(s/def ::OptionString-spec (s/keys :opt-un [])) -(def OptionString-defaults {}) - -(defn cis->OptionString - "CodedInputStream to OptionString" - [is] - (map->OptionString-record (tag-map OptionString-defaults (fn [tag index] (case index 1 [:value {:none (ecis->Empty is)}] 2 [:value {:some (serdes.core/cis->String is)}] [index (serdes.core/cis->undefined tag is)])) is))) - -(defn ecis->OptionString - "Embedded CodedInputStream to OptionString" - [is] - (serdes.core/cis->embedded cis->OptionString is)) - -(defn new-OptionString - "Creates a new instance from a map, similar to map->OptionString except that - it properly accounts for nested messages, when applicable. - " - [init] - {:pre [(if (s/valid? ::OptionString-spec init) true (throw (ex-info "Invalid input" (s/explain-data ::OptionString-spec init))))]} - (-> (merge OptionString-defaults init) - (convert-OptionString-value) - (map->OptionString-record))) - -(defn pb->OptionString - "Protobuf to OptionString" - [input] - (cis->OptionString (serdes.stream/new-cis input))) - -(def ^:protojure.protobuf.any/record OptionString-meta {:type "com.google.protobuf.OptionString" :decoder pb->OptionString}) - diff --git a/src/com/google/protobuf/GrpcApi/client.cljc b/src/com/google/protobuf/GrpcApi/client.cljc deleted file mode 100644 index f48f01a..0000000 --- a/src/com/google/protobuf/GrpcApi/client.cljc +++ /dev/null @@ -1,43 +0,0 @@ -;;;---------------------------------------------------------------------------------- -;;; Generated by protoc-gen-clojure. DO NOT EDIT -;;; -;;; GRPC com.google.protobuf.GrpcApi Client Implementation -;;;---------------------------------------------------------------------------------- -(ns com.google.protobuf.GrpcApi.client - (:require [com.google.protobuf :refer :all] - [com.google.protobuf :as com.google.protobuf] - [clojure.core.async :as async] - [protojure.grpc.client.utils :refer [send-unary-params invoke-unary]] - [promesa.core :as p] - [protojure.grpc.client.api :as grpc])) - -;----------------------------------------------------------------------------- -; GRPC Client Implementation -;----------------------------------------------------------------------------- - -(def GrpcApi-service-name "com.xtdb.protos.GrpcApi") - -(defn Status - ([client params] (Status client {} params)) - ([client metadata params] - (let [input (async/chan 1) - output (async/chan 1) - desc {:service "com.xtdb.protos.GrpcApi" - :method "Status" - :input {:f com.google.protobuf/new-Empty :ch input} - :output {:f com.google.protobuf/pb->StatusResponse :ch output} - :metadata metadata}] - (p/then (send-unary-params input params) (fn [_] (invoke-unary client desc output)))))) - -(defn SubmitTx - ([client params] (SubmitTx client {} params)) - ([client metadata params] - (let [input (async/chan 1) - output (async/chan 1) - desc {:service "com.xtdb.protos.GrpcApi" - :method "SubmitTx" - :input {:f com.google.protobuf/new-SubmitRequest :ch input} - :output {:f com.google.protobuf/pb->SubmitResponse :ch output} - :metadata metadata}] - (p/then (send-unary-params input params) (fn [_] (invoke-unary client desc output)))))) - diff --git a/src/com/google/protobuf/GrpcApi/server.cljc b/src/com/google/protobuf/GrpcApi/server.cljc deleted file mode 100644 index 3efdeb8..0000000 --- a/src/com/google/protobuf/GrpcApi/server.cljc +++ /dev/null @@ -1,28 +0,0 @@ -;;;---------------------------------------------------------------------------------- -;;; Generated by protoc-gen-clojure. DO NOT EDIT -;;; -;;; GRPC com.google.protobuf.GrpcApi Service Implementation -;;;---------------------------------------------------------------------------------- -(ns com.google.protobuf.GrpcApi.server - (:require [com.google.protobuf :refer :all] - [com.google.protobuf :as com.google.protobuf])) - -;----------------------------------------------------------------------------- -; GRPC GrpcApi -;----------------------------------------------------------------------------- -(defprotocol Service - (Status [this param]) - (SubmitTx [this param])) - -(def GrpcApi-service-name "com.xtdb.protos.GrpcApi") - -(defn- Status-dispatch - [ctx request] - (Status ctx request)) -(defn- SubmitTx-dispatch - [ctx request] - (SubmitTx ctx request)) - -(def ^:const rpc-metadata - [{:pkg "com.xtdb.protos" :service "GrpcApi" :method "Status" :method-fn Status-dispatch :server-streaming false :client-streaming false :input pb->Empty :output new-StatusResponse} - {:pkg "com.xtdb.protos" :service "GrpcApi" :method "SubmitTx" :method-fn SubmitTx-dispatch :server-streaming false :client-streaming false :input pb->SubmitRequest :output new-SubmitResponse}]) diff --git a/src/com/xtdb/protos.cljc b/src/com/xtdb/protos.cljc index ebc9c21..3512783 100644 --- a/src/com/xtdb/protos.cljc +++ b/src/com/xtdb/protos.cljc @@ -32,6 +32,9 @@ (declare cis->Put) (declare ecis->Put) (declare new-Put) +(declare cis->OptionInt64) +(declare ecis->OptionInt64) +(declare new-OptionInt64) (declare cis->Delete) (declare ecis->Delete) (declare new-Delete) @@ -44,6 +47,12 @@ (declare cis->OptionDatetime) (declare ecis->OptionDatetime) (declare new-OptionDatetime) +(declare cis->EntityTxRequest) +(declare ecis->EntityTxRequest) +(declare new-EntityTxRequest) +(declare cis->EntityTxResponse) +(declare ecis->EntityTxResponse) +(declare new-EntityTxResponse) (declare cis->Transaction) (declare ecis->Transaction) (declare new-Transaction) @@ -85,6 +94,27 @@ ([tag options value os] (serdes.core/write-Enum tag options (get-IdType value) os))) +;;---------------------------------------------------------------------------------- +;;---------------------------------------------------------------------------------- +;; OptionInt64-value's oneof Implementations +;;---------------------------------------------------------------------------------- +;;---------------------------------------------------------------------------------- + +(defn convert-OptionInt64-value [origkeyval] + (cond + (get-in origkeyval [:value :none]) (update-in origkeyval [:value :none] new-Empty) + (get-in origkeyval [:value :some]) origkeyval + :default origkeyval)) + +(defn write-OptionInt64-value [value os] + (let [field (first value) + k (when-not (nil? field) (key field)) + v (when-not (nil? field) (val field))] + (case k + :none (serdes.core/write-embedded 1 v os) + :some (serdes.core/write-Int64 2 {:optimize false} v os) + nil))) + ;;---------------------------------------------------------------------------------- ;;---------------------------------------------------------------------------------- ;; OptionDatetime-value's oneof Implementations @@ -342,6 +372,47 @@ (def ^:protojure.protobuf.any/record Put-meta {:type "com.xtdb.protos.Put" :decoder pb->Put}) +;----------------------------------------------------------------------------- +; OptionInt64 +;----------------------------------------------------------------------------- +(defrecord OptionInt64-record [value] + pb/Writer + (serialize [this os] + (write-OptionInt64-value (:value this) os)) + pb/TypeReflection + (gettype [this] + "com.xtdb.protos.OptionInt64")) + +(s/def ::OptionInt64-spec (s/keys :opt-un [])) +(def OptionInt64-defaults {}) + +(defn cis->OptionInt64 + "CodedInputStream to OptionInt64" + [is] + (map->OptionInt64-record (tag-map OptionInt64-defaults (fn [tag index] (case index 1 [:value {:none (ecis->Empty is)}] 2 [:value {:some (serdes.core/cis->Int64 is)}] [index (serdes.core/cis->undefined tag is)])) is))) + +(defn ecis->OptionInt64 + "Embedded CodedInputStream to OptionInt64" + [is] + (serdes.core/cis->embedded cis->OptionInt64 is)) + +(defn new-OptionInt64 + "Creates a new instance from a map, similar to map->OptionInt64 except that + it properly accounts for nested messages, when applicable. + " + [init] + {:pre [(if (s/valid? ::OptionInt64-spec init) true (throw (ex-info "Invalid input" (s/explain-data ::OptionInt64-spec init))))]} + (-> (merge OptionInt64-defaults init) + (convert-OptionInt64-value) + (map->OptionInt64-record))) + +(defn pb->OptionInt64 + "Protobuf to OptionInt64" + [input] + (cis->OptionInt64 (serdes.stream/new-cis input))) + +(def ^:protojure.protobuf.any/record OptionInt64-meta {:type "com.xtdb.protos.OptionInt64" :decoder pb->OptionInt64}) + ;----------------------------------------------------------------------------- ; Delete ;----------------------------------------------------------------------------- @@ -516,6 +587,106 @@ (def ^:protojure.protobuf.any/record OptionDatetime-meta {:type "com.xtdb.protos.OptionDatetime" :decoder pb->OptionDatetime}) +;----------------------------------------------------------------------------- +; EntityTxRequest +;----------------------------------------------------------------------------- +(defrecord EntityTxRequest-record [id-type entity-id open-snapshot tx-id valid-time tx-time] + pb/Writer + (serialize [this os] + (write-IdType 1 {:optimize true} (:id-type this) os) + (serdes.core/write-String 2 {:optimize true} (:entity-id this) os) + (serdes.core/write-Bool 3 {:optimize true} (:open-snapshot this) os) + (serdes.core/write-embedded 4 (:tx-id this) os) + (serdes.core/write-embedded 5 (:valid-time this) os) + (serdes.core/write-embedded 6 (:tx-time this) os)) + pb/TypeReflection + (gettype [this] + "com.xtdb.protos.EntityTxRequest")) + +(s/def :com.xtdb.protos.EntityTxRequest/id-type (s/or :keyword keyword? :int int?)) +(s/def :com.xtdb.protos.EntityTxRequest/entity-id string?) +(s/def :com.xtdb.protos.EntityTxRequest/open-snapshot boolean?) + +(s/def ::EntityTxRequest-spec (s/keys :opt-un [:com.xtdb.protos.EntityTxRequest/id-type :com.xtdb.protos.EntityTxRequest/entity-id :com.xtdb.protos.EntityTxRequest/open-snapshot])) +(def EntityTxRequest-defaults {:id-type IdType-default :entity-id "" :open-snapshot false}) + +(defn cis->EntityTxRequest + "CodedInputStream to EntityTxRequest" + [is] + (map->EntityTxRequest-record (tag-map EntityTxRequest-defaults (fn [tag index] (case index 1 [:id-type (cis->IdType is)] 2 [:entity-id (serdes.core/cis->String is)] 3 [:open-snapshot (serdes.core/cis->Bool is)] 4 [:tx-id (ecis->OptionInt64 is)] 5 [:valid-time (ecis->OptionDatetime is)] 6 [:tx-time (ecis->OptionDatetime is)] [index (serdes.core/cis->undefined tag is)])) is))) + +(defn ecis->EntityTxRequest + "Embedded CodedInputStream to EntityTxRequest" + [is] + (serdes.core/cis->embedded cis->EntityTxRequest is)) + +(defn new-EntityTxRequest + "Creates a new instance from a map, similar to map->EntityTxRequest except that + it properly accounts for nested messages, when applicable. + " + [init] + {:pre [(if (s/valid? ::EntityTxRequest-spec init) true (throw (ex-info "Invalid input" (s/explain-data ::EntityTxRequest-spec init))))]} + (-> (merge EntityTxRequest-defaults init) + (cond-> (some? (get init :tx-id)) (update :tx-id new-OptionInt64)) + (cond-> (some? (get init :valid-time)) (update :valid-time new-OptionDatetime)) + (cond-> (some? (get init :tx-time)) (update :tx-time new-OptionDatetime)) + (map->EntityTxRequest-record))) + +(defn pb->EntityTxRequest + "Protobuf to EntityTxRequest" + [input] + (cis->EntityTxRequest (serdes.stream/new-cis input))) + +(def ^:protojure.protobuf.any/record EntityTxRequest-meta {:type "com.xtdb.protos.EntityTxRequest" :decoder pb->EntityTxRequest}) + +;----------------------------------------------------------------------------- +; EntityTxResponse +;----------------------------------------------------------------------------- +(defrecord EntityTxResponse-record [xt-id content-hash valid-time tx-time tx-id] + pb/Writer + (serialize [this os] + (serdes.core/write-String 1 {:optimize true} (:xt-id this) os) + (serdes.core/write-String 2 {:optimize true} (:content-hash this) os) + (serdes.core/write-String 3 {:optimize true} (:valid-time this) os) + (serdes.core/write-String 4 {:optimize true} (:tx-time this) os) + (serdes.core/write-Int64 5 {:optimize true} (:tx-id this) os)) + pb/TypeReflection + (gettype [this] + "com.xtdb.protos.EntityTxResponse")) + +(s/def :com.xtdb.protos.EntityTxResponse/xt-id string?) +(s/def :com.xtdb.protos.EntityTxResponse/content-hash string?) +(s/def :com.xtdb.protos.EntityTxResponse/valid-time string?) +(s/def :com.xtdb.protos.EntityTxResponse/tx-time string?) +(s/def :com.xtdb.protos.EntityTxResponse/tx-id int?) +(s/def ::EntityTxResponse-spec (s/keys :opt-un [:com.xtdb.protos.EntityTxResponse/xt-id :com.xtdb.protos.EntityTxResponse/content-hash :com.xtdb.protos.EntityTxResponse/valid-time :com.xtdb.protos.EntityTxResponse/tx-time :com.xtdb.protos.EntityTxResponse/tx-id])) +(def EntityTxResponse-defaults {:xt-id "" :content-hash "" :valid-time "" :tx-time "" :tx-id 0}) + +(defn cis->EntityTxResponse + "CodedInputStream to EntityTxResponse" + [is] + (map->EntityTxResponse-record (tag-map EntityTxResponse-defaults (fn [tag index] (case index 1 [:xt-id (serdes.core/cis->String is)] 2 [:content-hash (serdes.core/cis->String is)] 3 [:valid-time (serdes.core/cis->String is)] 4 [:tx-time (serdes.core/cis->String is)] 5 [:tx-id (serdes.core/cis->Int64 is)] [index (serdes.core/cis->undefined tag is)])) is))) + +(defn ecis->EntityTxResponse + "Embedded CodedInputStream to EntityTxResponse" + [is] + (serdes.core/cis->embedded cis->EntityTxResponse is)) + +(defn new-EntityTxResponse + "Creates a new instance from a map, similar to map->EntityTxResponse except that + it properly accounts for nested messages, when applicable. + " + [init] + {:pre [(if (s/valid? ::EntityTxResponse-spec init) true (throw (ex-info "Invalid input" (s/explain-data ::EntityTxResponse-spec init))))]} + (map->EntityTxResponse-record (merge EntityTxResponse-defaults init))) + +(defn pb->EntityTxResponse + "Protobuf to EntityTxResponse" + [input] + (cis->EntityTxResponse (serdes.stream/new-cis input))) + +(def ^:protojure.protobuf.any/record EntityTxResponse-meta {:type "com.xtdb.protos.EntityTxResponse" :decoder pb->EntityTxResponse}) + ;----------------------------------------------------------------------------- ; Transaction ;----------------------------------------------------------------------------- diff --git a/src/com/xtdb/protos/GrpcApi/client.cljc b/src/com/xtdb/protos/GrpcApi/client.cljc index abbfaac..bb92a44 100644 --- a/src/com/xtdb/protos/GrpcApi/client.cljc +++ b/src/com/xtdb/protos/GrpcApi/client.cljc @@ -42,3 +42,15 @@ :metadata metadata}] (p/then (send-unary-params input params) (fn [_] (invoke-unary client desc output)))))) +(defn EntityTx + ([client params] (EntityTx client {} params)) + ([client metadata params] + (let [input (async/chan 1) + output (async/chan 1) + desc {:service "com.xtdb.protos.GrpcApi" + :method "EntityTx" + :input {:f com.xtdb.protos/new-EntityTxRequest :ch input} + :output {:f com.xtdb.protos/pb->EntityTxResponse :ch output} + :metadata metadata}] + (p/then (send-unary-params input params) (fn [_] (invoke-unary client desc output)))))) + diff --git a/src/com/xtdb/protos/GrpcApi/server.cljc b/src/com/xtdb/protos/GrpcApi/server.cljc index 48f65c0..ef1101e 100644 --- a/src/com/xtdb/protos/GrpcApi/server.cljc +++ b/src/com/xtdb/protos/GrpcApi/server.cljc @@ -13,7 +13,8 @@ ;----------------------------------------------------------------------------- (defprotocol Service (Status [this param]) - (SubmitTx [this param])) + (SubmitTx [this param]) + (EntityTx [this param])) (def GrpcApi-service-name "com.xtdb.protos.GrpcApi") @@ -23,7 +24,11 @@ (defn- SubmitTx-dispatch [ctx request] (SubmitTx ctx request)) +(defn- EntityTx-dispatch + [ctx request] + (EntityTx ctx request)) (def ^:const rpc-metadata [{:pkg "com.xtdb.protos" :service "GrpcApi" :method "Status" :method-fn Status-dispatch :server-streaming false :client-streaming false :input pb->Empty :output new-StatusResponse} - {:pkg "com.xtdb.protos" :service "GrpcApi" :method "SubmitTx" :method-fn SubmitTx-dispatch :server-streaming false :client-streaming false :input pb->SubmitRequest :output new-SubmitResponse}]) + {:pkg "com.xtdb.protos" :service "GrpcApi" :method "SubmitTx" :method-fn SubmitTx-dispatch :server-streaming false :client-streaming false :input pb->SubmitRequest :output new-SubmitResponse} + {:pkg "com.xtdb.protos" :service "GrpcApi" :method "EntityTx" :method-fn EntityTx-dispatch :server-streaming false :client-streaming false :input pb->EntityTxRequest :output new-EntityTxResponse}]) diff --git a/src/gxtdb/adapters/db.clj b/src/gxtdb/adapters/db.clj new file mode 100644 index 0000000..e72dfff --- /dev/null +++ b/src/gxtdb/adapters/db.clj @@ -0,0 +1,18 @@ +(ns gxtdb.adapters.db + (:require [gxtdb.adapters.tx-time :refer [->clj-time]] + [gxtdb.utils :refer [not-nil?]] + [xtdb.api :as xt])) + +(defn ->db-basis [params] + (let [valid-time (some-> params :valid-time ->clj-time) + tx-time (some-> params :tx-time ->clj-time) + tx-id (some-> params :tx-id :value :some)] + (case [(not-nil? valid-time) (not-nil? tx-time) (not-nil? tx-id)] + [true true true] {::xt/valid-time valid-time} + [true false false] {::xt/valid-time valid-time} + [true true false] {::xt/valid-time valid-time ::xt/tx-time tx-time} + [true false true] {::xt/valid-time valid-time ::xt/tx tx-id} + [false true false] {::xt/tx-time tx-time} + [false false true] {::xt/tx tx-id} + nil))) + diff --git a/src/gxtdb/adapters/entity.clj b/src/gxtdb/adapters/entity.clj new file mode 100644 index 0000000..b67ffd3 --- /dev/null +++ b/src/gxtdb/adapters/entity.clj @@ -0,0 +1,9 @@ +(ns gxtdb.adapters.entity + (:require [gxtdb.utils :as utils])) + +(defn entity-tx->proto [entity-tx-response] + {:xt-id (-> entity-tx-response :xt/id str), + :content-hash (-> entity-tx-response :xtdb.api/content-hash str), + :valid-time (-> entity-tx-response :xtdb.api/valid-time utils/->inst-str), + :tx-time (-> entity-tx-response :xtdb.api/tx-time utils/->inst-str), + :tx-id (:xtdb.api/tx-id entity-tx-response)}) \ No newline at end of file diff --git a/src/gxtdb/controllers.clj b/src/gxtdb/controllers.clj index d6ddea1..0e1a2ff 100644 --- a/src/gxtdb/controllers.clj +++ b/src/gxtdb/controllers.clj @@ -1,9 +1,18 @@ (ns gxtdb.controllers - (:require [gxtdb.adapters.tx-log :as tx-log-adapter] + (:require [gxtdb.adapters.db :refer [->db-basis]] + [gxtdb.adapters.entity :refer [entity-tx->proto]] + [gxtdb.adapters.tx-log :as tx-log-adapter] [gxtdb.logic.time :refer [assoc-some-time]] + [gxtdb.utils :refer [->id open-db]] [xtdb.api :as xt])) (defn submit-tx [xtdb-node tx-ops tx-time] (let [tx-log (tx-log-adapter/proto->tx-log tx-ops) xt-response (xt/submit-tx xtdb-node tx-log (assoc-some-time {} ::xt/tx-time tx-time))] - (tx-log-adapter/xtdb->proto xt-response))) \ No newline at end of file + (tx-log-adapter/xtdb->proto xt-response))) + +(defn entity-tx [xtdb-node params] + (let [id (->id (:id-type params) (:entity-id params)) + db-basis (->db-basis params) + db (open-db xtdb-node (:open-snapshot params) db-basis)] + (->> id (xt/entity-tx db) entity-tx->proto))) diff --git a/src/gxtdb/service.clj b/src/gxtdb/service.clj index 1b52f21..960c439 100644 --- a/src/gxtdb/service.clj +++ b/src/gxtdb/service.clj @@ -31,6 +31,9 @@ (SubmitTx [_this {{:keys [tx-ops tx-time]} :grpc-params}] {:status 200 :body (controllers/submit-tx xtdb-node tx-ops tx-time)}) + (EntityTx [_this {params :grpc-params}] + {:status 200 + :body (controllers/entity-tx xtdb-node params)}) (Status [_this _request] (let [status (xt/status xtdb-node)] diff --git a/src/gxtdb/utils.clj b/src/gxtdb/utils.clj index e6905dd..75b7d81 100644 --- a/src/gxtdb/utils.clj +++ b/src/gxtdb/utils.clj @@ -1,6 +1,7 @@ (ns gxtdb.utils (:require [clojure.instant :refer [read-instant-date]] - [clojure.string :as str]) + [clojure.string :as str] + [xtdb.api :as xt]) (:import java.text.SimpleDateFormat)) #_{:clj-kondo/ignore [:clojure-lsp/unused-public-var]} @@ -55,4 +56,11 @@ (let [f #(if (record? %) (record->map %) %) ks (keys record) vs (map f (vals record))] - (zipmap ks vs))) \ No newline at end of file + (zipmap ks vs))) + +(defn open-db [xtdb-node should-open-snapshot db-basis] + (case [should-open-snapshot (nil? db-basis)] + [true true] (xt/open-db xtdb-node) + [false true] (xt/db xtdb-node) + [true false] (xt/open-db xtdb-node db-basis) + [false false] (xt/db xtdb-node db-basis))) \ No newline at end of file diff --git a/test/gxtdb/adapters/db_test.clj b/test/gxtdb/adapters/db_test.clj new file mode 100644 index 0000000..4c35d0f --- /dev/null +++ b/test/gxtdb/adapters/db_test.clj @@ -0,0 +1,38 @@ +(ns gxtdb.adapters.db-test + (:require [clojure.test :refer [deftest testing is]] + [xtdb.api :as xt] + [gxtdb.adapters.db :as db])) + +(def all-none-input + {:valid-time {:value {:none {}}} + :tx-time {:value {:none {}}} + :tx-id {:value {:none {}}}}) + +(def valid-time-input + {:valid-time {:value {:some "2023-06-12T21:32:44.717-05:00"}} + :tx-time {:value {:none {}}} + :tx-id {:value {:none {}}}}) + +(def all-some-input + {:valid-time {:value {:some "2023-06-12T21:32:44.717-05:00"}} + :tx-time {:value {:some "2023-06-12T21:32:44.717-05:00"}} + :tx-id {:value {:some 3}}}) + +(def tx-some-inputs + {:valid-time {:value {:none {}}} + :tx-time {:value {:some "2023-06-12T21:32:44.717-05:00"}} + :tx-id {:value {:some 3}}}) + +(deftest ->db-basis-test + (testing "When all fields are none" + (is (= nil (db/->db-basis all-none-input)))) + (testing "When all tx inputs are some" + (is (= nil (db/->db-basis tx-some-inputs)))) + (testing "When only tx-id input is some" + (is (= {::xt/tx 3} (db/->db-basis {:tx-id {:value {:some 3}}})))) + (testing "When only tx-time input is some" + (is (= {::xt/tx-time #inst "2023-06-13T02:32:44.717-00:00"} (db/->db-basis {:tx-time {:value {:some "2023-06-12T21:32:44.717-05:00"}}})))) + (testing "When only valid-time is some" + (is (= {::xt/valid-time #inst "2023-06-13T02:32:44.717-00:00"} (db/->db-basis valid-time-input)))) + (testing "When all fields are some" + (is (= {::xt/valid-time #inst "2023-06-13T02:32:44.717-00:00"} (db/->db-basis all-some-input))))) \ No newline at end of file diff --git a/test/gxtdb/adapters/entity_test.clj b/test/gxtdb/adapters/entity_test.clj new file mode 100644 index 0000000..46c5fbd --- /dev/null +++ b/test/gxtdb/adapters/entity_test.clj @@ -0,0 +1,22 @@ +(ns gxtdb.adapters.entity-test + (:require [clojure.test :refer [deftest testing is]] + [gxtdb.adapters.entity :refer [entity-tx->proto]])) + +(def actual {:xt/id #xtdb/id "4e89d81a2e6fb4be2578d245fd8511c1f4ad0b58", + :xtdb.api/content-hash + #xtdb/id "9863c9ea3bb26e49759e0381db0bea848955a0db", + :xtdb.api/valid-time #inst "2023-06-16T16:23:12.448-05:00", + :xtdb.api/tx-time #inst "2023-06-16T16:23:12.448-05:00", + :xtdb.api/tx-id 1}) + +(def expected {:xt-id "4e89d81a2e6fb4be2578d245fd8511c1f4ad0b58", + :content-hash "9863c9ea3bb26e49759e0381db0bea848955a0db", + :valid-time "2023-06-16T16:23:12.448-05:00", + :tx-time "2023-06-16T16:23:12.448-05:00", + :tx-id 1}) + +(deftest entity-tx->proto-test + (testing "entity tx response map correctly parses to proto response" + (is (= (:xt-id expected) (-> actual entity-tx->proto :xt-id))) + (is (= (:content-hash expected) (-> actual entity-tx->proto :content-hash))) + (is (= (:tx-id expected) (-> actual entity-tx->proto :tx-id))))) \ No newline at end of file diff --git a/test/gxtdb/service_test.clj b/test/gxtdb/service_test.clj index 8c3c740..ee777c1 100644 --- a/test/gxtdb/service_test.clj +++ b/test/gxtdb/service_test.clj @@ -1,17 +1,18 @@ (ns gxtdb.service-test - (:require [clojure.test :refer [deftest testing is use-fixtures]] + (:require [clojure.test :refer [deftest is testing use-fixtures]] [com.xtdb.protos.GrpcApi.client :as client] + [gxtdb.service :as service] + [gxtdb.utils :as utils :refer [->inst]] [io.pedestal.http :as pedestal] [protojure.grpc.client.providers.http2 :refer [connect]] [protojure.pedestal.core :as protojure.pedestal] - [xtdb.api :as xt] - [gxtdb.service :as service] - [gxtdb.utils :as utils])) + [xtdb.api :as xt])) ;; Setup. (def ^:dynamic *opts* {}) +(def node (xt/start-node *opts*)) -(def xtdb-server (service/grpc-routes (xt/start-node *opts*))) +(defonce xtdb-server (service/grpc-routes node)) (def test-env (atom {})) @@ -78,3 +79,16 @@ (is (>= (:tx-id tx) 0))))) + +(deftest entity-tx-test + (testing "query of entity tx status after a simple put - no open snapshot" + (let [connected @(connect {:uri (str "http://localhost:" (:port @test-env))}) + put_tx @(client/SubmitTx + connected + {:tx-ops [{:transaction-type + {:put {:id-type :string, :xt-id "id1", :document {:fields {"key" {:kind {:string-value "value"}}}}}}}]}) + _await (xt/await-tx node {:xtdb.api/tx-id (:tx-id put_tx), :xtdb.api/tx-time (-> put_tx :tx-time ->inst)}) + e-tx @(client/EntityTx + connected + {:id-type :string :entity-id "id1" :open-snapshot false :valid-time {:value {:none {}}} :tx-time {:value {:none {}}} :tx-id {:value {:none {}}}})] + (is (= '(:xt-id :content-hash :valid-time :tx-time :tx-id) (keys e-tx))))))