1/* 2 * Copyright 2019 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17syntax = "proto3"; 18 19package androidx.sqlite.inspection; 20 21option java_package = "androidx.sqlite.inspection"; 22option java_outer_classname = "SqliteInspectorProtocol"; 23 24// --- Commands --- 25 26// Generic Command object grouping all Inspector Command types. Expected in 27// Inspector's onReceiveCommand. 28message Command { 29 // Wrapped specialised Command. 30 oneof OneOf { 31 TrackDatabasesCommand track_databases = 1; 32 GetSchemaCommand get_schema = 2; 33 QueryCommand query = 3; 34 KeepDatabasesOpenCommand keep_databases_open = 4; 35 AcquireDatabaseLockCommand acquire_database_lock = 5; 36 ReleaseDatabaseLockCommand release_database_lock = 6; 37 } 38} 39 40// Request for the Inspector to track database connections (existing and new) 41// and notify of those via DatabaseOpenedEvent objects. 42message TrackDatabasesCommand {} 43 44// Request for the Inspector to return schema information for a given database. 45message GetSchemaCommand { 46 // Id uniquely identifying a connection to the database. 47 int32 database_id = 1; 48} 49 50// Request for the Inspector to execute a query and return its results. 51// TODO: add support for parameterised queries 52message QueryCommand { 53 // Id uniquely identifying a connection to the database. 54 int32 database_id = 1; 55 // Query to execute. 56 string query = 2; 57 // The query may include ?s, which will be replaced by values from 58 // query_parameters, in the order that they appear in the query. Values will 59 // be bound as Strings. 60 repeated QueryParameterValue query_parameter_values = 3; 61 // Approximate response size limit in bytes. 62 // Best effort: 63 // - can deviate from the value up to 40% due to encoding overheads 64 // - in some cases can deviate by an extra ~2MB (max size of one row in Android SQLite) 65 // When unset, or set to <= `0`, it is considered unbounded. 66 int64 response_size_limit_hint = 4; 67} 68 69// Value of a parameter in QueryCommand. Currently only string and null values 70// are supported. 71message QueryParameterValue { 72 oneof OneOf { 73 string string_value = 1; 74 } 75} 76 77// Request to prevent databases from being closed by the app 78// (allowing for a larger time-window for inspection) 79message KeepDatabasesOpenCommand { 80 // True to enable the functionality; false to disable 81 bool set_enabled = 1; 82} 83 84// Request to lock a database to prevent modifications on it 85// (allowing for e.g. creating a consistent snapshot) 86message AcquireDatabaseLockCommand { 87 // Database to secure a lock on 88 int32 database_id = 1; 89} 90 91// Request to release a previously acquired database lock (see AcquireDatabaseLockCommand) 92message ReleaseDatabaseLockCommand { 93 // Id of the lock to release (see AcquireDatabaseLockResponse) 94 int32 lock_id = 1; 95} 96 97// --- Responses --- 98 99// Generic Response object grouping all Inspector Response types to Command 100// objects. 101message Response { 102 // Wrapped specialised Response. 103 oneof OneOf { 104 TrackDatabasesResponse track_databases = 1; 105 GetSchemaResponse get_schema = 2; 106 QueryResponse query = 3; 107 KeepDatabasesOpenResponse keep_databases_open = 4; 108 AcquireDatabaseLockResponse acquire_database_lock = 5; 109 ReleaseDatabaseLockResponse release_database_lock = 6; 110 ErrorOccurredResponse error_occurred = 400; 111 } 112} 113 114// Object expected as a response to TrackDatabasesCommand. 115message TrackDatabasesResponse {} 116 117// Object expected as a response to GetSchemaCommand. 118message GetSchemaResponse { 119 repeated Table tables = 1; 120} 121 122// Schema information for a table or a view. 123message Table { 124 string name = 1; 125 // True for a view; false for a regular table. 126 bool is_view = 2; 127 repeated Column columns = 3; 128} 129 130// Schema information for a table column. 131message Column { 132 string name = 1; 133 // Column type affinity. 134 string type = 2; 135 // PRIMARY KEY constraint: zero for columns that are not part of the primary 136 // key, or the index of the column in the primary key for columns that are 137 // part of the primary key. 138 int32 primary_key = 3; 139 // NOT NULL constraint. 140 bool is_not_null = 4; 141 // UNIQUE constraint on its own (i.e. not as a part of 142 // compound-unique-constraint-index). 143 bool is_unique = 5; 144} 145 146// Object expected as a response to QueryCommand. 147message QueryResponse { 148 repeated Row rows = 1; 149 // Names of columns in the result set 150 repeated string column_names = 2; 151} 152 153// Query result row. 154message Row { 155 repeated CellValue values = 1; 156} 157 158// Query result cell. 159message CellValue { 160 // Resulting cell value depending on type affinity rules. 161 oneof OneOf { 162 double double_value = 1; 163 int64 long_value = 2; 164 string string_value = 3; 165 bytes blob_value = 4; 166 } 167} 168 169message KeepDatabasesOpenResponse {} 170 171// Object expected as a response to AcquireDatabaseLockCommand. 172message AcquireDatabaseLockResponse { 173 // Id of the lock (allowing for releasing the lock later using ReleaseDatabaseLockRequest) 174 int32 lock_id = 1; 175} 176 177// Object expected as a response to ReleaseDatabaseLockCommand. 178message ReleaseDatabaseLockResponse {} 179 180// General Error message. 181// TODO: decide on a more fine-grained approach 182message ErrorOccurredResponse { 183 ErrorContent content = 1; 184} 185 186message ErrorContent { 187 // Main error message. 188 string message = 1; 189 // Optional stack trace. 190 string stack_trace = 2; 191 // Recoverability information 192 ErrorRecoverability recoverability = 3; 193 // Error code 194 enum ErrorCode { 195 NOT_SET = 0; 196 ERROR_UNKNOWN = 10; 197 ERROR_UNRECOGNISED_COMMAND = 20; 198 ERROR_DATABASE_VERSION_TOO_OLD = 30; 199 ERROR_ISSUE_WITH_PROCESSING_QUERY = 40; 200 ERROR_NO_OPEN_DATABASE_WITH_REQUESTED_ID = 50; 201 ERROR_ISSUE_WITH_PROCESSING_NEW_DATABASE_CONNECTION = 60; 202 ERROR_DB_CLOSED_DURING_OPERATION = 70; 203 ERROR_ISSUE_WITH_LOCKING_DATABASE = 80; 204 } 205 ErrorCode error_code = 4; 206} 207 208// Recoverability of an error: 209// - is_recoverable = true -> an error is recoverable (e.g. query syntax error) 210// - is_recoverable = false -> an error is not recoverable (e.g. corrupt internal inspector state) 211// - unset -> not enough information to determine recoverability (e.g. an issue that may or may not 212// prevent a user from continuing the session - and is left for the user to decide how to act on) 213message ErrorRecoverability { 214 oneof OneOf { 215 bool is_recoverable = 1; 216 } 217} 218 219// --- Events --- 220 221// Generic Event object grouping all Inspector Event types. Expected in 222// Connection's sendEvent method. 223message Event { 224 // Wrapped specialised Event. 225 oneof OneOf { 226 DatabaseOpenedEvent database_opened = 1; 227 DatabaseClosedEvent database_closed = 2; 228 DatabasePossiblyChangedEvent database_possibly_changed = 3; 229 ErrorOccurredEvent error_occurred = 400; 230 } 231} 232 233// Notification of a database connection established (new) / discovered 234// (existing). 235message DatabaseOpenedEvent { 236 // Id uniquely identifying a connection to a database. Required to perform 237 // requests on the database. 238 int32 database_id = 1; 239 // Path to db file or ":memory" if it is in-memory database. 240 // Note: there is no guarantee that it is necessarily unique between databases. 241 string path = 2; 242} 243 244// Notification of a database connection closed (database no longer query-able) 245// TODO: consider consolidating with DatabaseOpenedEvent 246message DatabaseClosedEvent { 247 // Id uniquely identifying a connection to a database. Required to perform 248 // requests on the database. 249 int32 database_id = 1; 250 // Path to db file or ":memory" if it is in-memory database. 251 // Note: there is no guarantee that it is necessarily unique between databases. 252 string path = 2; 253} 254 255// An event sent when an operation that could potentially change the contents of a database has 256// been detected. The event might be used in triggering a refresh of currently displayed query 257// results to keep the results current. 258message DatabasePossiblyChangedEvent { 259 // TODO: add database id 260} 261 262// General Error message. 263// TODO: decide on a more fine-grained approach 264message ErrorOccurredEvent { 265 ErrorContent content = 1; 266} 267