Bläddra i källkod

feat: US-002 - Protocol Buffer Definitions for gRPC

Add comprehensive gRPC service definitions for database communication:

- DocumentService: CRUD operations (create, get, update, delete, batch)
- CollectionService: collection management (create, drop, list, metadata, indexes)
- QueryService: querying with filters, sorting, pagination, aggregations
- SubscriptionService: streaming document and collection changes
- AdminService: snapshots, encryption config, database stats

CMake updated to generate C++ bindings from the new proto file.
Fszontagh 6 månader sedan
förälder
incheckning
7452f839ad
2 ändrade filer med 569 tillägg och 0 borttagningar
  1. 1 0
      proto/CMakeLists.txt
  2. 568 0
      proto/proto/database.proto

+ 1 - 0
proto/CMakeLists.txt

@@ -14,6 +14,7 @@ file(MAKE_DIRECTORY ${PROTO_GEN_DIR})
 # Proto source files
 set(PROTO_FILES
     ${PROTO_DIR}/crm.proto
+    ${PROTO_DIR}/database.proto
 )
 
 # Generate C++ sources from proto files

+ 568 - 0
proto/proto/database.proto

@@ -0,0 +1,568 @@
+syntax = "proto3";
+
+package smartbotic.database;
+
+option cc_enable_arenas = true;
+
+// ============================================================================
+// Common Types
+// ============================================================================
+
+message Empty {}
+
+message Timestamp {
+    int64 seconds = 1;
+    int32 nanos = 2;
+}
+
+// Document value types for flexible schema storage
+message Value {
+    oneof kind {
+        bool null_value = 1;
+        bool bool_value = 2;
+        int64 int_value = 3;
+        double double_value = 4;
+        string string_value = 5;
+        bytes bytes_value = 6;
+        Timestamp timestamp_value = 7;
+        ArrayValue array_value = 8;
+        MapValue map_value = 9;
+    }
+}
+
+message ArrayValue {
+    repeated Value values = 1;
+}
+
+message MapValue {
+    map<string, Value> fields = 1;
+}
+
+// ============================================================================
+// Document Types
+// ============================================================================
+
+message Document {
+    string id = 1;
+    string collection = 2;
+    MapValue data = 3;
+    Timestamp created_at = 4;
+    Timestamp updated_at = 5;
+    int64 version = 6;
+}
+
+message DocumentMetadata {
+    string id = 1;
+    string collection = 2;
+    Timestamp created_at = 3;
+    Timestamp updated_at = 4;
+    int64 version = 5;
+    int64 size_bytes = 6;
+}
+
+// ============================================================================
+// DocumentService - CRUD Operations
+// ============================================================================
+
+message CreateDocumentRequest {
+    string collection = 1;
+    string id = 2;  // Optional; auto-generated if empty
+    MapValue data = 3;
+}
+
+message GetDocumentRequest {
+    string collection = 1;
+    string id = 2;
+}
+
+message UpdateDocumentRequest {
+    string collection = 1;
+    string id = 2;
+    MapValue data = 3;
+    bool merge = 4;  // If true, merge with existing data; if false, replace entirely
+    int64 expected_version = 5;  // For optimistic locking; 0 means no version check
+}
+
+message DeleteDocumentRequest {
+    string collection = 1;
+    string id = 2;
+    int64 expected_version = 3;  // For optimistic locking; 0 means no version check
+}
+
+message DeleteDocumentResponse {
+    bool deleted = 1;
+}
+
+message BatchGetDocumentsRequest {
+    string collection = 1;
+    repeated string ids = 2;
+}
+
+message BatchGetDocumentsResponse {
+    repeated Document documents = 1;
+    repeated string missing_ids = 2;
+}
+
+message BatchWriteRequest {
+    repeated WriteOperation operations = 1;
+    bool atomic = 2;  // If true, all operations succeed or fail together
+}
+
+message WriteOperation {
+    oneof operation {
+        CreateDocumentRequest create = 1;
+        UpdateDocumentRequest update = 2;
+        DeleteDocumentRequest delete = 3;
+    }
+}
+
+message BatchWriteResponse {
+    repeated WriteResult results = 1;
+}
+
+message WriteResult {
+    bool success = 1;
+    string error_message = 2;
+    Document document = 3;  // Present for create/update operations
+}
+
+service DocumentService {
+    // Create a new document
+    rpc CreateDocument(CreateDocumentRequest) returns (Document);
+
+    // Get a document by ID
+    rpc GetDocument(GetDocumentRequest) returns (Document);
+
+    // Update an existing document
+    rpc UpdateDocument(UpdateDocumentRequest) returns (Document);
+
+    // Delete a document
+    rpc DeleteDocument(DeleteDocumentRequest) returns (DeleteDocumentResponse);
+
+    // Get multiple documents in a single request
+    rpc BatchGetDocuments(BatchGetDocumentsRequest) returns (BatchGetDocumentsResponse);
+
+    // Perform multiple write operations in a single request
+    rpc BatchWrite(BatchWriteRequest) returns (BatchWriteResponse);
+}
+
+// ============================================================================
+// CollectionService - Collection Management
+// ============================================================================
+
+message CollectionMetadata {
+    string name = 1;
+    int64 document_count = 2;
+    int64 size_bytes = 3;
+    Timestamp created_at = 4;
+    Timestamp updated_at = 5;
+    repeated IndexInfo indexes = 6;
+}
+
+message IndexInfo {
+    string name = 1;
+    repeated string fields = 2;
+    bool unique = 3;
+    IndexType type = 4;
+}
+
+enum IndexType {
+    INDEX_TYPE_UNSPECIFIED = 0;
+    INDEX_TYPE_BTREE = 1;
+    INDEX_TYPE_HASH = 2;
+    INDEX_TYPE_FULLTEXT = 3;
+}
+
+message CreateCollectionRequest {
+    string name = 1;
+    repeated CreateIndexRequest indexes = 2;  // Optional initial indexes
+}
+
+message CreateIndexRequest {
+    string collection = 1;
+    string index_name = 2;
+    repeated string fields = 3;
+    bool unique = 4;
+    IndexType type = 5;
+}
+
+message DropCollectionRequest {
+    string name = 1;
+    bool force = 2;  // If true, drop even if collection is not empty
+}
+
+message DropCollectionResponse {
+    bool dropped = 1;
+}
+
+message ListCollectionsRequest {
+    int32 page_size = 1;
+    string page_token = 2;
+}
+
+message ListCollectionsResponse {
+    repeated CollectionMetadata collections = 1;
+    string next_page_token = 2;
+}
+
+message GetCollectionMetadataRequest {
+    string name = 1;
+}
+
+message DropIndexRequest {
+    string collection = 1;
+    string index_name = 2;
+}
+
+message DropIndexResponse {
+    bool dropped = 1;
+}
+
+message ListIndexesRequest {
+    string collection = 1;
+}
+
+message ListIndexesResponse {
+    repeated IndexInfo indexes = 1;
+}
+
+service CollectionService {
+    // Create a new collection
+    rpc CreateCollection(CreateCollectionRequest) returns (CollectionMetadata);
+
+    // Drop an existing collection
+    rpc DropCollection(DropCollectionRequest) returns (DropCollectionResponse);
+
+    // List all collections
+    rpc ListCollections(ListCollectionsRequest) returns (ListCollectionsResponse);
+
+    // Get metadata for a specific collection
+    rpc GetCollectionMetadata(GetCollectionMetadataRequest) returns (CollectionMetadata);
+
+    // Create an index on a collection
+    rpc CreateIndex(CreateIndexRequest) returns (IndexInfo);
+
+    // Drop an index from a collection
+    rpc DropIndex(DropIndexRequest) returns (DropIndexResponse);
+
+    // List all indexes for a collection
+    rpc ListIndexes(ListIndexesRequest) returns (ListIndexesResponse);
+}
+
+// ============================================================================
+// QueryService - Find, Filter, Paginate
+// ============================================================================
+
+message QueryRequest {
+    string collection = 1;
+    Filter filter = 2;
+    repeated OrderBy order_by = 3;
+    int32 limit = 4;
+    int32 offset = 5;
+    string page_token = 6;  // For cursor-based pagination
+    repeated string select_fields = 7;  // Empty means all fields
+}
+
+message Filter {
+    oneof filter_type {
+        FieldFilter field = 1;
+        CompositeFilter composite = 2;
+    }
+}
+
+message FieldFilter {
+    string field = 1;
+    FilterOperator operator = 2;
+    Value value = 3;
+}
+
+enum FilterOperator {
+    FILTER_OPERATOR_UNSPECIFIED = 0;
+    FILTER_OPERATOR_EQUAL = 1;
+    FILTER_OPERATOR_NOT_EQUAL = 2;
+    FILTER_OPERATOR_LESS_THAN = 3;
+    FILTER_OPERATOR_LESS_THAN_OR_EQUAL = 4;
+    FILTER_OPERATOR_GREATER_THAN = 5;
+    FILTER_OPERATOR_GREATER_THAN_OR_EQUAL = 6;
+    FILTER_OPERATOR_IN = 7;
+    FILTER_OPERATOR_NOT_IN = 8;
+    FILTER_OPERATOR_CONTAINS = 9;
+    FILTER_OPERATOR_STARTS_WITH = 10;
+    FILTER_OPERATOR_ENDS_WITH = 11;
+    FILTER_OPERATOR_IS_NULL = 12;
+    FILTER_OPERATOR_IS_NOT_NULL = 13;
+}
+
+message CompositeFilter {
+    CompositeOperator operator = 1;
+    repeated Filter filters = 2;
+}
+
+enum CompositeOperator {
+    COMPOSITE_OPERATOR_UNSPECIFIED = 0;
+    COMPOSITE_OPERATOR_AND = 1;
+    COMPOSITE_OPERATOR_OR = 2;
+}
+
+message OrderBy {
+    string field = 1;
+    SortDirection direction = 2;
+}
+
+enum SortDirection {
+    SORT_DIRECTION_UNSPECIFIED = 0;
+    SORT_DIRECTION_ASCENDING = 1;
+    SORT_DIRECTION_DESCENDING = 2;
+}
+
+message QueryResponse {
+    repeated Document documents = 1;
+    string next_page_token = 2;
+    int64 total_count = 3;  // Total matching documents (may be expensive, set -1 if not computed)
+}
+
+message AggregateRequest {
+    string collection = 1;
+    Filter filter = 2;
+    repeated Aggregation aggregations = 3;
+    repeated string group_by = 4;
+}
+
+message Aggregation {
+    string alias = 1;  // Name for the result
+    AggregationType type = 2;
+    string field = 3;  // Field to aggregate (not needed for COUNT)
+}
+
+enum AggregationType {
+    AGGREGATION_TYPE_UNSPECIFIED = 0;
+    AGGREGATION_TYPE_COUNT = 1;
+    AGGREGATION_TYPE_SUM = 2;
+    AGGREGATION_TYPE_AVG = 3;
+    AGGREGATION_TYPE_MIN = 4;
+    AGGREGATION_TYPE_MAX = 5;
+}
+
+message AggregateResponse {
+    repeated AggregateResult results = 1;
+}
+
+message AggregateResult {
+    MapValue group_key = 1;  // Values of group_by fields
+    map<string, Value> aggregations = 2;  // alias -> aggregated value
+}
+
+message CountRequest {
+    string collection = 1;
+    Filter filter = 2;
+}
+
+message CountResponse {
+    int64 count = 1;
+}
+
+service QueryService {
+    // Execute a query with filtering, sorting, and pagination
+    rpc Query(QueryRequest) returns (QueryResponse);
+
+    // Stream query results for large result sets
+    rpc QueryStream(QueryRequest) returns (stream Document);
+
+    // Perform aggregations on documents
+    rpc Aggregate(AggregateRequest) returns (AggregateResponse);
+
+    // Count documents matching a filter
+    rpc Count(CountRequest) returns (CountResponse);
+}
+
+// ============================================================================
+// SubscriptionService - Streaming Document Changes
+// ============================================================================
+
+message SubscribeRequest {
+    string collection = 1;
+    Filter filter = 2;  // Optional filter for documents to watch
+    repeated string document_ids = 3;  // Specific document IDs to watch (alternative to filter)
+    bool include_initial = 4;  // If true, send current state before streaming changes
+}
+
+message DocumentChange {
+    ChangeType type = 1;
+    Document document = 2;
+    Document old_document = 3;  // Present for UPDATE changes
+    Timestamp change_time = 4;
+}
+
+enum ChangeType {
+    CHANGE_TYPE_UNSPECIFIED = 0;
+    CHANGE_TYPE_ADDED = 1;
+    CHANGE_TYPE_MODIFIED = 2;
+    CHANGE_TYPE_REMOVED = 3;
+}
+
+message SubscribeCollectionRequest {
+    bool include_initial = 1;  // If true, send current collections before streaming changes
+}
+
+message CollectionChange {
+    ChangeType type = 1;
+    CollectionMetadata collection = 2;
+    Timestamp change_time = 3;
+}
+
+service SubscriptionService {
+    // Subscribe to document changes in a collection
+    rpc Subscribe(SubscribeRequest) returns (stream DocumentChange);
+
+    // Subscribe to collection-level changes (create/drop)
+    rpc SubscribeCollections(SubscribeCollectionRequest) returns (stream CollectionChange);
+}
+
+// ============================================================================
+// AdminService - Snapshots and Encryption Configuration
+// ============================================================================
+
+message CreateSnapshotRequest {
+    string name = 1;  // Optional; auto-generated if empty
+    string description = 2;
+    repeated string collections = 3;  // Empty means all collections
+}
+
+message SnapshotMetadata {
+    string id = 1;
+    string name = 2;
+    string description = 3;
+    Timestamp created_at = 4;
+    int64 size_bytes = 5;
+    repeated string collections = 6;
+    SnapshotStatus status = 7;
+}
+
+enum SnapshotStatus {
+    SNAPSHOT_STATUS_UNSPECIFIED = 0;
+    SNAPSHOT_STATUS_CREATING = 1;
+    SNAPSHOT_STATUS_READY = 2;
+    SNAPSHOT_STATUS_FAILED = 3;
+    SNAPSHOT_STATUS_RESTORING = 4;
+}
+
+message ListSnapshotsRequest {
+    int32 page_size = 1;
+    string page_token = 2;
+}
+
+message ListSnapshotsResponse {
+    repeated SnapshotMetadata snapshots = 1;
+    string next_page_token = 2;
+}
+
+message GetSnapshotRequest {
+    string id = 1;
+}
+
+message DeleteSnapshotRequest {
+    string id = 1;
+}
+
+message DeleteSnapshotResponse {
+    bool deleted = 1;
+}
+
+message RestoreSnapshotRequest {
+    string snapshot_id = 1;
+    repeated string collections = 2;  // Empty means restore all collections in snapshot
+    bool drop_existing = 3;  // If true, drop existing collections before restore
+}
+
+message RestoreSnapshotResponse {
+    bool success = 1;
+    repeated string restored_collections = 2;
+    string error_message = 3;
+}
+
+message ExportSnapshotRequest {
+    string snapshot_id = 1;
+    string destination_path = 2;
+}
+
+message ExportSnapshotResponse {
+    bool success = 1;
+    string file_path = 2;
+    int64 size_bytes = 3;
+}
+
+message ImportSnapshotRequest {
+    string source_path = 1;
+    string name = 2;  // Optional name for imported snapshot
+}
+
+message EncryptionConfig {
+    bool enabled = 1;
+    EncryptionAlgorithm algorithm = 2;
+    string key_id = 3;  // Reference to the encryption key
+    Timestamp key_created_at = 4;
+    Timestamp key_rotated_at = 5;
+}
+
+enum EncryptionAlgorithm {
+    ENCRYPTION_ALGORITHM_UNSPECIFIED = 0;
+    ENCRYPTION_ALGORITHM_AES_256_GCM = 1;
+    ENCRYPTION_ALGORITHM_CHACHA20_POLY1305 = 2;
+}
+
+message GetEncryptionConfigRequest {}
+
+message SetEncryptionConfigRequest {
+    bool enabled = 1;
+    EncryptionAlgorithm algorithm = 2;
+}
+
+message RotateEncryptionKeyRequest {
+    bool reencrypt_data = 1;  // If true, re-encrypt all existing data with new key
+}
+
+message RotateEncryptionKeyResponse {
+    string new_key_id = 1;
+    bool reencryption_started = 2;
+}
+
+message DatabaseStats {
+    int64 total_collections = 1;
+    int64 total_documents = 2;
+    int64 total_size_bytes = 3;
+    int64 index_size_bytes = 4;
+    Timestamp last_snapshot_at = 5;
+    Timestamp started_at = 6;
+    int64 uptime_seconds = 7;
+}
+
+message GetDatabaseStatsRequest {}
+
+message CompactDatabaseRequest {
+    repeated string collections = 1;  // Empty means all collections
+}
+
+message CompactDatabaseResponse {
+    int64 bytes_reclaimed = 1;
+    int64 duration_ms = 2;
+}
+
+service AdminService {
+    // Snapshot management
+    rpc CreateSnapshot(CreateSnapshotRequest) returns (SnapshotMetadata);
+    rpc ListSnapshots(ListSnapshotsRequest) returns (ListSnapshotsResponse);
+    rpc GetSnapshot(GetSnapshotRequest) returns (SnapshotMetadata);
+    rpc DeleteSnapshot(DeleteSnapshotRequest) returns (DeleteSnapshotResponse);
+    rpc RestoreSnapshot(RestoreSnapshotRequest) returns (RestoreSnapshotResponse);
+    rpc ExportSnapshot(ExportSnapshotRequest) returns (ExportSnapshotResponse);
+    rpc ImportSnapshot(ImportSnapshotRequest) returns (SnapshotMetadata);
+
+    // Encryption configuration
+    rpc GetEncryptionConfig(GetEncryptionConfigRequest) returns (EncryptionConfig);
+    rpc SetEncryptionConfig(SetEncryptionConfigRequest) returns (EncryptionConfig);
+    rpc RotateEncryptionKey(RotateEncryptionKeyRequest) returns (RotateEncryptionKeyResponse);
+
+    // Database administration
+    rpc GetDatabaseStats(GetDatabaseStatsRequest) returns (DatabaseStats);
+    rpc CompactDatabase(CompactDatabaseRequest) returns (CompactDatabaseResponse);
+}